diff --git a/src/env_universal_common.rs b/src/env_universal_common.rs index 8ee9d8466..e065d129c 100644 --- a/src/env_universal_common.rs +++ b/src/env_universal_common.rs @@ -799,12 +799,14 @@ impl EnvUniversal { // unlikely to affect users. #[cfg(any(target_os = "linux", target_os = "android"))] { - let mut times: [libc::timespec; 2] = unsafe { std::mem::zeroed() }; - times[0].tv_nsec = libc::UTIME_OMIT; // don't change ctime - if unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, &mut times[1]) } != 0 { - unsafe { - libc::futimens(private_fd.as_raw_fd(), ×[0]); - } + use crate::libc::{clock_gettime64, futimens64, timespec64}; + #[allow(clippy::useless_conversion)] + let t0 = timespec64 { + tv_sec: 0, + tv_nsec: libc::UTIME_OMIT.try_into().unwrap(), // don't change ctime + }; + if let Some(t1) = clock_gettime64(libc::CLOCK_REALTIME) { + futimens64(private_fd.as_raw_fd(), t0, t1); } } diff --git a/src/libc.c b/src/libc.c index d35244857..af23e1ae9 100644 --- a/src/libc.c +++ b/src/libc.c @@ -285,3 +285,22 @@ int C_getrusage64(int resource, struct rusage64* usage) { usage->ru_nsignals = tmp.ru_nsignals; return result; } + +bool C_clock_gettime64(clockid_t clock_id, struct timespec64* tp) { + struct timespec tp_; + if (clock_gettime(clock_id, &tp_) == -1) { + return false; + } + tp->tv_sec = tp_.tv_sec; + tp->tv_nsec = tp_.tv_nsec; + return true; +} + +bool C_futimens64(int fd, struct timespec64 times0, struct timespec64 times1) { + struct timespec times[2]; + times[0].tv_sec = times0.tv_sec; + times[0].tv_nsec = times0.tv_nsec; + times[1].tv_sec = times1.tv_sec; + times[1].tv_nsec = times1.tv_nsec; + return futimens(fd, ×[0]) == 0; +} diff --git a/src/libc.rs b/src/libc.rs index 75ad254d2..2fcc672f6 100644 --- a/src/libc.rs +++ b/src/libc.rs @@ -201,3 +201,21 @@ pub fn getrusage64(resource: c_int) -> Option { extern "C" { fn C_getrusage64(resource: c_int, usage: *mut rusage64) -> c_int; } + +pub(crate) fn clock_gettime64(clk_id: libc::clockid_t) -> Option { + let mut tp = unsafe { std::mem::zeroed() }; + if !unsafe { C_clock_gettime64(clk_id, &mut tp) } { + return None; + } + Some(tp) +} +extern "C" { + fn C_clock_gettime64(clk_id: libc::clockid_t, tp: *mut timespec64) -> bool; +} + +pub(crate) fn futimens64(fd: c_int, time0: timespec64, time1: timespec64) -> bool { + unsafe { C_futimens64(fd, time0, time1) } +} +extern "C" { + fn C_futimens64(fd: c_int, time0: timespec64, time1: timespec64) -> bool; +}