use crate::filetime::FileTime;
use crate::{cstr, from_success_code};
use std::fs::File;
use std::io::Result;
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
pub fn utimensat(
dirfd: &File,
path: &str,
atime: FileTime,
mtime: FileTime,
symlink_nofollow: bool,
) -> Result<()> {
use crate::filetime::to_timespec;
use std::os::unix::prelude::*;
let flags = if symlink_nofollow {
libc::AT_SYMLINK_NOFOLLOW
} else {
0
};
static INVALID: AtomicBool = AtomicBool::new(false);
if !INVALID.load(Relaxed) {
let path = cstr(path)?;
let times = [to_timespec(&atime)?, to_timespec(&mtime)?];
let res = from_success_code(unsafe {
libc::syscall(
libc::SYS_utimensat,
dirfd.as_raw_fd(),
path.as_ptr(),
times.as_ptr(),
flags,
)
});
let err = match res {
Ok(()) => return Ok(()),
Err(e) => e,
};
if err.raw_os_error().unwrap() == libc::ENOSYS {
INVALID.store(true, Relaxed);
}
return Err(err);
}
#[cfg(not(target_os = "android"))]
return super::utimesat::utimesat(dirfd, path, atime, mtime, symlink_nofollow);
#[cfg(target_os = "android")]
unreachable!();
}