-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c51b9b6
commit 4fcebee
Showing
2 changed files
with
74 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
//@ run-pass | ||
//@ only-windows | ||
//@ needs-subprocess | ||
//@ no-prefer-dynamic | ||
|
||
// Test Windows std::process::Command search path semantics when setting PATH on the child process. | ||
// NOTE: The exact semantics here are (possibly) subject to change. | ||
|
||
use std::process::Command; | ||
use std::{env, fs, path}; | ||
|
||
fn main() { | ||
if env::args().skip(1).any(|s| s == "--child") { | ||
child(); | ||
} else if env::args().skip(1).any(|s| s == "--parent") { | ||
parent(); | ||
} else { | ||
setup(); | ||
} | ||
} | ||
|
||
// Set up the directories so that there are three app dirs: | ||
// app: Where the parent app is run from | ||
// parent: In the parent's PATH env var | ||
// child: In the child's PATH env var | ||
fn setup() { | ||
let exe = env::current_exe().unwrap(); | ||
|
||
fs::create_dir_all("app").unwrap(); | ||
fs::copy(&exe, "app/myapp.exe").unwrap(); | ||
fs::create_dir_all("parent").unwrap(); | ||
fs::copy(&exe, "parent/myapp.exe").unwrap(); | ||
fs::create_dir_all("child").unwrap(); | ||
fs::copy(&exe, "child/myapp.exe").unwrap(); | ||
|
||
let parent_path = path::absolute("parent").unwrap(); | ||
let status = | ||
Command::new("./app/myapp.exe").env("PATH", parent_path).arg("--parent").status().unwrap(); | ||
// print the status in case of abnormal exit | ||
dbg!(status); | ||
assert!(status.success()); | ||
} | ||
|
||
// The child simply prints the name of its parent directory. | ||
fn child() { | ||
let exe = env::current_exe().unwrap(); | ||
let parent = exe.parent().unwrap().file_name().unwrap(); | ||
println!("{}", parent.display()); | ||
} | ||
|
||
fn parent() { | ||
let exe = env::current_exe().unwrap(); | ||
let name = exe.file_name().unwrap(); | ||
|
||
// By default, the application dir will be search first for the exe | ||
let output = Command::new(&name).arg("--child").output().unwrap(); | ||
assert_eq!(output.stdout, b"app\n"); | ||
|
||
// Setting an environment variable should not change the above. | ||
let output = Command::new(&name).arg("--child").env("a", "b").output().unwrap(); | ||
assert_eq!(output.stdout, b"app\n"); | ||
|
||
// Setting a child path means that path will be searched first. | ||
let child_path = path::absolute("child").unwrap(); | ||
let output = Command::new(&name).arg("--child").env("PATH", child_path).output().unwrap(); | ||
assert_eq!(output.stdout, b"child\n"); | ||
|
||
// Setting a child path that does not contain the exe (currently) means | ||
// we fallback to searching the app dir. | ||
let output = Command::new(&name).arg("--child").env("PATH", "").output().unwrap(); | ||
assert_eq!(output.stdout, b"app\n"); | ||
} |