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