about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Carlier <devnexen@gmail.com>2024-05-18 23:14:14 +0000
committerDavid Carlier <devnexen@gmail.com>2024-05-22 16:06:26 +0000
commit3f638a92917ecbf43e4dda6fe8dd97f2209e5532 (patch)
tree39a083628e29296312495b3f21252ad45781c73e
parent7fd1429754504f67a7c80ef7e936065fc6f257b3 (diff)
downloadrust-3f638a92917ecbf43e4dda6fe8dd97f2209e5532.tar.gz
rust-3f638a92917ecbf43e4dda6fe8dd97f2209e5532.zip
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.
-rwxr-xr-xsrc/tools/miri/ci/ci.sh4
-rw-r--r--src/tools/miri/src/shims/time.rs64
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-time.rs5
3 files changed, 44 insertions, 29 deletions
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 4e92169b3d0..96319c0959c 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -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
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index 8d1f07f916c..941c61caa53 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -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)]
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-time.rs b/src/tools/miri/tests/pass-dep/libc/libc-time.rs
index ea1e49a0725..5e4bb73e368 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-time.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-time.rs
@@ -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.