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.
This commit is contained in:
parent
4fa202d23b
commit
ccef9696f1
1 changed files with 28 additions and 1 deletions
|
@ -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"))]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue