Axle v0.17.0
Package

std/sys/process

std/sys/process — what a program knows about its own invocation, and
how it starts another one.

Command-line arguments, working directory, environment variables,
process identity, abnormal termination — and ProcessBuilder /
Process for a child.

Distinct from std/sys, which exposes runtime-wide constants and
primitives (clock, OS info). Normal termination is exit, declared
once in std/sys and reachable bare from the prelude; this module
does not redeclare it.

Where the platform lives. Nowhere in this file, for the two
questions that have a stable C answer: the process id is getpid on
unix and _getpid on the Windows CRT, so each is bound under
@target(…) beside the one function that calls it. Everything else
that diverges is resolved once in the runtime and reached here as one
symbol per question — argv and the environment are UTF-16 on Windows
and only the wide entry points read them without loss, so std/ffi/runtime
is what this module reads them through rather than libc's narrow view.

API shape: free functions, some auto-imported via the prelude
(argc, hasEnv, pid, parentPid), the rest reachable via
use std::sys::process::…;.

Free functions

TypeMethod and description
string
cwd() : string Absolute path of the process's current working directory.

"" when the platform will not answer — the cwd was deleted out from
under the process, or its path is not representable. Not a throws:
this is read by a diagnostic or a path join, and forcing a try/catch
around a primitive that essentially never fails would cost every call
site more than the case is worth.
void
chdir(path : string) : void Change the process's working directory to path.

The platform answers only whether it moved, so the raise says what was
asked rather than why it was refused: the reasons — no such directory,
not a directory, no permission to enter it — are not distinguished by
the call, and inventing one of them would be worse than naming none.
i32
argc() : i32 Number of command-line arguments, including the program name at index 0.
string
__argAt(index : i32) : string The argument at index, or "" when there is none or it outruns the
scratch buffer. Private: argAt is the checked form and is what
source calls, so the sentinel never reaches a caller who did not ask
for it.
string
argAt(index : i32) : string The argument at index in argv.
string
programName() : string The program name — argv[0], or "" where the platform supplied
none.

Non-throwing where argAt(0) throws: a usage banner and a diagnostic
prefix are what read it, and neither has a catch to offer.
string
getEnv(key : string) : string Read environment variable key.
bool
hasEnv(key : string) : bool True iff environment variable key is present (even if empty).
void
setEnv(key : string, value : string) : void Set environment variable key to value; inherited by child processes.

Refused once the program has created a thread, and silently: a
reader holds a pointer into the environment table and a write frees
what it replaces, with no lock either side could join. Set what a
program needs before it spawns.
void
unsetEnv(key : string) : void Remove environment variable key from this process's environment.
Refused after a thread exists, for the reason setEnv gives.
string
envOrDefault(key : string, fallback : string) : string Read environment variable key, falling back when it is unset OR set
to the empty string.

The two cases are indistinguishable through getEnv, and a caller
that wants a fallback wants it for both — which is what saves an
if (!hasEnv("X")) guard at every call site.
i32
__getProcessId() : i32 The unix spelling of this process's own id.
i32
__getParentProcessId() : i32 The unix spelling of the id of the process that started this one.
i32
__getProcessId() : i32 The Windows CRT's spelling of the same query.
i64
pid() : i64 This process's own process ID.
i64
parentPid() : i64 The parent process's ID, or 0 where the platform keeps none a
process can read.

Windows is that case: the id of the creating process lives in a
structure only the snapshot API walks, and that walk names a reused
id as readily as a live one — a parent that has exited leaves its
number to somebody else. 0 is the honest answer, not a placeholder
for one that could be looked up.
i64
parentPid() : i64 See the unix arm: this platform keeps no readable link to a parent.
void
abort() : void Abnormally terminate the process by raising SIGABRT.

Method detail

#cwd

cwd() : string

Absolute path of the process's current working directory.

"" when the platform will not answer — the cwd was deleted out from
under the process, or its path is not representable. Not a throws:
this is read by a diagnostic or a path join, and forcing a try/catch
around a primitive that essentially never fails would cost every call
site more than the case is worth.

#chdir

chdir(path : string) : void ! IOException

Change the process's working directory to path.

The platform answers only whether it moved, so the raise says what was
asked rather than why it was refused: the reasons — no such directory,
not a directory, no permission to enter it — are not distinguished by
the call, and inventing one of them would be worse than naming none.

Parameters
path target directory (absolute or relative to the current cwd).
Throws
IOException when path does not exist or is not a directory.

#argc

argc() : i32

Number of command-line arguments, including the program name at index 0.

#__argAt

__argAt(index : i32) : string

The argument at index, or "" when there is none or it outruns the
scratch buffer. Private: argAt is the checked form and is what
source calls, so the sentinel never reaches a caller who did not ask
for it.

Parameters
index position in argv; 0 is the program name

#argAt

