summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorWesley Wiser <wesleywiser@microsoft.com>2022-11-28 13:14:06 -0500
committerWesley Wiser <wesleywiser@microsoft.com>2022-11-28 14:31:36 -0500
commit006fc6f7975b3a6b64329847b780622aab392109 (patch)
tree156cdf7be0cfc62a499fc29c600b4e5360ee9074 /src/sys
parent33a4d495d99590d17ce4ced675bb6bf4a11d9251 (diff)
downloadnix-006fc6f7975b3a6b64329847b780622aab392109.zip
Update use of libc::timespec to prepare for future libc version
In a future release of the `libc` crate, `libc::timespec` will contain private padding fields on `*-linux-musl` targets and so the struct will no longer be able to be created using the literal initialization syntax. Update places where `libc::timespec` is created to first zero initialize the value and then update the `tv_sec` and `tv_nsec` fields manually. Many of these places are in `const fn`s so a helper function `zero_init_timespec()` is introduced to help with this as `std::mem::MaybeUninit::zeroed()` is not a `const` function. Some matches on `libc::timespec` are also updated to include a trailing `..` pattern which works when `libc::timespec` has additional, private fields as well as when it does not (like for `x86_64-unknown-linux-gnu`).
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/time.rs68
1 files changed, 33 insertions, 35 deletions
diff --git a/src/sys/time.rs b/src/sys/time.rs
index a7240849..0042c450 100644
--- a/src/sys/time.rs
+++ b/src/sys/time.rs
@@ -6,6 +6,13 @@ use std::convert::From;
use std::time::Duration;
use std::{cmp, fmt, ops};
+const fn zero_init_timespec() -> timespec {
+ // `std::mem::MaybeUninit::zeroed()` is not yet a const fn
+ // (https://github.com/rust-lang/rust/issues/91850) so we will instead initialize an array of
+ // the appropriate size to zero and then transmute it to a timespec value.
+ unsafe { std::mem::transmute([0u8; std::mem::size_of::<timespec>()]) }
+}
+
#[cfg(any(
all(feature = "time", any(target_os = "android", target_os = "linux")),
all(
@@ -20,7 +27,7 @@ use std::{cmp, fmt, ops};
)
))]
pub(crate) mod timer {
- use crate::sys::time::TimeSpec;
+ use crate::sys::time::{zero_init_timespec, TimeSpec};
use bitflags::bitflags;
#[derive(Debug, Clone, Copy)]
@@ -29,14 +36,8 @@ pub(crate) mod timer {
impl TimerSpec {
pub const fn none() -> Self {
Self(libc::itimerspec {
- it_interval: libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- },
- it_value: libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- },
+ it_interval: zero_init_timespec(),
+ it_value: zero_init_timespec(),
})
}
}
@@ -57,10 +58,7 @@ pub(crate) mod timer {
fn from(expiration: Expiration) -> TimerSpec {
match expiration {
Expiration::OneShot(t) => TimerSpec(libc::itimerspec {
- it_interval: libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- },
+ it_interval: zero_init_timespec(),
it_value: *t.as_ref(),
}),
Expiration::IntervalDelayed(start, interval) => {
@@ -118,6 +116,7 @@ pub(crate) mod timer {
libc::timespec {
tv_sec: 0,
tv_nsec: 0,
+ ..
},
it_value: ts,
}) => Expiration::OneShot(ts.into()),
@@ -257,18 +256,17 @@ impl PartialOrd for TimeSpec {
impl TimeValLike for TimeSpec {
#[inline]
+ #[cfg_attr(target_env = "musl", allow(deprecated))]
+ // https://github.com/rust-lang/libc/issues/1848
fn seconds(seconds: i64) -> TimeSpec {
assert!(
(TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&seconds),
"TimeSpec out of bounds; seconds={}",
seconds
);
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- TimeSpec(timespec {
- tv_sec: seconds as time_t,
- tv_nsec: 0,
- })
+ let mut ts = zero_init_timespec();
+ ts.tv_sec = seconds as time_t;
+ TimeSpec(ts)
}
#[inline]
@@ -292,18 +290,18 @@ impl TimeValLike for TimeSpec {
/// Makes a new `TimeSpec` with given number of nanoseconds.
#[inline]
+ #[cfg_attr(target_env = "musl", allow(deprecated))]
+ // https://github.com/rust-lang/libc/issues/1848
fn nanoseconds(nanoseconds: i64) -> TimeSpec {
let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC);
assert!(
(TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs),
"TimeSpec out of bounds"
);
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- TimeSpec(timespec {
- tv_sec: secs as time_t,
- tv_nsec: nanos as timespec_tv_nsec_t,
- })
+ let mut ts = zero_init_timespec();
+ ts.tv_sec = secs as time_t;
+ ts.tv_nsec = nanos as timespec_tv_nsec_t;
+ TimeSpec(ts)
}
// The cast is not unnecessary on all platforms.
@@ -337,10 +335,10 @@ impl TimeSpec {
/// Construct a new `TimeSpec` from its components
#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
pub const fn new(seconds: time_t, nanoseconds: timespec_tv_nsec_t) -> Self {
- Self(timespec {
- tv_sec: seconds,
- tv_nsec: nanoseconds,
- })
+ let mut ts = zero_init_timespec();
+ ts.tv_sec = seconds;
+ ts.tv_nsec = nanoseconds;
+ Self(ts)
}
fn nanos_mod_sec(&self) -> timespec_tv_nsec_t {
@@ -360,13 +358,13 @@ impl TimeSpec {
self.0.tv_nsec
}
+ #[cfg_attr(target_env = "musl", allow(deprecated))]
+ // https://github.com/rust-lang/libc/issues/1848
pub const fn from_duration(duration: Duration) -> Self {
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- TimeSpec(timespec {
- tv_sec: duration.as_secs() as time_t,
- tv_nsec: duration.subsec_nanos() as timespec_tv_nsec_t,
- })
+ let mut ts = zero_init_timespec();
+ ts.tv_sec = duration.as_secs() as time_t;
+ ts.tv_nsec = duration.subsec_nanos() as timespec_tv_nsec_t;
+ TimeSpec(ts)
}
pub const fn from_timespec(timespec: timespec) -> Self {