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)]

`