From: Ashe Connor Date: Thu, 26 Oct 2017 07:30:50 +0000 (+1100) Subject: Try to replicate shell behavior more accurately X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~5^2~28^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=1bb43b081afbc76a5589a338ce10c5267c5ff256;p=cargo.git Try to replicate shell behavior more accurately --- diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index 465dc344e..e6aa79477 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -166,30 +166,33 @@ impl Config { fn from_argv() -> CargoResult { // Grab argv[0] and attempt to resolve it to an absolute path. - // Path::canonicalize succeeds only when the path is already absolute, - // or it's a relative path accessible from the current directory. + // If argv[0] has one component, it must have come from a PATH lookup, + // so probe PATH in that case. + // Otherwise, it has multiple components and is either: + // - a relative path (e.g. `./cargo`, `target/debug/cargo`), or + // - an absolute path (e.g. `/usr/local/bin/cargo`). + // In either case, Path::canonicalize will return the full absolute path + // to the target if it exists env::args_os() .next() .ok_or(CargoError::from("no argv[0]")) .map(PathBuf::from) - .and_then(|argv0| argv0.canonicalize().or_else(|_| probe_path(argv0))) + .and_then(|argv0| { + if argv0.components().count() == 1 { + probe_path(argv0) + } else { + argv0.canonicalize().map_err(CargoError::from) + } + }) } fn probe_path(argv0: PathBuf) -> CargoResult { - // Path::canonicalize failed, so finally, if argv[0] has no directory - // separator in it, we look through the PATH environment variable checking - // for a matching file in each directory. - // A directory separator implies either (a) an absolute path, so we - // shouldn't check PATH, or (b) a relative path with a directory component, - // which wouldn't search PATH in any shell anyway. - if argv0.components().count() > 1 { - return Err(CargoError::from("no cargo executable candidate found")); - } - let paths = env::var_os("PATH").ok_or(CargoError::from("no PATH"))?; for path in env::split_paths(&paths) { let candidate = PathBuf::from(path).join(&argv0); if candidate.is_file() { + // PATH may have a component like "." in it, so we still need to + // canonicalize. return candidate.canonicalize().map_err(CargoError::from); } }