Merge branch 'utimensat' into 'master'
Implement utimensat See merge request redox-os/relibc!1263
This commit is contained in:
@@ -6,7 +6,7 @@ use crate::{
|
||||
c_str::CStr,
|
||||
error::ResultExt,
|
||||
header::{
|
||||
fcntl::{O_NOFOLLOW, O_PATH},
|
||||
fcntl::{AT_SYMLINK_NOFOLLOW, O_NOFOLLOW, O_PATH},
|
||||
time::timespec,
|
||||
},
|
||||
out::Out,
|
||||
@@ -240,3 +240,22 @@ pub unsafe extern "C" fn stat(file: *const c_char, buf: *mut stat) -> c_int {
|
||||
pub extern "C" fn umask(mask: mode_t) -> mode_t {
|
||||
Sys::umask(mask)
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/utimensat.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn utimensat(
|
||||
fd: c_int,
|
||||
path: *const c_char,
|
||||
times: *const timespec,
|
||||
flag: c_int,
|
||||
) -> c_int {
|
||||
let path = unsafe { CStr::from_ptr(path) };
|
||||
match Sys::openat(fd, path, flag & AT_SYMLINK_NOFOLLOW, 0) {
|
||||
Ok(fd) => unsafe {
|
||||
let r = Sys::futimens(fd, times).map(|()| 0).or_minus_one_errno();
|
||||
let _ = Sys::close(fd);
|
||||
r
|
||||
},
|
||||
r => r.or_minus_one_errno(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ EXPECT_NAMES=\
|
||||
sys_stat/lstat \
|
||||
sys_stat/fstatat \
|
||||
sys_stat/umask \
|
||||
sys_stat/utimensat \
|
||||
sys_syslog/syslog \
|
||||
time/asctime \
|
||||
time/constants \
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main() {
|
||||
const char *test_file = "utimensat.txt";
|
||||
struct stat st;
|
||||
struct timespec times[2];
|
||||
|
||||
int fd = open(test_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
ERROR_IF(open, fd, == -1);
|
||||
close(fd);
|
||||
|
||||
times[0].tv_sec = 100;
|
||||
times[0].tv_nsec = 0;
|
||||
times[1].tv_sec = 200;
|
||||
times[1].tv_nsec = 0;
|
||||
|
||||
int utime_status = utimensat(AT_FDCWD, test_file, times, 0);
|
||||
ERROR_IF(utimensat, utime_status, == -1);
|
||||
|
||||
int stat_status = stat(test_file, &st);
|
||||
ERROR_IF(stat, stat_status, == -1);
|
||||
|
||||
UNEXP_IF(utimensat_atime, st.st_atime, != times[0].tv_sec);
|
||||
UNEXP_IF(utimensat_mtime, st.st_mtime, != times[1].tv_sec);
|
||||
|
||||
int unlink_status = unlink(test_file);
|
||||
ERROR_IF(unlink, unlink_status, == -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user