@@ -391,7 +391,9 @@ mod imp {
391
391
use std:: os:: unix:: prelude:: * ;
392
392
use std:: process:: Command ;
393
393
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 } ;
395
397
use std:: sync:: mpsc:: { self , Receiver , RecvTimeoutError } ;
396
398
use std:: sync:: { Arc , Once , ONCE_INIT } ;
397
399
use std:: thread:: { JoinHandle , Builder } ;
@@ -422,13 +424,21 @@ mod imp {
422
424
}
423
425
424
426
unsafe fn mk ( ) -> io:: Result < Client > {
427
+ static INVALID : AtomicBool = ATOMIC_BOOL_INIT ;
425
428
let mut pipes = [ 0 ; 2 ] ;
426
429
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 ) {
429
434
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
+ }
432
442
}
433
443
}
434
444
0 commit comments