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