-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Find the program using PATHEXT #37381
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
Changes from 4 commits
40ed572
cc9d064
a3c72fd
63b4c79
f364190
41a0df0
6b9b6f1
abe5e1a
0444a6d
e9e960e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,12 +125,9 @@ impl Command { | |
self.stderr = Some(stderr); | ||
} | ||
|
||
pub fn spawn(&mut self, default: Stdio, needs_stdin: bool) | ||
-> io::Result<(Process, StdioPipes)> { | ||
// To have the spawning semantics of unix/windows stay the same, we need | ||
// to read the *child's* PATH if one is provided. See #15149 for more | ||
// details. | ||
let program = self.env.as_ref().and_then(|env| { | ||
pub fn find_program(&mut self) -> Option<Path> { | ||
self.env.as_ref().and_then(|env| { | ||
let env_pathext = env.get("PATHEXT"); | ||
for (key, v) in env { | ||
if OsStr::new("PATH") != &**key { continue } | ||
|
||
|
@@ -141,12 +138,34 @@ impl Command { | |
.with_extension(env::consts::EXE_EXTENSION); | ||
if fs::metadata(&path).is_ok() { | ||
return Some(path.into_os_string()) | ||
} else { | ||
// Windows relies on path extensions to resolve commands. | ||
// Path extensions are found in the PATHEXT environment variable. | ||
if let Some(exts) = env_pathext { | ||
for ext in split_paths(&exts) { | ||
let ext_str = ext.to_string_lossy(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we'll want to call
|
||
let path = path.with_extension( | ||
ext_str.trim_matches('.') | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps this could fit on oneline? |
||
if fs::metadata(&path).is_ok() { | ||
return Some(path.into_os_string()) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
break | ||
} | ||
None | ||
}); | ||
} | ||
|
||
pub fn spawn(&mut self, default: Stdio, needs_stdin: bool) | ||
-> io::Result<(Process, StdioPipes)> { | ||
// To have the spawning semantics of unix/windows stay the same, we need | ||
// to read the *child's* PATH if one is provided. See #15149 for more | ||
// details. | ||
let program = self.find_program(); | ||
|
||
let mut si = zeroed_startupinfo(); | ||
si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD; | ||
|
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.
We typically try to avoid rightward drift where possible, so because of the
return
above you can omit thiselse
, de-indenting what's below. You can also change what's below to:to get rid of another layer of indentation.