Fork & Exec
fork() creates a child process. In the child (pid == 0), call execvp immediately to replace the process image — the Boehm GC requires this pattern since the child inherits an inconsistent GC state. waitpid in the parent blocks until the child exits.
Code
// Fork and exec — running external commands
// Fork y exec — ejecutar comandos externos
fn main() -> int {
let pid: int = fork()
if pid == 0 {
// Child process: exec immediately (GC requirement)
let args: Array = ["echo", "hello from child"]
execvp("echo", args)
// execvp replaces the process — this line never runs
return 1
}
if pid > 0 {
// Parent: wait for child to finish
print("parent: spawned child " + int_to_string(pid))
let status: int = waitpid(pid, 0)
print("parent: child exited with " + int_to_string(status))
} else {
print("fork failed")
}
return 0
}
Output
parent: spawned child 12345 hello from child parent: child exited with 0
Explanation
fork() duplicates the current process. It returns 0 in the child and the child's PID in the parent. Because Nyx uses the Boehm garbage collector, the child process must not allocate GC-managed memory — it must call execvp() immediately to replace its process image with a new program.
execvp(command, args) replaces the current process with the given command. The first element of args is conventionally the program name. If execvp succeeds, it never returns.
waitpid(pid, 0) blocks the parent until the child exits and returns the exit status. This is the standard Unix pattern for spawning subprocesses.