1 /* $NetBSD: localtime.c,v 1.157 2026/10/02 14:07:57 christos Exp $ */ 2 3 /* Convert timestamp from time_t to struct tm. */ 4 5 /* 6 ** This file is in the public domain, so clarified as of 7 ** 1996-06-05 by Arthur David Olson. 8 */ 9 10 #include <sys/cdefs.h> 11 #if defined(LIBC_SCCS) && !defined(lint) 12 #if 0 13 static char elsieid[] = "@(#)localtime.c 8.17"; 14 #else 15 __RCSID("$NetBSD: localtime.c,v 1.157 2026/10/02 14:07:57 christos Exp $"); 16 #endif 17 #endif /* LIBC_SCCS and not lint */ 18 19 /* 20 ** Leap second handling from Bradley White. 21 ** POSIX.1-1988 style TZ environment variable handling from Guy Harris. 22 */ 23 24 /*LINTLIBRARY*/ 25 26 #ifdef _REENTRANT 27 # define THREAD_SAFE 1 28 # define THREAD_RWLOCK 1 29 # define THREAD_TM_MULTI 1 30 # define THREAD_PREFER_SINGLE 1 31 #endif 32 33 #define HAVE_SYS_STAT_H 1 34 #define HAVE_ISSETUGID 1 35 36 #include "namespace.h" 37 #define LOCALTIME_IMPLEMENTATION 38 #include "private.h" 39 40 #include "tzfile.h" 41 #include <fcntl.h> 42 43 /* Expose stuff for the benefit of strftime/libc12 */ 44 #define lclptr __lcl_ptr 45 #define get_monotonic_time __lcl_get_monotonic_time 46 #define lock __lcl_lock 47 #define unlock __lcl_unlock 48 49 /* Expose for compat libc12 */ 50 #define rd2wrlock __lcl_rd2wrlock 51 int rd2wrlock(bool); 52 #define is_threaded __lcl_isthreaded 53 bool is_threaded(void); 54 55 typedef int_fast64_t __time_t; 56 57 #if defined(__weak_alias) 58 __weak_alias(daylight,_daylight) 59 __weak_alias(tzname,_tzname) 60 #endif 61 62 #if HAVE_SYS_STAT_H 63 # include <sys/stat.h> 64 # ifndef S_ISREG 65 # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) /* Ancient UNIX. */ 66 # endif 67 #else 68 struct stat { char st_ctime, st_dev, st_ino; }; 69 # define dev_t char 70 # define ino_t char 71 # define fstat(fd, st) (memset(st, 0, sizeof *(st)), 0) 72 # define stat(name, st) fstat(0, st) 73 # define S_ISREG(mode) 1 74 #endif 75 76 #ifndef HAVE_STRUCT_STAT_ST_CTIM 77 # define HAVE_STRUCT_STAT_ST_CTIM 1 78 #endif 79 #if !defined st_ctim && defined __APPLE__ && defined __MACH__ 80 # define st_ctim st_ctimespec 81 #endif 82 83 #ifndef THREAD_SAFE 84 # define THREAD_SAFE 0 85 #endif 86 87 #ifndef THREAD_RWLOCK 88 # define THREAD_RWLOCK 0 89 #endif 90 91 #ifndef THREAD_TM_MULTI 92 # define THREAD_TM_MULTI 0 93 #endif 94 95 #ifndef __LIBC12_SOURCE__ 96 #if THREAD_SAFE 97 # include <pthread.h> 98 99 # ifndef THREAD_PREFER_SINGLE 100 # define THREAD_PREFER_SINGLE 0 101 # endif 102 # if THREAD_PREFER_SINGLE 103 # ifndef HAVE___ISTHREADED 104 # if defined __FreeBSD__ || defined __OpenBSD__ || defined __DragonFly__ || defined __NetBSD__ 105 # define HAVE___ISTHREADED 1 106 # else 107 # define HAVE___ISTHREADED 0 108 # endif 109 # endif 110 # if HAVE___ISTHREADED 111 extern int __isthreaded; 112 # else 113 # if !defined HAVE_SYS_SINGLE_THREADED_H && defined __has_include 114 # if __has_include(<sys/single_threaded.h>) 115 # define HAVE_SYS_SINGLE_THREADED_H 1 116 # else 117 # define HAVE_SYS_SINGLE_THREADED_H 0 118 # endif 119 # endif 120 # ifndef HAVE_SYS_SINGLE_THREADED_H 121 # if defined __GLIBC__ && 2 < __GLIBC__ + (32 <= __GLIBC_MINOR__) 122 # define HAVE_SYS_SINGLE_THREADED_H 1 123 # else 124 # define HAVE_SYS_SINGLE_THREADED_H 0 125 # endif 126 # endif 127 # if HAVE_SYS_SINGLE_THREADED_H 128 # include <sys/single_threaded.h> 129 # endif 130 # endif 131 # endif 132 #endif 133 134 #if !defined TM_GMTOFF || !USE_TIMEX_T 135 # if THREAD_SAFE 136 137 /* True if the current process might be multi-threaded, 138 false if it is definitely single-threaded. 139 If false, it will be false the next time it is called 140 unless the caller creates a thread in the meantime. 141 If true, it might become false the next time it is called 142 if all other threads exit in the meantime. */ 143 bool 144 is_threaded(void) 145 { 146 # if THREAD_PREFER_SINGLE && HAVE___ISTHREADED 147 return !!__isthreaded; 148 # elif THREAD_PREFER_SINGLE && HAVE_SYS_SINGLE_THREADED_H 149 return !__libc_single_threaded; 150 # else 151 return true; 152 # endif 153 } 154 #endif 155 156 # if THREAD_RWLOCK 157 static pthread_rwlock_t locallock = PTHREAD_RWLOCK_INITIALIZER; 158 static int dolock(void) { return pthread_rwlock_rdlock(&locallock); } 159 static void dounlock(void) { pthread_rwlock_unlock(&locallock); } 160 # else 161 static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER; 162 static int dolock(void) { return pthread_mutex_lock(&locallock); } 163 static void dounlock(void) { pthread_mutex_unlock(&locallock); } 164 # endif 165 /* Get a lock. Return 0 on success, a positive errno value on failure, 166 negative if known to be single-threaded so no lock is needed. */ 167 int 168 lock(void) 169 { 170 if (!is_threaded()) 171 return -1; 172 return dolock(); 173 } 174 void 175 unlock(bool threaded) 176 { 177 if (threaded) 178 dounlock(); 179 } 180 # else 181 int lock(void) { return -1; } 182 void unlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) { } 183 # endif 184 #endif 185 186 #if THREAD_SAFE 187 #ifndef __lint__ // XXX: Broken 188 typedef pthread_once_t once_t; 189 #else 190 #define once_t pthread_once_t 191 #endif 192 # define ONCE_INIT PTHREAD_ONCE_INIT 193 #else 194 typedef bool once_t; 195 # define ONCE_INIT false 196 #endif 197 198 static void 199 once(once_t *once_control, void init_routine(void)) 200 { 201 #if THREAD_SAFE 202 pthread_once(once_control, init_routine); 203 #else 204 if (!*once_control) { 205 *once_control = true; 206 init_routine(); 207 } 208 #endif 209 } 210 211 enum tm_multi { LOCALTIME_TM_MULTI, GMTIME_TM_MULTI, OFFTIME_TM_MULTI }; 212 213 #if THREAD_SAFE && THREAD_TM_MULTI 214 215 enum { N_TM_MULTI = OFFTIME_TM_MULTI + 1 }; 216 static pthread_key_t tm_multi_key; 217 static int tm_multi_key_err; 218 219 static void 220 tm_multi_key_init(void) 221 { 222 tm_multi_key_err = pthread_key_create(&tm_multi_key, free); 223 } 224 225 #endif 226 227 /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs. 228 Use this carefully, as the casts disable type checking. 229 This is a macro so that it can be used in static initializers. */ 230 #ifdef INTPTR_MAX 231 # define UNCONST(a) ((char *) (intptr_t) (a)) 232 #else 233 # define UNCONST(a) ((char *) (a)) 234 #endif 235 236 /* A signed type wider than int, so that we can add 1900 + tm_mon/12 to tm_year 237 without overflow. The static_assert checks that it is indeed wider 238 than int; if this fails on your platform please let us know. */ 239 #if INT_MAX < LONG_MAX 240 typedef long iinntt; 241 # define IINNTT_MIN LONG_MIN 242 # define IINNTT_MAX LONG_MAX 243 #elif INT_MAX < LLONG_MAX 244 typedef long long iinntt; 245 # define IINNTT_MIN LLONG_MIN 246 # define IINNTT_MAX LLONG_MAX 247 #else 248 typedef intmax_t iinntt; 249 # define IINNTT_MIN INTMAX_MIN 250 # define IINNTT_MAX INTMAX_MAX 251 #endif 252 /*CONSTCOND*/ 253 static_assert(IINNTT_MIN < INT_MIN && INT_MAX < IINNTT_MAX); 254 255 #ifndef HAVE_STRUCT_TIMESPEC 256 # define HAVE_STRUCT_TIMESPEC 1 257 #endif 258 #if !HAVE_STRUCT_TIMESPEC 259 struct timespec { time_t tv_sec; long tv_nsec; }; 260 #endif 261 262 #if !defined CLOCK_MONOTONIC_COARSE && defined CLOCK_MONOTONIC 263 # define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC 264 #endif 265 #ifndef CLOCK_MONOTONIC_COARSE 266 # undef clock_gettime 267 # define clock_gettime(id, t) ((t)->tv_sec = time(NULL), (t)->tv_nsec = 0, 0) 268 #endif 269 270 /* How many seconds to wait before checking the default TZif file again. 271 Negative means no checking. Default to 61 if DETECT_TZ_CHANGES 272 (as FreeBSD optionally builds its localtime.c with -DDETECT_TZ_CHANGES), 273 and to -1 otherwise. */ 274 #ifndef TZ_CHANGE_INTERVAL 275 # ifdef DETECT_TZ_CHANGES 276 # define TZ_CHANGE_INTERVAL 61 277 # else 278 # define TZ_CHANGE_INTERVAL (-1) 279 # endif 280 #endif 281 static_assert(TZ_CHANGE_INTERVAL < 0 || HAVE_SYS_STAT_H); 282 283 /* The change detection interval. */ 284 #if TZ_CHANGE_INTERVAL < 0 || !defined __FreeBSD__ 285 enum { tz_change_interval = TZ_CHANGE_INTERVAL }; 286 #else 287 /* FreeBSD uses this private-but-extern var in its internal test suite. */ 288 int __tz_change_interval = TZ_CHANGE_INTERVAL; 289 # define tz_change_interval __tz_change_interval 290 #endif 291 292 /* The type of monotonic times. 293 This is the system time_t, even if USE_TIMEX_T #defines time_t below. */ 294 typedef __time_t monotime_t; 295 296 /* On platforms where offtime or mktime might overflow, 297 strftime.c defines USE_TIMEX_T to be true and includes us. 298 This tells us to #define time_t to an internal type timex_t that is 299 wide enough so that strftime %s never suffers from integer overflow, 300 and to #define offtime (if TM_GMTOFF is defined) or mktime (otherwise) 301 to a static function that returns the redefined time_t. 302 It also tells us to define only data and code needed 303 to support the offtime or mktime variant. */ 304 #if USE_TIMEX_T 305 # undef TIME_T_MIN 306 # undef TIME_T_MAX 307 # undef time_t 308 # define time_t timex_t 309 # if MKTIME_FITS_IN(LONG_MIN, LONG_MAX) 310 typedef long timex_t; 311 # define TIME_T_MIN LONG_MIN 312 # define TIME_T_MAX LONG_MAX 313 # elif MKTIME_FITS_IN(LLONG_MIN, LLONG_MAX) 314 typedef long long timex_t; 315 # define TIME_T_MIN LLONG_MIN 316 # define TIME_T_MAX LLONG_MAX 317 # else 318 typedef intmax_t timex_t; 319 # define TIME_T_MIN INTMAX_MIN 320 # define TIME_T_MAX INTMAX_MAX 321 # endif 322 323 # ifdef TM_GMTOFF 324 # undef timeoff 325 # define timeoff timex_timeoff 326 # undef EXTERN_TIMEOFF 327 # else 328 # undef mktime 329 # define mktime timex_mktime 330 # endif 331 #endif 332 333 /* Placeholders for platforms lacking AT_FCWD, openat, and fstatat. */ 334 #ifndef AT_FDCWD 335 # define AT_FDCWD (-1) /* any negative value will do */ 336 static int openat(int dd, char const *path, int oflag) { unreachable (); } 337 static int fstatat(int dd, char const *path, struct stat *st, int flags) 338 { unreachable(); } 339 #endif 340 341 /* Port to platforms that lack some O_* flags. Unless otherwise 342 specified, the flags are standardized by POSIX. */ 343 344 #ifndef O_BINARY 345 # define O_BINARY 0 /* MS-Windows */ 346 #endif 347 #ifndef O_CLOEXEC 348 # define O_CLOEXEC 0 349 #endif 350 #ifndef O_CLOFORK 351 # define O_CLOFORK 0 352 #endif 353 #ifndef O_DIRECTORY 354 # define O_DIRECTORY 0 355 #endif 356 #ifndef O_IGNORE_CTTY 357 # define O_IGNORE_CTTY 0 /* GNU/Hurd */ 358 #endif 359 #ifndef O_NOCTTY 360 # define O_NOCTTY 0 361 #endif 362 #ifndef O_PATH 363 # define O_PATH 0 364 #endif 365 #ifndef O_REGULAR 366 # define O_REGULAR 0 367 #endif 368 #ifndef O_RESOLVE_BENEATH 369 # define O_RESOLVE_BENEATH 0 370 #endif 371 #ifndef O_SEARCH 372 # define O_SEARCH 0 373 #endif 374 375 #if !HAVE_ISSETUGID 376 377 # if !defined HAVE_SYS_AUXV_H && defined __has_include 378 # if __has_include(<sys/auxv.h>) 379 # define HAVE_SYS_AUXV_H 1 380 # endif 381 # endif 382 # ifndef HAVE_SYS_AUXV_H 383 # if defined __GLIBC__ && 2 < __GLIBC__ + (19 <= __GLIBC_MINOR__) 384 # define HAVE_SYS_AUXV_H 1 385 # else 386 # define HAVE_SYS_AUXV_H 0 387 # endif 388 # endif 389 # if HAVE_SYS_AUXV_H 390 # include <sys/auxv.h> 391 # endif 392 393 /* Avoid clash if headers declare but libraries do not define issetugid. */ 394 # undef issetugid 395 # define issetugid localtime_issetugid 396 397 /* Return 1 if the process is privileged, 0 otherwise. */ 398 static int 399 issetugid(void) 400 { 401 # if HAVE_SYS_AUXV_H && defined AT_SECURE 402 unsigned long val; 403 errno = 0; 404 val = getauxval(AT_SECURE); 405 if (val || errno != ENOENT) 406 return !!val; 407 # endif 408 # if HAVE_GETRESUID 409 { 410 uid_t ruid, euid, suid; 411 gid_t rgid, egid, sgid; 412 if (0 <= getresuid (&ruid, &euid, &suid)) { 413 if ((ruid ^ euid) | (ruid ^ suid)) 414 return 1; 415 if (0 <= getresgid (&rgid, &egid, &sgid)) 416 return !!((rgid ^ egid) | (rgid ^ sgid)); 417 } 418 } 419 # endif 420 # if HAVE_GETEUID 421 return geteuid() != getuid() || getegid() != getgid(); 422 # else 423 return 0; 424 # endif 425 } 426 #endif 427 428 #ifndef WILDABBR 429 /* 430 ** Someone might make incorrect use of a time zone abbreviation: 431 ** 1. They might reference tzname[0] before calling tzset (explicitly 432 ** or implicitly). 433 ** 2. They might reference tzname[1] before calling tzset (explicitly 434 ** or implicitly). 435 ** 3. They might reference tzname[1] after setting to a time zone 436 ** in which Daylight Saving Time is never observed. 437 ** 4. They might reference tzname[0] after setting to a time zone 438 ** in which Standard Time is never observed. 439 ** 5. They might reference tm.TM_ZONE after calling offtime. 440 ** What's best to do in the above cases is open to debate; 441 ** for now, we just set things up so that in any of the five cases 442 ** WILDABBR is used. Another possibility: initialize tzname[0] to the 443 ** string "tzname[0] used before set", and similarly for the other cases. 444 ** And another: initialize tzname[0] to "ERA", with an explanation in the 445 ** manual page of what this "time zone abbreviation" means (doing this so 446 ** that tzname[0] has the "normal" length of three characters). 447 */ 448 # define WILDABBR " " 449 #endif /* !defined WILDABBR */ 450 451 static const char wildabbr[] = WILDABBR; 452 453 static char const etc_utc[] = "Etc/UTC"; 454 455 #if !USE_TIMEX_T || defined TM_ZONE || !defined TM_GMTOFF 456 static char const *utc = etc_utc + sizeof "Etc/" - 1; 457 #endif 458 459 /* 460 ** The DST rules to use if TZ has no rules. 461 ** Default to US rules as of 2017-05-07. 462 ** POSIX does not specify the default DST rules; 463 ** for historical reasons, US rules are a common default. 464 */ 465 #ifndef TZDEFRULESTRING 466 # define TZDEFRULESTRING ",M3.2.0,M11.1.0" 467 #endif 468 469 /* If compiled with -DOPENAT_TZDIR, then when accessing a relative 470 name like "America/Los_Angeles", first open TZDIR (default 471 "/usr/share/zoneinfo") as a directory and then use the result in 472 openat with "America/Los_Angeles", rather than the traditional 473 approach of opening "/usr/share/zoneinfo/America/Los_Angeles". 474 Although the OPENAT_TZDIR approach is less efficient, suffers from 475 spurious EMFILE and ENFILE failures, and is no more secure in practice, 476 bleeding edge FreeBSD started doing it this way in August 2025. */ 477 #ifndef OPENAT_TZDIR 478 # define OPENAT_TZDIR 0 479 #endif 480 481 /* If compiled with -DSUPPRESS_TZDIR, do not prepend TZDIR to relative TZ. 482 This is intended for specialized applications only, due to its 483 security implications. */ 484 #ifndef SUPPRESS_TZDIR 485 # define SUPPRESS_TZDIR 0 486 #endif 487 488 /* Limit to time zone abbreviation length in proleptic TZ strings. 489 This is distinct from TZ_MAX_CHARS, which limits TZif file contents. 490 It defaults to 254, not 255, so that desigidx_type can be an unsigned char. 491 unsigned char suffices for TZif files, so the only reason to increase 492 TZNAME_MAXIMUM is to support TZ strings specifying abbreviations 493 longer than 254 bytes. There is little reason to do that, though, 494 as strings that long are hardly "abbreviations". */ 495 #ifndef TZNAME_MAXIMUM 496 # ifdef _TZNAME_MAXIMUM 497 # if _TZNAME_MAXIMUM < 254 498 # define TZNAME_MAXIMUM 254 /* No reason to ever make this < 254 */ 499 # else 500 # define TZNAME_MAXIMUM _TZNAME_MAXIMUM 501 # endif 502 # else 503 # define TZNAME_MAXIMUM 254 504 # endif 505 #elif defined(_TZNAME_MAXIMUM) && TZNAME_MAXIMUM < _TZNAME_MAXIMUM 506 # error TZNAME_MAXIMUM too small (see _TZNAME_MAXIMUM in <time.h>) 507 #endif 508 509 #if TZNAME_MAXIMUM < UCHAR_MAX 510 typedef unsigned char desigidx_type; 511 #elif TZNAME_MAXIMUM < INT_MAX 512 typedef int desigidx_type; 513 #elif TZNAME_MAXIMUM < PTRDIFF_MAX 514 typedef ptrdiff_t desigidx_type; 515 #else 516 # error "TZNAME_MAXIMUM too large" 517 #endif 518 519 /* A type that can represent any 32-bit two's complement integer, 520 i.e., any integer in the range -2**31 .. 2**31 - 1. 521 Ordinarily this is int_fast32_t, but on non-C23 hosts 522 that are not two's complement it is int_fast64_t. */ 523 #if INT_FAST32_MIN < -TWO_31_MINUS_1 524 typedef int_fast32_t int_fast32_2s; 525 #else 526 typedef int_fast64_t int_fast32_2s; 527 #endif 528 529 struct ttinfo { /* time type information */ 530 int_least32_t tt_utoff; /* UT offset in seconds; in the range 531 -2**31 + 1 .. 2**31 - 1 */ 532 desigidx_type tt_desigidx; /* abbreviation list index */ 533 bool tt_isdst; /* used to set tm_isdst */ 534 }; 535 536 struct lsinfo { /* leap second information */ 537 __time_t ls_trans; /* transition time (positive) */ 538 int_fast32_2s ls_corr; /* correction to apply */ 539 }; 540 541 /* This abbreviation means local time is unspecified. */ 542 static char const UNSPEC[] = "-00"; 543 544 /* How many extra bytes are needed at the end of struct state's chars array. 545 This needs to be at least 1 for null termination in case the input 546 data isn't properly terminated, and it also needs to be big enough 547 for ttunspecified to work without crashing. */ 548 enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 }; 549 550 /* A representation of the contents of a TZif file. Ideally this 551 would have no size limits; the following sizes should suffice for 552 practical use. This struct should not be too large, as instances 553 are put on the stack and stacks are relatively small on some platforms. 554 See tzfile.h for more about the sizes. */ 555 struct state { 556 #if TZ_RUNTIME_LEAPS 557 int leapcnt; 558 #endif 559 int timecnt; 560 int typecnt; 561 int charcnt; 562 bool goahead; 563 __time_t ats[TZ_MAX_TIMES]; 564 unsigned char types[TZ_MAX_TIMES]; 565 struct ttinfo ttis[TZ_MAX_TYPES]; 566 /*CONSTCOND*/ 567 char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"), 568 2 * (TZNAME_MAXIMUM + 1))]; 569 #if TZ_RUNTIME_LEAPS 570 struct lsinfo lsis[TZ_MAX_LEAPS]; 571 #endif 572 }; 573 574 static int 575 leapcount(ATTRIBUTE_MAYBE_UNUSED struct state const *sp) 576 { 577 #if TZ_RUNTIME_LEAPS 578 return sp->leapcnt; 579 #else 580 return 0; 581 #endif 582 } 583 static void 584 set_leapcount(ATTRIBUTE_MAYBE_UNUSED struct state *sp, 585 ATTRIBUTE_MAYBE_UNUSED int leapcnt) 586 { 587 #if TZ_RUNTIME_LEAPS 588 sp->leapcnt = leapcnt; 589 #endif 590 } 591 static struct lsinfo 592 lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, 593 ATTRIBUTE_MAYBE_UNUSED int i) 594 { 595 #if TZ_RUNTIME_LEAPS 596 return sp->lsis[i]; 597 #else 598 unreachable(); 599 #endif 600 } 601 static void 602 set_lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state *sp, 603 ATTRIBUTE_MAYBE_UNUSED int i, 604 ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo) 605 { 606 #if TZ_RUNTIME_LEAPS 607 sp->lsis[i] = lsinfo; 608 #endif 609 } 610 611 enum r_type { 612 JULIAN_DAY, /* Jn = Julian day */ 613 DAY_OF_YEAR, /* n = day of year */ 614 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ 615 }; 616 617 struct rule { 618 enum r_type r_type; /* type of rule */ 619 int r_day; /* day number of rule */ 620 int r_week; /* week number of rule */ 621 int r_mon; /* month number of rule */ 622 int_fast32_t r_time; /* transition time of rule */ 623 }; 624 625 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, 626 struct tm *, time_t *); 627 static bool increment_overflow_time(__time_t *, int_fast32_2s); 628 static int_fast32_2s leapcorr(struct state const *, __time_t); 629 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, 630 struct tm *, time_t *); 631 static bool tzparse(char const *, struct state *, struct state const *); 632 633 #ifndef ALL_STATE 634 # define ALL_STATE 0 635 #endif 636 637 #if ALL_STATE 638 static struct state * gmtptr; 639 #else 640 static struct state gmtmem; 641 static struct state *const gmtptr = &gmtmem; 642 #endif /* State Farm */ 643 644 /* Maximum number of bytes in an efficiently-handled TZ string. 645 Longer strings work, albeit less efficiently. */ 646 #ifndef TZ_STRLEN_MAX 647 # define TZ_STRLEN_MAX 255 648 #endif /* !defined TZ_STRLEN_MAX */ 649 650 #if !USE_TIMEX_T || !defined TM_GMTOFF 651 #ifndef __LIBC12_SOURCE__ 652 static char lcl_TZname[TZ_STRLEN_MAX + 1]; 653 #endif 654 static int lcl_is_set; 655 #endif 656 657 658 #if !defined(__LIBC12_SOURCE__) 659 # if ALL_STATE 660 struct state * lclptr; 661 # else 662 static struct state lclmem; 663 struct state *lclptr = &lclmem; 664 # endif /* State Farm */ 665 #endif 666 667 /* 668 ** Section 4.12.3 of X3.159-1989 requires that 669 ** Except for the strftime function, these functions [asctime, 670 ** ctime, gmtime, localtime] return values in one of two static 671 ** objects: a broken-down time structure and an array of char. 672 ** Thanks to Paul Eggert for noting this. 673 ** 674 ** Although this requirement was removed in C99 it is still present in POSIX. 675 ** Follow the requirement if SUPPORT_C89, even though this is more likely to 676 ** trigger latent bugs in programs. 677 */ 678 679 #if !USE_TIMEX_T 680 681 # if SUPPORT_C89 682 static struct tm tm; 683 # endif 684 685 # if 2 <= HAVE_TZNAME + TZ_TIME_T || defined(__NetBSD__) 686 # if !defined(__LIBC12_SOURCE__) 687 __aconst char *tzname[2] = { 688 (__aconst char *) UNCONST(wildabbr), 689 (__aconst char *) UNCONST(wildabbr), 690 }; 691 # else 692 693 extern __aconst char * tzname[2]; 694 695 # endif /* __LIBC12_SOURCE__ */ 696 # endif 697 698 # if 2 <= USG_COMPAT + TZ_TIME_T || defined(__NetBSD__) 699 # if !defined(__LIBC12_SOURCE__) 700 long timezone = 0; 701 int daylight = 0; 702 # endif /* __LIBC12_SOURCE__ */ 703 # endif /* 2<= USG_COMPAT + TZ_TIME_T */ 704 705 # if 2 <= ALTZONE + TZ_TIME_T 706 long altzone = 0; 707 # endif /* 2 <= ALTZONE + TZ_TIME_T */ 708 #endif 709 710 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ 711 static void 712 init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, 713 desigidx_type desigidx) 714 { 715 s->tt_utoff = (int_least32_t)utoff; 716 s->tt_isdst = isdst; 717 s->tt_desigidx = desigidx; 718 } 719 720 /* Return true if SP's time type I does not specify local time. */ 721 static bool 722 ttunspecified(struct state const *sp, int i) 723 { 724 char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx]; 725 /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */ 726 return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0; 727 } 728 729 static int_fast32_2s 730 detzcode(const char *const codep) 731 { 732 register int i; 733 int_fast32_2s 734 maxval = TWO_31_MINUS_1, 735 minval = -1 - maxval, 736 result; 737 738 result = codep[0] & 0x7f; 739 for (i = 1; i < 4; ++i) 740 result = (result << 8) | (codep[i] & 0xff); 741 742 if (codep[0] & 0x80) { 743 /* Do two's-complement negation even on non-two's-complement machines. 744 This cannot overflow, as int_fast32_2s is wide enough. */ 745 result += minval; 746 } 747 return result; 748 } 749 750 static int_fast64_t 751 detzcode64(const char *const codep) 752 { 753 register int_fast64_t result; 754 register int i; 755 int_fast64_t one = 1; 756 int_fast64_t halfmaxval = one << (64 - 2); 757 int_fast64_t maxval = halfmaxval - 1 + halfmaxval; 758 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; 759 760 result = codep[0] & 0x7f; 761 for (i = 1; i < 8; ++i) 762 result = (result << 8) | (codep[i] & 0xff); 763 764 if (codep[0] & 0x80) { 765 /* Do two's-complement negation even on non-two's-complement machines. 766 If the result would be minval - 1, return minval. */ 767 result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; 768 result += minval; 769 } 770 return result; 771 } 772 773 #include <stdio.h> 774 775 const char * 776 tzgetname(const timezone_t sp, int isdst) 777 { 778 int i; 779 const char *name = NULL; 780 for (i = 0; i < sp->typecnt; ++i) { 781 const struct ttinfo *const ttisp = &sp->ttis[i]; 782 if (ttisp->tt_isdst == isdst) 783 name = &sp->chars[ttisp->tt_desigidx]; 784 } 785 if (name != NULL) 786 return name; 787 errno = ESRCH; 788 return NULL; 789 } 790 791 long 792 tzgetgmtoff(const timezone_t sp, int isdst) 793 { 794 int i; 795 long l = -1; 796 for (i = 0; i < sp->typecnt; ++i) { 797 const struct ttinfo *const ttisp = &sp->ttis[i]; 798 799 if (ttisp->tt_isdst == isdst) { 800 l = ttisp->tt_utoff; 801 } 802 } 803 if (l == -1) 804 errno = ESRCH; 805 return l; 806 } 807 808 #if !USE_TIMEX_T || !defined TM_GMTOFF 809 810 static void 811 update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp) 812 { 813 # if HAVE_TZNAME 814 tzname[ttisp->tt_isdst] = UNCONST(&sp->chars[ttisp->tt_desigidx]); 815 # endif 816 # if USG_COMPAT 817 if (!ttisp->tt_isdst) 818 timezone = - ttisp->tt_utoff; 819 # endif 820 # if ALTZONE 821 if (ttisp->tt_isdst) 822 altzone = - ttisp->tt_utoff; 823 # endif 824 } 825 826 #ifndef __LIBC12_SOURCE__ 827 /* If STDDST_MASK indicates that SP's TYPE provides useful info, 828 update tzname, timezone, and/or altzone and return STDDST_MASK, 829 diminished by the provided info if it is a specified local time. 830 Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */ 831 static int 832 may_update_tzname_etc(int stddst_mask, struct state *sp, int type) 833 { 834 struct ttinfo *ttisp = &sp->ttis[type]; 835 int this_bit = 1 << ttisp->tt_isdst; 836 if (stddst_mask & this_bit) { 837 update_tzname_etc(sp, ttisp); 838 if (!ttunspecified(sp, type)) 839 return stddst_mask & ~this_bit; 840 } 841 return stddst_mask; 842 } 843 844 static void 845 settzname(void) 846 { 847 register struct state * const sp = lclptr; 848 register int i; 849 850 /* If STDDST_MASK & 1 we need info about a standard time. 851 If STDDST_MASK & 2 we need info about a daylight saving time. 852 When STDDST_MASK becomes zero we can stop looking. */ 853 int stddst_mask = 0; 854 855 # if HAVE_TZNAME 856 tzname[0] = tzname[1] = UNCONST(sp ? wildabbr : utc); 857 stddst_mask = 3; 858 # endif 859 # if USG_COMPAT 860 timezone = 0; 861 stddst_mask = 3; 862 # endif 863 # if ALTZONE 864 altzone = 0; 865 stddst_mask |= 2; 866 # endif 867 /* 868 ** And to get the latest time zone abbreviations into tzname. . . 869 */ 870 if (sp) { 871 for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--) 872 stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]); 873 for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--) 874 stddst_mask = may_update_tzname_etc(stddst_mask, sp, i); 875 } 876 # if USG_COMPAT 877 daylight = (unsigned int)stddst_mask >> 1 ^ 1; 878 # endif 879 } 880 #endif 881 882 /* Replace bogus characters in time zone abbreviations. 883 Return 0 on success, an errno value if a time zone abbreviation is 884 too long. */ 885 static int 886 scrub_abbrs(struct state *sp) 887 { 888 int i; 889 890 /* Reject overlong abbreviations. */ 891 for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) { 892 int len = (int)strnlen(&sp->chars[i], TZNAME_MAXIMUM + 1); 893 if (TZNAME_MAXIMUM < len) 894 return EOVERFLOW; 895 i += len + 1; 896 } 897 898 /* Replace bogus characters. */ 899 for (i = 0; i < sp->charcnt; ++i) 900 switch (sp->chars[i]) { 901 case '\0': 902 case '+': case '-': case '.': 903 case '0': case '1': case '2': case '3': case '4': 904 case '5': case '6': case '7': case '8': case '9': 905 case ':': 906 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 907 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 908 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 909 case 'V': case 'W': case 'X': case 'Y': case 'Z': 910 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': 911 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 912 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': 913 case 'v': case 'w': case 'x': case 'y': case 'z': 914 break; 915 916 default: 917 sp->chars[i] = '_'; 918 break; 919 } 920 921 return 0; 922 } 923 924 #endif 925 926 /* Return true if the TZif file with descriptor FD changed, 927 or may have changed, since the last time we were called. 928 Return false if it did not change. 929 If *ST is valid it is the file's current status; 930 otherwise, update *ST to the status if possible. */ 931 static bool 932 tzfile_changed(int fd, struct stat *st) 933 { 934 /* If old_ctim.tv_sec, these variables hold the corresponding part 935 of the file's metadata the last time this function was called. */ 936 static struct timespec old_ctim; 937 static dev_t old_dev; 938 static ino_t old_ino; 939 940 if (!st->st_ctime && fstat(fd, st) < 0) { 941 /* We do not know the file's state, so reset. */ 942 old_ctim.tv_sec = 0; 943 return true; 944 } else { 945 /* Use the change time, as it changes more reliably; mod time can 946 be set back with futimens etc. Use subsecond timestamp 947 resolution if available, as this can help distinguish files on 948 non-POSIX platforms where st_dev and st_ino are unreliable. */ 949 struct timespec ctim; 950 /* Copy via members, as AIX 7.3 defaults to an incompatible st_ctim. */ 951 ctim.tv_sec = (time_t)st->st_ctime; 952 #if HAVE_STRUCT_STAT_ST_CTIM 953 ctim.tv_nsec = st->st_ctim.tv_nsec; 954 #else 955 ctim.tv_nsec = 0; 956 #endif 957 958 if ((ctim.tv_sec ^ old_ctim.tv_sec) | (ctim.tv_nsec ^ old_ctim.tv_nsec) 959 | (st->st_dev ^ old_dev) | (st->st_ino ^ old_ino)) { 960 old_ctim = ctim; 961 old_dev = st->st_dev; 962 old_ino = st->st_ino; 963 return true; 964 } 965 966 return false; 967 } 968 } 969 970 /* Input buffer for data read from a compiled tz file. */ 971 union input_buffer { 972 /* The first part of the buffer, interpreted as a header. */ 973 struct tzhead tzhead; 974 975 /* The entire buffer. Ideally this would have no size limits; 976 the following should suffice for practical use. */ 977 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state) 978 + 4 * TZ_MAX_TIMES]; 979 }; 980 981 /* TZDIR with a trailing '/'. It is null-terminated if OPENAT_TZDIR. */ 982 #if !OPENAT_TZDIR 983 ATTRIBUTE_NONSTRING 984 #endif 985 static char const tzdirslash[sizeof TZDIR + OPENAT_TZDIR] = TZDIR "/"; 986 enum { tzdirslashlen = sizeof TZDIR }; 987 #ifdef PATH_MAX 988 static_assert(tzdirslashlen <= PATH_MAX); /* Sanity check; assumed below. */ 989 #endif 990 991 /* Local storage needed for 'tzloadbody'. */ 992 union local_storage { 993 /* The results of analyzing the file's contents after it is opened. */ 994 struct file_analysis { 995 /* The input buffer. */ 996 union input_buffer u; 997 998 /* A temporary state used for parsing a TZ string in the file. */ 999 struct state st; 1000 } u; 1001 1002 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR 1003 /* The name of the file to be opened. */ 1004 char fullname[PATH_MAX]; 1005 #endif 1006 }; 1007 1008 /* These tzload flags can be ORed together, and fit into 'char'. */ 1009 1010 /* TZLOAD_FROMENV means the TZ string is a process-wide setting either 1011 taken from the TZ environment variable or inferred from TZ being unset. 1012 When 0 <= tz_change_interval, TZLOAD_FROMENV lets us skip reanalysis 1013 of a TZif file that did not change during the interval. */ 1014 enum { TZLOAD_FROMENV = 1 }; 1015 1016 /* Read any newline-surrounded TZ string. */ 1017 enum { TZLOAD_TZSTRING = 2 }; 1018 1019 /* TZ should be a file under TZDIR. */ 1020 enum { TZLOAD_TZDIR_SUB = 4 }; 1021 1022 1023 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 1024 Use **LSPP for temporary storage. Return 0 on 1025 success, an errno value on failure. */ 1026 static int 1027 tzloadbody(char const *name, struct state *sp, char tzloadflags, 1028 union local_storage **lspp) 1029 { 1030 register int i; 1031 register int fid; 1032 register int stored; 1033 register ssize_t nread; 1034 char const *relname; 1035 union local_storage *lsp = *lspp; 1036 union input_buffer *up; 1037 register size_t tzheadsize = sizeof(struct tzhead); 1038 int dd = AT_FDCWD; 1039 int oflags = (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK 1040 | O_IGNORE_CTTY | O_NOCTTY | O_REGULAR); 1041 bool might_escape = false; 1042 int err; 1043 struct stat st; 1044 st.st_ctime = 0; 1045 1046 sp->goahead = false; 1047 1048 if (! name) { 1049 name = TZDEFAULT; 1050 if (! name) 1051 return EINVAL; 1052 /* Omit "tzloadflags &= ~TZLOAD_FROMENV;" here, as that 1053 would hurt performance by rereading and reanalyzing the 1054 TZDEFAULT file even when it is unchanged. */ 1055 } 1056 1057 if (name[0] == ':') 1058 ++name; 1059 1060 relname = name; 1061 1062 /* If the program is privileged, NAME is TZDEFAULT or 1063 subsidiary to TZDIR. Also, NAME is not a device. */ 1064 if (name[0] == '/' && strcmp(name, TZDEFAULT) != 0) { 1065 if (!SUPPRESS_TZDIR 1066 && strncmp(relname, tzdirslash, tzdirslashlen) == 0) 1067 for (relname += tzdirslashlen; *relname == '/'; relname++) 1068 continue; 1069 else if (issetugid()) 1070 return ENOTCAPABLE; 1071 else 1072 might_escape = true; 1073 } 1074 1075 if (relname[0] != '/') { 1076 if (!OPENAT_TZDIR || !O_RESOLVE_BENEATH) { 1077 /* Fail if a relative name contains a non-terminal ".." component, 1078 as such a name could read a non-directory outside TZDIR 1079 when AT_FDCWD and O_RESOLVE_BENEATH are not available. */ 1080 char const *component; 1081 for (component = relname; component[0]; component++) 1082 if (component[0] == '.' && component[1] == '.' 1083 && component[2] == '/' 1084 && (component == relname || component[-1] == '/')) { 1085 if (issetugid()) 1086 return ENOTCAPABLE; 1087 might_escape = true; 1088 break; 1089 } 1090 } 1091 1092 if (OPENAT_TZDIR && !SUPPRESS_TZDIR) { 1093 /* Prefer O_SEARCH or O_PATH if available; 1094 O_RDONLY should be OK too, as TZDIR is invariably readable. 1095 O_DIRECTORY should be redundant but might help 1096 on old platforms that mishandle trailing '/'. */ 1097 dd = open(tzdirslash, /*NOTREACHED*/ 1098 ((O_SEARCH ? O_SEARCH : O_PATH ? O_PATH : O_RDONLY) 1099 | O_BINARY | O_CLOEXEC | O_CLOFORK | O_DIRECTORY)); 1100 if (dd < 0) 1101 return errno; 1102 if (O_RESOLVE_BENEATH && issetugid()) { 1103 oflags |= O_RESOLVE_BENEATH; 1104 might_escape = false; 1105 } 1106 } 1107 } 1108 1109 if (!OPENAT_TZDIR && !SUPPRESS_TZDIR && name[0] != '/') { 1110 char *cp; 1111 size_t fullnamesize; 1112 #ifdef PATH_MAX 1113 size_t namesizemax = PATH_MAX - tzdirslashlen; 1114 size_t namelen = strnlen (name, namesizemax); 1115 if (namesizemax <= namelen) 1116 return ENAMETOOLONG; 1117 #else 1118 size_t namelen = strlen (name); 1119 #endif 1120 fullnamesize = tzdirslashlen + namelen + 1; 1121 1122 /* Create a string "TZDIR/NAME". Using sprintf here 1123 would pull in stdio (and would fail if the 1124 resulting string length exceeded INT_MAX!). */ 1125 if (ALL_STATE || sizeof *lsp < fullnamesize) { 1126 lsp = malloc(max(sizeof *lsp, fullnamesize)); 1127 if (!lsp) 1128 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 1129 *lspp = lsp; 1130 } 1131 cp = mempcpy(lsp, tzdirslash, tzdirslashlen); 1132 cp = mempcpy(cp, name, namelen); 1133 *cp = '\0'; 1134 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR 1135 name = lsp->fullname; 1136 #else 1137 name = (char *) lsp; 1138 #endif 1139 } 1140 1141 /* For a platform that lacks O_REGULAR and a file that might 1142 be outside TZDIR, check that it is a regular file, 1143 as merely opening a device could have unwanted side effects. 1144 Though racy, there is no portable way to fix the race. */ 1145 if (!O_REGULAR && might_escape) { 1146 /* (oflags & O_RESOLVE_BENEATH) must be zero here. */ 1147 if ((OPENAT_TZDIR ? fstatat(dd, relname, &st, 0) : stat(name, &st)) 1148 < 0) 1149 return errno; 1150 if (!S_ISREG(st.st_mode)) 1151 return EFTYPE; 1152 } 1153 fid = OPENAT_TZDIR ? openat(dd, relname, oflags) : open(name, oflags); 1154 err = errno; 1155 if (0 <= dd) 1156 close(dd); 1157 if (fid < 0) 1158 return err; 1159 1160 /* If detecting changes to the the primary TZif file's state and 1161 the file's status is unchanged, save time by returning now. 1162 Otherwise read the file's contents. Close the file either way. */ 1163 if (0 <= tz_change_interval && (tzloadflags & TZLOAD_FROMENV) 1164 && !tzfile_changed(fid, &st)) 1165 err = -1; 1166 else { 1167 if (ALL_STATE && !lsp) { 1168 lsp = malloc(sizeof *lsp); 1169 if (!lsp) 1170 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 1171 *lspp = lsp; 1172 } 1173 up = &lsp->u.u; 1174 nread = read(fid, up->buf, sizeof up->buf); 1175 err = (ssize_t)tzheadsize <= nread ? 0 : nread < 0 ? errno : EFTYPE; 1176 } 1177 close(fid); 1178 if (err) 1179 return err < 0 ? 0 : err; 1180 1181 for (stored = 4; stored <= 8; stored *= 2) { 1182 char version = up->tzhead.tzh_version[0]; 1183 bool skip_datablock = stored == 4 && version; 1184 int_fast32_t datablock_size; 1185 int_fast32_2s 1186 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt), 1187 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt), 1188 leapcnt = detzcode(up->tzhead.tzh_leapcnt), 1189 timecnt = detzcode(up->tzhead.tzh_timecnt), 1190 typecnt = detzcode(up->tzhead.tzh_typecnt), 1191 charcnt = detzcode(up->tzhead.tzh_charcnt); 1192 char const *p = up->buf + tzheadsize; 1193 /* Although tzfile(5) currently requires typecnt to be nonzero, 1194 support future formats that may allow zero typecnt 1195 in files that have a TZ string and no transitions. */ 1196 if (! (0 <= leapcnt 1197 && leapcnt <= (TZ_RUNTIME_LEAPS ? TZ_MAX_LEAPS : 0) 1198 && 0 <= typecnt && typecnt <= TZ_MAX_TYPES 1199 && 0 <= timecnt && timecnt <= TZ_MAX_TIMES 1200 && 0 <= charcnt && charcnt <= TZ_MAX_CHARS 1201 && 0 <= ttisstdcnt && ttisstdcnt <= TZ_MAX_TYPES 1202 && 0 <= ttisutcnt && ttisutcnt <= TZ_MAX_TYPES)) 1203 return EFTYPE; 1204 datablock_size 1205 = (timecnt * stored /* ats */ 1206 + timecnt /* types */ 1207 + typecnt * 6 /* ttinfos */ 1208 + charcnt /* chars */ 1209 + leapcnt * (stored + 4) /* lsinfos */ 1210 + ttisstdcnt /* ttisstds */ 1211 + ttisutcnt); /* ttisuts */ 1212 if (nread < (ssize_t)(tzheadsize + datablock_size)) 1213 return EFTYPE; 1214 if (skip_datablock) 1215 p += datablock_size; 1216 else if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) 1217 && (ttisutcnt == typecnt || ttisutcnt == 0))) 1218 return EFTYPE; 1219 else { 1220 int_fast64_t prevtr = -1; 1221 int_fast32_2s prevcorr = 0; 1222 set_leapcount(sp, (int)leapcnt); 1223 sp->timecnt = (int)timecnt; 1224 sp->typecnt = (int)typecnt; 1225 sp->charcnt = (int)charcnt; 1226 1227 /* Read transitions, discarding those out of time_t range. 1228 But pretend the last transition before TIME_T_MIN 1229 occurred at TIME_T_MIN. */ 1230 timecnt = 0; 1231 for (i = 0; i < sp->timecnt; ++i) { 1232 int_fast64_t at 1233 = stored == 4 ? detzcode(p) : detzcode64(p); 1234 sp->types[i] = at <= TIME_T_MAX; 1235 if (sp->types[i]) { 1236 time_t attime 1237 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) 1238 ? TIME_T_MIN : (time_t)at); 1239 if (timecnt && attime <= sp->ats[timecnt - 1]) { 1240 if (attime < sp->ats[timecnt - 1]) 1241 return EFTYPE; 1242 sp->types[i - 1] = 0; 1243 timecnt--; 1244 } 1245 sp->ats[timecnt++] = attime; 1246 } 1247 p += stored; 1248 } 1249 1250 timecnt = 0; 1251 for (i = 0; i < sp->timecnt; ++i) { 1252 unsigned char typ = *p++; 1253 if (sp->typecnt <= typ) 1254 return EFTYPE; 1255 if (sp->types[i]) 1256 sp->types[timecnt++] = typ; 1257 } 1258 sp->timecnt = (int)timecnt; 1259 for (i = 0; i < sp->typecnt; ++i) { 1260 register struct ttinfo * ttisp; 1261 unsigned char isdst, desigidx; 1262 int_fast32_2s utoff = detzcode(p); 1263 1264 /* Reject a UT offset equal to -2**31, as it might 1265 cause trouble both in this file and in callers. 1266 Also, it violates RFC 9636 section 3.2. */ 1267 if (utoff < -TWO_31_MINUS_1) 1268 return EFTYPE; 1269 1270 ttisp = &sp->ttis[i]; 1271 ttisp->tt_utoff = (int)utoff; 1272 p += 4; 1273 isdst = *p++; 1274 if (! (isdst < 2)) 1275 return EFTYPE; 1276 ttisp->tt_isdst = isdst; 1277 desigidx = *p++; 1278 if (! (desigidx < sp->charcnt)) 1279 return EFTYPE; 1280 ttisp->tt_desigidx = desigidx; 1281 } 1282 for (i = 0; i < sp->charcnt; ++i) 1283 sp->chars[i] = *p++; 1284 /* Ensure '\0'-terminated, and make it safe to call 1285 ttunspecified later. */ 1286 memset(&sp->chars[i], 0, CHARS_EXTRA); 1287 1288 /* Read leap seconds, discarding those out of time_t range. */ 1289 leapcnt = 0; 1290 for (i = 0; i < leapcount(sp); i++) { 1291 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); 1292 int_fast32_2s corr = detzcode(p + stored); 1293 p += stored + 4; 1294 1295 /* Leap seconds cannot occur before the Epoch, 1296 or out of order. */ 1297 if (tr <= prevtr) 1298 return EFTYPE; 1299 1300 /* To avoid other botches in this code, each leap second's 1301 correction must differ from the previous one's by 1 1302 second or less, except that the first correction can be 1303 any value; these requirements are more generous than 1304 RFC 9636, to allow future RFC extensions. */ 1305 if (! (i == 0 1306 || (prevcorr < corr 1307 ? corr == prevcorr + 1 1308 : (corr == prevcorr 1309 || corr == prevcorr - 1)))) 1310 return EFTYPE; 1311 prevtr = tr; 1312 prevcorr = corr; 1313 1314 if (tr <= TIME_T_MAX) { 1315 struct lsinfo ls; 1316 ls.ls_trans = tr; 1317 ls.ls_corr = (int)corr; 1318 set_lsinfo(sp, (int)leapcnt, ls); 1319 leapcnt++; 1320 } 1321 } 1322 set_leapcount(sp, (int)leapcnt); 1323 1324 /* Do not bother to validate standard/wall and UT/local 1325 indicators, as they are no longer used here. */ 1326 p += ttisstdcnt + ttisutcnt; 1327 } 1328 1329 nread -= p - up->buf; 1330 memmove(up->buf, p, (size_t)nread); 1331 1332 /* If this is an old file, we're done. */ 1333 if (!version) 1334 break; 1335 } 1336 if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 && 1337 up->buf[0] == '\n' && up->buf[nread - 1] == '\n') { 1338 struct state *ts = &lsp->u.st; 1339 1340 up->buf[nread - 1] = '\0'; 1341 if (!tzparse(&up->buf[1], ts, sp)) 1342 return EFTYPE; 1343 else { 1344 /* Attempt to reuse existing abbreviations. 1345 Without this, America/Anchorage would 1346 consume 50 bytes for abbreviations, as 1347 sp->charcnt equals 40 (for LMT AST AWT APT AHST 1348 AHDT YST AKDT AKST) and ts->charcnt equals 10 1349 (for AKST AKDT). Reusing means sp->charcnt can 1350 stay 40 in this example. */ 1351 int charcnt = sp->charcnt; 1352 for (i = 0; i < ts->typecnt; i++) { 1353 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; 1354 int j; 1355 for (j = 0; j < charcnt; j++) 1356 if (strcmp(sp->chars + j, tsabbr) == 0) { 1357 ts->ttis[i].tt_desigidx = j; 1358 break; 1359 } 1360 if (! (j < charcnt)) { 1361 size_t tsabbrlen = strnlen(tsabbr, TZ_MAX_CHARS - j); 1362 if (TZ_MAX_CHARS <= j + tsabbrlen) 1363 return EOVERFLOW; 1364 else { 1365 char *cp = sp->chars + j; 1366 cp = mempcpy(cp, tsabbr, tsabbrlen); 1367 *cp = '\0'; 1368 charcnt = (int)(j + tsabbrlen + 1); 1369 ts->ttis[i].tt_desigidx = j; 1370 } 1371 } 1372 } 1373 1374 if (TZ_MAX_TYPES - sp->typecnt < ts->typecnt) 1375 return EOVERFLOW; 1376 else { 1377 sp->charcnt = charcnt; 1378 1379 /* Ignore any trailing, no-op transitions generated 1380 by zic as they don't help here and can run afoul 1381 of bugs in zic 2016j or earlier. */ 1382 while (1 < sp->timecnt 1383 && (sp->types[sp->timecnt - 1] 1384 == sp->types[sp->timecnt - 2])) 1385 sp->timecnt--; 1386 1387 sp->goahead = ts->goahead; 1388 1389 for (i = 0; i < ts->timecnt; i++) { 1390 __time_t t = ts->ats[i]; 1391 if (increment_overflow_time(&t, leapcorr(sp, t)) 1392 || (0 < sp->timecnt 1393 && t <= sp->ats[sp->timecnt - 1])) 1394 continue; 1395 if (TZ_MAX_TIMES <= sp->timecnt) 1396 return EOVERFLOW; 1397 sp->ats[sp->timecnt] = t; 1398 sp->types[sp->timecnt] = (sp->typecnt 1399 + ts->types[i]); 1400 sp->timecnt++; 1401 } 1402 for (i = 0; i < ts->typecnt; i++) 1403 sp->ttis[sp->typecnt++] = ts->ttis[i]; 1404 } 1405 } 1406 } 1407 if (sp->typecnt == 0) 1408 return EFTYPE; 1409 1410 return 0; 1411 } 1412 1413 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 1414 Return 0 on success, an errno value on failure. */ 1415 static int 1416 tzload(char const *name, struct state *sp, char tzloadflags) 1417 { 1418 int r; 1419 union local_storage *lsp0; 1420 union local_storage *lsp; 1421 #if ALL_STATE 1422 lsp = NULL; 1423 #else 1424 union local_storage ls; 1425 lsp = &ls; 1426 #endif 1427 lsp0 = lsp; 1428 r = tzloadbody(name, sp, tzloadflags, &lsp); 1429 if (lsp != lsp0) 1430 free(lsp); 1431 return r; 1432 } 1433 1434 static const int mon_lengths[2][MONSPERYEAR] = { 1435 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 1436 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 1437 }; 1438 1439 /* Is C an ASCII digit? */ 1440 static bool 1441 is_digit(char c) 1442 { 1443 return '0' <= c && c <= '9'; 1444 } 1445 1446 /* 1447 ** Given a pointer into a timezone string, scan until a character that is not 1448 ** a valid character in a time zone abbreviation is found. 1449 ** Return a pointer to that character. 1450 */ 1451 1452 ATTRIBUTE_PURE_114833 static const char * 1453 getzname(register const char *strp) 1454 { 1455 register char c; 1456 1457 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 1458 c != '+') 1459 ++strp; 1460 return strp; 1461 } 1462 1463 /* 1464 ** Given a pointer into an extended timezone string, scan until the ending 1465 ** delimiter of the time zone abbreviation is located. 1466 ** Return a pointer to the delimiter. 1467 ** 1468 ** As with getzname above, the legal character set is actually quite 1469 ** restricted, with other characters producing undefined results. 1470 ** We don't do any checking here; checking is done later in common-case code. 1471 */ 1472 1473 ATTRIBUTE_PURE_114833 static const char * 1474 getqzname(register const char *strp, const int delim) 1475 { 1476 register int c; 1477 1478 while ((c = *strp) != '\0' && c != delim) 1479 ++strp; 1480 return strp; 1481 } 1482 1483 /* 1484 ** Given a pointer into a timezone string, extract a number from that string. 1485 ** Check that the number is within a specified range; if it is not, return 1486 ** NULL. 1487 ** Otherwise, return a pointer to the first character not part of the number. 1488 */ 1489 1490 static const char * 1491 getnum(register const char *strp, int *const nump, const int min, const int max) 1492 { 1493 register char c; 1494 register int num; 1495 1496 if (strp == NULL || !is_digit(c = *strp)) { 1497 errno = EINVAL; 1498 return NULL; 1499 } 1500 num = 0; 1501 do { 1502 num = num * 10 + (c - '0'); 1503 if (num > max) { 1504 errno = EOVERFLOW; 1505 return NULL; /* illegal value */ 1506 } 1507 c = *++strp; 1508 } while (is_digit(c)); 1509 if (num < min) { 1510 errno = EINVAL; 1511 return NULL; /* illegal value */ 1512 } 1513 *nump = num; 1514 return strp; 1515 } 1516 1517 /* 1518 ** Given a pointer into a timezone string, extract a number of seconds, 1519 ** in hh[:mm[:ss]] form, from the string. 1520 ** If any error occurs, return NULL. 1521 ** Otherwise, return a pointer to the first character not part of the number 1522 ** of seconds. 1523 */ 1524 1525 static const char * 1526 getsecs(register const char *strp, int_fast32_t *const secsp) 1527 { 1528 int num; 1529 int_fast32_t secsperhour = SECSPERHOUR; 1530 1531 /* 1532 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like 1533 ** "M10.4.6/26", which does not conform to POSIX, 1534 ** but which specifies the equivalent of 1535 ** "02:00 on the first Sunday on or after 23 Oct". 1536 */ 1537 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 1538 if (strp == NULL) 1539 return NULL; 1540 *secsp = num * secsperhour; 1541 if (*strp == ':') { 1542 ++strp; 1543 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 1544 if (strp == NULL) 1545 return NULL; 1546 *secsp += num * SECSPERMIN; 1547 if (*strp == ':') { 1548 ++strp; 1549 /* 'SECSPERMIN' allows for leap seconds. */ 1550 strp = getnum(strp, &num, 0, SECSPERMIN); 1551 if (strp == NULL) 1552 return NULL; 1553 *secsp += num; 1554 } 1555 } 1556 return strp; 1557 } 1558 1559 /* 1560 ** Given a pointer into a timezone string, extract an offset, in 1561 ** [+-]hh[:mm[:ss]] form, from the string. 1562 ** If any error occurs, return NULL. 1563 ** Otherwise, return a pointer to the first character not part of the time. 1564 */ 1565 1566 static const char * 1567 getoffset(register const char *strp, int_fast32_t *const offsetp) 1568 { 1569 register bool neg = false; 1570 1571 if (*strp == '-') { 1572 neg = true; 1573 ++strp; 1574 } else if (*strp == '+') 1575 ++strp; 1576 strp = getsecs(strp, offsetp); 1577 if (strp == NULL) 1578 return NULL; /* illegal time */ 1579 if (neg) 1580 *offsetp = -*offsetp; 1581 return strp; 1582 } 1583 1584 /* 1585 ** Given a pointer into a timezone string, extract a rule in the form 1586 ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ 1587 ** for the format of "date" and "time". 1588 ** If a valid rule is not found, return NULL. 1589 ** Otherwise, return a pointer to the first character not part of the rule. 1590 */ 1591 1592 static const char * 1593 getrule(const char *strp, register struct rule *const rulep) 1594 { 1595 if (*strp == 'J') { 1596 /* 1597 ** Julian day. 1598 */ 1599 rulep->r_type = JULIAN_DAY; 1600 ++strp; 1601 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 1602 } else if (*strp == 'M') { 1603 /* 1604 ** Month, week, day. 1605 */ 1606 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 1607 ++strp; 1608 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 1609 if (strp == NULL) 1610 return NULL; 1611 if (*strp++ != '.') 1612 return NULL; 1613 strp = getnum(strp, &rulep->r_week, 1, 5); 1614 if (strp == NULL) 1615 return NULL; 1616 if (*strp++ != '.') 1617 return NULL; 1618 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1619 } else if (is_digit(*strp)) { 1620 /* 1621 ** Day of year. 1622 */ 1623 rulep->r_type = DAY_OF_YEAR; 1624 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1625 } else return NULL; /* invalid format */ 1626 if (strp == NULL) 1627 return NULL; 1628 if (*strp == '/') { 1629 /* 1630 ** Time specified. 1631 */ 1632 ++strp; 1633 strp = getoffset(strp, &rulep->r_time); 1634 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1635 return strp; 1636 } 1637 1638 /* 1639 ** Given a year, a rule, and the offset from UT at the time that rule takes 1640 ** effect, calculate the year-relative time that rule takes effect. 1641 */ 1642 1643 static int_fast32_t 1644 transtime(time_t year, register const struct rule *const rulep, 1645 const int_fast32_t offset) 1646 { 1647 int d; /* Day of year (zero-origin). */ 1648 register bool leapyear; 1649 1650 leapyear = isleap(year); 1651 1652 if (rulep->r_type <= DAY_OF_YEAR) { 1653 /* 1654 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1655 ** years. 1656 ** In non-leap years, or if the day number is 59 or less, just 1657 ** use the day number - 1. 1658 ** 1659 ** n - day of year. 1660 */ 1661 d = rulep->r_day - ((rulep->r_type < DAY_OF_YEAR) 1662 & (!leapyear | (rulep->r_day <= 59))); 1663 } else { 1664 /* 1665 ** Mm.n.d - nth "dth day" of month m. 1666 */ 1667 1668 /* 1669 ** Use Zeller's Congruence to get day-of-week of first day of 1670 ** month. 1671 */ 1672 int i; 1673 bool janfeb = rulep->r_mon <= 2; 1674 int month = (rulep->r_mon 1675 + (janfeb ? MONSPERYEAR : 0)); /* 3..14 */ 1676 int adjustment = (TYPE_SIGNED(time_t) ? 0 : 400) - janfeb; 1677 int ay_rem = (year + adjustment) % YEARSPERREPEAT; 1678 int y = ay_rem + (ay_rem < 0 ? YEARSPERREPEAT : 0); 1679 int dow = (((13 * (month + 1)) / 5 1680 + y + y / 4 - y / 100 + y / 400) 1681 % DAYSPERWEEK); 1682 1683 /* 1684 ** "dow" is the day-of-week of the first day of the month. Get 1685 ** the day-of-month (zero-origin) of the first "dow" day of the 1686 ** month. 1687 */ 1688 d = rulep->r_day - dow; 1689 d += (rulep->r_week - (0 <= d)) * DAYSPERWEEK; 1690 if (mon_lengths[leapyear][rulep->r_mon - 1] <= d) 1691 d -= DAYSPERWEEK; 1692 1693 /* 1694 ** "d" is the day-of-month (zero-origin) of the day we want. 1695 */ 1696 for (i = 0; i < rulep->r_mon - 1; ++i) 1697 d += mon_lengths[leapyear][i]; 1698 } 1699 1700 /* 1701 ** d is the origin-0 year-relative day in 1702 ** question. To get the year-relative time of the specified local 1703 ** time on that day, add the transition time and the current offset 1704 ** from UT to d * SECSPERDAY. 1705 */ 1706 return d * SECSPERDAY + rulep->r_time + offset; 1707 } 1708 1709 /* 1710 ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as 1711 ** appropriate. 1712 */ 1713 1714 static bool 1715 tzparse(const char *name, struct state *sp, struct state const *basep) 1716 { 1717 const char * stdname; 1718 const char * dstname; 1719 int_fast32_t stdoffset; 1720 int_fast32_t dstoffset; 1721 register char * cp; 1722 ptrdiff_t stdlen, dstlen, charcnt; 1723 __time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; 1724 1725 dstname = NULL; /* XXX gcc */ 1726 stdname = name; 1727 if (*name == '<') { 1728 name++; 1729 stdname = name; 1730 name = getqzname(name, '>'); 1731 if (*name != '>') 1732 return false; 1733 stdlen = name - stdname; 1734 name++; 1735 } else { 1736 name = getzname(name); 1737 stdlen = name - stdname; 1738 } 1739 if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM)) 1740 return false; 1741 name = getoffset(name, &stdoffset); 1742 if (name == NULL) 1743 return false; 1744 charcnt = stdlen + 1; 1745 if (basep) { 1746 if (0 < basep->timecnt) 1747 atlo = basep->ats[basep->timecnt - 1]; 1748 set_leapcount(sp, leapcount(basep)); 1749 if (0 < leapcount(sp)) { 1750 int i; 1751 for (i = 0; i < leapcount(sp); i++) 1752 set_lsinfo(sp, i, lsinfo(basep, i)); 1753 leaplo = lsinfo(sp, leapcount(sp) - 1).ls_trans; 1754 } 1755 } else 1756 set_leapcount(sp, 0); /* So, we're off a little. */ 1757 sp->goahead = false; 1758 if (*name != '\0') { 1759 struct rule start, end; 1760 int timecnt; 1761 __time_t janfirst; 1762 time_t repeatbeg, year, yearlim, yearbeg; 1763 int_fast32_t janoffset = 0; 1764 1765 if (*name == '<') { 1766 dstname = ++name; 1767 name = getqzname(name, '>'); 1768 if (*name != '>') 1769 return false; 1770 dstlen = name - dstname; 1771 name++; 1772 } else { 1773 dstname = name; 1774 name = getzname(name); 1775 dstlen = name - dstname; /* length of DST abbr. */ 1776 } 1777 if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM)) 1778 return false; 1779 charcnt += dstlen + 1; 1780 if (*name != '\0' && *name != ',' && *name != ';') { 1781 name = getoffset(name, &dstoffset); 1782 if (name == NULL) 1783 return false; 1784 } else dstoffset = stdoffset - SECSPERHOUR; 1785 1786 if (*name == '\0') 1787 name = TZDEFRULESTRING; 1788 if (! (*name == ',' || *name == ';')) 1789 return false; 1790 1791 name = getrule(name + 1, &start); 1792 if (!name) 1793 return false; 1794 if (*name++ != ',') 1795 return false; 1796 name = getrule(name, &end); 1797 if (!name || *name) 1798 return false; 1799 sp->typecnt = 2; /* standard time and DST */ 1800 1801 /* Two transitions per year, from atlo forward, and going on 1802 for years_of_observations past max(atlo, leaplo). */ 1803 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1804 init_ttinfo(&sp->ttis[1], -dstoffset, true, (desigidx_type)(stdlen + 1)); 1805 timecnt = 0; 1806 repeatbeg = (time_t)(atlo / SECSPERREPEAT 1807 + (atlo < 0 && 0 < atlo % SECSPERREPEAT)); 1808 yearbeg = repeatbeg * YEARSPERREPEAT + EPOCH_YEAR; 1809 janfirst = repeatbeg * SECSPERREPEAT; 1810 1811 do { 1812 int_fast32_t yearsecs 1813 = year_days(yearbeg - 1) * SECSPERDAY; 1814 __time_t janfirst1 = janfirst; 1815 yearbeg--; 1816 if (increment_overflow_time(&janfirst1, -yearsecs)) { 1817 janoffset = -yearsecs; 1818 break; 1819 } 1820 janfirst = janfirst1; 1821 } while (atlo < janfirst); 1822 1823 for (;;) { 1824 int_fast32_t yearsecs 1825 = year_days(yearbeg) * SECSPERDAY; 1826 __time_t janfirst1 = janfirst; 1827 if (increment_overflow_time(&janfirst1, yearsecs) 1828 || atlo <= janfirst1) 1829 break; 1830 yearbeg++; 1831 janfirst = janfirst1; 1832 } 1833 1834 yearlim = yearbeg + years_of_observations; 1835 for (year = yearbeg; year < yearlim; year++) { 1836 int_fast32_t 1837 starttime = transtime(year, &start, stdoffset), 1838 endtime = transtime(year, &end, dstoffset), 1839 yearsecs = year_days(year) * SECSPERDAY; 1840 bool reversed = endtime < starttime; 1841 if (reversed) { 1842 int_fast32_t swap = starttime; 1843 starttime = endtime; 1844 endtime = swap; 1845 } 1846 if (reversed 1847 || (starttime < endtime 1848 && endtime - starttime < yearsecs)) { 1849 time_t at_added = TIME_T_MAX; 1850 __time_t at = janfirst; 1851 if (! increment_overflow_time(&at, janoffset + starttime) 1852 && atlo <= at) { 1853 if (TZ_MAX_TIMES <= timecnt) 1854 return false; 1855 sp->ats[timecnt] = at_added = (time_t)at; 1856 sp->types[timecnt++] = !reversed; 1857 } 1858 at = janfirst; 1859 if (! increment_overflow_time(&at, janoffset + endtime) 1860 && atlo <= at) { 1861 if (TZ_MAX_TIMES <= timecnt) 1862 return false; 1863 sp->ats[timecnt] = at_added = (time_t)at; 1864 sp->types[timecnt++] = reversed; 1865 } 1866 if (at_added < leaplo) 1867 yearlim = year + years_of_observations; 1868 } 1869 if (increment_overflow_time(&janfirst, janoffset + yearsecs)) 1870 break; 1871 janoffset = 0; 1872 } 1873 sp->timecnt = timecnt; 1874 if (! timecnt) { 1875 sp->ttis[0] = sp->ttis[1]; 1876 sp->typecnt = 1; /* Perpetual DST. */ 1877 } else if (years_of_observations <= year - yearbeg) 1878 sp->goahead = true; 1879 } else { 1880 dstlen = 0; 1881 sp->typecnt = 1; /* only standard time */ 1882 sp->timecnt = 0; 1883 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1884 init_ttinfo(&sp->ttis[1], 0, false, 0); 1885 } 1886 sp->charcnt = (int)charcnt; 1887 cp = sp->chars; 1888 cp = mempcpy(cp, stdname, stdlen); 1889 *cp++ = '\0'; 1890 if (dstlen != 0) { 1891 cp = mempcpy(cp, dstname, dstlen); 1892 *cp = '\0'; 1893 } 1894 return true; 1895 } 1896 1897 static void 1898 gmtload(struct state *const sp) 1899 { 1900 if (!TZ_RUNTIME_LEAPS || tzload(etc_utc, sp, TZLOAD_TZSTRING) != 0) 1901 (void)tzparse("UTC0", sp, NULL); 1902 } 1903 1904 #if !USE_TIMEX_T || !defined TM_GMTOFF 1905 1906 /* Return true if primary cached time zone data are fresh, 1907 i.e., if this function is known to have recently returned false. 1908 A call is recent if it occurred less than tz_change_interval seconds ago. 1909 NOW should be the current time. */ 1910 /*LINTED: unused*/ 1911 #ifndef __LIBC12_SOURCE__ 1912 static bool 1913 fresh_tzdata(monotime_t now) 1914 { 1915 /* If nonzero, the time of the last false return. */ 1916 static monotime_t last_checked; 1917 1918 if (last_checked && now - last_checked < tz_change_interval) 1919 return true; 1920 last_checked = now; 1921 return false; 1922 } 1923 #endif 1924 1925 /* Initialize *SP to a value appropriate for the TZ setting NAME. 1926 Respect TZLOADFLAGS. 1927 Return 0 on success, an errno value on failure. */ 1928 static int 1929 zoneinit(struct state *sp, char const *name, char tzloadflags) 1930 { 1931 if (name && ! name[0]) { 1932 /* 1933 ** User wants it fast rather than right. 1934 */ 1935 set_leapcount(sp, 0); /* so, we're off a little */ 1936 sp->timecnt = 0; 1937 sp->typecnt = 1; 1938 sp->charcnt = 0; 1939 sp->goahead = false; 1940 init_ttinfo(&sp->ttis[0], 0, false, 0); 1941 strcpy(sp->chars, utc); 1942 return 0; 1943 } else { 1944 int err = tzload(name, sp, tzloadflags); 1945 if (err != 0 && name && name[0] != ':' && !(tzloadflags & TZLOAD_TZDIR_SUB) 1946 && tzparse(name, sp, NULL)) 1947 err = 0; 1948 if (err == 0) 1949 err = scrub_abbrs(sp); 1950 return err; 1951 } 1952 } 1953 1954 #ifndef __LIBC12_SOURCE__ 1955 /* If THREADED, upgrade a read lock to a write lock. 1956 Return 0 on success, a positive errno value otherwise. */ 1957 int 1958 rd2wrlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) 1959 { 1960 # if THREAD_RWLOCK 1961 if (threaded) { 1962 dounlock(); 1963 return pthread_rwlock_wrlock(&locallock); 1964 } 1965 # endif 1966 return 0; 1967 } 1968 1969 /* Like tzset(), but in a critical section. 1970 If THREADED && THREAD_RWLOCK the caller has a read lock, 1971 and this function might upgrade it to a write lock. 1972 If WALL, act as if TZ is unset; although always false in this file, 1973 a wrapper .c file's obsolete and ineffective tzsetwall function can use it. 1974 If tz_change_interval is positive the time is NOW; otherwise ignore NOW. */ 1975 void 1976 tzset_unlocked(bool threaded, bool wall, monotime_t now) 1977 { 1978 char const *name; 1979 struct state *sp; 1980 char tzloadflags; 1981 size_t namelen; 1982 bool writing = false; 1983 1984 for (;;) { 1985 name = wall ? NULL : getenv("TZ"); 1986 sp = lclptr; 1987 tzloadflags = TZLOAD_FROMENV | TZLOAD_TZSTRING; 1988 namelen = sizeof lcl_TZname + 1; /* placeholder for no name */ 1989 1990 if (name) { 1991 namelen = strnlen(name, sizeof lcl_TZname); 1992 1993 /* Abbreviate a string like "/usr/share/zoneinfo/America/Los_Angeles" 1994 to its shorter equivalent "America/Los_Angeles". */ 1995 if (!SUPPRESS_TZDIR && tzdirslashlen < namelen 1996 && memcmp(name, tzdirslash, tzdirslashlen) == 0) { 1997 char const *p = name + tzdirslashlen; 1998 while (*p == '/') 1999 p++; 2000 if (*p && *p != ':') { 2001 name = p; 2002 namelen = strnlen(name, sizeof lcl_TZname); 2003 tzloadflags |= TZLOAD_TZDIR_SUB; 2004 } 2005 } 2006 } 2007 2008 if ((tz_change_interval <= 0 ? tz_change_interval < 0 : fresh_tzdata(now)) 2009 && (name 2010 ? 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0 2011 : lcl_is_set < 0)) 2012 return; 2013 2014 if (!THREAD_RWLOCK || writing) 2015 break; 2016 if (rd2wrlock(threaded) != 0) 2017 return; 2018 writing = true; 2019 } 2020 2021 # if ALL_STATE 2022 if (! sp) 2023 lclptr = sp = malloc(sizeof *lclptr); 2024 # endif 2025 if (sp) { 2026 int err = zoneinit(sp, name, tzloadflags); 2027 if (err != 0) { 2028 zoneinit(sp, "", 0); 2029 /* Abbreviate with "-00" if there was an error. 2030 Do not treat a missing TZDEFAULT file as an error. */ 2031 if (name || err != ENOENT) 2032 strcpy(sp->chars, UNSPEC); 2033 } 2034 if (namelen < sizeof lcl_TZname) { 2035 char *cp = lcl_TZname; 2036 cp = mempcpy(cp, name, namelen); 2037 *cp = '\0'; 2038 } 2039 } 2040 settzname(); 2041 lcl_is_set = (sizeof lcl_TZname > namelen) - (sizeof lcl_TZname < namelen); 2042 } 2043 2044 /* If tz_change_interval is positive, 2045 return the current time as a monotonically nondecreasing value. 2046 Otherwise the return value does not matter. */ 2047 monotime_t 2048 get_monotonic_time(void) 2049 { 2050 struct timespec now; 2051 now.tv_sec = 0; 2052 if (0 < tz_change_interval) 2053 /*NOTREACHED*/ 2054 clock_gettime(CLOCK_MONOTONIC_COARSE, &now); 2055 return now.tv_sec; 2056 } 2057 #endif 2058 #endif 2059 2060 #if !USE_TIMEX_T 2061 2062 void 2063 tzset(void) 2064 { 2065 monotime_t now = get_monotonic_time(); 2066 int err = lock(); 2067 if (0 < err) { 2068 errno = err; 2069 return; 2070 } 2071 tzset_unlocked(!err, false, now); 2072 unlock(!err); 2073 } 2074 2075 #ifdef STD_INSPIRED 2076 void 2077 tzsetwall(void) 2078 { 2079 monotime_t now = get_monotonic_time(); 2080 int err = lock(); 2081 if (0 < err) { 2082 errno = err; 2083 return; 2084 } 2085 tzset_unlocked(!err, true, now); 2086 unlock(!err); 2087 } 2088 2089 #endif 2090 #endif 2091 2092 static void 2093 gmtcheck1(void) 2094 { 2095 #if ALL_STATE 2096 gmtptr = malloc(sizeof *gmtptr); 2097 #endif 2098 if (gmtptr) 2099 gmtload(gmtptr); 2100 } 2101 2102 static void 2103 gmtcheck(void) 2104 { 2105 static once_t gmt_once = ONCE_INIT; 2106 once(&gmt_once, gmtcheck1); 2107 } 2108 2109 #if NETBSD_INSPIRED && !USE_TIMEX_T 2110 2111 timezone_t 2112 tzalloc(char const *name) 2113 { 2114 timezone_t sp = malloc(sizeof *sp); 2115 if (sp) { 2116 int err = zoneinit(sp, name, TZLOAD_TZSTRING); 2117 if (err != 0) { 2118 free(sp); 2119 errno = err; 2120 return NULL; 2121 } 2122 } else if (/*CONSTCOND*/!HAVE_MALLOC_ERRNO) 2123 /*NOTREACHED*/ 2124 errno = ENOMEM; 2125 return sp; 2126 } 2127 2128 #ifndef FREE_PRESERVES_ERRNO 2129 # if ((defined _POSIX_VERSION && 202405 <= _POSIX_VERSION) \ 2130 || (defined __GLIBC__ && 2 < __GLIBC__ + (33 <= __GLIBC_MINOR__)) \ 2131 || defined __OpenBSD__ || defined __sun) 2132 # define FREE_PRESERVES_ERRNO 1 2133 # else 2134 # define FREE_PRESERVES_ERRNO 0 2135 # endif 2136 #endif 2137 2138 void 2139 tzfree(timezone_t sp) 2140 { 2141 int err; 2142 if (!FREE_PRESERVES_ERRNO) 2143 err = errno; 2144 free(sp); 2145 if (!FREE_PRESERVES_ERRNO) 2146 errno = err; 2147 } 2148 2149 /* 2150 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and 2151 ** POSIX.1-2024 removes ctime_r. Both have potential security problems that 2152 ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 2153 ** 2154 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 2155 ** in zones with three or more time zone abbreviations. 2156 ** Callers can instead use localtime_rz + strftime. 2157 */ 2158 2159 #endif 2160 2161 #if !USE_TIMEX_T || !defined TM_GMTOFF 2162 2163 /* 2164 ** The easy way to behave "as if no library function calls" localtime 2165 ** is to not call it, so we drop its guts into "localsub", which can be 2166 ** freely called. (And no, the PANS doesn't require the above behavior, 2167 ** but it *is* desirable.) 2168 ** 2169 ** If successful and SETNAME is nonzero, 2170 ** set the applicable parts of tzname, timezone and altzone; 2171 ** however, it's OK to omit this step for proleptic TZ strings 2172 ** since in that case tzset should have already done this step correctly. 2173 ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 2174 ** but it is actually a boolean and its value should be 0 or 1. 2175 ** 2176 ** If LTM_YEAR, store the resulting year-1900 into *LTM_YEAR rather 2177 ** than into the default TMP->tm_year; this prevents year overflow. 2178 */ 2179 2180 /*ARGSUSED*/ 2181 static struct tm * 2182 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 2183 struct tm *tmp, time_t *ltm_year) 2184 { 2185 register const struct ttinfo * ttisp; 2186 register int i; 2187 register struct tm * result; 2188 const time_t t = *timep; 2189 2190 if (sp == NULL) { 2191 /* Don't bother to set tzname etc.; tzset has already done it. */ 2192 return gmtsub(gmtptr, timep, 0, tmp, ltm_year); 2193 } 2194 if (sp->goahead && sp->ats[sp->timecnt - 1] < t) { 2195 /* Avoid integer overflow when time_t is signed, by 2196 using secs_div_2 twice; the full value would 2197 always be even, so halving does not round. */ 2198 __time_t 2199 tlo = sp->ats[sp->timecnt - 1], 2200 diffyears = ((t / 2 - tlo / 2 2201 + ((t % 2 - tlo % 2 + 2) / 2 - 1)) 2202 / (SECSPERREPEAT / 2) 2203 * YEARSPERREPEAT), 2204 years = diffyears + YEARSPERREPEAT, 2205 secs_div_2 = (diffyears * (AVGSECSPERYEAR / 2) 2206 + SECSPERREPEAT / 2); 2207 time_t newt = (time_t)(t - secs_div_2 - secs_div_2); 2208 time_t ryear; 2209 2210 result = localsub(sp, &newt, setname, tmp, &ryear); 2211 if (result) { 2212 if (ltm_year) 2213 *ltm_year = (time_t)(ryear + years); 2214 else { 2215 # ifdef ckd_add 2216 if (ckd_add(&result->tm_year, ryear, years)) 2217 return NULL; 2218 # else 2219 time_t newy = ryear + years; 2220 if (! (INT_MIN <= newy && newy <= INT_MAX)) { 2221 errno = EOVERFLOW; 2222 return NULL; 2223 } 2224 result->tm_year = (int)newy; 2225 # endif 2226 } 2227 } 2228 return result; 2229 } 2230 if (sp->timecnt == 0 || t < sp->ats[0]) { 2231 i = 0; 2232 } else { 2233 register int lo = 1; 2234 register int hi = sp->timecnt; 2235 2236 while (lo < hi) { 2237 register int mid = (lo + hi) / 2; 2238 2239 if (t < sp->ats[mid]) 2240 hi = mid; 2241 else lo = mid + 1; 2242 } 2243 i = sp->types[lo - 1]; 2244 } 2245 ttisp = &sp->ttis[i]; 2246 /* 2247 ** To get (wrong) behavior that's compatible with System V Release 2.0 2248 ** you'd replace the statement below with 2249 ** t += ttisp->tt_utoff; 2250 ** timesub(&t, 0, sp, tmp, ltm_year); 2251 */ 2252 result = timesub(&t, ttisp->tt_utoff, sp, tmp, ltm_year); 2253 if (result) { 2254 result->tm_isdst = ttisp->tt_isdst; 2255 # ifdef TM_ZONE 2256 result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]); 2257 # endif 2258 if (setname) 2259 update_tzname_etc(sp, ttisp); 2260 } 2261 return result; 2262 } 2263 #endif 2264 2265 #if !USE_TIMEX_T 2266 2267 /* Return TMP, or a thread-specific struct tm * selected by WHICH. */ 2268 static struct tm * 2269 tm_multi(struct tm *tmp, ATTRIBUTE_MAYBE_UNUSED enum tm_multi which) 2270 { 2271 # if THREAD_SAFE && THREAD_TM_MULTI 2272 /* It is OK to check is_threaded() separately here; even if it 2273 returns a different value in other places in the caller, 2274 this function's behavior is still valid. */ 2275 if (is_threaded()) { 2276 /* Try to get a thread-specific struct tm *. 2277 Fall back on TMP if this fails. */ 2278 static pthread_once_t tm_multi_once = PTHREAD_ONCE_INIT; 2279 pthread_once(&tm_multi_once, tm_multi_key_init); 2280 if (!tm_multi_key_err) { 2281 struct tm *p = pthread_getspecific(tm_multi_key); 2282 if (!p) { 2283 p = malloc(N_TM_MULTI * sizeof *p); 2284 if (p && pthread_setspecific(tm_multi_key, p) != 0) { 2285 free(p); 2286 p = NULL; 2287 } 2288 } 2289 if (p) 2290 return &p[which]; 2291 } 2292 } 2293 # endif 2294 return tmp; 2295 } 2296 2297 # if NETBSD_INSPIRED 2298 struct tm * 2299 localtime_rz(struct state *__restrict sp, time_t const *__restrict timep, 2300 struct tm *__restrict tmp) 2301 { 2302 return localsub(sp, timep, 0, tmp, NULL); 2303 } 2304 # endif 2305 2306 static struct tm * 2307 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 2308 { 2309 monotime_t now = get_monotonic_time(); 2310 int err = lock(); 2311 if (0 < err) { 2312 errno = err; 2313 return NULL; 2314 } 2315 if (0 <= tz_change_interval || setname || !lcl_is_set) 2316 tzset_unlocked(!err, false, now); 2317 tmp = localsub(lclptr, timep, setname, tmp, NULL); 2318 unlock(!err); 2319 return tmp; 2320 } 2321 2322 struct tm * 2323 localtime(const time_t *timep) 2324 { 2325 # if !SUPPORT_C89 2326 static struct tm tm; 2327 # endif 2328 return localtime_tzset(timep, tm_multi(&tm, LOCALTIME_TM_MULTI), true); 2329 } 2330 2331 struct tm * 2332 localtime_r(const time_t *__restrict timep, struct tm *__restrict tmp) 2333 { 2334 return localtime_tzset(timep, tmp, false); 2335 } 2336 #endif 2337 2338 /* 2339 ** gmtsub is to gmtime as localsub is to localtime. 2340 */ 2341 2342 static struct tm * 2343 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 2344 int_fast32_t offset, struct tm *tmp, time_t *ltm_year) 2345 { 2346 register struct tm * result; 2347 2348 result = timesub(timep, offset, gmtptr, tmp, ltm_year); 2349 #ifdef TM_ZONE 2350 /* 2351 ** Could get fancy here and deliver something such as 2352 ** "+xx" or "-xx" if offset is non-zero, 2353 ** but this is no time for a treasure hunt. 2354 */ 2355 if (result) 2356 result->TM_ZONE = UNCONST(offset ? wildabbr 2357 : gmtptr ? gmtptr->chars : utc); 2358 #endif /* defined TM_ZONE */ 2359 return result; 2360 } 2361 2362 #if !USE_TIMEX_T 2363 2364 /* 2365 * Re-entrant version of gmtime. 2366 */ 2367 2368 struct tm * 2369 gmtime_r(time_t const *__restrict timep, struct tm *__restrict tmp) 2370 { 2371 gmtcheck(); 2372 return gmtsub(gmtptr, timep, 0, tmp, NULL); 2373 } 2374 2375 struct tm * 2376 gmtime(const time_t *timep) 2377 { 2378 # if !SUPPORT_C89 2379 static struct tm tm; 2380 # endif 2381 return gmtime_r(timep, tm_multi(&tm, GMTIME_TM_MULTI)); 2382 } 2383 2384 # if STD_INSPIRED 2385 2386 /* This function is obsolescent and may disappear in future releases. 2387 Callers can instead use localtime_rz with a fixed-offset zone. */ 2388 2389 struct tm * 2390 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) 2391 { 2392 gmtcheck(); 2393 return gmtsub(gmtptr, timep, (int_fast32_t)offset, tmp, NULL); 2394 } 2395 2396 struct tm * 2397 offtime(time_t const *timep, long offset) 2398 { 2399 # if !SUPPORT_C89 2400 static struct tm tm; 2401 # endif 2402 return offtime_r(timep, offset, tm_multi(&tm, OFFTIME_TM_MULTI)); 2403 } 2404 2405 # endif 2406 #endif 2407 2408 /* 2409 ** Return the number of leap years through the end of the given year 2410 ** where, to make the math easy, the answer for year zero is defined as zero. 2411 */ 2412 2413 static time_t 2414 leaps_thru_end_of_nonneg(time_t y) 2415 { 2416 return y / 4 - y / 100 + y / 400; 2417 } 2418 2419 static time_t 2420 leaps_thru_end_of(time_t y) 2421 { 2422 return (y < 0 2423 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 2424 : leaps_thru_end_of_nonneg(y)); 2425 } 2426 2427 static struct tm * 2428 timesub(const time_t *timep, int_fast32_t offset, 2429 const struct state *sp, struct tm *tmp, time_t *ltm_year) 2430 { 2431 register time_t tdays; 2432 register const int * ip; 2433 int_fast32_2s corr; 2434 register int i; 2435 int_fast32_t idays, rem, dayoff, dayrem; 2436 time_t y; 2437 2438 /* If less than SECSPERMIN, the number of seconds since the 2439 most recent positive leap second; otherwise, do not add 1 2440 to localtime tm_sec because of leap seconds. */ 2441 __time_t secs_since_posleap = SECSPERMIN; 2442 2443 corr = 0; 2444 i = sp ? leapcount(sp) : 0; 2445 while (--i >= 0) { 2446 struct lsinfo ls = lsinfo(sp, i); 2447 if (ls.ls_trans <= *timep) { 2448 corr = ls.ls_corr; 2449 if ((i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < corr) 2450 secs_since_posleap = *timep - ls.ls_trans; 2451 break; 2452 } 2453 } 2454 2455 /* Calculate the year, avoiding integer overflow even if 2456 time_t is unsigned. */ 2457 tdays = (time_t)(*timep / SECSPERDAY); 2458 rem = (int)(*timep % SECSPERDAY); 2459 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 2460 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 2461 rem %= SECSPERDAY; 2462 /* y = (EPOCH_YEAR 2463 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 2464 sans overflow. But calculate against 1570 (EPOCH_YEAR - 2465 YEARSPERREPEAT) instead of against 1970 so that things work 2466 for localtime values before 1970 when time_t is unsigned. */ 2467 dayrem = (int)(tdays % DAYSPERREPEAT); 2468 dayrem += dayoff % DAYSPERREPEAT; 2469 y = (time_t)(EPOCH_YEAR - YEARSPERREPEAT 2470 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 2471 - ((dayrem % DAYSPERREPEAT) < 0) 2472 + tdays / DAYSPERREPEAT) 2473 * YEARSPERREPEAT)); 2474 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 2475 idays = (int)(tdays % DAYSPERREPEAT); 2476 idays += (dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT); 2477 idays %= DAYSPERREPEAT; 2478 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 2479 while (year_days(y) <= idays) { 2480 int_fast32_t tdelta = idays / DAYSPERLYEAR; 2481 int_fast32_t ydelta = tdelta + !tdelta; 2482 time_t newy = (time_t)(y + ydelta); 2483 register int leapdays; 2484 leapdays = (int)(leaps_thru_end_of(newy - 1) - 2485 leaps_thru_end_of(y - 1)); 2486 idays -= ydelta * DAYSPERNYEAR; 2487 idays -= leapdays; 2488 y = newy; 2489 } 2490 2491 if (ltm_year) { 2492 *ltm_year = y - TM_YEAR_BASE; 2493 } else { 2494 #ifdef ckd_add 2495 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 2496 errno = EOVERFLOW; 2497 return NULL; 2498 } 2499 #else 2500 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 2501 int signed_y = y; 2502 tmp->tm_year = signed_y - TM_YEAR_BASE; 2503 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 2504 && y - TM_YEAR_BASE <= INT_MAX) 2505 tmp->tm_year = y - TM_YEAR_BASE; 2506 else { 2507 errno = EOVERFLOW; 2508 return NULL; 2509 } 2510 #endif 2511 } 2512 tmp->tm_yday = (int)idays; 2513 /* 2514 ** The "extra" mods below avoid overflow problems. 2515 */ 2516 tmp->tm_wday = (int)(TM_WDAY_BASE 2517 + ((y % DAYSPERWEEK - TM_YEAR_BASE % DAYSPERWEEK) 2518 % DAYSPERWEEK 2519 * (DAYSPERNYEAR % DAYSPERWEEK)) 2520 + leaps_thru_end_of(y - 1) 2521 - leaps_thru_end_of(TM_YEAR_BASE - 1) 2522 + idays); 2523 tmp->tm_wday %= DAYSPERWEEK; 2524 if (tmp->tm_wday < 0) 2525 tmp->tm_wday += DAYSPERWEEK; 2526 tmp->tm_hour = (int) (rem / SECSPERHOUR); 2527 rem %= SECSPERHOUR; 2528 tmp->tm_min = (int)(rem / SECSPERMIN); 2529 tmp->tm_sec = (int)(rem % SECSPERMIN); 2530 2531 /* Use "... ??:??:60" at the end of the localtime minute containing 2532 the second just before the positive leap second. */ 2533 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2534 2535 ip = mon_lengths[isleap(y)]; 2536 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2537 idays -= ip[tmp->tm_mon]; 2538 tmp->tm_mday = (int)(idays + 1); 2539 tmp->tm_isdst = 0; 2540 #ifdef TM_GMTOFF 2541 tmp->TM_GMTOFF = offset; 2542 #endif /* defined TM_GMTOFF */ 2543 return tmp; 2544 } 2545 2546 /* 2547 ** Adapted from code provided by Robert Elz, who writes: 2548 ** The "best" way to do mktime I think is based on an idea of Bob 2549 ** Kridle's (so its said...) from a long time ago. 2550 ** It does a binary search of the time_t space. Since time_t's are 2551 ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2552 ** would still be very reasonable). 2553 */ 2554 2555 #ifndef WRONG 2556 # define WRONG ((time_t)-1) 2557 #endif /* !defined WRONG */ 2558 2559 /* 2560 ** Normalize logic courtesy Paul Eggert. 2561 */ 2562 2563 static bool 2564 increment_overflow_64(int *ip, int_fast64_t j) 2565 { 2566 #ifdef ckd_add 2567 return ckd_add(ip, *ip, j); 2568 #else 2569 if (j < 0 ? *ip < INT_MIN - j : INT_MAX - j < *ip) 2570 return true; 2571 *ip += j; 2572 return false; 2573 #endif 2574 } 2575 2576 static bool 2577 increment_overflow_time_iinntt(time_t *tp, iinntt j) 2578 { 2579 #ifdef ckd_add 2580 return ckd_add(tp, *tp, j); 2581 #else 2582 if (j < 0 2583 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2584 : TIME_T_MAX - j < *tp) 2585 return true; 2586 *tp += j; 2587 return false; 2588 #endif 2589 } 2590 2591 static bool 2592 increment_overflow_time_64(time_t *tp, int_fast64_t j) 2593 { 2594 #ifdef ckd_add 2595 return ckd_add(tp, *tp, j); 2596 #else 2597 if (j < 0 2598 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2599 : TIME_T_MAX - j < *tp) 2600 return true; 2601 *tp += j; 2602 return false; 2603 #endif 2604 } 2605 2606 static bool 2607 increment_overflow_time(__time_t *tp, int_fast32_2s j) 2608 { 2609 #ifdef ckd_add 2610 return ckd_add(tp, *tp, j); 2611 #else 2612 /* 2613 ** This is like 2614 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2615 ** except that it does the right thing even if *tp + j would overflow. 2616 */ 2617 if (! (j < 0 2618 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2619 : *tp <= TIME_T_MAX - j)) 2620 return true; 2621 *tp += j; 2622 return false; 2623 #endif 2624 } 2625 2626 /* Return A - B, where both are in the range -2**31 + 1 .. 2**31 - 1. 2627 The result cannot overflow. */ 2628 static int_fast64_t 2629 utoff_diff (int_fast32_t a, int_fast32_t b) 2630 { 2631 int_fast64_t aa = a; 2632 return aa - b; 2633 } 2634 2635 static int 2636 tmcomp(register const struct tm *const atmp, 2637 register const struct tm *const btmp) 2638 { 2639 register int result; 2640 2641 if (atmp->tm_year != btmp->tm_year) 2642 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2643 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2644 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2645 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2646 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2647 result = atmp->tm_sec - btmp->tm_sec; 2648 return result; 2649 } 2650 2651 /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2652 as other members might not be initialized. */ 2653 static void 2654 mktmcpy(struct tm *dest, struct tm const *src) 2655 { 2656 dest->tm_sec = src->tm_sec; 2657 dest->tm_min = src->tm_min; 2658 dest->tm_hour = src->tm_hour; 2659 dest->tm_mday = src->tm_mday; 2660 dest->tm_mon = src->tm_mon; 2661 dest->tm_year = src->tm_year; 2662 dest->tm_isdst = src->tm_isdst; 2663 #if defined TM_GMTOFF && ! UNINIT_TRAP 2664 dest->TM_GMTOFF = src->TM_GMTOFF; 2665 #endif 2666 } 2667 2668 static time_t 2669 time2sub(struct tm *const tmp, 2670 struct tm *funcp(struct state const *, time_t const *, 2671 int_fast32_t, struct tm *, time_t *), 2672 struct state const *sp, 2673 const int_fast32_t offset, 2674 bool *okayp, 2675 bool do_norm_secs) 2676 { 2677 register int dir; 2678 register int i, j; 2679 register time_t lo; 2680 register time_t hi; 2681 #ifdef NO_ERROR_IN_DST_GAP 2682 time_t ilo; 2683 #endif 2684 iinntt y, mday, hour, min, saved_seconds; 2685 time_t newt; 2686 time_t t; 2687 struct tm yourtm, mytm; 2688 2689 *okayp = false; 2690 mktmcpy(&yourtm, tmp); 2691 2692 #ifdef NO_ERROR_IN_DST_GAP 2693 again: 2694 #endif 2695 min = yourtm.tm_min; 2696 if (do_norm_secs) { 2697 min += yourtm.tm_sec / SECSPERMIN; 2698 yourtm.tm_sec %= SECSPERMIN; 2699 if (yourtm.tm_sec < 0) { 2700 yourtm.tm_sec += SECSPERMIN; 2701 min--; 2702 } 2703 } 2704 2705 hour = yourtm.tm_hour; 2706 hour += min / MINSPERHOUR; 2707 yourtm.tm_min = min % MINSPERHOUR; 2708 if (yourtm.tm_min < 0) { 2709 yourtm.tm_min += MINSPERHOUR; 2710 hour--; 2711 } 2712 2713 mday = yourtm.tm_mday; 2714 mday += hour / HOURSPERDAY; 2715 yourtm.tm_hour = hour % HOURSPERDAY; 2716 if (yourtm.tm_hour < 0) { 2717 yourtm.tm_hour += HOURSPERDAY; 2718 mday--; 2719 } 2720 2721 y = yourtm.tm_year; 2722 y += yourtm.tm_mon / MONSPERYEAR; 2723 yourtm.tm_mon %= MONSPERYEAR; 2724 if (yourtm.tm_mon < 0) { 2725 yourtm.tm_mon += MONSPERYEAR; 2726 y--; 2727 } 2728 2729 /* 2730 ** Turn y into an actual year number for now. 2731 ** It is converted back to an offset from TM_YEAR_BASE later. 2732 */ 2733 y += TM_YEAR_BASE; 2734 2735 while (mday <= 0) { 2736 iinntt li = y - (yourtm.tm_mon <= 1); 2737 mday += year_days(li); 2738 y--; 2739 } 2740 while (DAYSPERLYEAR < mday) { 2741 iinntt li = y + (1 < yourtm.tm_mon); 2742 mday -= year_days(li); 2743 y++; 2744 } 2745 2746 yourtm.tm_mday = (int)mday; 2747 for ( ; ; ) { 2748 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2749 if (yourtm.tm_mday <= i) 2750 break; 2751 yourtm.tm_mday -= i; 2752 if (++yourtm.tm_mon >= MONSPERYEAR) { 2753 yourtm.tm_mon = 0; 2754 y++; 2755 } 2756 } 2757 #ifdef ckd_add 2758 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2759 goto out_of_range; 2760 #else 2761 y -= TM_YEAR_BASE; 2762 if (! (INT_MIN <= y && y <= INT_MAX)) 2763 goto out_of_range; 2764 yourtm.tm_year = (int)y; 2765 #endif 2766 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2767 saved_seconds = 0; 2768 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) { 2769 /* 2770 ** We can't set tm_sec to 0, because that might push the 2771 ** time below the minimum representable time. 2772 ** Set tm_sec to 59 instead. 2773 ** This assumes that the minimum representable time is 2774 ** not in the same minute that a leap second was deleted from, 2775 ** which is a safer assumption than using 58 would be. 2776 */ 2777 saved_seconds = yourtm.tm_sec; 2778 saved_seconds -= SECSPERMIN - 1; 2779 yourtm.tm_sec = SECSPERMIN - 1; 2780 } else { 2781 saved_seconds = yourtm.tm_sec; 2782 yourtm.tm_sec = 0; 2783 } 2784 /* 2785 ** Do a binary search (this works whatever time_t's type is). 2786 */ 2787 lo = TIME_T_MIN; 2788 hi = TIME_T_MAX; 2789 #ifdef NO_ERROR_IN_DST_GAP 2790 ilo = lo; 2791 #endif 2792 for ( ; ; ) { 2793 t = lo / 2 + hi / 2; 2794 if (t < lo) 2795 t = lo; 2796 else if (t > hi) 2797 t = hi; 2798 if (! funcp(sp, &t, offset, &mytm, NULL)) { 2799 /* 2800 ** Assume that t is too extreme to be represented in 2801 ** a struct tm; arrange things so that it is less 2802 ** extreme on the next pass. 2803 */ 2804 dir = (t > 0) ? 1 : -1; 2805 } else dir = tmcomp(&mytm, &yourtm); 2806 if (dir != 0) { 2807 if (t == lo) { 2808 if (t == TIME_T_MAX) 2809 goto out_of_range; 2810 ++t; 2811 ++lo; 2812 } else if (t == hi) { 2813 if (t == TIME_T_MIN) 2814 goto out_of_range; 2815 --t; 2816 --hi; 2817 } 2818 #ifdef NO_ERROR_IN_DST_GAP 2819 if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 && 2820 do_norm_secs) { 2821 for (i = sp->typecnt - 1; i >= 0; --i) { 2822 for (j = sp->typecnt - 1; j >= 0; --j) { 2823 time_t off; 2824 if (sp->ttis[j].tt_isdst == 2825 sp->ttis[i].tt_isdst) 2826 continue; 2827 if (ttunspecified(sp, j)) 2828 continue; 2829 off = sp->ttis[j].tt_utoff - 2830 sp->ttis[i].tt_utoff; 2831 yourtm.tm_sec += off < 0 ? 2832 -off : off; 2833 goto again; 2834 } 2835 } 2836 } 2837 #endif 2838 if (lo > hi) 2839 goto invalid; 2840 if (dir > 0) 2841 hi = t; 2842 else lo = t; 2843 continue; 2844 } 2845 #if defined TM_GMTOFF && ! UNINIT_TRAP 2846 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2847 && (yourtm.TM_GMTOFF < 0 2848 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2849 && (mytm.TM_GMTOFF <= 2850 /*CONSTCOND*/ 2851 (min(INT_FAST32_MAX, LONG_MAX) 2852 + yourtm.TM_GMTOFF))) 2853 : (yourtm.TM_GMTOFF <= SECSPERDAY 2854 /*CONSTCOND*/ 2855 && ((max(INT_FAST32_MIN, LONG_MIN) 2856 + yourtm.TM_GMTOFF) 2857 <= mytm.TM_GMTOFF)))) { 2858 /* MYTM matches YOURTM except with the wrong UT offset. 2859 YOURTM.TM_GMTOFF is plausible, so try it instead. 2860 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2861 since the guess gets checked. */ 2862 time_t altt = t; 2863 int_fast64_t offdiff; 2864 bool v; 2865 # ifdef ckd_sub 2866 v = ckd_sub(&offdiff, mytm.TM_GMTOFF, yourtm.TM_GMTOFF); 2867 # else 2868 /* A ckd_sub approximation that is good enough here. */ 2869 v = !(-TWO_31_MINUS_1 <= yourtm.TM_GMTOFF 2870 && yourtm.TM_GMTOFF <= TWO_31_MINUS_1); 2871 if (!v) 2872 offdiff = utoff_diff(mytm.TM_GMTOFF, yourtm.TM_GMTOFF); 2873 # endif 2874 if (!v && !increment_overflow_time_64(&altt, offdiff)) { 2875 struct tm alttm; 2876 time_t xaltt = (time_t)altt; 2877 if (funcp(sp, &xaltt, offset, &alttm, NULL) 2878 && alttm.tm_isdst == mytm.tm_isdst 2879 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2880 && tmcomp(&alttm, &yourtm) == 0) { 2881 t = xaltt; 2882 mytm = alttm; 2883 } 2884 } 2885 } 2886 #endif 2887 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2888 break; 2889 /* 2890 ** Right time, wrong type. 2891 ** Hunt for right time, right type. 2892 ** It's okay to guess wrong since the guess 2893 ** gets checked. 2894 */ 2895 if (sp == NULL) 2896 goto invalid; 2897 for (i = sp->typecnt - 1; i >= 0; --i) { 2898 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2899 continue; 2900 for (j = sp->typecnt - 1; j >= 0; --j) { 2901 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2902 continue; 2903 if (ttunspecified(sp, j)) 2904 continue; 2905 newt = t; 2906 if (increment_overflow_time_64 2907 (&newt, 2908 utoff_diff(sp->ttis[j].tt_utoff, 2909 sp->ttis[i].tt_utoff))) 2910 continue; 2911 if (! funcp(sp, &newt, offset, &mytm, NULL)) 2912 continue; 2913 if (tmcomp(&mytm, &yourtm) != 0) 2914 continue; 2915 if (mytm.tm_isdst != yourtm.tm_isdst) 2916 continue; 2917 /* 2918 ** We have a match. 2919 */ 2920 t = newt; 2921 goto label; 2922 } 2923 } 2924 goto invalid; 2925 } 2926 label: 2927 if (increment_overflow_time_iinntt(&t, saved_seconds)) 2928 return WRONG; 2929 if (funcp(sp, &t, offset, tmp, NULL)) { 2930 *okayp = true; 2931 return t; 2932 } 2933 out_of_range: 2934 errno = EOVERFLOW; 2935 return WRONG; 2936 invalid: 2937 errno = EINVAL; 2938 return WRONG; 2939 } 2940 2941 static time_t 2942 time2(struct tm * const tmp, 2943 struct tm *funcp(struct state const *, time_t const *, 2944 int_fast32_t, struct tm *, time_t *), 2945 struct state const *sp, 2946 const int_fast32_t offset, 2947 bool *okayp) 2948 { 2949 time_t t; 2950 2951 /* 2952 ** First try without normalization of seconds 2953 ** (in case tm_sec contains a value associated with a leap second). 2954 ** If that fails, try with normalization of seconds. 2955 */ 2956 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2957 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2958 } 2959 2960 static time_t 2961 time1(struct tm *const tmp, 2962 struct tm *funcp(struct state const *, time_t const *, 2963 int_fast32_t, struct tm *, time_t *), 2964 struct state const *sp, 2965 const int_fast32_t offset) 2966 { 2967 register time_t t; 2968 register int samei, otheri; 2969 register int sameind, otherind; 2970 register int i; 2971 register int nseen; 2972 int save_errno; 2973 char seen[TZ_MAX_TYPES]; 2974 unsigned char types[TZ_MAX_TYPES]; 2975 bool okay; 2976 2977 if (tmp == NULL) { 2978 errno = EINVAL; 2979 return WRONG; 2980 } 2981 if (tmp->tm_isdst > 1) 2982 tmp->tm_isdst = 1; 2983 save_errno = errno; 2984 t = time2(tmp, funcp, sp, offset, &okay); 2985 if (okay) { 2986 errno = save_errno; 2987 return t; 2988 } 2989 if (tmp->tm_isdst < 0) 2990 #ifdef PCTS 2991 /* 2992 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2993 */ 2994 tmp->tm_isdst = 0; /* reset to std and try again */ 2995 #else 2996 return t; 2997 #endif /* !defined PCTS */ 2998 /* 2999 ** We're supposed to assume that somebody took a time of one type 3000 ** and did some math on it that yielded a "struct tm" that's bad. 3001 ** We try to divine the type they started from and adjust to the 3002 ** type they need. 3003 */ 3004 if (sp == NULL) { 3005 errno = EINVAL; 3006 return WRONG; 3007 } 3008 for (i = 0; i < sp->typecnt; ++i) 3009 seen[i] = false; 3010 nseen = 0; 3011 for (i = sp->timecnt - 1; i >= 0; --i) 3012 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 3013 seen[sp->types[i]] = true; 3014 types[nseen++] = sp->types[i]; 3015 } 3016 for (sameind = 0; sameind < nseen; ++sameind) { 3017 samei = types[sameind]; 3018 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 3019 continue; 3020 for (otherind = 0; otherind < nseen; ++otherind) { 3021 otheri = types[otherind]; 3022 if (sp->ttis[otheri].tt_isdst != tmp->tm_isdst) { 3023 int sec = tmp->tm_sec; 3024 if (!increment_overflow_64 3025 (&tmp->tm_sec, 3026 utoff_diff(sp->ttis[otheri].tt_utoff, 3027 sp->ttis[samei].tt_utoff))) { 3028 tmp->tm_isdst = !tmp->tm_isdst; 3029 t = time2(tmp, funcp, sp, offset, &okay); 3030 if (okay) { 3031 errno = save_errno; 3032 return t; 3033 } 3034 tmp->tm_isdst = !tmp->tm_isdst; 3035 } 3036 tmp->tm_sec = sec; 3037 } 3038 } 3039 } 3040 errno = EOVERFLOW; 3041 return WRONG; 3042 } 3043 3044 #if !defined TM_GMTOFF || !USE_TIMEX_T 3045 3046 static time_t 3047 mktime_tzname(struct state *sp, struct tm *tmp, bool setname) 3048 { 3049 if (sp) 3050 return time1(tmp, localsub, sp, setname); 3051 else { 3052 gmtcheck(); 3053 return time1(tmp, gmtsub, gmtptr, 0); 3054 } 3055 } 3056 3057 # if USE_TIMEX_T 3058 static 3059 # endif 3060 time_t 3061 mktime(struct tm *tmp) 3062 { 3063 monotime_t now = get_monotonic_time(); 3064 time_t t; 3065 int err = lock(); 3066 if (0 < err) { 3067 errno = err; 3068 return -1; 3069 } 3070 tzset_unlocked(!err, false, now); 3071 t = mktime_tzname(lclptr, tmp, true); 3072 unlock(!err); 3073 return t; 3074 } 3075 3076 #endif 3077 3078 #if NETBSD_INSPIRED && !USE_TIMEX_T 3079 time_t 3080 mktime_z(struct state *restrict sp, struct tm *restrict tmp) 3081 { 3082 return mktime_tzname(sp, tmp, false); 3083 } 3084 #endif 3085 3086 #if STD_INSPIRED && !USE_TIMEX_T 3087 /* This function is obsolescent and may disappear in future releases. 3088 Callers can instead use mktime. */ 3089 time_t 3090 timelocal_z(const timezone_t sp, struct tm *const tmp) 3091 { 3092 if (tmp != NULL) 3093 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 3094 return mktime_z(sp, tmp); 3095 } 3096 3097 time_t 3098 timelocal(struct tm *tmp) 3099 { 3100 if (tmp != NULL) 3101 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 3102 return mktime(tmp); 3103 } 3104 #endif 3105 3106 #if defined TM_GMTOFF || !USE_TIMEX_T 3107 3108 # ifndef EXTERN_TIMEOFF 3109 # ifndef timeoff 3110 # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 3111 # endif 3112 # define EXTERN_TIMEOFF static 3113 # endif 3114 3115 /* This function is obsolescent and may disappear in future releases. 3116 Callers can instead use mktime_z with a fixed-offset zone. */ 3117 EXTERN_TIMEOFF time_t 3118 timeoff(struct tm *tmp, long offset) 3119 { 3120 if (tmp) 3121 tmp->tm_isdst = 0; 3122 gmtcheck(); 3123 return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset); 3124 } 3125 #endif 3126 3127 #if !USE_TIMEX_T 3128 time_t 3129 timegm(struct tm *tmp) 3130 { 3131 time_t t; 3132 struct tm tmcpy; 3133 mktmcpy(&tmcpy, tmp); 3134 tmcpy.tm_wday = -1; 3135 t = timeoff(&tmcpy, 0); 3136 if (0 <= tmcpy.tm_wday) 3137 *tmp = tmcpy; 3138 return t; 3139 } 3140 #endif 3141 3142 static int_fast32_t 3143 leapcorr(struct state const *sp, __time_t t) 3144 { 3145 register int i; 3146 3147 i = leapcount(sp); 3148 while (--i >= 0) { 3149 struct lsinfo ls = lsinfo(sp, i); 3150 if (ls.ls_trans <= t) 3151 return ls.ls_corr; 3152 } 3153 return 0; 3154 } 3155 3156 /* 3157 ** XXX--is the below the right way to conditionalize?? 3158 */ 3159 3160 #if !USE_TIMEX_T 3161 # if STD_INSPIRED 3162 3163 static bool 3164 decrement_overflow_time(time_t *tp, int_fast32_2s j) 3165 { 3166 #ifdef ckd_sub 3167 return ckd_sub(tp, *tp, j); 3168 #else 3169 if (! (j < 0 3170 ? *tp <= TIME_T_MAX + j 3171 : (TYPE_SIGNED(time_t) ? TIME_T_MIN + j <= *tp : j <= *tp))) 3172 return true; 3173 *tp -= j; 3174 return false; 3175 #endif 3176 } 3177 3178 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if 3179 NETBSD_INSPIRED is defined, and are private otherwise. */ 3180 # if NETBSD_INSPIRED 3181 # define NETBSD_INSPIRED_EXTERN 3182 # else 3183 # define NETBSD_INSPIRED_EXTERN static 3184 # endif 3185 3186 /* 3187 ** IEEE Std 1003.1 (POSIX) says that 536457599 3188 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 3189 ** is not the case if we are accounting for leap seconds. 3190 ** So, we provide the following conversion routines for use 3191 ** when exchanging timestamps with POSIX conforming systems. 3192 */ 3193 3194 NETBSD_INSPIRED_EXTERN time_t 3195 time2posix_z(struct state *sp, time_t t) 3196 { 3197 if (decrement_overflow_time(&t, leapcorr(sp, t))) { 3198 /* Overflow near maximum time_t value with negative correction. 3199 This can happen with unrealistic-but-valid TZif files. */ 3200 errno = EOVERFLOW; 3201 return -1; 3202 } 3203 return t; 3204 } 3205 3206 time_t 3207 time2posix(time_t t) 3208 { 3209 monotime_t now = get_monotonic_time(); 3210 int err = lock(); 3211 if (0 < err) { 3212 errno = err; 3213 return -1; 3214 } 3215 if (0 <= tz_change_interval || !lcl_is_set) 3216 tzset_unlocked(!err, false, now); 3217 if (lclptr) 3218 t = (time_t)(t - leapcorr(lclptr, t)); 3219 unlock(!err); 3220 return t; 3221 } 3222 3223 NETBSD_INSPIRED_EXTERN time_t 3224 posix2time_z(struct state *sp, time_t t) 3225 { 3226 int i; 3227 for (i = leapcount(sp); 0 <= --i; ) { 3228 struct lsinfo ls = lsinfo(sp, i); 3229 __time_t t_corr = t; 3230 3231 if (increment_overflow_time(&t_corr, ls.ls_corr)) { 3232 if (0 <= ls.ls_corr) { 3233 /* Overflow near maximum time_t value with positive correction. 3234 This can happen with ordinary TZif files with leap seconds. */ 3235 errno = EOVERFLOW; 3236 return -1; 3237 } else { 3238 /* A negative correction overflowed, so keep going. 3239 This can happen with unrealistic-but-valid TZif files. */ 3240 } 3241 } else if (ls.ls_trans <= t_corr) 3242 return (time_t)(t_corr 3243 - (ls.ls_trans == t_corr 3244 && (i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < ls.ls_corr)); 3245 } 3246 return t; 3247 } 3248 3249 time_t 3250 posix2time(time_t t) 3251 { 3252 monotime_t now = get_monotonic_time(); 3253 int err = lock(); 3254 if (err) { 3255 errno = err; 3256 return -1; 3257 } 3258 if (0 <= tz_change_interval || !lcl_is_set) 3259 tzset_unlocked(!err, false, now); 3260 if (lclptr) 3261 t = posix2time_z(lclptr, t); 3262 unlock(!err); 3263 return t; 3264 } 3265 3266 # endif /* STD_INSPIRED */ 3267 3268 # if TZ_TIME_T 3269 3270 # if !USG_COMPAT 3271 # define timezone 0 3272 # endif 3273 3274 /* Convert from the underlying system's time_t to the ersatz time_tz, 3275 which is called 'time_t' in this file. Typically, this merely 3276 converts the time's integer width. On some platforms, the system 3277 time is local time not UT, or uses some epoch other than the POSIX 3278 epoch. 3279 3280 Although this code appears to define a function named 'time' that 3281 returns time_t, the macros in private.h cause this code to actually 3282 define a function named 'tz_time' that returns tz_time_t. The call 3283 to sys_time invokes the underlying system's 'time' function. */ 3284 3285 time_t 3286 time(time_t *p) 3287 { 3288 __time_t r = sys_time(NULL); 3289 if (r != (time_t) -1) { 3290 iinntt offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0; 3291 if (offset < IINNTT_MIN + EPOCH_OFFSET 3292 || increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) { 3293 errno = EOVERFLOW; 3294 r = -1; 3295 } 3296 } 3297 if (p) 3298 *p = (time_t)r; 3299 return (time_t)r; 3300 } 3301 3302 # endif 3303 #endif 3304