| use crate::io; | |
| use crate::os::fd::FromRawFd; | |
| use crate::sys::fd::FileDesc; | |
| use crate::sys::pal::cvt; | |
| pub type Pipe = FileDesc; | |
| pub fn pipe() -> io::Result<(Pipe, Pipe)> { | |
| let mut fds = [0; 2]; | |
| // The only known way right now to create atomically set the CLOEXEC flag is | |
| // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9 | |
| // and musl 0.9.3, and some other targets also have it. | |
| cfg_select! { | |
| any( | |
| target_os = "android", | |
| target_os = "dragonfly", | |
| target_os = "freebsd", | |
| target_os = "hurd", | |
| target_os = "illumos", | |
| target_os = "linux", | |
| target_os = "netbsd", | |
| target_os = "openbsd", | |
| target_os = "cygwin", | |
| target_os = "redox" | |
| ) => { | |
| unsafe { | |
| cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?; | |
| Ok((Pipe::from_raw_fd(fds[0]), Pipe::from_raw_fd(fds[1]))) | |
| } | |
| } | |
| _ => { | |
| unsafe { | |
| cvt(libc::pipe(fds.as_mut_ptr()))?; | |
| let fd0 = Pipe::from_raw_fd(fds[0]); | |
| let fd1 = Pipe::from_raw_fd(fds[1]); | |
| fd0.set_cloexec()?; | |
| fd1.set_cloexec()?; | |
| Ok((fd0, fd1)) | |
| } | |
| } | |
| } | |
| } |