Auto merge of #3614 - devnexen:illumos_time_support, r=oli-obk · rust-lang/rust@04a9a1a (original) (raw)
`@@ -62,6 +62,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
`
62
62
`// We need to support it because std uses it.
`
63
63
` relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW"));
`
64
64
`}
`
``
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
`+
}
`
65
75
`` target => throw_unsup_format!("clock_gettime
is not supported on target OS {target}"),
``
66
76
`}
`
67
77
``
`@@ -153,30 +163,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
`
153
163
`// chrono crate yet.
`
154
164
`// This may not be consistent with libc::localtime_r's result.
`
155
165
`let 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")?)?;
`
180
166
` this.write_int_fields_named(
`
181
167
`&[
`
182
168
`("tm_sec", dt.second().into()),
`
`@@ -188,11 +174,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
`
188
174
`("tm_wday", dt.weekday().num_days_from_sunday().into()),
`
189
175
`("tm_yday", dt.ordinal0().into()),
`
190
176
`("tm_isdst", tm_isdst),
`
191
``
`-
("tm_gmtoff", tm_gmtoff.into()),
`
192
177
`],
`
193
178
`&result,
`
194
179
`)?;
`
195
180
``
``
181
`+
// 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
`+
}
`
196
210
`Ok(result.ptr())
`
197
211
`}
`
198
212
`#[allow(non_snake_case, clippy::arithmetic_side_effects)]
`