@@ -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) ]
0 commit comments