A foundational subprocess management library for the Carp programming language.
carp-process provides a well-behaved synchronous runtime for spawning and managing child processes with POSIX semantics. It handles the nuances of fork/exec, pipe management, and signal-aware process waiting.
- Seeded Command Pattern: Ergonomic building of process arguments without shell-injection risks.
- Robust Redirection: Capture
stdoutandstderrseparately or combined. - Stdin Piping: Support for passing strings to a child process's standard input.
- Lifecycle Management: Structured
ExitStatusfor distinguishing normal exits from signal terminations. - Resource Hygiene: Strict use of
FD_CLOEXECand systematic descriptor cleanup to prevent leaks. - Syscall Resilience: Explicit handling of
EINTRandEPIPE.
See examples.md for usage examples.
As a synchronous systems library, users should be aware of the following architectural trade-offs:
The Process.run function drains stdout and then stderr sequentially. This can deadlock if the child process concurrently generates enough output to fill the pipe buffers for both streams.
- Guidance: For processes with high-volume or concurrent output, use
Process.run-combinedto merge streams at the OS level.
All output is read entirely into memory before the function returns.
- Guidance: Not suitable for streaming massive log files or data pipelines that exceed available RAM.
This library uses _exit in child processes to ensure async-signal safety and avoid corrupting shared runtime state after a fork. It also ignores SIGPIPE by default to rely on stable EPIPE error handling.
Run the test suite with:
carp -x test/process_test.carp(Command.new path): Create a new command.(Command.arg cmd arg): Add an argument to the command.(Command.set-stdin cmd str): Set the string to be piped to stdin.
(Process.spawn path args): Spawn a process and return a(Result Process.T String).(Process.run cmd): Run to completion, capturing streams separately (Deadlock prone for large output).(Process.run-combined cmd): Run to completion, merging stderr into stdout (Deadlock safe).(Process.wait p): Block until exit, returning a structuredExitStatus.(Process.terminate p): SendSIGTERMto the process.(Process.kill! p): SendSIGKILLto the process.
MIT