diff --git a/build/emtests.rs b/build/emtests.rs index 591be871b..5dc3225e3 100644 --- a/build/emtests.rs +++ b/build/emtests.rs @@ -11,11 +11,12 @@ use std::process::Command; static BANNER: &str = "// Rust test file autogenerated with cargo build (build/emtests.rs). // Please do NOT modify it by hand, as it will be reseted on next build.\n"; -const TESTS: [&str; 4] = [ +const TESTS: [&str; 5] = [ "emtests/env.c", "emtests/puts.c", "emtests/printf.c", "emtests/clock_gettime.c", + "emtests/localtime.c", ]; pub fn compile(file: &str) -> String { diff --git a/emtests/localtime.c b/emtests/localtime.c index 9dffefd9b..a2ad4162c 100644 --- a/emtests/localtime.c +++ b/emtests/localtime.c @@ -2,19 +2,14 @@ #include int main (int argc, char *argv[]) { - printf("Hello wasmer!\n"); time_t rawtime; struct tm *info; - char buffer[80]; - time( &rawtime ); - info = localtime( &rawtime ); - - printf("Almost!\n"); - printf("Current local time and date: %s\n", asctime(info)); - printf("Done!\n"); - + struct tm info2; + time (&rawtime ); + struct tm *p = localtime_r(&rawtime, &info2); + printf("localtime\n"); return(0); } diff --git a/emtests/localtime.output b/emtests/localtime.output new file mode 100644 index 000000000..826f3db8a --- /dev/null +++ b/emtests/localtime.output @@ -0,0 +1 @@ +localtime diff --git a/emtests/localtime.wasm b/emtests/localtime.wasm index b8641411e..1da0cd5a9 100644 Binary files a/emtests/localtime.wasm and b/emtests/localtime.wasm differ diff --git a/src/apis/emscripten/time.rs b/src/apis/emscripten/time.rs index 614a38540..3554d6386 100644 --- a/src/apis/emscripten/time.rs +++ b/src/apis/emscripten/time.rs @@ -155,21 +155,24 @@ pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int { // NOTE: emscripten seems to want tzset() called in this function // https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r - unsafe { + let timespec = unsafe { let time_p_addr = instance.memory_offset_addr(0, time_p as _) as *mut i64; - let result_tm = &*localtime(time_p_addr); + let seconds = *time_p_addr.clone(); + time::Timespec::new(seconds, 0) + }; + let result_tm = time::at(timespec); + + unsafe { let tm_struct_offset = (instance.emscripten_data.as_ref().unwrap().malloc)( mem::size_of::() as _, instance, ); - let tm_struct_ptr = instance.memory_offset_addr(0, tm_struct_offset as _) as *mut guest_tm; // debug!( // ">>>>>>> time = {}, {}, {}, {}, {}, {}, {}, {}", // result_tm.tm_sec, result_tm.tm_min, result_tm.tm_hour, result_tm.tm_mday, // result_tm.tm_mon, result_tm.tm_year, result_tm.tm_wday, result_tm.tm_yday, // ); - (*tm_struct_ptr).tm_sec = result_tm.tm_sec; (*tm_struct_ptr).tm_min = result_tm.tm_min; (*tm_struct_ptr).tm_hour = result_tm.tm_hour; @@ -179,8 +182,8 @@ pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int { (*tm_struct_ptr).tm_wday = result_tm.tm_wday; (*tm_struct_ptr).tm_yday = result_tm.tm_yday; (*tm_struct_ptr).tm_isdst = result_tm.tm_isdst; - (*tm_struct_ptr).tm_gmtoff = result_tm.tm_gmtoff as i32; - (*tm_struct_ptr).tm_zone = copy_cstr_into_wasm(instance, result_tm.tm_zone) as i32; + (*tm_struct_ptr).tm_gmtoff = 0; + (*tm_struct_ptr).tm_zone = 0; tm_struct_offset as _ } @@ -193,31 +196,18 @@ pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance // https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r unsafe { - let time_p_addr = instance.memory_offset_addr(0, time_p as _) as *mut i64; - let result_addr = instance.memory_offset_addr(0, result as _) as *mut guest_tm; + let seconds = instance.memory_offset_addr(0, time_p as _) as *const i64; + let timespec = time::Timespec::new(*seconds, 0); + let result_tm = time::at(timespec); - let mut result_tm = tm { - tm_sec: (*result_addr).tm_sec, - tm_min: (*result_addr).tm_min, - tm_hour: (*result_addr).tm_hour, - tm_mday: (*result_addr).tm_mday, - tm_mon: (*result_addr).tm_mon, - tm_year: (*result_addr).tm_year, - tm_wday: (*result_addr).tm_wday, - tm_yday: (*result_addr).tm_yday, - tm_isdst: (*result_addr).tm_isdst, - tm_gmtoff: (*result_addr).tm_gmtoff as _, - tm_zone: instance.memory_offset_addr(0, (*result_addr).tm_zone as _) as _, - }; - - localtime_r(time_p_addr, &mut result_tm); - // let tm_struct = result_tm; // debug!( // ">>>>>>> time = {}, {}, {}, {}, {}, {}, {}, {}", // result_tm.tm_sec, result_tm.tm_min, result_tm.tm_hour, result_tm.tm_mday, // result_tm.tm_mon, result_tm.tm_year, result_tm.tm_wday, result_tm.tm_yday, // ); + let result_addr = instance.memory_offset_addr(0, result as _) as *mut guest_tm; + (*result_addr).tm_sec = result_tm.tm_sec; (*result_addr).tm_min = result_tm.tm_min; (*result_addr).tm_hour = result_tm.tm_hour; @@ -227,8 +217,8 @@ pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance (*result_addr).tm_wday = result_tm.tm_wday; (*result_addr).tm_yday = result_tm.tm_yday; (*result_addr).tm_isdst = result_tm.tm_isdst; - (*result_addr).tm_gmtoff = result_tm.tm_gmtoff as _; - (*result_addr).tm_zone = copy_cstr_into_wasm(instance, result_tm.tm_zone) as _; + (*result_addr).tm_gmtoff = 0; + (*result_addr).tm_zone = 0; result as _ } diff --git a/src/emtests/localtime.rs b/src/emtests/localtime.rs new file mode 100644 index 000000000..6ee4ad406 --- /dev/null +++ b/src/emtests/localtime.rs @@ -0,0 +1,9 @@ +#[test] +fn test_localtime() { + assert_emscripten_output!( + "../../emtests/localtime.wasm", + "localtime", + vec![], + "../../emtests/localtime.output" + ); +} diff --git a/src/emtests/mod.rs b/src/emtests/mod.rs index 8e7884ef6..7b579dc42 100644 --- a/src/emtests/mod.rs +++ b/src/emtests/mod.rs @@ -6,5 +6,6 @@ mod _common; mod clock_gettime; mod env; +mod localtime; mod printf; mod puts;