-
Notifications
You must be signed in to change notification settings - Fork 13.9k
libstd: unix process spawning: fix bug with setting stdio #30490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
r? @brson (rust_highfive has picked a reviewer for you, use r? to override) |
src/libstd/sys/unix/process.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this use FileDesc instead of RawStdio here? (as RawStdio is just a type alias)
|
Thanks! Could you be sure to also add a test for this? |
|
@alexcrichton addressed all comments! I wasn't sure about the right place for such a test, but I think run-pass is a good fit. |
src/test/run-pass/issue-30490.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this test be written without creating files? Keeping everything in-memory is generally better for isolation. I think this should basically just be able to use combinations of pipes, right?
|
@alexcrichton rewrote the test to use pipes instead of files and to re-exec itself instead of calling a shell |
|
@bors: r+ 751fce0974dd4f634539c37ba759d13c4f894d09 Thanks! |
|
http://buildbot.rust-lang.org/builders/auto-win-gnu-64-nopt-t/builds/2525/steps/test/logs/stdio |
* If the requested descriptors to inherit are stdio descriptors there
are situations where they will not be set correctly
* Example: parent's stdout --> child's stderr
parent's stderr --> child's stdout
* Solution: if the requested descriptors for the child are stdio
descriptors, `dup` them before overwriting the child's stdio
|
Doh! Forgot some @alexcrichton @Manishearth should be fixed now |
|
⌛ Testing commit 7f7a059 with merge 6f86431... |
|
💔 Test failed - auto-win-msvc-32-opt |
|
@bors: retry On Mon, Jan 11, 2016 at 3:21 PM, bors notifications@github.com wrote:
|
* If the requested descriptors to inherit are stdio descriptors there
are situations where they will not be set correctly
* Example: parent's stdout --> child's stderr
parent's stderr --> child's stdout
* Solution: if the requested descriptors for the child are stdio
descriptors, `dup` them before overwriting the child's stdio
Example of a program which exhibits the bug:
```rust
// stdio.rs
use std::io::Write;
use std::io::{stdout, stderr};
use std::process::{Command, Stdio};
use std::os::unix::io::FromRawFd;
fn main() {
stdout().write_all("parent stdout\n".as_bytes()).unwrap();
stderr().write_all("parent stderr\n".as_bytes()).unwrap();
Command::new("sh")
.arg("-c")
.arg("echo 'child stdout'; echo 'child stderr' 1>&2")
.stdin(Stdio::inherit())
.stdout(unsafe { FromRawFd::from_raw_fd(2) })
.stderr(unsafe { FromRawFd::from_raw_fd(1) })
.status()
.unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
}
```
Before:
```
$ rustc --version
rustc 1.7.0-nightly (8ad12c3 2015-12-19)
$ rustc stdio.rs && ./stdio >out 2>err
$ cat out
parent stdout
$ cat err
parent stderr
child stdout
child stderr
```
After (expected):
```
$ rustc --version
rustc 1.7.0-dev (712ecce 2015-12-19)
$ rustc stdio.rs && ./stdio >out 2>err
$ cat out
parent stdout
child stderr
$ cat err
parent stderr
child stdout
```
|
I think the original report here shows an program which has undefined behaviour. The documentation for
Calling this on 0, 1 or 2 is clearly wrong. |
are situations where they will not be set correctly
parent's stderr --> child's stdout
descriptors,
dupthem before overwriting the child's stdioExample of a program which exhibits the bug:
Before:
After (expected):