Skip to content

Commit d530473

Browse files
committed
Add 64-bit time_t support on 32-bit glibc Linux to set_times
1 parent 4f87a63 commit d530473

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

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)