Pipes
pipe_new() creates a unidirectional pipe returning [read_fd, write_fd]. Combined with fork, dup2, and execvp, this lets you capture the output of an external command — the same mechanism Unix shells use for | (pipe).
Code
// 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
}
Output
ls output (first 200 chars): ...
Explanation
pipe_new() creates a unidirectional byte stream and returns an array of two file descriptors: [read_fd, write_fd]. Data written to write_fd can be read from read_fd.
After fork(), the child closes the read end, uses dup2(write_fd, 1) to redirect its stdout to the pipe's write end, then calls execvp to run ls. The child's output flows through the pipe instead of the terminal.
The parent closes the write end (so reads will see EOF when the child exits), reads the pipe contents with tcp_read, and waits for the child with waitpid. This is exactly how Unix shells implement the | operator.
Source: examples/by-example/65-pipes.nx