1
Fork 0

Don't use posix_spawn() if PATH was modified in the environment.

The expected behavior is that the environment's PATH should be used
to find the process.  posix_spawn() could be used if we iterated
PATH to search for the binary to execute.  For now just skip
posix_spawn() if PATH is modified.
This commit is contained in:
Bryan Drewery 2018-03-19 15:40:09 -07:00
parent 00dac20e01
commit 6212904dd8
3 changed files with 16 additions and 0 deletions

View file

@ -184,6 +184,9 @@ impl Command {
let maybe_env = self.env.capture_if_changed(); let maybe_env = self.env.capture_if_changed();
maybe_env.map(|env| construct_envp(env, &mut self.saw_nul)) maybe_env.map(|env| construct_envp(env, &mut self.saw_nul))
} }
pub fn env_saw_path(&self) -> bool {
self.env.have_changed_path()
}
pub fn setup_io(&self, default: Stdio, needs_stdin: bool) pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
-> io::Result<(StdioPipes, ChildPipes)> { -> io::Result<(StdioPipes, ChildPipes)> {

View file

@ -256,6 +256,7 @@ impl Command {
if self.get_cwd().is_some() || if self.get_cwd().is_some() ||
self.get_gid().is_some() || self.get_gid().is_some() ||
self.get_uid().is_some() || self.get_uid().is_some() ||
self.env_saw_path() ||
self.get_closures().len() != 0 { self.get_closures().len() != 0 {
return Ok(None) return Ok(None)
} }

View file

@ -47,6 +47,7 @@ impl EnvKey for DefaultEnvKey {}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CommandEnv<K> { pub struct CommandEnv<K> {
clear: bool, clear: bool,
saw_path: bool,
vars: BTreeMap<K, Option<OsString>> vars: BTreeMap<K, Option<OsString>>
} }
@ -54,6 +55,7 @@ impl<K: EnvKey> Default for CommandEnv<K> {
fn default() -> Self { fn default() -> Self {
CommandEnv { CommandEnv {
clear: false, clear: false,
saw_path: false,
vars: Default::default() vars: Default::default()
} }
} }
@ -108,9 +110,11 @@ impl<K: EnvKey> CommandEnv<K> {
// The following functions build up changes // The following functions build up changes
pub fn set(&mut self, key: &OsStr, value: &OsStr) { pub fn set(&mut self, key: &OsStr, value: &OsStr) {
self.maybe_saw_path(&key);
self.vars.insert(key.to_owned().into(), Some(value.to_owned())); self.vars.insert(key.to_owned().into(), Some(value.to_owned()));
} }
pub fn remove(&mut self, key: &OsStr) { pub fn remove(&mut self, key: &OsStr) {
self.maybe_saw_path(&key);
if self.clear { if self.clear {
self.vars.remove(key); self.vars.remove(key);
} else { } else {
@ -121,4 +125,12 @@ impl<K: EnvKey> CommandEnv<K> {
self.clear = true; self.clear = true;
self.vars.clear(); self.vars.clear();
} }
pub fn have_changed_path(&self) -> bool {
self.saw_path || self.clear
}
fn maybe_saw_path(&mut self, key: &OsStr) {
if !self.saw_path && key.to_os_string() == OsString::from("PATH") {
self.saw_path = true;
}
}
} }