@@ -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