|
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