diff options
| author | Jonathan A. Kollasch <jakllsch@kollasch.net> | 2017-11-29 11:31:09 -0600 |
|---|---|---|
| committer | Jonathan A. Kollasch <jakllsch@kollasch.net> | 2017-11-30 12:17:44 -0600 |
| commit | ccef9696f13b39b619f7b12d770a2908cc2ecdd3 (patch) | |
| tree | 978bfed05020e11d0de2be1108732b5edd28b42b /src/libstd/sys | |
| parent | 4fa202d23b4c8c81b8ac6cf89cf843d35854d437 (diff) | |
| download | rust-ccef9696f13b39b619f7b12d770a2908cc2ecdd3.tar.gz rust-ccef9696f13b39b619f7b12d770a2908cc2ecdd3.zip | |
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/libstd/sys')
| -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"))] |
