Skip to content

Commit 9e863ae

Browse files
authored
Rollup merge of #110093 - beetrees:set-times-32-bit, r=joshtriplett
Add 64-bit `time_t` support on 32-bit glibc Linux to `set_times` Add support to `set_times` for 64-bit `time_t` on 32-bit glibc Linux platforms which have a 32-bit `time_t`. Split from #109773. Tracking issue: #98245
2 parents 4da8a7a + d530473 commit 9e863ae

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

library/std/src/sys/unix/fs.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -1193,8 +1193,6 @@ impl File {
11931193
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
11941194
}
11951195
};
1196-
#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
1197-
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
11981196
cfg_if::cfg_if! {
11991197
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
12001198
// Redox doesn't appear to support `UTIME_OMIT`.
@@ -1206,6 +1204,7 @@ impl File {
12061204
"setting file times not supported",
12071205
))
12081206
} else if #[cfg(any(target_os = "android", target_os = "macos"))] {
1207+
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
12091208
// futimens requires macOS 10.13, and Android API level 19
12101209
cvt(unsafe {
12111210
weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
@@ -1232,6 +1231,22 @@ impl File {
12321231
})?;
12331232
Ok(())
12341233
} else {
1234+
#[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))]
1235+
{
1236+
use crate::sys::{time::__timespec64, weak::weak};
1237+
1238+
// Added in glibc 2.34
1239+
weak!(fn __futimens64(libc::c_int, *const __timespec64) -> libc::c_int);
1240+
1241+
if let Some(futimens64) = __futimens64.get() {
1242+
let to_timespec = |time: Option<SystemTime>| time.map(|time| time.t.to_timespec64())
1243+
.unwrap_or(__timespec64::new(0, libc::UTIME_OMIT as _));
1244+
let times = [to_timespec(times.accessed), to_timespec(times.modified)];
1245+
cvt(unsafe { futimens64(self.as_raw_fd(), times.as_ptr()) })?;
1246+
return Ok(());
1247+
}
1248+
}
1249+
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
12351250
cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?;
12361251
Ok(())
12371252
}

library/std/src/sys/unix/time.rs

+22
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ impl Timespec {
166166
}
167167
self.to_timespec()
168168
}
169+
170+
#[cfg(all(
171+
target_os = "linux",
172+
target_env = "gnu",
173+
target_pointer_width = "32",
174+
not(target_arch = "riscv32")
175+
))]
176+
pub fn to_timespec64(&self) -> __timespec64 {
177+
__timespec64::new(self.tv_sec, self.tv_nsec.0 as _)
178+
}
169179
}
170180

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

203+
#[cfg(all(
204+
target_os = "linux",
205+
target_env = "gnu",
206+
target_pointer_width = "32",
207+
not(target_arch = "riscv32")
208+
))]
209+
impl __timespec64 {
210+
pub(in crate::sys::unix) fn new(tv_sec: i64, tv_nsec: i32) -> Self {
211+
Self { tv_sec, tv_nsec, _padding: 0 }
212+
}
213+
}
214+
193215
#[cfg(all(
194216
target_os = "linux",
195217
target_env = "gnu",

0 commit comments

Comments
 (0)