sigildocs

(sigil process)

(sigil process) - Process Management Library

Process management operations including spawning subprocesses, environment variable access, and command execution. Native functions are implemented in C with higher-level utilities defined here.

Running Commands

(import (sigil process))

;; Run and wait for completion
(process-run "ls" "-l")

;; Capture output as string
(process-output->string "date")  ; => "Thu Jan 15 14:30:00 2025"

;; Capture output as lines
(process-lines "ls")  ; => ("file1" "file2" ...)

Spawning Processes

(let ((p (process-spawn "cat")))
  (display "Hello\n" (process-stdin p))
  (close-output-port (process-stdin p))
  (display (read-line (process-stdout p)))
  (process-wait p))

Environment

(getenv "HOME")      ; => "/home/user"
(setenv! "MY_VAR" "value")

Exports

process-runprocedure

Run a command and wait for it to complete.

Returns the exit status (0 for success; 128+N when the child died from signal N). Raises an io-error when the process cannot be started or waited on (for example, fork failing under process pressure) -- it never returns a non-integer.

(process-run "ls" "-l")  ; => 0
process-spawnprocedure

Spawn a subprocess without waiting.

Returns a process object, or #f if the process cannot be started. Use process-wait to wait for completion and retrieve the exit status.

With die-with-parent: #t, the child is killed automatically when this (parent) process dies, even on an uncatchable SIGKILL. On Linux this uses PR_SET_PDEATHSIG; on other platforms it is a no-op.

(let ((p (process-spawn "sleep" "10")))
  (process-kill! p))

