solaris/illumos localtime_r / clock_getime support enabled. · rust-lang/rust@3f638a9
@@ -62,6 +62,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
6262// We need to support it because std uses it.
6363 relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW"));
6464}
65+"solaris" | "illumos" => {
66+// The REALTIME clock returns the actual time since the Unix epoch.
67+ absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")];
68+// MONOTONIC, in the other hand, is the high resolution, non-adjustable
69+// clock from an arbitrary time in the past.
70+// Note that the man page mentions HIGHRES but it is just
71+// an alias of MONOTONIC and the libc crate does not expose it anyway.
72+// https://docs.oracle.com/cd/E23824_01/html/821-1465/clock-gettime-3c.html
73+ relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")];
74+}
6575 target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"),
6676}
6777@@ -153,30 +163,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
153163// chrono crate yet.
154164// This may not be consistent with libc::localtime_r's result.
155165let tm_isdst = -1;
156-157-// tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08.
158-// This may not be consistent with libc::localtime_r's result.
159-let offset_in_seconds = dt.offset().fix().local_minus_utc();
160-let tm_gmtoff = offset_in_seconds;
161-let mut tm_zone = String::new();
162-if offset_in_seconds < 0 {
163- tm_zone.push('-');
164-} else {
165- tm_zone.push('+');
166-}
167-let offset_hour = offset_in_seconds.abs() / 3600;
168-write!(tm_zone, "{:02}", offset_hour).unwrap();
169-let offset_min = (offset_in_seconds.abs() % 3600) / 60;
170-if offset_min != 0 {
171-write!(tm_zone, "{:02}", offset_min).unwrap();
172-}
173-174-// FIXME: String de-duplication is needed so that we only allocate this string only once
175-// even when there are multiple calls to this function.
176-let tm_zone_ptr =
177- this.alloc_os_str_as_c_str(&OsString::from(tm_zone), MiriMemoryKind::Machine.into())?;
178-179- this.write_pointer(tm_zone_ptr, &this.project_field_named(&result, "tm_zone")?)?;
180166 this.write_int_fields_named(
181167&[
182168("tm_sec", dt.second().into()),
@@ -188,11 +174,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
188174("tm_wday", dt.weekday().num_days_from_sunday().into()),
189175("tm_yday", dt.ordinal0().into()),
190176("tm_isdst", tm_isdst),
191-("tm_gmtoff", tm_gmtoff.into()),
192177],
193178&result,
194179)?;
195180181+// solaris/illumos system tm struct does not have
182+// the additional tm_zone/tm_gmtoff fields.
183+// https://docs.oracle.com/cd/E36784_01/html/E36874/localtime-r-3c.html
184+if !matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") {
185+// tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08.
186+// This may not be consistent with libc::localtime_r's result.
187+let offset_in_seconds = dt.offset().fix().local_minus_utc();
188+let tm_gmtoff = offset_in_seconds;
189+let mut tm_zone = String::new();
190+if offset_in_seconds < 0 {
191+ tm_zone.push('-');
192+} else {
193+ tm_zone.push('+');
194+}
195+let offset_hour = offset_in_seconds.abs() / 3600;
196+write!(tm_zone, "{:02}", offset_hour).unwrap();
197+let offset_min = (offset_in_seconds.abs() % 3600) / 60;
198+if offset_min != 0 {
199+write!(tm_zone, "{:02}", offset_min).unwrap();
200+}
201+202+// FIXME: String de-duplication is needed so that we only allocate this string only once
203+// even when there are multiple calls to this function.
204+let tm_zone_ptr = this
205+.alloc_os_str_as_c_str(&OsString::from(tm_zone), MiriMemoryKind::Machine.into())?;
206+207+ this.write_pointer(tm_zone_ptr, &this.project_field_named(&result, "tm_zone")?)?;
208+ this.write_int_fields_named(&[("tm_gmtoff", tm_gmtoff.into())], &result)?;
209+}
196210Ok(result.ptr())
197211}
198212#[allow(non_snake_case, clippy::arithmetic_side_effects)]