Skip to content

Commit d268591

Browse files
authored
Fix compilation on i686-apple-darwin. (#1000)
On i686-apple-darwin, `time_t` is 32-bit, so it needs `fix_y2038` and conversions for `Timespec` values. Fixes #991.
1 parent 6ec74e0 commit d268591

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

src/backend/libc/fs/syscalls.rs

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -802,8 +802,8 @@ pub(crate) fn utimensat(
802802
flags: AtFlags,
803803
) -> io::Result<()> {
804804
// Old 32-bit version: libc has `utimensat` but it is not y2038 safe by
805-
// default. But there may be a `__utimensat16` we can use.
806-
#[cfg(fix_y2038)]
805+
// default. But there may be a `__utimensat64` we can use.
806+
#[cfg(all(fix_y2038, not(apple)))]
807807
{
808808
#[cfg(target_env = "gnu")]
809809
if let Some(libc_utimensat) = __utimensat64.get() {
@@ -874,6 +874,10 @@ pub(crate) fn utimensat(
874874
));
875875
}
876876

877+
// Convert `times`. We only need this in the child, but do it before
878+
// calling `fork` because it might fail.
879+
let (attrbuf_size, times, attrs) = times_to_attrlist(times)?;
880+
877881
// `setattrlistat` was introduced in 10.13 along with `utimensat`, so
878882
// if we don't have `utimensat`, we don't have `setattrlistat` either.
879883
// Emulate it using `fork`, and `fchdir` and [`setattrlist`].
@@ -896,8 +900,6 @@ pub(crate) fn utimensat(
896900
flags_arg |= FSOPT_NOFOLLOW;
897901
}
898902

899-
let (attrbuf_size, times, attrs) = times_to_attrlist(times);
900-
901903
if setattrlist(
902904
c_str(path),
903905
&attrs,
@@ -954,7 +956,7 @@ pub(crate) fn utimensat(
954956
}
955957
}
956958

957-
#[cfg(fix_y2038)]
959+
#[cfg(all(fix_y2038, not(apple)))]
958960
fn utimensat_old(
959961
dirfd: BorrowedFd<'_>,
960962
path: &CStr,
@@ -1505,7 +1507,7 @@ fn libc_statvfs_to_statvfs(from: c::statvfs) -> StatVfs {
15051507
pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> {
15061508
// Old 32-bit version: libc has `futimens` but it is not y2038 safe by
15071509
// default. But there may be a `__futimens64` we can use.
1508-
#[cfg(fix_y2038)]
1510+
#[cfg(all(fix_y2038, not(apple)))]
15091511
{
15101512
#[cfg(target_env = "gnu")]
15111513
if let Some(libc_futimens) = __futimens64.get() {
@@ -1556,7 +1558,7 @@ pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()>
15561558
}
15571559

15581560
// Otherwise use `fsetattrlist`.
1559-
let (attrbuf_size, times, attrs) = times_to_attrlist(times);
1561+
let (attrbuf_size, times, attrs) = times_to_attrlist(times)?;
15601562

15611563
ret(fsetattrlist(
15621564
borrowed_fd(fd),
@@ -1568,7 +1570,7 @@ pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()>
15681570
}
15691571
}
15701572

1571-
#[cfg(fix_y2038)]
1573+
#[cfg(all(fix_y2038, not(apple)))]
15721574
fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> {
15731575
let old_times = [
15741576
c::timespec {
@@ -2125,7 +2127,7 @@ pub(crate) fn fcntl_global_nocache(fd: BorrowedFd<'_>, value: bool) -> io::Resul
21252127
/// Convert `times` from a `futimens`/`utimensat` argument into `setattrlist`
21262128
/// arguments.
21272129
#[cfg(apple)]
2128-
fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrlist) {
2130+
fn times_to_attrlist(times: &Timestamps) -> io::Result<(c::size_t, [c::timespec; 2], Attrlist)> {
21292131
// ABI details.
21302132
const ATTR_CMN_MODTIME: u32 = 0x0000_0400;
21312133
const ATTR_CMN_ACCTIME: u32 = 0x0000_1000;
@@ -2134,7 +2136,8 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
21342136
let mut times = times.clone();
21352137

21362138
// If we have any `UTIME_NOW` elements, replace them with the current time.
2137-
if times.last_access.tv_nsec == c::UTIME_NOW || times.last_modification.tv_nsec == c::UTIME_NOW
2139+
if times.last_access.tv_nsec == c::UTIME_NOW.into()
2140+
|| times.last_modification.tv_nsec == c::UTIME_NOW.into()
21382141
{
21392142
let now = {
21402143
let mut tv = c::timeval {
@@ -2150,11 +2153,17 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
21502153
tv_nsec: (tv.tv_usec * 1000) as _,
21512154
}
21522155
};
2153-
if times.last_access.tv_nsec == c::UTIME_NOW {
2154-
times.last_access = now;
2156+
if times.last_access.tv_nsec == c::UTIME_NOW.into() {
2157+
times.last_access = crate::timespec::Timespec {
2158+
tv_sec: now.tv_sec.into(),
2159+
tv_nsec: now.tv_nsec as _,
2160+
};
21552161
}
2156-
if times.last_modification.tv_nsec == c::UTIME_NOW {
2157-
times.last_modification = now;
2162+
if times.last_modification.tv_nsec == c::UTIME_NOW.into() {
2163+
times.last_modification = crate::timespec::Timespec {
2164+
tv_sec: now.tv_sec.into(),
2165+
tv_nsec: now.tv_nsec as _,
2166+
};
21582167
}
21592168
}
21602169

@@ -2176,19 +2185,33 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
21762185
tv_nsec: 0,
21772186
}; 2];
21782187
let mut times_index = 0;
2179-
if times.last_modification.tv_nsec != c::UTIME_OMIT {
2188+
if times.last_modification.tv_nsec != c::UTIME_OMIT.into() {
21802189
attrs.commonattr |= ATTR_CMN_MODTIME;
2181-
return_times[times_index] = times.last_modification;
2190+
return_times[times_index] = c::timespec {
2191+
tv_sec: times
2192+
.last_modification
2193+
.tv_sec
2194+
.try_into()
2195+
.map_err(|_| io::Errno::OVERFLOW)?,
2196+
tv_nsec: times.last_modification.tv_nsec as _,
2197+
};
21822198
times_index += 1;
21832199
times_size += size_of::<c::timespec>();
21842200
}
2185-
if times.last_access.tv_nsec != c::UTIME_OMIT {
2201+
if times.last_access.tv_nsec != c::UTIME_OMIT.into() {
21862202
attrs.commonattr |= ATTR_CMN_ACCTIME;
2187-
return_times[times_index] = times.last_access;
2203+
return_times[times_index] = c::timespec {
2204+
tv_sec: times
2205+
.last_access
2206+
.tv_sec
2207+
.try_into()
2208+
.map_err(|_| io::Errno::OVERFLOW)?,
2209+
tv_nsec: times.last_access.tv_nsec as _,
2210+
};
21882211
times_size += size_of::<c::timespec>();
21892212
}
21902213

2191-
(times_size, return_times, attrs)
2214+
Ok((times_size, return_times, attrs))
21922215
}
21932216

21942217
/// Support type for `Attrlist`.

0 commit comments

Comments
 (0)