@@ -271,32 +271,28 @@ fn exec(mut cmd: Command) -> ! {
271
271
272
272
/// Execute the `Command`, where possible by replacing the current process with a new process
273
273
/// described by the `Command`. Then exit this process with the exit code of the new process.
274
- /// `input` is also piped to the new process's stdin.
275
- fn exec_with_pipe ( mut cmd : Command , input : & [ u8 ] ) -> ! {
274
+ /// `input` is also piped to the new process's stdin, on cfg(unix) platforms by writing its
275
+ /// contents to `path` first, then setting stdin to that file.
276
+ fn exec_with_pipe < P > ( mut cmd : Command , input : & [ u8 ] , path : P ) -> !
277
+ where
278
+ P : AsRef < Path > ,
279
+ {
276
280
#[ cfg( unix) ]
277
281
{
278
- use std :: os :: unix :: io :: FromRawFd ;
279
- use std:: process :: Stdio ;
282
+ // Write the bytes we want to send to stdin out to a file
283
+ std:: fs :: write ( & path , input ) . unwrap ( ) ;
280
284
281
- let mut fds: [ libc:: c_int ; 2 ] = [ 0 , 0 ] ;
282
- // SAFETY: fds is an array of 2 libc::c_int
283
- let res = unsafe { libc:: pipe ( fds. as_mut_ptr ( ) ) } ;
284
- assert_eq ! ( res, 0 , "failed to create pipe" ) ;
285
+ // Open the file for reading, and set our new stdin to it
286
+ let stdin = File :: open ( & path) . unwrap ( ) ;
287
+ cmd. stdin ( stdin) ;
285
288
286
- // SAFETY: Both elements of fds are open file descriptors, because pipe returned 0
287
- let dst = unsafe { Stdio :: from_raw_fd ( fds[ 0 ] ) } ;
288
- let mut src = unsafe { File :: from_raw_fd ( fds[ 1 ] ) } ;
289
-
290
- src. write_all ( input) . expect ( "failed to write out test source" ) ;
291
-
292
- // Close the writing part of the pipe in the parent process
293
- drop ( src) ;
294
-
295
- cmd. stdin ( dst) ;
289
+ // Unlink the file so that it is fully cleaned up as soon as the new process exits
290
+ std:: fs:: remove_file ( & path) . unwrap ( ) ;
296
291
exec ( cmd)
297
292
}
298
293
#[ cfg( not( unix) ) ]
299
294
{
295
+ drop ( path) ; // We don't need the path, we can pipe the bytes directly
300
296
cmd. stdin ( process:: Stdio :: piped ( ) ) ;
301
297
let mut child = cmd. spawn ( ) . expect ( "failed to spawn process" ) ;
302
298
{
@@ -943,7 +939,7 @@ fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
943
939
eprintln ! ( "[cargo-miri rustc inside rustdoc] going to run:\n {:?}" , cmd) ;
944
940
}
945
941
946
- exec_with_pipe ( cmd, & env. stdin ) ;
942
+ exec_with_pipe ( cmd, & env. stdin , format ! ( "{}.stdin" , out_filename ( "" , "" ) . display ( ) ) ) ;
947
943
}
948
944
949
945
return ;
@@ -1143,7 +1139,7 @@ fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: RunnerPhas
1143
1139
// Run it.
1144
1140
debug_cmd ( "[cargo-miri runner]" , verbose, & cmd) ;
1145
1141
match phase {
1146
- RunnerPhase :: Rustdoc => exec_with_pipe ( cmd, & info. stdin ) ,
1142
+ RunnerPhase :: Rustdoc => exec_with_pipe ( cmd, & info. stdin , format ! ( "{}.stdin" , binary ) ) ,
1147
1143
RunnerPhase :: Cargo => exec ( cmd) ,
1148
1144
}
1149
1145
}
0 commit comments