argAt(index : i32) : string ! IndexOutOfBoundsException

The argument at index in argv.

Parameters
index position in argv; 0 is the program name.
Throws
IndexOutOfBoundsException when index is < 0 or >= argc().

#programName

programName() : string

The program name — argv[0], or "" where the platform supplied
none.

Non-throwing where argAt(0) throws: a usage banner and a diagnostic
prefix are what read it, and neither has a catch to offer.

#getEnv

getEnv(key : string) : string

Read environment variable key.

Parameters
key environment variable name to look up.
Returns its value, or "" when unset — use hasEnv to disambiguate.

#hasEnv

hasEnv(key : string) : bool

True iff environment variable key is present (even if empty).

Parameters
key environment variable name to test for existence.

#setEnv

setEnv(key : string, value : string) : void

Set environment variable key to value; inherited by child processes.

Refused once the program has created a thread, and silently: a
reader holds a pointer into the environment table and a write frees
what it replaces, with no lock either side could join. Set what a
program needs before it spawns.

Parameters
key environment variable name to assign.
value value to bind; overwrites any prior binding.

#unsetEnv

unsetEnv(key : string) : void

Remove environment variable key from this process's environment.
Refused after a thread exists, for the reason setEnv gives.

Parameters
key environment variable name to remove; a no-op when already unset.

#envOrDefault

envOrDefault(key : string, fallback : string) : string

Read environment variable key, falling back when it is unset OR set
to the empty string.

The two cases are indistinguishable through getEnv, and a caller
that wants a fallback wants it for both — which is what saves an
if (!hasEnv("X")) guard at every call site.

Parameters
key environment variable to read.
fallback value returned when key is unset or empty.

#__getProcessId

__getProcessId() : i32

The unix spelling of this process's own id.

#__getParentProcessId

__getParentProcessId() : i32

The unix spelling of the id of the process that started this one.

#__getProcessId

__getProcessId() : i32

The Windows CRT's spelling of the same query.

#pid

pid() : i64

This process's own process ID.

#parentPid

parentPid() : i64

The parent process's ID, or 0 where the platform keeps none a
process can read.

Windows is that case: the id of the creating process lives in a
structure only the snapshot API walks, and that walk names a reused
id as readily as a live one — a parent that has exited leaves its
number to somebody else. 0 is the honest answer, not a placeholder
for one that could be looked up.

#parentPid

parentPid() : i64

See the unix arm: this platform keeps no readable link to a parent.

#abort

abort() : void

Abnormally terminate the process by raising SIGABRT.

C class ProcessBuilder

Pattern: build the command with ProcessBuilder, call
start() to spawn, then drive the child through Process.
stdout/stderr are captured by default; the user reads them
after waitFor() returns. The program is named to the constructor and
every further argv entry is one addArg(arg), because Axle marshals no
array of strings across the FFI boundary.

Constructors

TypeMethod and description
constructor(command : string) Begin building a command.

Method detail

#constructor

constructor(command : string)

Begin building a command.

Parameters
command the program to run (looked up via $PATH if not a path).

Methods

Method detail

#addArg

addArg(self, arg : string) : ProcessBuilder

#setDirectory

setDirectory(self, dir : string) : ProcessBuilder

#setEnv

setEnv(self, key : string, value : string) : ProcessBuilder

#inheritIO

inheritIO(self) : ProcessBuilder

#start

start(self) : Process ! IOException

C class Process

A spawned child process. Drive it through waitFor() /
isAlive() / destroy(); once it has exited, read the captured
getStdout() / getStderr() and its exitValue().

Methods

TypeMethod and description
i32
waitFor(self) : i32 Wait until the child exits. A task parks and its carrier keeps running
the tasks that share it. A second waitFor from another task waits for
the first to record the status and answers the same one.
i32
exitValue(self) : i32
bool
isAlive(self) : bool
void
destroy(self) : void
i64
pid(self) : i64
string
getStdout(self) : string
string
getStderr(self) : string
void
close(self) : void close() aliases destroy() so a try-resources binding can clean
up a child process on scope exit. Pure Axle over destroy: the
two are the same act, and one of them being a second FFI symbol
would be a second place for that to stop being true.

Method detail

#waitFor

waitFor(self) : i32

Wait until the child exits. A task parks and its carrier keeps running
the tasks that share it. A second waitFor from another task waits for
the first to record the status and answers the same one.

Returns the child's exit status.

#exitValue

exitValue(self) : i32

#isAlive

isAlive(self) : bool

#destroy

destroy(self) : void

#pid

pid(self) : i64

#getStdout

getStdout(self) : string

#getStderr

getStderr(self) : string

#close

close(self) : void ! IOException

close() aliases destroy() so a try-resources binding can clean
up a child process on scope exit. Pure Axle over destroy: the
two are the same act, and one of them being a second FFI symbol
would be a second place for that to stop being true.