@@ -28,7 +28,7 @@ pub struct Acquired {
2828
2929impl Client {
3030 pub fn new ( mut limit : usize ) -> io:: Result < Client > {
31- let client = unsafe { Client :: mk ( ) ? } ;
31+ let ( client, string_arg ) = unsafe { Client :: mk ( ) ? } ;
3232
3333 // I don't think the character written here matters, but I could be
3434 // wrong!
@@ -47,39 +47,21 @@ impl Client {
4747
4848 set_nonblocking ( write. as_raw_fd ( ) , false ) ?;
4949
50+ // TODO: what if this var has already been set?
51+ std:: env:: set_var ( "CARGO_MAKEFLAGS" , string_arg) ;
52+
5053 Ok ( client)
5154 }
5255
53- unsafe fn mk ( ) -> io:: Result < Client > {
56+ unsafe fn mk ( ) -> io:: Result < ( Client , String ) > {
5457 let mut pipes = [ 0 ; 2 ] ;
55-
56- // Attempt atomically-create-with-cloexec if we can on Linux,
57- // detected by using the `syscall` function in `libc` to try to work
58- // with as many kernels/glibc implementations as possible.
59- #[ cfg( target_os = "linux" ) ]
60- {
61- use std:: sync:: atomic:: { AtomicBool , Ordering } ;
62-
63- static PIPE2_AVAILABLE : AtomicBool = AtomicBool :: new ( true ) ;
64- if PIPE2_AVAILABLE . load ( Ordering :: SeqCst ) {
65- match libc:: syscall ( libc:: SYS_pipe2 , pipes. as_mut_ptr ( ) , libc:: O_CLOEXEC ) {
66- -1 => {
67- let err = io:: Error :: last_os_error ( ) ;
68- if err. raw_os_error ( ) == Some ( libc:: ENOSYS ) {
69- PIPE2_AVAILABLE . store ( false , Ordering :: SeqCst ) ;
70- } else {
71- return Err ( err) ;
72- }
73- }
74- _ => return Ok ( Client :: from_fds ( pipes[ 0 ] , pipes[ 1 ] ) ) ,
75- }
76- }
77- }
78-
7958 cvt ( libc:: pipe ( pipes. as_mut_ptr ( ) ) ) ?;
80- drop ( set_cloexec ( pipes[ 0 ] , true ) ) ;
81- drop ( set_cloexec ( pipes[ 1 ] , true ) ) ;
82- Ok ( Client :: from_fds ( pipes[ 0 ] , pipes[ 1 ] ) )
59+ let string_arg = format ! (
60+ "--jobserver-fds={},{}" ,
61+ pipes[ 0 ] . as_raw_fd( ) ,
62+ pipes[ 1 ] . as_raw_fd( )
63+ ) ;
64+ Ok ( ( Client :: from_fds ( pipes[ 0 ] , pipes[ 1 ] ) , string_arg) )
8365 }
8466
8567 pub ( crate ) unsafe fn open ( s : & str , check_pipe : bool ) -> Result < Client , FromEnvErrorInner > {
@@ -149,8 +131,10 @@ impl Client {
149131 }
150132 }
151133
152- drop ( set_cloexec ( read, true ) ) ;
153- drop ( set_cloexec ( write, true ) ) ;
134+ // // Unless env var was explicitly removed, file descriptors should be passed.
135+ // drop(set_cloexec(read, false));
136+ // drop(set_cloexec(write, false));
137+
154138 Ok ( Some ( Client :: from_fds ( read, write) ) )
155139 }
156140
@@ -263,38 +247,26 @@ impl Client {
263247 }
264248 }
265249
266- pub fn string_arg ( & self ) -> String {
267- match self {
268- Client :: Pipe { read, write } => format ! ( "{},{}" , read. as_raw_fd( ) , write. as_raw_fd( ) ) ,
269- Client :: Fifo { path, .. } => format ! ( "fifo:{}" , path. to_str( ) . unwrap( ) ) ,
270- }
271- }
272-
273250 pub fn available ( & self ) -> io:: Result < usize > {
274251 let mut len = MaybeUninit :: < c_int > :: uninit ( ) ;
275252 cvt ( unsafe { libc:: ioctl ( self . read ( ) . as_raw_fd ( ) , libc:: FIONREAD , len. as_mut_ptr ( ) ) } ) ?;
276253 Ok ( unsafe { len. assume_init ( ) } as usize )
277254 }
278255
279- pub fn configure ( & self , cmd : & mut Command ) {
280- match self {
281- // We `File::open`ed it when inheriting from environment,
282- // so no need to set cloexec for fifo.
283- Client :: Fifo { .. } => return ,
284- Client :: Pipe { .. } => { }
285- } ;
286- // Here we basically just want to say that in the child process
287- // we'll configure the read/write file descriptors to *not* be
288- // cloexec, so they're inherited across the exec and specified as
289- // integers through `string_arg` above.
290- let read = self . read ( ) . as_raw_fd ( ) ;
291- let write = self . write ( ) . as_raw_fd ( ) ;
292- unsafe {
293- cmd. pre_exec ( move || {
294- set_cloexec ( read, false ) ?;
295- set_cloexec ( write, false ) ?;
296- Ok ( ( ) )
297- } ) ;
256+ pub fn disable_inheritance ( & self , cmd : & mut Command ) {
257+ if let Client :: Pipe { .. } = self {
258+ // Here we basically just want to say that in the child process
259+ // we'll configure the read/write file descriptors to be cloexec,
260+ // so they aren't inherited across the exec.
261+ let read = self . read ( ) . as_raw_fd ( ) ;
262+ let write = self . write ( ) . as_raw_fd ( ) ;
263+ unsafe {
264+ cmd. pre_exec ( move || {
265+ set_cloexec ( read, true ) ?;
266+ set_cloexec ( write, true ) ?;
267+ Ok ( ( ) )
268+ } ) ;
269+ }
298270 }
299271 }
300272}
0 commit comments