;; Child dies on its own if this process is killed:
(process-spawn "my-worker" "--serve" die-with-parent: #t)

Spawn a subprocess on a pseudo-terminal (Unix only).

Allocates a pty, forks, and runs the command as a session leader with the pty slave as its controlling terminal wired to stdin/stdout/stderr. All fork discipline is handled in C; do not attempt fork or forkpty from Scheme.

Returns a process object whose I/O rides the pty MASTER, not pipes: use process-pty-read / process-pty-write (guarded by await-readable-fd / await-writable-fd on process-pty-fd in async code), NOT process-stdout / process-stdin.

The master fd is non-blocking. process-pty-read returns an empty bytevector when no data is ready and an eof-object once the child exited and the stream drained. cwd: sets the child's working directory; term: sets its TERM (default "xterm-256color"; pass #f to inherit).

(let ((p (process-spawn-pty "sh" cols: 120 rows: 40)))
  (process-pty-write p "ls\n")
  ...
  (process-pty-close! p)
  (process-wait p))

Spawn a subprocess on non-blocking pipes for a stream session (Unix only).

The pipe analog of process-spawn-pty, for a child that speaks a line/byte protocol over stdin/stdout rather than a terminal — e.g. tmux -C, which hard-fails on a tty. stdin and stdout are NON-BLOCKING pipes; the child's stderr is inherited (not captured), keeping the stdout stream clean for a strict control protocol.

Returns a process object whose I/O rides raw pipe fds: use process-pipe-read / process-pipe-write (guarded by await-readable-fd / await-writable-fd on process-stdout-fd / process-stdin-fd), NOT process-stdout / process-stdin. process-pipe-read returns an empty bytevector when no data is ready and an eof-object once the child closes stdout. cwd: sets the child's working directory.

(let ((p (process-spawn-pipe "tmux" "-C" "new-session")))
  (process-pipe-write p "list-sessions\n")
  ...
  (process-pipe-close-stdin! p)
  (process-wait p))

Send a signal to a spawned process.

Accepts a signal name symbol ('hup 'int 'quit 'kill 'usr1 'usr2 'term 'cont 'stop 'tstp 'winch) or a raw signal number. For pty-spawned processes the signal goes to the child's whole process group (the child is a session leader), matching terminal semantics; plain-spawned processes are signalled individually. Returns #t if the signal was delivered.

(process-signal! p 'int)   ; like Ctrl-C
(process-signal! p 'term)
process-waitprocedure

Wait for a process to complete.

Returns the exit status.

(process-wait p)  ; => 0
process-kill!procedure

Kill a running process.

(process-kill! p)
process?procedure

Check if a value is a process object.

process-pty?procedure

Check if a process was spawned with a pty (via process-spawn-pty).

Get the raw pty master file descriptor of a pty-spawned process.

Feed this to await-readable-fd / await-writable-fd from (sigil async) before calling process-pty-read / process-pty-write so the single-threaded VM never blocks.

Read available bytes from the pty master.

Returns a bytevector (EMPTY when no data is ready — the fd is non-blocking) or an eof-object once the child exited and the stream is drained. Optional second argument caps the read size (default 4096).

Write a string or bytevector to the pty master (child input).

Returns the number of bytes actually written; may be 0 (kernel buffer full) or partial. Await writability and retry with the remainder.

Set the pty window size. The kernel delivers SIGWINCH to the child's foreground process group automatically.

Close the pty master fd (idempotent). A still-running child sees terminal hangup.

Get the raw stdout (read) pipe fd of a pipe-spawned process.

Feed this to await-readable-fd from (sigil async) before calling process-pipe-read so the single-threaded VM never blocks. The fd is non-blocking.

Get the raw stdin (write) pipe fd of a pipe-spawned process.

Feed this to await-writable-fd from (sigil async) before calling process-pipe-write. The fd is non-blocking.

Read available bytes from the child's stdout pipe.

Returns a bytevector (EMPTY when no data is ready — the fd is non-blocking) or an eof-object once the child closes its stdout. Optional second argument caps the read size (default 4096).

Write a string or bytevector to the child's stdin pipe.

Returns the number of bytes actually written; may be 0 (kernel buffer full) or partial. Await writability and retry with the remainder. Raises an io-error if the child has closed its stdin.

Close the child's stdin pipe (idempotent), delivering EOF to the child.

process-pidprocedure

Get the OS process id of a spawned process.

Check if a process is still running.

(process-alive? p)  ; => #t or #f
process-stdinprocedure

Get the stdin port of a spawned process.

Returns an output port for writing to the process.

Get the stdout port of a spawned process.

Returns an input port for reading the process output.

Get the stderr port of a spawned process.

Returns an input port for reading error output.

getenvprocedure

Get an environment variable.

Returns the value as a string, or #f if not set.

(getenv "HOME")    ; => "/home/user"
(getenv "MISSING") ; => #f
setenv!procedure

Set an environment variable.

(setenv! "MY_VAR" "my-value")
command-lineprocedure

Get the command-line arguments.

Returns a list where the first element is the program name.

(command-line)  ; => ("./my-program" "arg1" "arg2")
exitprocedure

Exit the process with a status code.

(exit 0)  ; success
(exit 1)  ; failure
process-idprocedure

Get the current process ID.

(process-id)  ; => 12345

Check if a command exists in PATH.

(command-exists? "ls")   ; => #t
(command-exists? "foo")  ; => #f

Call a procedure with a spawned process.

The process is automatically waited for when proc returns.

(call-with-process "ls" '("-l")
  (lambda (p)
    (read-line (process-stdout p))))

Run a command and capture its stdout as a string.

Returns #f if the process cannot be started.

(process-output->string "echo" "hello")  ; => "hello"
(process-output->string "date")          ; => "Thu Jan 15..."

Read all content from a port as a string. Helper for process-output->string.

process-linesprocedure

Run a command and return its stdout as a list of lines.

Returns #f if the process cannot be started.

(process-lines "ls")           ; => ("file1" "file2" ...)
(process-lines "ls" "-la")     ; => ("total 42" "drwxr-x..." ...)

Read all lines from a port. Helper for process-lines.

(No description)

(No description)

(No description)

(No description)

process-pgidvariable

(No description)

(No description)

(No description)

(No description)

(No description)

(No description)

(No description)

(No description)

(No description)

(No description)