Auto merge of #3614 - devnexen:illumos_time_support, r=oli-obk · rust-lang/rust@04a9a1a

@@ -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.

155165

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")?)?;

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+

}

196210

Ok(result.ptr())

197211

}

198212

#[allow(non_snake_case, clippy::arithmetic_side_effects)]