Skip to content

Commit dc1f23f

Browse files
authored
Merge pull request #5 from cuviper/pipe2-ENOSYS
Handle ENOSYS when calling `pipe2`
2 parents 3d89d89 + 01f8642 commit dc1f23f

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/lib.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,9 @@ mod imp {
391391
use std::os::unix::prelude::*;
392392
use std::process::Command;
393393
use std::ptr;
394-
use std::sync::atomic::{AtomicBool, AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
394+
use std::sync::atomic::{AtomicBool, AtomicUsize,
395+
ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT,
396+
Ordering};
395397
use std::sync::mpsc::{self, Receiver, RecvTimeoutError};
396398
use std::sync::{Arc, Once, ONCE_INIT};
397399
use std::thread::{JoinHandle, Builder};
@@ -422,13 +424,21 @@ mod imp {
422424
}
423425

424426
unsafe fn mk() -> io::Result<Client> {
427+
static INVALID: AtomicBool = ATOMIC_BOOL_INIT;
425428
let mut pipes = [0; 2];
426429

427-
// Attempt atomically-create-with-cloexec if we can
428-
if cfg!(target_os = "linux") {
430+
// Attempt atomically-create-with-cloexec if we can. Note that even
431+
// when libc has the symbol, `pipe2` might still not be supported on
432+
// the running kernel -> `ENOSYS`, then we need to use the fallback.
433+
if cfg!(target_os = "linux") && !INVALID.load(Ordering::SeqCst) {
429434
if let Some(pipe2) = pipe2() {
430-
cvt(pipe2(pipes.as_mut_ptr(), libc::O_CLOEXEC))?;
431-
return Ok(Client::from_fds(pipes[0], pipes[1]))
435+
match cvt(pipe2(pipes.as_mut_ptr(), libc::O_CLOEXEC)) {
436+
Ok(_) => return Ok(Client::from_fds(pipes[0], pipes[1])),
437+
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
438+
INVALID.store(true, Ordering::SeqCst);
439+
}
440+
Err(e) => return Err(e),
441+
}
432442
}
433443
}
434444

0 commit comments

Comments
 (0)