mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Auto merge of #3614 - devnexen:illumos_time_support, r=oli-obk
solaris/illumos localtime_r / clock_getime support enabled. clock_gettime support CLOCK_REALTIME/CLOCK_MONOTONIC clockid_t. localtime_r is supported only tm struct is more limited than other supported platforms.
This commit is contained in:
commit
04a9a1a531
@ -148,8 +148,8 @@ case $HOST_TARGET in
|
||||
UNIX="panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
|
||||
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
|
||||
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
|
||||
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX pthread-sync
|
||||
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX pthread-sync
|
||||
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX pthread-sync libc-time
|
||||
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX pthread-sync libc-time
|
||||
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX
|
||||
TEST_TARGET=wasm32-wasip2 run_tests_minimal empty_main wasm heap_alloc libc-mem
|
||||
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
|
||||
|
@ -62,6 +62,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// We need to support it because std uses it.
|
||||
relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW"));
|
||||
}
|
||||
"solaris" | "illumos" => {
|
||||
// The REALTIME clock returns the actual time since the Unix epoch.
|
||||
absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")];
|
||||
// MONOTONIC, in the other hand, is the high resolution, non-adjustable
|
||||
// clock from an arbitrary time in the past.
|
||||
// Note that the man page mentions HIGHRES but it is just
|
||||
// an alias of MONOTONIC and the libc crate does not expose it anyway.
|
||||
// https://docs.oracle.com/cd/E23824_01/html/821-1465/clock-gettime-3c.html
|
||||
relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")];
|
||||
}
|
||||
target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"),
|
||||
}
|
||||
|
||||
@ -153,30 +163,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// chrono crate yet.
|
||||
// This may not be consistent with libc::localtime_r's result.
|
||||
let tm_isdst = -1;
|
||||
|
||||
// tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08.
|
||||
// This may not be consistent with libc::localtime_r's result.
|
||||
let offset_in_seconds = dt.offset().fix().local_minus_utc();
|
||||
let tm_gmtoff = offset_in_seconds;
|
||||
let mut tm_zone = String::new();
|
||||
if offset_in_seconds < 0 {
|
||||
tm_zone.push('-');
|
||||
} else {
|
||||
tm_zone.push('+');
|
||||
}
|
||||
let offset_hour = offset_in_seconds.abs() / 3600;
|
||||
write!(tm_zone, "{:02}", offset_hour).unwrap();
|
||||
let offset_min = (offset_in_seconds.abs() % 3600) / 60;
|
||||
if offset_min != 0 {
|
||||
write!(tm_zone, "{:02}", offset_min).unwrap();
|
||||
}
|
||||
|
||||
// FIXME: String de-duplication is needed so that we only allocate this string only once
|
||||
// even when there are multiple calls to this function.
|
||||
let tm_zone_ptr =
|
||||
this.alloc_os_str_as_c_str(&OsString::from(tm_zone), MiriMemoryKind::Machine.into())?;
|
||||
|
||||
this.write_pointer(tm_zone_ptr, &this.project_field_named(&result, "tm_zone")?)?;
|
||||
this.write_int_fields_named(
|
||||
&[
|
||||
("tm_sec", dt.second().into()),
|
||||
@ -188,11 +174,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
("tm_wday", dt.weekday().num_days_from_sunday().into()),
|
||||
("tm_yday", dt.ordinal0().into()),
|
||||
("tm_isdst", tm_isdst),
|
||||
("tm_gmtoff", tm_gmtoff.into()),
|
||||
],
|
||||
&result,
|
||||
)?;
|
||||
|
||||
// solaris/illumos system tm struct does not have
|
||||
// the additional tm_zone/tm_gmtoff fields.
|
||||
// https://docs.oracle.com/cd/E36784_01/html/E36874/localtime-r-3c.html
|
||||
if !matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") {
|
||||
// tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08.
|
||||
// This may not be consistent with libc::localtime_r's result.
|
||||
let offset_in_seconds = dt.offset().fix().local_minus_utc();
|
||||
let tm_gmtoff = offset_in_seconds;
|
||||
let mut tm_zone = String::new();
|
||||
if offset_in_seconds < 0 {
|
||||
tm_zone.push('-');
|
||||
} else {
|
||||
tm_zone.push('+');
|
||||
}
|
||||
let offset_hour = offset_in_seconds.abs() / 3600;
|
||||
write!(tm_zone, "{:02}", offset_hour).unwrap();
|
||||
let offset_min = (offset_in_seconds.abs() % 3600) / 60;
|
||||
if offset_min != 0 {
|
||||
write!(tm_zone, "{:02}", offset_min).unwrap();
|
||||
}
|
||||
|
||||
// FIXME: String de-duplication is needed so that we only allocate this string only once
|
||||
// even when there are multiple calls to this function.
|
||||
let tm_zone_ptr = this
|
||||
.alloc_os_str_as_c_str(&OsString::from(tm_zone), MiriMemoryKind::Machine.into())?;
|
||||
|
||||
this.write_pointer(tm_zone_ptr, &this.project_field_named(&result, "tm_zone")?)?;
|
||||
this.write_int_fields_named(&[("tm_gmtoff", tm_gmtoff.into())], &result)?;
|
||||
}
|
||||
Ok(result.ptr())
|
||||
}
|
||||
#[allow(non_snake_case, clippy::arithmetic_side_effects)]
|
||||
|
@ -1,6 +1,5 @@
|
||||
//@ignore-target-windows: no libc time APIs on Windows
|
||||
//@compile-flags: -Zmiri-disable-isolation
|
||||
use std::ffi::CStr;
|
||||
use std::{env, mem, ptr};
|
||||
|
||||
fn main() {
|
||||
@ -64,7 +63,9 @@ fn test_localtime_r() {
|
||||
tm_wday: 0,
|
||||
tm_yday: 0,
|
||||
tm_isdst: 0,
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))]
|
||||
tm_gmtoff: 0,
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))]
|
||||
tm_zone: std::ptr::null_mut::<libc::c_char>(),
|
||||
};
|
||||
let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) };
|
||||
@ -82,7 +83,7 @@ fn test_localtime_r() {
|
||||
assert_eq!(tm.tm_gmtoff, 0);
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))]
|
||||
unsafe {
|
||||
assert_eq!(CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00")
|
||||
assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00")
|
||||
};
|
||||
|
||||
// The returned value is the pointer passed in.
|
||||
|
Loading…
Reference in New Issue
Block a user