1
- use crate::fmt;
2
1
use crate::time::Duration;
2
+ use crate::{fmt, io};
3
3
4
4
const NSEC_PER_SEC: u64 = 1_000_000_000;
5
5
pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
@@ -34,8 +34,8 @@ pub(crate) struct Timespec {
34
34
35
35
impl SystemTime {
36
36
#[cfg_attr(any(target_os = "horizon", target_os = "hurd"), allow(unused))]
37
- pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime {
38
- SystemTime { t: Timespec::new(tv_sec, tv_nsec) }
37
+ pub fn new(tv_sec: i64, tv_nsec: i64) -> Result< SystemTime, io::Error> {
38
+ Ok( SystemTime { t: Timespec::new(tv_sec, tv_nsec)? })
39
39
}
40
40
41
41
pub fn now() -> SystemTime {
@@ -55,12 +55,6 @@ impl SystemTime {
55
55
}
56
56
}
57
57
58
- impl From<libc::timespec> for SystemTime {
59
- fn from(t: libc::timespec) -> SystemTime {
60
- SystemTime { t: Timespec::from(t) }
61
- }
62
- }
63
-
64
58
impl fmt::Debug for SystemTime {
65
59
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66
60
f.debug_struct("SystemTime")
@@ -71,11 +65,15 @@ impl fmt::Debug for SystemTime {
71
65
}
72
66
73
67
impl Timespec {
68
+ const unsafe fn new_unchecked(tv_sec: i64, tv_nsec: i64) -> Timespec {
69
+ Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } }
70
+ }
71
+
74
72
pub const fn zero() -> Timespec {
75
- Timespec::new (0, 0)
73
+ unsafe { Self::new_unchecked (0, 0) }
76
74
}
77
75
78
- const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
76
+ const fn new(tv_sec: i64, tv_nsec: i64) -> Result< Timespec, io::Error> {
79
77
// On Apple OS, dates before epoch are represented differently than on other
80
78
// Unix platforms: e.g. 1/10th of a second before epoch is represented as `seconds=-1`
81
79
// and `nanoseconds=100_000_000` on other platforms, but is `seconds=0` and
@@ -100,9 +98,11 @@ impl Timespec {
100
98
} else {
101
99
(tv_sec, tv_nsec)
102
100
};
103
- assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64);
104
- // SAFETY: The assert above checks tv_nsec is within the valid range
105
- Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } }
101
+ if tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 {
102
+ Ok(unsafe { Self::new_unchecked(tv_sec, tv_nsec) })
103
+ } else {
104
+ Err(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid timestamp"))
105
+ }
106
106
}
107
107
108
108
pub fn now(clock: libc::clockid_t) -> Timespec {
@@ -126,13 +126,15 @@ impl Timespec {
126
126
if let Some(clock_gettime64) = __clock_gettime64.get() {
127
127
let mut t = MaybeUninit::uninit();
128
128
cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap();
129
- return Timespec::from(unsafe { t.assume_init() });
129
+ let t = unsafe { t.assume_init() };
130
+ return Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap();
130
131
}
131
132
}
132
133
133
134
let mut t = MaybeUninit::uninit();
134
135
cvt(unsafe { libc::clock_gettime(clock, t.as_mut_ptr()) }).unwrap();
135
- Timespec::from(unsafe { t.assume_init() })
136
+ let t = unsafe { t.assume_init() };
137
+ Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap()
136
138
}
137
139
138
140
pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
@@ -178,7 +180,7 @@ impl Timespec {
178
180
nsec -= NSEC_PER_SEC as u32;
179
181
secs = secs.checked_add(1)?;
180
182
}
181
- Some(Timespec::new (secs, nsec.into()))
183
+ Some(unsafe { Timespec::new_unchecked (secs, nsec.into()) } )
182
184
}
183
185
184
186
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
@@ -190,7 +192,7 @@ impl Timespec {
190
192
nsec += NSEC_PER_SEC as i32;
191
193
secs = secs.checked_sub(1)?;
192
194
}
193
- Some(Timespec::new (secs, nsec.into()))
195
+ Some(unsafe { Timespec::new_unchecked (secs, nsec.into()) } )
194
196
}
195
197
196
198
#[allow(dead_code)]
@@ -226,12 +228,6 @@ impl Timespec {
226
228
}
227
229
}
228
230
229
- impl From<libc::timespec> for Timespec {
230
- fn from(t: libc::timespec) -> Timespec {
231
- Timespec::new(t.tv_sec as i64, t.tv_nsec as i64)
232
- }
233
- }
234
-
235
231
#[cfg(all(
236
232
target_os = "linux",
237
233
target_env = "gnu",
@@ -260,18 +256,6 @@ impl __timespec64 {
260
256
}
261
257
}
262
258
263
- #[cfg(all(
264
- target_os = "linux",
265
- target_env = "gnu",
266
- target_pointer_width = "32",
267
- not(target_arch = "riscv32")
268
- ))]
269
- impl From<__timespec64> for Timespec {
270
- fn from(t: __timespec64) -> Timespec {
271
- Timespec::new(t.tv_sec, t.tv_nsec.into())
272
- }
273
- }
274
-
275
259
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
276
260
pub struct Instant {
277
261
t: Timespec,
0 commit comments