Skip to content

Commit 40ed572

Browse files
author
Salim Afiune
committed
Find the program using PATHEXT
Windows relies on path extensions to resolve commands, extensions are found in the `PATHEXT` environment variable. We are adding a new function called `Command:find_program()` that will return the `Path` of the program found using the above env variable. Closes #37380 Signed-off-by: Salim Afiune <[email protected]>
1 parent 7bd2427 commit 40ed572

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

src/libstd/sys/windows/process.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,8 @@ impl Command {
125125
self.stderr = Some(stderr);
126126
}
127127

128-
pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
129-
-> io::Result<(Process, StdioPipes)> {
130-
// To have the spawning semantics of unix/windows stay the same, we need
131-
// to read the *child's* PATH if one is provided. See #15149 for more
132-
// details.
133-
let program = self.env.as_ref().and_then(|env| {
128+
pub fn find_program(&mut self) -> Option<Path> {
129+
self.env.as_ref().and_then(|env| {
134130
for (key, v) in env {
135131
if OsStr::new("PATH") != &**key { continue }
136132

@@ -141,12 +137,33 @@ impl Command {
141137
.with_extension(env::consts::EXE_EXTENSION);
142138
if fs::metadata(&path).is_ok() {
143139
return Some(path.into_os_string())
140+
} else {
141+
// Windows relies on path extensions to resolve commands.
142+
// Path extensions are found in the PATHEXT environment variable.
143+
if let Some(exts) = self.env.get("PATHEXT") {
144+
for ext in split_paths(&exts) {
145+
let ext_str = pathext.to_str().unwrap().trim_matches('.');
146+
let path = path.join(self.program.to_str().unwrap())
147+
.with_extension(ext_str);
148+
if fs::metadata(&path).is_ok() {
149+
return Some(path.into_os_string())
150+
}
151+
}
152+
}
144153
}
145154
}
146155
break
147156
}
148157
None
149158
});
159+
}
160+
161+
pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
162+
-> io::Result<(Process, StdioPipes)> {
163+
// To have the spawning semantics of unix/windows stay the same, we need
164+
// to read the *child's* PATH if one is provided. See #15149 for more
165+
// details.
166+
let program = self.find_program();
150167

151168
let mut si = zeroed_startupinfo();
152169
si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;

0 commit comments

Comments
 (0)