|
9 | 9 | // except according to those terms. |
10 | 10 |
|
11 | 11 | use collections::hash_map::HashMap; |
12 | | -use env; |
| 12 | +use env::{self, split_paths}; |
13 | 13 | use ffi::OsStr; |
| 14 | +use os::unix::ffi::OsStrExt; |
14 | 15 | use fmt; |
15 | 16 | use io::{self, Error, ErrorKind}; |
16 | | -use path::Path; |
| 17 | +use path::{Path, PathBuf}; |
17 | 18 | use sys::fd::FileDesc; |
18 | 19 | use sys::fs::{File, OpenOptions}; |
19 | 20 | use sys::pipe::{self, AnonPipe}; |
@@ -313,23 +314,29 @@ impl Command { |
313 | 314 | } |
314 | 315 |
|
315 | 316 | let program = if self.program.contains(':') || self.program.contains('/') { |
316 | | - self.program.to_owned() |
317 | | - } else { |
318 | | - let mut path_env = ::env::var("PATH").unwrap_or(".".to_string()); |
319 | | - |
320 | | - if ! path_env.ends_with('/') { |
321 | | - path_env.push('/'); |
| 317 | + Some(PathBuf::from(&self.program)) |
| 318 | + } else if let Ok(path_env) = ::env::var("PATH") { |
| 319 | + let mut program = None; |
| 320 | + for mut path in split_paths(&path_env) { |
| 321 | + path.push(&self.program); |
| 322 | + if path.exists() { |
| 323 | + program = Some(path); |
| 324 | + break; |
| 325 | + } |
322 | 326 | } |
323 | | - |
324 | | - path_env.push_str(&self.program); |
325 | | - |
326 | | - path_env |
| 327 | + program |
| 328 | + } else { |
| 329 | + None |
327 | 330 | }; |
328 | 331 |
|
329 | | - if let Err(err) = syscall::execve(&program, &args) { |
330 | | - io::Error::from_raw_os_error(err.errno as i32) |
| 332 | + if let Some(program) = program { |
| 333 | + if let Err(err) = syscall::execve(program.as_os_str().as_bytes(), &args) { |
| 334 | + io::Error::from_raw_os_error(err.errno as i32) |
| 335 | + } else { |
| 336 | + panic!("return from exec without err"); |
| 337 | + } |
331 | 338 | } else { |
332 | | - panic!("return from exec without err"); |
| 339 | + io::Error::new(io::ErrorKind::NotFound, "") |
333 | 340 | } |
334 | 341 | } |
335 | 342 |
|
|
0 commit comments