Auto merge of #42521 - alexcrichton:enosys, r=cuviper
std: Handle ENOSYS when calling `pipe2` Should help fix an accidental regression from #39386.
This commit is contained in:
commit
a7ac71b978
|
@ -11,8 +11,9 @@
|
|||
use io;
|
||||
use libc::{self, c_int};
|
||||
use mem;
|
||||
use sys::{cvt, cvt_r};
|
||||
use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
|
||||
use sys::fd::FileDesc;
|
||||
use sys::{cvt, cvt_r};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Anonymous pipes
|
||||
|
@ -21,6 +22,9 @@ use sys::fd::FileDesc;
|
|||
pub struct AnonPipe(FileDesc);
|
||||
|
||||
pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||
weak! { fn pipe2(*mut c_int, c_int) -> c_int }
|
||||
static INVALID: AtomicBool = ATOMIC_BOOL_INIT;
|
||||
|
||||
let mut fds = [0; 2];
|
||||
|
||||
// Unfortunately the only known way right now to create atomically set the
|
||||
|
@ -31,13 +35,26 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
|||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))
|
||||
target_os = "openbsd")) &&
|
||||
!INVALID.load(Ordering::SeqCst)
|
||||
{
|
||||
weak! { fn pipe2(*mut c_int, c_int) -> c_int }
|
||||
|
||||
if let Some(pipe) = pipe2.get() {
|
||||
cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) })?;
|
||||
return Ok((AnonPipe(FileDesc::new(fds[0])),
|
||||
AnonPipe(FileDesc::new(fds[1]))));
|
||||
// Note that despite calling a glibc function here we may still
|
||||
// get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to
|
||||
// emulate on older kernels, so if you happen to be running on
|
||||
// an older kernel you may see `pipe2` as a symbol but still not
|
||||
// see the syscall.
|
||||
match cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
|
||||
Ok(_) => {
|
||||
return Ok((AnonPipe(FileDesc::new(fds[0])),
|
||||
AnonPipe(FileDesc::new(fds[1]))));
|
||||
}
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
|
||||
INVALID.store(true, Ordering::SeqCst);
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?;
|
||||
|
|
Loading…
Reference in New Issue