Skip to main content

std/sys/pipe/
unix.rs

1use crate::io;
2use crate::os::fd::FromRawFd;
3use crate::sys::fd::FileDesc;
4use crate::sys::pal::cvt;
5
6pub type Pipe = FileDesc;
7
8pub fn pipe() -> io::Result<(Pipe, Pipe)> {
9    let mut fds = [0; 2];
10
11    // The only known way right now to create atomically set the CLOEXEC flag is
12    // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9
13    // and musl 0.9.3, and some other targets also have it.
14    cfg_select! {
15        any(
16            target_os = "android",
17            target_os = "dragonfly",
18            target_os = "freebsd",
19            target_os = "hurd",
20            target_os = "illumos",
21            target_os = "linux",
22            target_os = "netbsd",
23            target_os = "openbsd",
24            target_os = "cygwin",
25            target_os = "redox"
26        ) => {
27            unsafe {
28                cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?;
29                Ok((Pipe::from_raw_fd(fds[0]), Pipe::from_raw_fd(fds[1])))
30            }
31        }
32        _ => {
33            unsafe {
34                cvt(libc::pipe(fds.as_mut_ptr()))?;
35
36                let fd0 = Pipe::from_raw_fd(fds[0]);
37                let fd1 = Pipe::from_raw_fd(fds[1]);
38                fd0.set_cloexec()?;
39                fd1.set_cloexec()?;
40                Ok((fd0, fd1))
41            }
42        }
43    }
44}