Merge branch 'utimensat' into 'master'

add utimensat

See merge request redox-os/relibc!1268
This commit is contained in:
Jeremy Soller
2026-05-05 11:49:05 -06:00
4 changed files with 47 additions and 17 deletions
+2
View File
@@ -30,7 +30,9 @@ pub const O_NDELAY: c_int = O_NONBLOCK;
// Flags for capability based "at" functions
pub const AT_FDCWD: c_int = -100;
// fchmodat, fchownat, fstatat, utimensat
pub const AT_SYMLINK_NOFOLLOW: c_int = 0x200;
// unlinkat
pub const AT_REMOVEDIR: c_int = 0x200;
// Used by linkat()
pub const AT_SYMLINK_FOLLOW: c_int = 0x2000;
+7 -6
View File
@@ -304,12 +304,13 @@ impl Pal for Sys {
.map(|n| n as u32)
}
unsafe fn futimens(fd: c_int, times: *const timespec) -> Result<()> {
e_raw(unsafe { syscall!(UTIMENSAT, fd, ptr::null::<c_char>(), times, 0) }).map(|_| ())
}
unsafe fn utimens(path: CStr, times: *const timespec) -> Result<()> {
e_raw(unsafe { syscall!(UTIMENSAT, AT_FDCWD, path.as_ptr(), times, 0) }).map(|_| ())
unsafe fn utimensat(
dirfd: c_int,
path: CStr,
times: *const timespec,
flag: c_int,
) -> Result<()> {
e_raw(unsafe { syscall!(UTIMENSAT, dirfd, path.as_ptr(), times, flag) }).map(|_| ())
}
fn getcwd(mut buf: Out<[u8]>) -> Result<()> {
+16 -3
View File
@@ -149,10 +149,23 @@ pub trait Pal {
unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32>;
/// Platform implementation of [`futimens()`](crate::header::sys_stat::futimens) from [`sys/stat.h`](crate::header::sys_stat).
unsafe fn futimens(fd: c_int, times: *const timespec) -> Result<()>;
unsafe fn futimens(fd: c_int, times: *const timespec) -> Result<()> {
unsafe { Self::utimensat(fd, c"".into(), times, AT_EMPTY_PATH) }
}
/// Platform implementation of `utimens()` (TODO) from [`sys/stat.h`](crate::header::sys_stat).
unsafe fn utimens(path: CStr, times: *const timespec) -> Result<()>;
/// Platform implementation of [`utimens()`](crate::header::unistd::utimens) (from [`sys/stat.h`](crate::header::sys_stat).
/// This is an extension of POSIX.
unsafe fn utimens(path: CStr, times: *const timespec) -> Result<()> {
unsafe { Self::utimensat(AT_FDCWD, path, times, 0) }
}
/// Platform implementation of [`utimensat()`](crate::header::unistd::utimensat) (from [`sys/stat.h`](crate::header::sys_stat).
unsafe fn utimensat(
dirfd: c_int,
path: CStr,
times: *const timespec,
flag: c_int,
) -> Result<()>;
/// Platform implementation of [`getcwd()`](crate::header::unistd::getcwd) from [`unistd.h`](crate::header::unistd).
fn getcwd(buf: Out<[u8]>) -> Result<()>;
+22 -8
View File
@@ -543,14 +543,28 @@ impl Pal for Sys {
Ok(unsafe { redox_rt::sys::sys_futex_wake(addr, num) }?)
}
unsafe fn futimens(fd: c_int, times: *const timespec) -> Result<()> {
(unsafe { libredox::futimens(fd as usize, times) })?;
Ok(())
}
unsafe fn utimensat(
dirfd: c_int,
path: CStr,
times: *const timespec,
flag: c_int,
) -> Result<()> {
let mut path = path.to_str().map_err(|_| Errno(ENOENT))?;
if path.is_empty() {
if flag & AT_EMPTY_PATH == AT_EMPTY_PATH {
if dirfd == AT_FDCWD {
path = ".";
} else {
return Ok(unsafe { libredox::futimens(dirfd as usize, times) }?);
}
} else {
// If the path is empty but `AT_EMPTY_PATH` is **not** set, bail out.
return Err(Errno(ENOENT));
}
}
unsafe fn utimens(path: CStr, times: *const timespec) -> Result<()> {
let file = File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC)?;
unsafe { Self::futimens(*file, times) }
let file = openat2(dirfd, path, flag, fcntl::O_PATH | fcntl::O_CLOEXEC)?;
Ok(unsafe { libredox::futimens(*file as usize, times) }?)
}
fn getcwd(buf: Out<[u8]>) -> Result<()> {
@@ -1491,7 +1505,7 @@ impl Pal for Sys {
// <sysname>\n e.g. "Redox"
// <release>\n e.g. "0.9.0"
// <machine>\n e.g. "x86_64"
// <version>\n e.g. "yyyy-mm-ddThh:mm:ssZ"
// <version>\n e.g. "<commit hash of kernel>
// A future file format might add the domainname.