Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix compilation on i686-apple-darwin. #1000

Merged
merged 1 commit into from
Jan 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions src/backend/libc/fs/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,8 +802,8 @@ pub(crate) fn utimensat(
flags: AtFlags,
) -> io::Result<()> {
// Old 32-bit version: libc has `utimensat` but it is not y2038 safe by
// default. But there may be a `__utimensat16` we can use.
#[cfg(fix_y2038)]
// default. But there may be a `__utimensat64` we can use.
#[cfg(all(fix_y2038, not(apple)))]
{
#[cfg(target_env = "gnu")]
if let Some(libc_utimensat) = __utimensat64.get() {
Expand Down Expand Up @@ -874,6 +874,10 @@ pub(crate) fn utimensat(
));
}

// Convert `times`. We only need this in the child, but do it before
// calling `fork` because it might fail.
let (attrbuf_size, times, attrs) = times_to_attrlist(times)?;

// `setattrlistat` was introduced in 10.13 along with `utimensat`, so
// if we don't have `utimensat`, we don't have `setattrlistat` either.
// Emulate it using `fork`, and `fchdir` and [`setattrlist`].
Expand All @@ -896,8 +900,6 @@ pub(crate) fn utimensat(
flags_arg |= FSOPT_NOFOLLOW;
}

let (attrbuf_size, times, attrs) = times_to_attrlist(times);

if setattrlist(
c_str(path),
&attrs,
Expand Down Expand Up @@ -954,7 +956,7 @@ pub(crate) fn utimensat(
}
}

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

// Otherwise use `fsetattrlist`.
let (attrbuf_size, times, attrs) = times_to_attrlist(times);
let (attrbuf_size, times, attrs) = times_to_attrlist(times)?;

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

#[cfg(fix_y2038)]
#[cfg(all(fix_y2038, not(apple)))]
fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> {
let old_times = [
c::timespec {
Expand Down Expand Up @@ -2147,7 +2149,7 @@ pub(crate) fn fcntl_global_nocache(fd: BorrowedFd<'_>, value: bool) -> io::Resul
/// Convert `times` from a `futimens`/`utimensat` argument into `setattrlist`
/// arguments.
#[cfg(apple)]
fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrlist) {
fn times_to_attrlist(times: &Timestamps) -> io::Result<(c::size_t, [c::timespec; 2], Attrlist)> {
// ABI details.
const ATTR_CMN_MODTIME: u32 = 0x0000_0400;
const ATTR_CMN_ACCTIME: u32 = 0x0000_1000;
Expand All @@ -2156,7 +2158,8 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
let mut times = times.clone();

// If we have any `UTIME_NOW` elements, replace them with the current time.
if times.last_access.tv_nsec == c::UTIME_NOW || times.last_modification.tv_nsec == c::UTIME_NOW
if times.last_access.tv_nsec == c::UTIME_NOW.into()
|| times.last_modification.tv_nsec == c::UTIME_NOW.into()
{
let now = {
let mut tv = c::timeval {
Expand All @@ -2172,11 +2175,17 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
tv_nsec: (tv.tv_usec * 1000) as _,
}
};
if times.last_access.tv_nsec == c::UTIME_NOW {
times.last_access = now;
if times.last_access.tv_nsec == c::UTIME_NOW.into() {
times.last_access = crate::timespec::Timespec {
tv_sec: now.tv_sec.into(),
tv_nsec: now.tv_nsec as _,
};
}
if times.last_modification.tv_nsec == c::UTIME_NOW {
times.last_modification = now;
if times.last_modification.tv_nsec == c::UTIME_NOW.into() {
times.last_modification = crate::timespec::Timespec {
tv_sec: now.tv_sec.into(),
tv_nsec: now.tv_nsec as _,
};
}
}

Expand All @@ -2198,19 +2207,33 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
tv_nsec: 0,
}; 2];
let mut times_index = 0;
if times.last_modification.tv_nsec != c::UTIME_OMIT {
if times.last_modification.tv_nsec != c::UTIME_OMIT.into() {
attrs.commonattr |= ATTR_CMN_MODTIME;
return_times[times_index] = times.last_modification;
return_times[times_index] = c::timespec {
tv_sec: times
.last_modification
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_modification.tv_nsec as _,
};
times_index += 1;
times_size += size_of::<c::timespec>();
}
if times.last_access.tv_nsec != c::UTIME_OMIT {
if times.last_access.tv_nsec != c::UTIME_OMIT.into() {
attrs.commonattr |= ATTR_CMN_ACCTIME;
return_times[times_index] = times.last_access;
return_times[times_index] = c::timespec {
tv_sec: times
.last_access
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_access.tv_nsec as _,
};
times_size += size_of::<c::timespec>();
}

(times_size, return_times, attrs)
Ok((times_size, return_times, attrs))
}

/// Support type for `Attrlist`.
Expand Down
Loading