[OS]ProcessSubprocesses, on the scheduler: run: parks the calling task (other tasks keep running) until the child exits, answering a ProcessResult; start: spawns for streaming and answers this handle — read stdout/stderr like a socket, write with writeStdin:/closeStdin, wait/kill/terminate it. The command is a List (program + arguments) — there is NO shell, so nothing splits, globs, or injects. An undetached child dies with its handle (and a cancelled run: kills its child); detach opts out.
([OS]Process.run:#( 'echo' 'hi' )).stdout "* -> 'hi\n'
The ergonomic selector family over the native kitchen sinks (primRun:env:dir:input:, primStart:env:dir: — src/runtime/process.rs). One shape: run: parks until exit and answers a ProcessResult; start: answers the streaming handle.
Internal: the nil-tolerant kitchen sink behind the run: family (see run:, run:input:, run:env:, run:dir:, run:input:env:dir:), answering the raw result Map the ProcessResult wraps.
Internal: the nil-tolerant kitchen sink behind the start: family (see start:, start:env:, start:dir:, start:env:dir:).
Run a command to completion — the calling task parks (others keep running) — and answer a ProcessResult. The command is a List (program + arguments; no shell, nothing splits or globs) or a bare String (program alone).
([OS]Process.run:#( 'echo' 'hi' )).stdout "* -> 'hi\n' ([OS]Process.run:#( 'false' )).ok? "* -> false
run: with the child's working directory.
run: with String → String vars set ON TOP of the inherited environment — the sound way to give a CHILD an environment ([OS]Env itself stays read-only).
run:env: + run:dir: combined.
run: feeding the String or Bytes to the child's standard input (then EOF).
([OS]Process.run:#( 'cat' ) input:'meow').stdout "* -> 'meow'
The kitchen sink — every option, nil where unused.
Spawn for streaming and answer the Process handle: stdout/stderr(-Text) read like sockets, writeStdin:/closeStdin feed it, wait/kill/ terminate/detach manage it. An undetached child dies with its handle.
var p = [OS]Process.start:#( 'cat' ) p.writeStdin:'hi ' p.closeStdin p.stdoutText.readLine "* -> 'hi'
start: with the child's working directory.
start: with child-environment vars (see run:env:).
start:env: + start:dir: combined.
Close the child's standard input — the child sees EOF. Idempotent; answers the receiver.
Let the child outlive this handle AND the VM (neither collection nor exit kills it). Its pipes still close when the handle goes — a detached child that keeps writing gets EPIPE, so drain or redirect first. Answers the receiver.
The exit code a completed wait observed — nil before the wait, and nil for a signal-terminated child.
SIGKILL the child (unblockable). A parked wait resolves with the signal exit. A no-op once the child has exited; answers the receiver.
The operating-system process id.
Whether the child is still running — exact (a non-blocking status probe), not a pid guess.
The inspect string: the class and pid.
The signal that ended the child, per a completed wait — nil otherwise.
The child's standard error as a ByteStream — see stdout for the one-stream-per-pipe rule and the two-pipe deadlock note.
The child's standard error as a StringStream — see stdoutText.
The child's standard output as a ByteStream (like a socket's). One stream per pipe: a second take throws. Reading only stdout while the child floods stderr can deadlock on the pipe buffer — drain both (two tasks), or use run:, which does.
The child's standard output as a StringStream (readLine/eachLine:). Same one-stream-per-pipe rule as stdout.
var p = [OS]Process.start:#( 'printf' 'a\nb\n' ) p.stdoutText.readLine "* -> 'a'
SIGTERM the child — the polite kill (the child may catch it to shut down cleanly, or ignore it). Answers the receiver.
Park until the child exits (idempotent once it has); answers the exit code, or nil when a signal ended it (signal says which). One task waits at a time — a concurrent second wait throws.
Write a String (UTF-8) or Bytes to the child's standard input; answers the receiver. Finish with closeStdin — most filters read until EOF.