Skip to content

Commit f1a0615

Browse files
committed
pipe by writing input to a file then setting that file as stdin
1 parent 4cb98df commit f1a0615

File tree

3 files changed

+16
-22
lines changed

3 files changed

+16
-22
lines changed

cargo-miri/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cargo-miri/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ doctest = false # and no doc tests
1717
directories = "3"
1818
rustc_version = "0.4"
1919
serde_json = "1.0.40"
20-
libc = "0.2"
2120

2221
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
2322
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`

cargo-miri/bin.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -271,32 +271,28 @@ fn exec(mut cmd: Command) -> ! {
271271

272272
/// Execute the `Command`, where possible by replacing the current process with a new process
273273
/// 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+
{
276280
#[cfg(unix)]
277281
{
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();
280284

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);
285288

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();
296291
exec(cmd)
297292
}
298293
#[cfg(not(unix))]
299294
{
295+
drop(path); // We don't need the path, we can pipe the bytes directly
300296
cmd.stdin(process::Stdio::piped());
301297
let mut child = cmd.spawn().expect("failed to spawn process");
302298
{
@@ -943,7 +939,7 @@ fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
943939
eprintln!("[cargo-miri rustc inside rustdoc] going to run:\n{:?}", cmd);
944940
}
945941

946-
exec_with_pipe(cmd, &env.stdin);
942+
exec_with_pipe(cmd, &env.stdin, format!("{}.stdin", out_filename("", "").display()));
947943
}
948944

949945
return;
@@ -1143,7 +1139,7 @@ fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: RunnerPhas
11431139
// Run it.
11441140
debug_cmd("[cargo-miri runner]", verbose, &cmd);
11451141
match phase {
1146-
RunnerPhase::Rustdoc => exec_with_pipe(cmd, &info.stdin),
1142+
RunnerPhase::Rustdoc => exec_with_pipe(cmd, &info.stdin, format!("{}.stdin", binary)),
11471143
RunnerPhase::Cargo => exec(cmd),
11481144
}
11491145
}

0 commit comments

Comments
 (0)