Merge branch 'faccessat-fchownat' into 'master'
add faccessat(2) and fchownat(2) See merge request redox-os/relibc!1213
This commit is contained in:
@@ -81,14 +81,12 @@ impl Sys {
|
||||
}
|
||||
|
||||
impl Pal for Sys {
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
|
||||
fn access(path: CStr, mode: c_int) -> Result<()> {
|
||||
e_raw(unsafe { syscall!(ACCESS, path.as_ptr(), mode) }).map(|_| ())
|
||||
Sys::faccessat(AT_FDCWD, path, mode, 0)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn access(path: CStr, mode: c_int) -> Result<()> {
|
||||
e_raw(unsafe { syscall!(FACCESSAT, AT_FDCWD, path.as_ptr(), mode, 0) }).map(|_| ())
|
||||
fn faccessat(fd: c_int, path: CStr, amode: c_int, flags: c_int) -> Result<()> {
|
||||
e_raw(unsafe { syscall!(FACCESSAT, fd, path.as_ptr(), amode, flags) }).map(|_| ())
|
||||
}
|
||||
|
||||
unsafe fn brk(addr: *mut c_void) -> Result<*mut c_void> {
|
||||
@@ -104,11 +102,14 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
fn chown(path: CStr, owner: uid_t, group: gid_t) -> Result<()> {
|
||||
let flags: c_int = 0;
|
||||
Sys::fchownat(AT_FDCWD, path, owner, group, 0)
|
||||
}
|
||||
|
||||
fn fchownat(fildes: c_int, path: CStr, owner: uid_t, group: gid_t, flags: c_int) -> Result<()> {
|
||||
e_raw(unsafe {
|
||||
syscall!(
|
||||
FCHOWNAT,
|
||||
AT_FDCWD,
|
||||
fildes,
|
||||
path.as_ptr(),
|
||||
owner as u32,
|
||||
group as u32,
|
||||
|
||||
@@ -37,6 +37,9 @@ pub trait Pal {
|
||||
/// Platform implementation of [`access()`](crate::header::unistd::access) from [`unistd.h`](crate::header::unistd).
|
||||
fn access(path: CStr, mode: c_int) -> Result<()>;
|
||||
|
||||
/// Platform implementation of [`faccessat()`](crate::header::unistd::faccessat) from [`unistd.h`](crate::header::unistd).
|
||||
fn faccessat(fd: c_int, path: CStr, amode: c_int, flags: c_int) -> Result<()>;
|
||||
|
||||
/// Platform implementation of [`brk()`](crate::header::unistd::brk) from [`unistd.h`](crate::header::unistd).
|
||||
unsafe fn brk(addr: *mut c_void) -> Result<*mut c_void>;
|
||||
|
||||
@@ -95,6 +98,9 @@ pub trait Pal {
|
||||
/// Platform implementation of [`fchown()`](crate::header::unistd::fchown) from [`unistd.h`](crate::header::unistd).
|
||||
fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> Result<()>;
|
||||
|
||||
/// Platform implementation of [`fchownat()`](crate::header::unistd::fchownat) from [`unistd.h`](crate::header::unistd).
|
||||
fn fchownat(fildes: c_int, path: CStr, owner: uid_t, group: gid_t, flags: c_int) -> Result<()>;
|
||||
|
||||
/// Platform implementation of [`fdatasync()`](crate::header::unistd::fdatasync) from [`unistd.h`](crate::header::unistd).
|
||||
fn fdatasync(fildes: c_int) -> Result<()>;
|
||||
|
||||
|
||||
@@ -32,8 +32,9 @@ use crate::{
|
||||
ENOSYS, EOPNOTSUPP, EPERM,
|
||||
},
|
||||
fcntl::{
|
||||
self, AT_EMPTY_PATH, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_FOLLOW, AT_SYMLINK_NOFOLLOW,
|
||||
F_GETLK, F_OFD_GETLK, F_OFD_SETLK, F_RDLCK, F_SETLK, F_SETLKW, F_UNLCK, F_WRLCK, flock,
|
||||
self, AT_EACCESS, AT_EMPTY_PATH, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_FOLLOW,
|
||||
AT_SYMLINK_NOFOLLOW, F_GETLK, F_OFD_GETLK, F_OFD_SETLK, F_RDLCK, F_SETLK, F_SETLKW,
|
||||
F_UNLCK, F_WRLCK, flock,
|
||||
},
|
||||
limits,
|
||||
pthread::{pthread_cancel, pthread_create},
|
||||
@@ -107,7 +108,15 @@ pub struct Sys;
|
||||
|
||||
impl Pal for Sys {
|
||||
fn access(path: CStr, mode: c_int) -> Result<()> {
|
||||
let fd = FdGuard::new(Sys::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC, 0)? as usize);
|
||||
Sys::faccessat(AT_FDCWD, path, mode, 0)
|
||||
}
|
||||
|
||||
fn faccessat(fd: c_int, path: CStr, mode: c_int, flags: c_int) -> Result<()> {
|
||||
let fd = FdGuard::new(Sys::openat(fd, path, fcntl::O_PATH | fcntl::O_CLOEXEC, 0)? as usize);
|
||||
|
||||
if (flags & !(AT_EACCESS)) != 0 {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
|
||||
if mode == F_OK {
|
||||
return Ok(());
|
||||
@@ -117,11 +126,22 @@ impl Pal for Sys {
|
||||
|
||||
fd.fstat(&mut stat)?;
|
||||
|
||||
let Resugid { ruid, rgid, .. } = redox_rt::sys::posix_getresugid();
|
||||
let Resugid {
|
||||
ruid,
|
||||
rgid,
|
||||
euid,
|
||||
egid,
|
||||
..
|
||||
} = redox_rt::sys::posix_getresugid();
|
||||
let (uid, gid) = if (flags & AT_EACCESS) == AT_EACCESS {
|
||||
(euid, egid)
|
||||
} else {
|
||||
(ruid, rgid)
|
||||
};
|
||||
|
||||
let perms = (if stat.st_uid == ruid {
|
||||
let perms = (if stat.st_uid == uid {
|
||||
stat.st_mode >> (3 * 2)
|
||||
} else if stat.st_gid == rgid {
|
||||
} else if stat.st_gid == gid {
|
||||
stat.st_mode >> (3 * 1)
|
||||
} else {
|
||||
stat.st_mode
|
||||
@@ -277,7 +297,7 @@ impl Pal for Sys {
|
||||
fn fchmodat(dirfd: c_int, path: Option<CStr>, mode: mode_t, flags: c_int) -> Result<()> {
|
||||
const MASK: c_int = !(fcntl::AT_SYMLINK_NOFOLLOW | fcntl::AT_EMPTY_PATH);
|
||||
if MASK & flags != 0 {
|
||||
return Err(Errno(EOPNOTSUPP));
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
let mut path = path
|
||||
.and_then(|cs| str::from_utf8(cs.to_bytes()).ok())
|
||||
@@ -306,6 +326,21 @@ impl Pal for Sys {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fchownat(fildes: c_int, path: CStr, owner: uid_t, group: gid_t, flags: c_int) -> Result<()> {
|
||||
const MASK: c_int = !(fcntl::AT_SYMLINK_NOFOLLOW | fcntl::AT_EMPTY_PATH);
|
||||
if MASK & flags != 0 {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
let path = path.to_str().map_err(|_| Errno(EINVAL))?;
|
||||
let file = openat2(fildes, path, flags, 0)?;
|
||||
libredox::fchown(
|
||||
*file as usize,
|
||||
owner.try_into().map_err(|_| Errno(EINVAL))?,
|
||||
group.try_into().map_err(|_| Errno(EINVAL))?,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fcntl(fd: c_int, cmd: c_int, args: c_ulonglong) -> Result<c_int> {
|
||||
match cmd {
|
||||
F_SETLK | F_OFD_SETLK => {
|
||||
|
||||
Reference in New Issue
Block a user