1 // Wrapper over the access syscall that doesn't touch errno variable, 2 // Do not use outside of ld_so 3 4 #[cfg(target_os = "redox")] 5 use crate::header::unistd::{F_OK, R_OK, W_OK, X_OK}; 6 use crate::{ 7 c_str::{CStr, CString}, 8 platform::types::*, 9 }; 10 11 pub fn accessible(path: &str, mode: c_int) -> c_int { 12 let path_c = CString::new(path.as_bytes()).unwrap(); /*.map_err(|err| { 13 Error::Malformed(format!("invalid path '{}': {}", path, err)) 14 })?;*/ 15 unsafe { access(path_c.as_ptr(), mode) } 16 } 17 18 #[cfg(target_os = "linux")] 19 unsafe fn access(path: *const c_char, mode: c_int) -> c_int { 20 let path = CStr::from_ptr(path); 21 syscall!(ACCESS, (path).as_ptr(), mode) as c_int 22 } 23 24 #[cfg(target_os = "dragonos")] 25 unsafe fn access(path: *const c_char, mode: c_int) -> c_int { 26 // let path = CStr::from_ptr(path); 27 // syscall!(ACCESS, (path).as_ptr(), mode) as c_int 28 return -1; 29 } 30 31 // Wrapper over the systemcall, Do not use outside of ld_so 32 #[cfg(target_os = "redox")] 33 unsafe fn access(path: *const c_char, mode: c_int) -> c_int { 34 use core::str; 35 let path = match str::from_utf8(CStr::from_ptr(path).to_bytes()) { 36 Ok(ok) => ok, 37 Err(_) => return -1, 38 }; 39 let fd = match crate::platform::sys::path::open(path, syscall::O_CLOEXEC) { 40 Ok(fd) => fd, 41 _ => return -1, 42 }; 43 if mode == F_OK { 44 return 0; 45 } 46 let mut stat = syscall::Stat::default(); 47 if syscall::fstat(fd, &mut stat).is_err() { 48 return -1; 49 } 50 let _ = syscall::close(fd); 51 let uid = match syscall::getuid() { 52 Ok(uid) => uid, 53 Err(_) => return -1, 54 }; 55 let gid = match syscall::getgid() { 56 Ok(gid) => gid, 57 Err(_) => return -1, 58 }; 59 60 let perms = if stat.st_uid as usize == uid { 61 stat.st_mode >> (3 * 2 & 0o7) 62 } else if stat.st_gid as usize == gid { 63 stat.st_mode >> (3 * 1 & 0o7) 64 } else { 65 stat.st_mode & 0o7 66 }; 67 if (mode & R_OK == R_OK && perms & 0o4 != 0o4) 68 || (mode & W_OK == W_OK && perms & 0o2 != 0o2) 69 || (mode & X_OK == X_OK && perms & 0o1 != 0o1) 70 { 71 return -1; 72 } 73 0 74 } 75