|
3 | 3 | // For the full copyright and license information, please view the LICENSE |
4 | 4 | // file that was distributed with this source code. |
5 | 5 |
|
6 | | -// spell-checker:ignore prefixcat testcat |
| 6 | +// spell-checker:ignore prefixcat testcat getauxval EXECFN |
7 | 7 |
|
8 | 8 | use std::ffi::{OsStr, OsString}; |
9 | 9 | use std::path::{Path, PathBuf}; |
@@ -67,15 +67,29 @@ fn get_canonical_util_name(util_name: &str) -> &str { |
67 | 67 | } |
68 | 68 |
|
69 | 69 | /// Gets the binary path from command line arguments |
70 | | -/// # Panics |
71 | 70 | /// Panics if the binary path cannot be determined |
| 71 | +#[cfg(not(any(target_os = "linux", target_os = "android")))] |
72 | 72 | pub fn binary_path(args: &mut impl Iterator<Item = OsString>) -> PathBuf { |
73 | 73 | match args.next() { |
74 | 74 | Some(ref s) if !s.is_empty() => PathBuf::from(s), |
75 | 75 | _ => std::env::current_exe().unwrap(), |
76 | 76 | } |
77 | 77 | } |
78 | | - |
| 78 | +/// protect against env -a |
| 79 | +#[cfg(any(target_os = "linux", target_os = "android"))] |
| 80 | +pub fn binary_path(args: &mut impl Iterator<Item = OsString>) -> PathBuf { |
| 81 | + use std::ffi::{CStr, OsString}; |
| 82 | + use std::os::unix::ffi::OsStringExt; |
| 83 | + let p: *const libc::c_char = unsafe { libc::getauxval(libc::AT_EXECFN) as _ }; |
| 84 | + if p.is_null() { |
| 85 | + use std::io::{Write as _, stderr}; |
| 86 | + let _ = writeln!(stderr(), "getauxval failed"); |
| 87 | + process::exit(1); |
| 88 | + } |
| 89 | + let _ = args.next(); |
| 90 | + let n = unsafe { CStr::from_ptr(p) }; |
| 91 | + OsString::from_vec(n.to_bytes().to_vec()).into() |
| 92 | +} |
79 | 93 | /// Extracts the binary name from a path |
80 | 94 | pub fn name(binary_path: &Path) -> Option<&str> { |
81 | 95 | binary_path.file_stem()?.to_str() |
|
0 commit comments