@@ -28,7 +28,7 @@ pub struct Acquired {
28
28
29
29
impl Client {
30
30
pub fn new ( mut limit : usize ) -> io:: Result < Client > {
31
- let client = unsafe { Client :: mk ( ) ? } ;
31
+ let ( client, string_arg ) = unsafe { Client :: mk ( ) ? } ;
32
32
33
33
// I don't think the character written here matters, but I could be
34
34
// wrong!
@@ -47,39 +47,21 @@ impl Client {
47
47
48
48
set_nonblocking ( write. as_raw_fd ( ) , false ) ?;
49
49
50
+ // TODO: what if this var has already been set?
51
+ std:: env:: set_var ( "CARGO_MAKEFLAGS" , string_arg) ;
52
+
50
53
Ok ( client)
51
54
}
52
55
53
- unsafe fn mk ( ) -> io:: Result < Client > {
56
+ unsafe fn mk ( ) -> io:: Result < ( Client , String ) > {
54
57
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
-
79
58
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) )
83
65
}
84
66
85
67
pub ( crate ) unsafe fn open ( s : & str , check_pipe : bool ) -> Result < Client , FromEnvErrorInner > {
@@ -149,8 +131,10 @@ impl Client {
149
131
}
150
132
}
151
133
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
+
154
138
Ok ( Some ( Client :: from_fds ( read, write) ) )
155
139
}
156
140
@@ -263,38 +247,26 @@ impl Client {
263
247
}
264
248
}
265
249
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
-
273
250
pub fn available ( & self ) -> io:: Result < usize > {
274
251
let mut len = MaybeUninit :: < c_int > :: uninit ( ) ;
275
252
cvt ( unsafe { libc:: ioctl ( self . read ( ) . as_raw_fd ( ) , libc:: FIONREAD , len. as_mut_ptr ( ) ) } ) ?;
276
253
Ok ( unsafe { len. assume_init ( ) } as usize )
277
254
}
278
255
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
+ }
298
270
}
299
271
}
300
272
}
0 commit comments