Mercurial > hg > octave-jordi > gnulib-hg
comparison lib/time_rz.c @ 18065:fd4663ad7454
time_rz: port to Solaris etc.
Works around a tzname problem on platforms like Solaris that have
tzname but not tm_zone, by setting tzname at the appropriate time
and restoring it later.
* lib/time_rz.c (tzname_address, tzname_value) [HAVE_TZNAME]:
New static vars.
(save_abbr) [HAVE_TZNAME]: Set them.
(revert_tz) [HAVE_TZNAME]: Clear or use them.
(restore_tzname): New function.
(localtime_rz, mktime_z): Use it.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Sat, 25 Jul 2015 15:20:10 -0700 |
parents | 29e0bb74097d |
children | 1c6c8e9218c9 |
comparison
equal
deleted
inserted
replaced
18064:e848c8248a0b | 18065:fd4663ad7454 |
---|---|
128 extend_abbrs (tz->abbrs, name, name_size); | 128 extend_abbrs (tz->abbrs, name, name_size); |
129 } | 129 } |
130 return tz; | 130 return tz; |
131 } | 131 } |
132 | 132 |
133 #if HAVE_TZNAME | |
134 /* If TZNAME_ADDRESS is nonnull, an assignment of a saved abbreviation. | |
135 TZNAME_ADDRESS should be either null, or &tzname[0], or &tzname[1]. | |
136 *TZNAME_ADDRESS = TZNAME_VALUE should be done after revert_tz | |
137 (indirectly) calls tzset, so that revert_tz can overwrite tzset's | |
138 assignment to tzname. Also, it should be done at the start of | |
139 the next localtime_tz or mktime_z, to undo the overwrite. */ | |
140 static char **tzname_address; | |
141 static char *tzname_value; | |
142 #endif | |
143 | |
133 /* Save into TZ any nontrivial time zone abbreviation used by TM, | 144 /* Save into TZ any nontrivial time zone abbreviation used by TM, |
134 and update *TM or tzname if they point to the abbreviation. | 145 and update *TM (or prepare to update tzname) if they use the abbreviation. |
135 Return true if successful, false (setting errno) otherwise. */ | 146 Return true if successful, false (setting errno) otherwise. */ |
136 static bool | 147 static bool |
137 save_abbr (timezone_t tz, struct tm *tm) | 148 save_abbr (timezone_t tz, struct tm *tm) |
138 { | 149 { |
139 #if HAVE_TM_ZONE || HAVE_TZNAME | 150 #if HAVE_TM_ZONE || HAVE_TZNAME |
187 # if HAVE_TM_ZONE | 198 # if HAVE_TM_ZONE |
188 if (!tzname_zone) | 199 if (!tzname_zone) |
189 tm->tm_zone = zone_copy; | 200 tm->tm_zone = zone_copy; |
190 # endif | 201 # endif |
191 # if HAVE_TZNAME | 202 # if HAVE_TZNAME |
192 if (tzname_zone) | 203 tzname_address = tzname_zone; |
193 *tzname_zone = zone_copy; | 204 tzname_value = zone_copy; |
194 # endif | 205 # endif |
195 #endif | 206 #endif |
196 return true; | 207 return true; |
197 } | 208 } |
198 | 209 |
279 { | 290 { |
280 int saved_errno = errno; | 291 int saved_errno = errno; |
281 bool ok = change_env (tz); | 292 bool ok = change_env (tz); |
282 if (!ok) | 293 if (!ok) |
283 saved_errno = errno; | 294 saved_errno = errno; |
295 #if HAVE_TZNAME | |
296 if (!ok) | |
297 tzname_address = NULL; | |
298 if (tzname_address) | |
299 { | |
300 char *old_value = *tzname_address; | |
301 *tzname_address = tzname_value; | |
302 tzname_value = old_value; | |
303 } | |
304 #endif | |
284 tzfree (tz); | 305 tzfree (tz); |
285 errno = saved_errno; | 306 errno = saved_errno; |
286 return ok; | 307 return ok; |
287 } | 308 } |
288 } | 309 } |
289 | 310 |
311 /* Restore an old tzname setting that was temporarily munged by revert_tz. */ | |
312 static void | |
313 restore_tzname (void) | |
314 { | |
315 #if HAVE_TZNAME | |
316 if (tzname_address) | |
317 { | |
318 *tzname_address = tzname_value; | |
319 tzname_address = NULL; | |
320 } | |
321 #endif | |
322 } | |
323 | |
290 /* Use time zone TZ to compute localtime_r (T, TM). */ | 324 /* Use time zone TZ to compute localtime_r (T, TM). */ |
291 struct tm * | 325 struct tm * |
292 localtime_rz (timezone_t tz, time_t const *t, struct tm *tm) | 326 localtime_rz (timezone_t tz, time_t const *t, struct tm *tm) |
293 { | 327 { |
328 restore_tzname (); | |
329 | |
294 if (!tz) | 330 if (!tz) |
295 return gmtime_r (t, tm); | 331 return gmtime_r (t, tm); |
296 else | 332 else |
297 { | 333 { |
298 timezone_t old_tz = set_tz (tz); | 334 timezone_t old_tz = set_tz (tz); |
310 | 346 |
311 /* Use time zone TZ to compute mktime (TM). */ | 347 /* Use time zone TZ to compute mktime (TM). */ |
312 time_t | 348 time_t |
313 mktime_z (timezone_t tz, struct tm *tm) | 349 mktime_z (timezone_t tz, struct tm *tm) |
314 { | 350 { |
351 restore_tzname (); | |
352 | |
315 if (!tz) | 353 if (!tz) |
316 return timegm (tm); | 354 return timegm (tm); |
317 else | 355 else |
318 { | 356 { |
319 timezone_t old_tz = set_tz (tz); | 357 timezone_t old_tz = set_tz (tz); |