diff options
| author | kennytm <kennytm@gmail.com> | 2017-12-02 01:38:54 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-12-02 01:38:54 +0800 |
| commit | 9493d4b95c55a4ed502751170a0d86f9b5e305d8 (patch) | |
| tree | a497deded4ebcae8e3697af1f6d076df96b9976f /src | |
| parent | 263eb4d7ef221e075102c76d85bd7b0d874457b2 (diff) | |
| parent | ccef9696f13b39b619f7b12d770a2908cc2ecdd3 (diff) | |
| download | rust-9493d4b95c55a4ed502751170a0d86f9b5e305d8.tar.gz rust-9493d4b95c55a4ed502751170a0d86f9b5e305d8.zip | |
Rollup merge of #46373 - jakllsch:netbsd-kern_proc_pathname, r=kennytm
NetBSD: add sysctl backend for std::env::current_exe Use the CTL_KERN.KERN_PROC_ARGS.-1.KERN_PROC_PATHNAME sysctl in preference over the /proc/curproc/exe symlink. Additionally, perform more validation of aformentioned symlink. Particularly on pre-8.x NetBSD this symlink will point to '/' when accurate information is unavailable.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 7e965b4b4c5..4f33a2b12fe 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -223,7 +223,34 @@ pub fn current_exe() -> io::Result<PathBuf> { #[cfg(target_os = "netbsd")] pub fn current_exe() -> io::Result<PathBuf> { - ::fs::read_link("/proc/curproc/exe") + fn sysctl() -> io::Result<PathBuf> { + unsafe { + let mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, -1, libc::KERN_PROC_PATHNAME]; + let mut path_len: usize = 0; + cvt(libc::sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint, + ptr::null_mut(), &mut path_len, + ptr::null(), 0))?; + if path_len <= 1 { + return Err(io::Error::new(io::ErrorKind::Other, + "KERN_PROC_PATHNAME sysctl returned zero-length string")) + } + let mut path: Vec<u8> = Vec::with_capacity(path_len); + cvt(libc::sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint, + path.as_ptr() as *mut libc::c_void, &mut path_len, + ptr::null(), 0))?; + path.set_len(path_len - 1); // chop off NUL + Ok(PathBuf::from(OsString::from_vec(path))) + } + } + fn procfs() -> io::Result<PathBuf> { + let curproc_exe = path::Path::new("/proc/curproc/exe"); + if curproc_exe.is_file() { + return ::fs::read_link(curproc_exe); + } + Err(io::Error::new(io::ErrorKind::Other, + "/proc/curproc/exe doesn't point to regular file.")) + } + sysctl().or_else(|_| procfs()) } #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] |
