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