1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- // Wrapper over the access syscall that doesn't touch errno variable,
- // Do not use outside of ld_so
- #[cfg(target_os = "redox")]
- use crate::header::unistd::{F_OK, R_OK, W_OK, X_OK};
- use crate::{
- c_str::{CStr, CString},
- platform::types::*,
- };
- pub fn accessible(path: &str, mode: c_int) -> c_int {
- let path_c = CString::new(path.as_bytes()).unwrap(); /*.map_err(|err| {
- Error::Malformed(format!("invalid path '{}': {}", path, err))
- })?;*/
- unsafe { access(path_c.as_ptr(), mode) }
- }
- #[cfg(target_os = "linux")]
- unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
- let path = CStr::from_ptr(path);
- syscall!(ACCESS, (path).as_ptr(), mode) as c_int
- }
- // Wrapper over the systemcall, Do not use outside of ld_so
- #[cfg(target_os = "redox")]
- unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
- let path = CStr::from_ptr(path).to_bytes();
- let fd = match syscall::open(path, syscall::O_CLOEXEC) {
- Ok(fd) => fd,
- _ => return -1,
- };
- if mode == F_OK {
- return 0;
- }
- let mut stat = syscall::Stat::default();
- if syscall::fstat(fd, &mut stat).is_err() {
- return -1;
- }
- let uid = match syscall::getuid() {
- Ok(uid) => uid,
- Err(_) => return -1,
- };
- let gid = match syscall::getgid() {
- Ok(gid) => gid,
- Err(_) => return -1,
- };
- let perms = if stat.st_uid as usize == uid {
- stat.st_mode >> (3 * 2 & 0o7)
- } else if stat.st_gid as usize == gid {
- stat.st_mode >> (3 * 1 & 0o7)
- } else {
- stat.st_mode & 0o7
- };
- if (mode & R_OK == R_OK && perms & 0o4 != 0o4)
- || (mode & W_OK == W_OK && perms & 0o2 != 0o2)
- || (mode & X_OK == X_OK && perms & 0o1 != 0o1)
- {
- return -1;
- }
- 0
- }
|