Skip to content

Commit

Permalink
Make Nsecs be 64-bit on 32-bit x86 Linux.
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Oct 9, 2023
1 parent 28f25ad commit 52573b4
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
24 changes: 20 additions & 4 deletions src/backend/libc/fs/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,15 +933,23 @@ fn utimensat_old(
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_access.tv_nsec,
tv_nsec: times
.last_access
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
c::timespec {
tv_sec: times
.last_modification
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_modification.tv_nsec,
tv_nsec: times
.last_modification
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
];
unsafe {
Expand Down Expand Up @@ -1515,15 +1523,23 @@ fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> {
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_access.tv_nsec,
tv_nsec: times
.last_access
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
c::timespec {
tv_sec: times
.last_modification
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_modification.tv_nsec,
tv_nsec: times
.last_modification
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
];

Expand Down
25 changes: 15 additions & 10 deletions src/timespec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! `Timespec` and related types, which are used by multiple public API
//! modules.
#[cfg(not(fix_y2038))]
use crate::backend::c;

/// `struct timespec`
Expand Down Expand Up @@ -28,18 +29,22 @@ pub type Secs = c::time_t;
#[cfg(fix_y2038)]
pub type Secs = i64;

/// A type for the `tv_nsec` field of [`Timespec`].
#[cfg(all(libc, target_arch = "x86_64", target_pointer_width = "32"))]
/// A type for the `tv_sec` field of [`Timespec`].
#[cfg(any(
fix_y2038,
linux_raw,
all(libc, target_arch = "x86_64", target_pointer_width = "32")
))]
pub type Nsecs = i64;

/// A type for the `tv_nsec` field of [`Timespec`].
#[cfg(all(libc, not(all(target_arch = "x86_64", target_pointer_width = "32"))))]
#[cfg(all(
not(fix_y2038),
libc,
not(all(target_arch = "x86_64", target_pointer_width = "32"))
))]
pub type Nsecs = c::c_long;

/// A type for the `tv_nsec` field of [`Timespec`].
#[cfg(linux_raw)]
pub type Nsecs = i64;

/// On 32-bit glibc platforms, `timespec` has anonymous padding fields, which
/// Rust doesn't support yet (see `unnamed_fields`), so we define our own
/// struct with explicit padding, with bidirectional `From` impls.
Expand All @@ -52,7 +57,7 @@ pub(crate) struct LibcTimespec {
#[cfg(target_endian = "big")]
padding: core::mem::MaybeUninit<u32>,

pub(crate) tv_nsec: Nsecs,
pub(crate) tv_nsec: i32,

#[cfg(target_endian = "little")]
padding: core::mem::MaybeUninit<u32>,
Expand All @@ -64,7 +69,7 @@ impl From<LibcTimespec> for Timespec {
fn from(t: LibcTimespec) -> Self {
Self {
tv_sec: t.tv_sec,
tv_nsec: t.tv_nsec,
tv_nsec: t.tv_nsec as _,
}
}
}
Expand All @@ -75,7 +80,7 @@ impl From<Timespec> for LibcTimespec {
fn from(t: Timespec) -> Self {
Self {
tv_sec: t.tv_sec,
tv_nsec: t.tv_nsec,
tv_nsec: t.tv_nsec as _,
padding: core::mem::MaybeUninit::uninit(),
}
}
Expand Down

0 comments on commit 52573b4

Please sign in to comment.