Skip to content

Commit

Permalink
Add 64-bit time_t support on 32-bit glibc Linux to set_times
Browse files Browse the repository at this point in the history
  • Loading branch information
beetrees committed Apr 8, 2023
1 parent 4f87a63 commit d530473
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
19 changes: 17 additions & 2 deletions library/std/src/sys/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1192,8 +1192,6 @@ impl File {
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
}
};
#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
cfg_if::cfg_if! {
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
// Redox doesn't appear to support `UTIME_OMIT`.
Expand All @@ -1205,6 +1203,7 @@ impl File {
"setting file times not supported",
))
} else if #[cfg(any(target_os = "android", target_os = "macos"))] {
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
// futimens requires macOS 10.13, and Android API level 19
cvt(unsafe {
weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
Expand All @@ -1231,6 +1230,22 @@ impl File {
})?;
Ok(())
} else {
#[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))]
{
use crate::sys::{time::__timespec64, weak::weak};

// Added in glibc 2.34
weak!(fn __futimens64(libc::c_int, *const __timespec64) -> libc::c_int);

if let Some(futimens64) = __futimens64.get() {
let to_timespec = |time: Option<SystemTime>| time.map(|time| time.t.to_timespec64())
.unwrap_or(__timespec64::new(0, libc::UTIME_OMIT as _));
let times = [to_timespec(times.accessed), to_timespec(times.modified)];
cvt(unsafe { futimens64(self.as_raw_fd(), times.as_ptr()) })?;
return Ok(());
}
}
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?;
Ok(())
}
Expand Down
22 changes: 22 additions & 0 deletions library/std/src/sys/unix/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,16 @@ impl Timespec {
}
self.to_timespec()
}

#[cfg(all(
target_os = "linux",
target_env = "gnu",
target_pointer_width = "32",
not(target_arch = "riscv32")
))]
pub fn to_timespec64(&self) -> __timespec64 {
__timespec64::new(self.tv_sec, self.tv_nsec.0 as _)
}
}

impl From<libc::timespec> for Timespec {
Expand All @@ -190,6 +200,18 @@ pub(in crate::sys::unix) struct __timespec64 {
_padding: i32,
}

#[cfg(all(
target_os = "linux",
target_env = "gnu",
target_pointer_width = "32",
not(target_arch = "riscv32")
))]
impl __timespec64 {
pub(in crate::sys::unix) fn new(tv_sec: i64, tv_nsec: i32) -> Self {
Self { tv_sec, tv_nsec, _padding: 0 }
}
}

#[cfg(all(
target_os = "linux",
target_env = "gnu",
Expand Down

0 comments on commit d530473

Please sign in to comment.