diff --git a/src/header/sys_stat/mod.rs b/src/header/sys_stat/mod.rs index 0975a20dec..c1dcd3dd2f 100644 --- a/src/header/sys_stat/mod.rs +++ b/src/header/sys_stat/mod.rs @@ -142,6 +142,39 @@ pub unsafe extern "C" fn futimens(fd: c_int, times: *const timespec) -> c_int { .or_minus_one_errno() } +/// See . +#[unsafe(no_mangle)] +pub unsafe extern "C" fn utimensat( + dirfd: c_int, + path: *const c_char, + times: *const timespec, + flags: c_int, +) -> c_int { + // If path is NULL, behave like futimens. + if path.is_null() { + return unsafe { futimens(dirfd, times) }; + } + + let path = unsafe { CStr::from_ptr(path) }; + + let mut oflag = O_PATH; + if flags & crate::header::fcntl::AT_SYMLINK_NOFOLLOW != 0 { + oflag |= O_NOFOLLOW; + } + + let fd = Sys::openat(dirfd, path, oflag, 0).or_minus_one_errno(); + if fd < 0 { + return -1; + } + + let res = unsafe { Sys::futimens(fd, times) } + .map(|()| 0) + .or_minus_one_errno(); + + let _ = Sys::close(fd); + res +} + /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn lstat(path: *const c_char, buf: *mut stat) -> c_int {