Rollup merge of #21498 - quantheory:master, r=alexcrichton

While trying to experiment with changes for some other issues, I noticed that the test for #15149 was failing because I have `/tmp` mounted as `noexec` on my Linux box, and that test tries to run out of a temporary directory. This may not be the most common case, but it's not rare by any means, because executing from a world-writable directory is a security problem. (For this reason, some kernel options/mods such as grsecurity also can prevent this on Linux.) I instead copy the executable to a directory created in the build tree, following the example of the `process-spawn-with-unicode-params` test.

After I made that change, I noticed that I'd made a mistake, but the test was still passing, because the "parent" process was not actually checking the status of the "child" process, meaning that the assertion in the child could never cause the overall test to fail. (I don't know if this has always been the case, or if it has something to do with either Windows or a change in the semantics of `spawn`.) So I fixed the test so that it would fail correctly, then fixed my original mistake so that it would pass again.

The one big problem with this is that I haven't set up any machines of my own so that I can build on Windows, which is the platform this test was targeted at in the first place! That might take a while to address on my end. So I need someone else to check this on Windows.
This commit is contained in:
Flavio Percoco Premoli 2015-01-24 10:42:40 +01:00
commit 65d14d2661

View file

@ -8,33 +8,50 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::io::{TempDir, Command, fs};
use std::io::{Command, fs, USER_RWX};
use std::os;
use std::path::BytesContainer;
use std::rand::random;
fn main() {
// If we're the child, make sure we were invoked correctly
let args = os::args();
if args.len() > 1 && args[1].as_slice() == "child" {
return assert_eq!(args[0].as_slice(), "mytest");
return assert_eq!(args[0],
format!("mytest{}", os::consts::EXE_SUFFIX));
}
test();
}
fn test() {
// If we're the parent, copy our own binary to a tempr directory, and then
// make it executable.
let dir = TempDir::new("mytest").unwrap();
let me = os::self_exe_name().unwrap();
let dest = dir.path().join(format!("mytest{}", os::consts::EXE_SUFFIX));
fs::copy(&me, &dest).unwrap();
// If we're the parent, copy our own binary to a new directory.
let my_path = os::self_exe_name().unwrap();
let my_dir = my_path.dir_path();
// Append the temp directory to our own PATH.
let random_u32: u32 = random();
let child_dir = Path::new(my_dir.join(format!("issue-15149-child-{}",
random_u32)));
fs::mkdir(&child_dir, USER_RWX).unwrap();
let child_path = child_dir.join(format!("mytest{}",
os::consts::EXE_SUFFIX));
fs::copy(&my_path, &child_path).unwrap();
// Append the new directory to our own PATH.
let mut path = os::split_paths(os::getenv("PATH").unwrap_or(String::new()));
path.push(dir.path().clone());
path.push(child_dir.clone());
let path = os::join_paths(path.as_slice()).unwrap();
Command::new("mytest").env("PATH", path.as_slice())
.arg("child")
.spawn().unwrap();
let child_output = Command::new("mytest").env("PATH", path.as_slice())
.arg("child")
.output().unwrap();
assert!(child_output.status.success(),
format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}",
child_output.output.container_as_str().unwrap(),
child_output.error.container_as_str().unwrap()));
fs::rmdir_recursive(&child_dir).unwrap();
}