Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions src/libstd/sys/unix/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use io;
use libc::{self, c_int};
use mem;
use ptr;
use sys::cvt_r;
use sync::atomic::{AtomicBool, Ordering};
use sys::{cvt, cvt_r};
use sys::fd::FileDesc;

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -29,34 +30,33 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
// CLOEXEC flag is to use the `pipe2` syscall on Linux. This was added in
// 2.6.27, however, and because we support 2.6.18 we must detect this
// support dynamically.
if cfg!(target_os = "linux") {
static TRY_PIPE2: AtomicBool = AtomicBool::new(cfg!(target_os = "linux"));
Copy link
Member

@nagisa nagisa Jan 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preexisting:

pipe2 is also supported on freebsd (>= 10.0), netbsd (>= 6.0), dragonflybsd (appeared ~4.0-ish?), openbsd (>= 5.7). These probably should also appear in that cfg! above.

if TRY_PIPE2.load(Ordering::Relaxed) {
weak! { fn pipe2(*mut c_int, c_int) -> c_int }
if let Some(pipe) = pipe2.get() {
match cvt_r(|| unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
Ok(_) => {
match cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
TRY_PIPE2.store(false, Ordering::Relaxed);
// Fall through
},
res => {
res?;
return Ok((AnonPipe(FileDesc::new(fds[0])),
AnonPipe(FileDesc::new(fds[1]))))
AnonPipe(FileDesc::new(fds[1]))));
}
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
Err(e) => return Err(e),
}
}
}
if unsafe { libc::pipe(fds.as_mut_ptr()) == 0 } {
let fd0 = FileDesc::new(fds[0]);
let fd1 = FileDesc::new(fds[1]);
Ok((AnonPipe::from_fd(fd0)?, AnonPipe::from_fd(fd1)?))
} else {
Err(io::Error::last_os_error())
}
cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?;

let fd0 = FileDesc::new(fds[0]);
let fd1 = FileDesc::new(fds[1]);
fd0.set_cloexec()?;
fd1.set_cloexec()?;
Ok((AnonPipe(fd0), AnonPipe(fd1)))
}

impl AnonPipe {
pub fn from_fd(fd: FileDesc) -> io::Result<AnonPipe> {
fd.set_cloexec()?;
Ok(AnonPipe(fd))
}

pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
}
Expand Down