1
1
use super :: utils:: { copy_cstr_into_wasm, write_to_buf} ;
2
- use crate :: { allocate_on_stack, EmEnv } ;
2
+ use crate :: { allocate_on_stack, lazy_static , EmEnv } ;
3
3
use libc:: { c_char, c_int} ;
4
4
// use libc::{c_char, c_int, clock_getres, clock_settime};
5
5
use std:: mem;
@@ -93,24 +93,24 @@ pub fn _clock_gettime(ctx: &EmEnv, clk_id: clockid_t, tp: c_int) -> c_int {
93
93
}
94
94
95
95
#[ allow( unreachable_patterns) ]
96
- let timespec = match clk_id {
97
- CLOCK_REALTIME => time:: get_time ( ) ,
96
+ let duration = match clk_id {
97
+ CLOCK_REALTIME => time:: OffsetDateTime :: now_utc ( ) . unix_timestamp_nanos ( ) ,
98
98
99
99
CLOCK_MONOTONIC | CLOCK_MONOTONIC_COARSE => {
100
- let precise_ns = time :: precise_time_ns ( ) ;
101
- time:: Timespec :: new (
102
- ( precise_ns / 1000000000 ) as i64 ,
103
- ( precise_ns % 1000000000 ) as i32 ,
104
- )
100
+ lazy_static ! {
101
+ static ref PRECISE0 : time:: Instant = time :: Instant :: now ( ) ;
102
+ } ;
103
+ let precise_ns = * PRECISE0 ;
104
+ ( time :: Instant :: now ( ) - precise_ns ) . whole_nanoseconds ( )
105
105
}
106
106
_ => panic ! ( "Clock with id \" {}\" is not supported." , clk_id) ,
107
107
} ;
108
108
109
109
unsafe {
110
110
let timespec_struct_ptr =
111
111
emscripten_memory_pointer ! ( ctx. memory( 0 ) , tp) as * mut GuestTimeSpec ;
112
- ( * timespec_struct_ptr) . tv_sec = timespec . sec as _ ;
113
- ( * timespec_struct_ptr) . tv_nsec = timespec . nsec as _ ;
112
+ ( * timespec_struct_ptr) . tv_sec = ( duration / 1_000_000_000 ) as _ ;
113
+ ( * timespec_struct_ptr) . tv_nsec = ( duration % 1_000_000_000 ) as _ ;
114
114
}
115
115
0
116
116
}
@@ -242,9 +242,8 @@ pub fn _localtime(ctx: &EmEnv, time_p: u32) -> c_int {
242
242
let timespec = unsafe {
243
243
let time_p_addr = emscripten_memory_pointer ! ( ctx. memory( 0 ) , time_p) as * mut i64 ;
244
244
let seconds = * time_p_addr;
245
- time:: Timespec :: new ( seconds, 0 )
245
+ time:: OffsetDateTime :: from_unix_timestamp ( seconds)
246
246
} ;
247
- let result_tm = time:: at ( timespec) ;
248
247
249
248
unsafe {
250
249
let tm_struct_offset = env:: call_malloc ( ctx, mem:: size_of :: < guest_tm > ( ) as _ ) ;
@@ -255,15 +254,15 @@ pub fn _localtime(ctx: &EmEnv, time_p: u32) -> c_int {
255
254
// result_tm.tm_sec, result_tm.tm_min, result_tm.tm_hour, result_tm.tm_mday,
256
255
// result_tm.tm_mon, result_tm.tm_year, result_tm.tm_wday, result_tm.tm_yday,
257
256
// );
258
- ( * tm_struct_ptr) . tm_sec = result_tm . tm_sec ;
259
- ( * tm_struct_ptr) . tm_min = result_tm . tm_min ;
260
- ( * tm_struct_ptr) . tm_hour = result_tm . tm_hour ;
261
- ( * tm_struct_ptr) . tm_mday = result_tm . tm_mday ;
262
- ( * tm_struct_ptr) . tm_mon = result_tm . tm_mon ;
263
- ( * tm_struct_ptr) . tm_year = result_tm . tm_year ;
264
- ( * tm_struct_ptr) . tm_wday = result_tm . tm_wday ;
265
- ( * tm_struct_ptr) . tm_yday = result_tm . tm_yday ;
266
- ( * tm_struct_ptr) . tm_isdst = result_tm . tm_isdst ;
257
+ ( * tm_struct_ptr) . tm_sec = timespec . second ( ) as _ ;
258
+ ( * tm_struct_ptr) . tm_min = timespec . minute ( ) as _ ;
259
+ ( * tm_struct_ptr) . tm_hour = timespec . hour ( ) as _ ;
260
+ ( * tm_struct_ptr) . tm_mon = timespec . month ( ) as _ ;
261
+ ( * tm_struct_ptr) . tm_mday = timespec . day ( ) as _ ;
262
+ ( * tm_struct_ptr) . tm_year = timespec . year ( ) ;
263
+ ( * tm_struct_ptr) . tm_wday = timespec . weekday ( ) as _ ;
264
+ ( * tm_struct_ptr) . tm_yday = timespec . ordinal ( ) as _ ;
265
+ ( * tm_struct_ptr) . tm_isdst = - 1 ; // DST information unknown with time 0.2+
267
266
( * tm_struct_ptr) . tm_gmtoff = 0 ;
268
267
( * tm_struct_ptr) . tm_zone = 0 ;
269
268
@@ -280,8 +279,7 @@ pub fn _localtime_r(ctx: &EmEnv, time_p: u32, result: u32) -> c_int {
280
279
281
280
unsafe {
282
281
let seconds = emscripten_memory_pointer ! ( ctx. memory( 0 ) , time_p) as * const i32 ;
283
- let timespec = time:: Timespec :: new ( * seconds as _ , 0 ) ;
284
- let result_tm = time:: at ( timespec) ;
282
+ let timespec = time:: OffsetDateTime :: from_unix_timestamp_nanos ( * seconds as _ ) ;
285
283
286
284
// debug!(
287
285
// ">>>>>>> time = {}, {}, {}, {}, {}, {}, {}, {}",
@@ -291,15 +289,15 @@ pub fn _localtime_r(ctx: &EmEnv, time_p: u32, result: u32) -> c_int {
291
289
292
290
let result_addr = emscripten_memory_pointer ! ( ctx. memory( 0 ) , result) as * mut guest_tm ;
293
291
294
- ( * result_addr) . tm_sec = result_tm . tm_sec ;
295
- ( * result_addr) . tm_min = result_tm . tm_min ;
296
- ( * result_addr) . tm_hour = result_tm . tm_hour ;
297
- ( * result_addr) . tm_mday = result_tm . tm_mday ;
298
- ( * result_addr) . tm_mon = result_tm . tm_mon ;
299
- ( * result_addr) . tm_year = result_tm . tm_year ;
300
- ( * result_addr) . tm_wday = result_tm . tm_wday ;
301
- ( * result_addr) . tm_yday = result_tm . tm_yday ;
302
- ( * result_addr) . tm_isdst = result_tm . tm_isdst ;
292
+ ( * result_addr) . tm_sec = timespec . second ( ) as _ ;
293
+ ( * result_addr) . tm_min = timespec . minute ( ) as _ ;
294
+ ( * result_addr) . tm_hour = timespec . hour ( ) as _ ;
295
+ ( * result_addr) . tm_mon = timespec . month ( ) as _ ;
296
+ ( * result_addr) . tm_mday = timespec . day ( ) as _ ;
297
+ ( * result_addr) . tm_year = timespec . year ( ) ;
298
+ ( * result_addr) . tm_wday = timespec . weekday ( ) as _ ;
299
+ ( * result_addr) . tm_yday = timespec . ordinal ( ) as _ ;
300
+ ( * result_addr) . tm_isdst = - 1 ; // DST information unknown with time 0.2+
303
301
( * result_addr) . tm_gmtoff = 0 ;
304
302
( * result_addr) . tm_zone = 0 ;
305
303
@@ -406,25 +404,18 @@ pub fn _strftime(ctx: &EmEnv, s_ptr: c_int, maxsize: u32, format_ptr: c_int, tm_
406
404
407
405
let tm = unsafe { & * tm } ;
408
406
409
- let rust_tm = :: time:: Tm {
410
- tm_sec : tm. tm_sec ,
411
- tm_min : tm. tm_min ,
412
- tm_hour : tm. tm_hour ,
413
- tm_mday : tm. tm_mday ,
414
- tm_mon : tm. tm_mon ,
415
- tm_year : tm. tm_year ,
416
- tm_wday : tm. tm_wday ,
417
- tm_yday : tm. tm_yday ,
418
- tm_isdst : tm. tm_isdst ,
419
- tm_utcoff : tm. tm_gmtoff ,
420
- tm_nsec : 0 ,
421
- } ;
407
+ let rust_date = time:: Date :: try_from_ymd ( tm. tm_year , tm. tm_mon as u8 , tm. tm_mday as u8 ) ;
408
+ if !rust_date. is_ok ( ) {
409
+ return 0 ;
410
+ }
411
+ let rust_time = time:: Time :: try_from_hms ( tm. tm_hour as u8 , tm. tm_min as u8 , tm. tm_sec as u8 ) ;
412
+ if !rust_time. is_ok ( ) {
413
+ return 0 ;
414
+ }
415
+ let rust_datetime = time:: PrimitiveDateTime :: new ( rust_date. unwrap ( ) , rust_time. unwrap ( ) ) ;
416
+ let rust_odt = rust_datetime. assume_offset ( time:: UtcOffset :: seconds ( tm. tm_gmtoff ) ) ;
422
417
423
- let result_str = match :: time:: strftime ( format_string, & rust_tm) {
424
- Ok ( res_string) => res_string,
425
- // TODO: maybe match on e in Err(e) and return different values if required
426
- _ => return 0 ,
427
- } ;
418
+ let result_str = rust_odt. format ( format_string) ;
428
419
429
420
// pad for null?
430
421
let bytes = result_str. chars ( ) . count ( ) ;
0 commit comments