Fork & Exec
fork() crea un proceso hijo. En el hijo (pid == 0), hay que llamar a execvp de inmediato para reemplazar la imagen del proceso — el GC de Boehm requiere este patrón, ya que el hijo hereda un estado de GC inconsistente. waitpid en el padre bloquea hasta que el hijo termina.
Código
// 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
}
Salida
parent: spawned child 12345 hello from child parent: child exited with 0
Explicación
fork() duplica el proceso actual. Devuelve 0 en el hijo y el PID del hijo en el padre. Dado que Nyx usa el recolector de basura de Boehm, el proceso hijo no debe alocar memoria gestionada por el GC — debe llamar a execvp() de inmediato para reemplazar su imagen de proceso con un nuevo programa.
execvp(command, args) reemplaza el proceso actual con el comando dado. El primer elemento de args es, por convención, el nombre del programa. Si execvp tiene éxito, nunca retorna.
waitpid(pid, 0) bloquea al padre hasta que el hijo termina y devuelve el código de salida. Este es el patrón estándar de Unix para lanzar subprocesos.