Pipes
pipe_new() crea una tubería (pipe) unidireccional que devuelve [read_fd, write_fd]. Combinado con fork, dup2 y execvp, esto permite capturar la salida de un comando externo — el mismo mecanismo que usan las shells de Unix para el operador | (pipe).
Código
// Pipes — connecting two processes via pipe
// Pipes — conectar dos procesos via pipe
fn main() -> int {
// pipe_new() returns [read_fd, write_fd]
let fds: Array = pipe_new()
let read_fd: int = fds[0]
let write_fd: int = fds[1]
let pid: int = fork()
if pid == 0 {
// Child: redirect stdout to write end of pipe
close_fd(read_fd)
dup2(write_fd, 1)
close_fd(write_fd)
// exec ls — output goes into pipe
let args: Array = ["ls", "/tmp"]
execvp("ls", args)
return 1
}
// Parent: read from pipe
close_fd(write_fd)
let output: String = tcp_read(read_fd, 4096)
close_fd(read_fd)
waitpid(pid, 0)
print("ls output (first 200 chars):")
if output.length() > 200 {
print(output.substring(0, 200))
} else {
print(output)
}
return 0
}
Salida
ls output (first 200 chars): ...
Explicación
pipe_new() crea un flujo de bytes unidireccional y devuelve un arreglo de dos descriptores de archivo: [read_fd, write_fd]. Los datos escritos en write_fd se pueden leer desde read_fd.
Después de fork(), el hijo cierra el extremo de lectura, usa dup2(write_fd, 1) para redirigir su stdout al extremo de escritura del pipe, y luego llama a execvp para ejecutar ls. La salida del hijo fluye a través del pipe en lugar de la terminal.
El padre cierra el extremo de escritura (para que las lecturas vean EOF cuando el hijo termine), lee el contenido del pipe con tcp_read, y espera al hijo con waitpid. Así es exactamente como las shells de Unix implementan el operador |.
Source: examples/by-example/65-pipes.nx