localtime.c revision 8a8b0c9bfcd80c67154ed2aca1e60d815c822acb
1/* 2** This file is in the public domain, so clarified as of 3** 1996-06-05 by Arthur David Olson. 4*/ 5 6/* 7** Leap second handling from Bradley White. 8** POSIX-style TZ environment variable handling from Guy Harris. 9*/ 10 11/*LINTLIBRARY*/ 12 13#include "private.h" 14#include "tzfile.h" 15#include "fcntl.h" 16 17#ifndef TZ_ABBR_MAX_LEN 18#define TZ_ABBR_MAX_LEN 16 19#endif /* !defined TZ_ABBR_MAX_LEN */ 20 21#ifndef TZ_ABBR_CHAR_SET 22#define TZ_ABBR_CHAR_SET \ 23 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" 24#endif /* !defined TZ_ABBR_CHAR_SET */ 25 26#ifndef TZ_ABBR_ERR_CHAR 27#define TZ_ABBR_ERR_CHAR '_' 28#endif /* !defined TZ_ABBR_ERR_CHAR */ 29 30/* 31** SunOS 4.1.1 headers lack O_BINARY. 32*/ 33 34#ifdef O_BINARY 35#define OPEN_MODE (O_RDONLY | O_BINARY) 36#endif /* defined O_BINARY */ 37#ifndef O_BINARY 38#define OPEN_MODE O_RDONLY 39#endif /* !defined O_BINARY */ 40 41#if 0 42# define XLOG(xx) printf xx , fflush(stdout) 43#else 44# define XLOG(x) do{}while (0) 45#endif 46 47/* BEGIN android-added: thread-safety. */ 48#include <pthread.h> 49static pthread_mutex_t _tzMutex = PTHREAD_MUTEX_INITIALIZER; 50static inline void _tzLock(void) { pthread_mutex_lock(&_tzMutex); } 51static inline void _tzUnlock(void) { pthread_mutex_unlock(&_tzMutex); } 52/* END android-added */ 53 54#ifndef WILDABBR 55/* 56** Someone might make incorrect use of a time zone abbreviation: 57** 1. They might reference tzname[0] before calling tzset (explicitly 58** or implicitly). 59** 2. They might reference tzname[1] before calling tzset (explicitly 60** or implicitly). 61** 3. They might reference tzname[1] after setting to a time zone 62** in which Daylight Saving Time is never observed. 63** 4. They might reference tzname[0] after setting to a time zone 64** in which Standard Time is never observed. 65** 5. They might reference tm.TM_ZONE after calling offtime. 66** What's best to do in the above cases is open to debate; 67** for now, we just set things up so that in any of the five cases 68** WILDABBR is used. Another possibility: initialize tzname[0] to the 69** string "tzname[0] used before set", and similarly for the other cases. 70** And another: initialize tzname[0] to "ERA", with an explanation in the 71** manual page of what this "time zone abbreviation" means (doing this so 72** that tzname[0] has the "normal" length of three characters). 73*/ 74#define WILDABBR " " 75#endif /* !defined WILDABBR */ 76 77static char wildabbr[] = WILDABBR; 78 79static const char gmt[] = "GMT"; 80 81/* 82** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. 83** We default to US rules as of 1999-08-17. 84** POSIX 1003.1 section 8.1.1 says that the default DST rules are 85** implementation dependent; for historical reasons, US rules are a 86** common default. 87*/ 88#ifndef TZDEFRULESTRING 89#define TZDEFRULESTRING ",M4.1.0,M10.5.0" 90#endif /* !defined TZDEFDST */ 91 92struct ttinfo { /* time type information */ 93 int_fast32_t tt_gmtoff; /* UT offset in seconds */ 94 int tt_isdst; /* used to set tm_isdst */ 95 int tt_abbrind; /* abbreviation list index */ 96 int tt_ttisstd; /* TRUE if transition is std time */ 97 int tt_ttisgmt; /* TRUE if transition is UT */ 98}; 99 100struct lsinfo { /* leap second information */ 101 time_t ls_trans; /* transition time */ 102 int_fast64_t ls_corr; /* correction to apply */ 103}; 104 105#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) 106 107#ifdef TZNAME_MAX 108#define MY_TZNAME_MAX TZNAME_MAX 109#endif /* defined TZNAME_MAX */ 110#ifndef TZNAME_MAX 111#define MY_TZNAME_MAX 255 112#endif /* !defined TZNAME_MAX */ 113 114struct state { 115 int leapcnt; 116 int timecnt; 117 int typecnt; 118 int charcnt; 119 int goback; 120 int goahead; 121 time_t ats[TZ_MAX_TIMES]; 122 unsigned char types[TZ_MAX_TIMES]; 123 struct ttinfo ttis[TZ_MAX_TYPES]; 124 char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), 125 (2 * (MY_TZNAME_MAX + 1)))]; 126 struct lsinfo lsis[TZ_MAX_LEAPS]; 127 int defaulttype; /* for early times or if no transitions */ 128}; 129 130struct rule { 131 int r_type; /* type of rule--see below */ 132 int r_day; /* day number of rule */ 133 int r_week; /* week number of rule */ 134 int r_mon; /* month number of rule */ 135 int_fast32_t r_time; /* transition time of rule */ 136}; 137 138#define JULIAN_DAY 0 /* Jn - Julian day */ 139#define DAY_OF_YEAR 1 /* n - day of year */ 140#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ 141 142/* 143** Prototypes for static functions. 144*/ 145 146/* NOTE: all internal functions assume that _tzLock() was already called */ 147 148static int __bionic_open_tzdata(const char*, int*); 149static int_fast32_t detzcode(const char * codep); 150static int_fast64_t detzcode64(const char * codep); 151static int differ_by_repeat(time_t t1, time_t t0); 152static const char * getzname(const char * strp) ATTRIBUTE_PURE; 153static const char * getqzname(const char * strp, const int delim) 154 ATTRIBUTE_PURE; 155static const char * getnum(const char * strp, int * nump, int min, 156 int max); 157static const char * getsecs(const char * strp, int_fast32_t * secsp); 158static const char * getoffset(const char * strp, int_fast32_t * offsetp); 159static const char * getrule(const char * strp, struct rule * rulep); 160static void gmtload(struct state * sp); 161static struct tm * gmtsub(const time_t * timep, const int_fast32_t offset, 162 struct tm * tmp, const struct state * sp); // android-changed: added sp. 163static struct tm * localsub(const time_t * timep, int_fast32_t offset, 164 struct tm * tmp, const struct state * sp); // android-changed: added sp. 165static int increment_overflow(int * number, int delta); 166static int leaps_thru_end_of(int y) ATTRIBUTE_PURE; 167static int increment_overflow32(int_fast32_t * number, int delta); 168static int increment_overflow_time(time_t *t, int_fast32_t delta); 169static int normalize_overflow32(int_fast32_t * tensptr, 170 int * unitsptr, int base); 171static int normalize_overflow(int * tensptr, int * unitsptr, 172 int base); 173static void settzname(void); 174static time_t time1(struct tm * tmp, 175 struct tm * (*funcp)(const time_t *, 176 int_fast32_t, struct tm *, const struct state *), // android-changed: added state*. 177 int_fast32_t offset, const struct state * sp); // android-changed: added sp. 178static time_t time2(struct tm * const tmp, 179 struct tm * (*const funcp)(const time_t *, 180 int_fast32_t, struct tm*, const struct state *), // android-changed: added state*. 181 int_fast32_t offset, int * okayp, const struct state * sp); // android-changed: added sp. 182static time_t time2sub(struct tm *tmp, 183 struct tm * (*funcp) (const time_t *, 184 int_fast32_t, struct tm*, const struct state *), // android-changed: added state*. 185 int_fast32_t offset, int * okayp, int do_norm_secs, const struct state * sp); // android-change: added sp. 186static struct tm * timesub(const time_t * timep, int_fast32_t offset, 187 const struct state * sp, struct tm * tmp); 188static int tmcomp(const struct tm * atmp, 189 const struct tm * btmp); 190static int_fast32_t transtime(int year, const struct rule * rulep, 191 int_fast32_t offset) 192 ATTRIBUTE_PURE; 193static int typesequiv(const struct state * sp, int a, int b); 194static int tzload(const char * name, struct state * sp, 195 int doextend); 196static int tzparse(const char * name, struct state * sp, 197 int lastditch); 198 199#ifdef ALL_STATE 200static struct state * lclptr; 201static struct state * gmtptr; 202#endif /* defined ALL_STATE */ 203 204#ifndef ALL_STATE 205static struct state lclmem; 206static struct state gmtmem; 207#define lclptr (&lclmem) 208#define gmtptr (&gmtmem) 209#endif /* State Farm */ 210 211#ifndef TZ_STRLEN_MAX 212#define TZ_STRLEN_MAX 255 213#endif /* !defined TZ_STRLEN_MAX */ 214 215static char lcl_TZname[TZ_STRLEN_MAX + 1]; 216static int lcl_is_set; 217static int gmt_is_set; 218 219char * tzname[2] = { 220 wildabbr, 221 wildabbr 222}; 223 224/* 225** Section 4.12.3 of X3.159-1989 requires that 226** Except for the strftime function, these functions [asctime, 227** ctime, gmtime, localtime] return values in one of two static 228** objects: a broken-down time structure and an array of char. 229** Thanks to Paul Eggert for noting this. 230*/ 231 232static struct tm tmGlobal; 233 234#ifdef USG_COMPAT 235long timezone = 0; 236int daylight = 0; 237#endif /* defined USG_COMPAT */ 238 239#ifdef ALTZONE 240long altzone = 0; 241#endif /* defined ALTZONE */ 242 243static int_fast32_t 244detzcode(const char *const codep) 245{ 246 register int_fast32_t result; 247 register int i; 248 249 result = (codep[0] & 0x80) ? -1 : 0; 250 for (i = 0; i < 4; ++i) 251 result = (result << 8) | (codep[i] & 0xff); 252 return result; 253} 254 255static int_fast64_t 256detzcode64(const char *const codep) 257{ 258 register int_fast64_t result; 259 register int i; 260 261 result = (codep[0] & 0x80) ? -1 : 0; 262 for (i = 0; i < 8; ++i) 263 result = (result << 8) | (codep[i] & 0xff); 264 return result; 265} 266 267static void 268settzname(void) 269{ 270 register struct state * const sp = lclptr; 271 register int i; 272 273 tzname[0] = wildabbr; 274 tzname[1] = wildabbr; 275#ifdef USG_COMPAT 276 daylight = 0; 277 timezone = 0; 278#endif /* defined USG_COMPAT */ 279#ifdef ALTZONE 280 altzone = 0; 281#endif /* defined ALTZONE */ 282#ifdef ALL_STATE 283 if (sp == NULL) { 284 tzname[0] = tzname[1] = gmt; 285 return; 286 } 287#endif /* defined ALL_STATE */ 288 /* 289 ** And to get the latest zone names into tzname. . . 290 */ 291 for (i = 0; i < sp->typecnt; ++i) { 292 register const struct ttinfo * const ttisp = &sp->ttis[i]; 293 294 tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind]; 295 } 296 for (i = 0; i < sp->timecnt; ++i) { 297 register const struct ttinfo * const ttisp = 298 &sp->ttis[ 299 sp->types[i]]; 300 301 tzname[ttisp->tt_isdst] = 302 &sp->chars[ttisp->tt_abbrind]; 303#ifdef USG_COMPAT 304 if (ttisp->tt_isdst) 305 daylight = 1; 306 if (!ttisp->tt_isdst) 307 timezone = -(ttisp->tt_gmtoff); 308#endif /* defined USG_COMPAT */ 309#ifdef ALTZONE 310 if (ttisp->tt_isdst) 311 altzone = -(ttisp->tt_gmtoff); 312#endif /* defined ALTZONE */ 313 } 314 /* 315 ** Finally, scrub the abbreviations. 316 ** First, replace bogus characters. 317 */ 318 for (i = 0; i < sp->charcnt; ++i) 319 if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) 320 sp->chars[i] = TZ_ABBR_ERR_CHAR; 321 /* 322 ** Second, truncate long abbreviations. 323 */ 324 for (i = 0; i < sp->typecnt; ++i) { 325 register const struct ttinfo * const ttisp = &sp->ttis[i]; 326 register char * cp = &sp->chars[ttisp->tt_abbrind]; 327 328 if (strlen(cp) > TZ_ABBR_MAX_LEN && 329 strcmp(cp, GRANDPARENTED) != 0) 330 *(cp + TZ_ABBR_MAX_LEN) = '\0'; 331 } 332} 333 334static int 335differ_by_repeat(const time_t t1, const time_t t0) 336{ 337 if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) 338 return 0; 339#if __LP64__ // 32-bit Android only has a signed 32-bit time_t; 64-bit Android is fixed. 340 return t1 - t0 == SECSPERREPEAT; 341#endif 342} 343 344static int 345tzload(register const char* name, register struct state* const sp, 346 register const int doextend) 347{ 348 register const char * p; 349 register int i; 350 register int fid; 351 register int stored; 352 register int nread; 353 typedef union { 354 struct tzhead tzhead; 355 char buf[2 * sizeof(struct tzhead) + 356 2 * sizeof *sp + 357 4 * TZ_MAX_TIMES]; 358 } u_t; 359#ifdef ALL_STATE 360 register u_t * up; 361 362 up = (u_t *) calloc(1, sizeof *up); 363 if (up == NULL) 364 return -1; 365#else /* !defined ALL_STATE */ 366 u_t u; 367 register u_t * const up = &u; 368#endif /* !defined ALL_STATE */ 369 370 sp->goback = sp->goahead = FALSE; 371 if (name == NULL && (name = TZDEFAULT) == NULL) 372 goto oops; 373 int toread; 374 fid = __bionic_open_tzdata(name, &toread); 375 if (fid < 0) 376 goto oops; 377 nread = read(fid, up->buf, toread); 378 if (close(fid) < 0 || nread <= 0) 379 goto oops; 380 for (stored = 4; stored <= 8; stored *= 2) { 381 int ttisstdcnt; 382 int ttisgmtcnt; 383 int timecnt; 384 385 ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt); 386 ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt); 387 sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt); 388 sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt); 389 sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt); 390 sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt); 391 p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt; 392 if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || 393 sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || 394 sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || 395 sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || 396 (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || 397 (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) 398 goto oops; 399 if (nread - (p - up->buf) < 400 sp->timecnt * stored + /* ats */ 401 sp->timecnt + /* types */ 402 sp->typecnt * 6 + /* ttinfos */ 403 sp->charcnt + /* chars */ 404 sp->leapcnt * (stored + 4) + /* lsinfos */ 405 ttisstdcnt + /* ttisstds */ 406 ttisgmtcnt) /* ttisgmts */ 407 goto oops; 408 timecnt = 0; 409 for (i = 0; i < sp->timecnt; ++i) { 410 int_fast64_t at 411 = stored == 4 ? detzcode(p) : detzcode64(p); 412 sp->types[i] = ((TYPE_SIGNED(time_t) 413 ? time_t_min <= at 414 : 0 <= at) 415 && at <= time_t_max); 416 if (sp->types[i]) { 417 if (i && !timecnt && at != time_t_min) { 418 /* 419 ** Keep the earlier record, but tweak 420 ** it so that it starts with the 421 ** minimum time_t value. 422 */ 423 sp->types[i - 1] = 1; 424 sp->ats[timecnt++] = time_t_min; 425 } 426 sp->ats[timecnt++] = at; 427 } 428 p += stored; 429 } 430 timecnt = 0; 431 for (i = 0; i < sp->timecnt; ++i) { 432 unsigned char typ = *p++; 433 if (sp->typecnt <= typ) 434 goto oops; 435 if (sp->types[i]) 436 sp->types[timecnt++] = typ; 437 } 438 sp->timecnt = timecnt; 439 for (i = 0; i < sp->typecnt; ++i) { 440 register struct ttinfo * ttisp; 441 442 ttisp = &sp->ttis[i]; 443 ttisp->tt_gmtoff = detzcode(p); 444 p += 4; 445 ttisp->tt_isdst = (unsigned char) *p++; 446 if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) 447 goto oops; 448 ttisp->tt_abbrind = (unsigned char) *p++; 449 if (ttisp->tt_abbrind < 0 || 450 ttisp->tt_abbrind > sp->charcnt) 451 goto oops; 452 } 453 for (i = 0; i < sp->charcnt; ++i) 454 sp->chars[i] = *p++; 455 sp->chars[i] = '\0'; /* ensure '\0' at end */ 456 for (i = 0; i < sp->leapcnt; ++i) { 457 register struct lsinfo * lsisp; 458 459 lsisp = &sp->lsis[i]; 460 lsisp->ls_trans = (stored == 4) ? 461 detzcode(p) : detzcode64(p); 462 p += stored; 463 lsisp->ls_corr = detzcode(p); 464 p += 4; 465 } 466 for (i = 0; i < sp->typecnt; ++i) { 467 register struct ttinfo * ttisp; 468 469 ttisp = &sp->ttis[i]; 470 if (ttisstdcnt == 0) 471 ttisp->tt_ttisstd = FALSE; 472 else { 473 ttisp->tt_ttisstd = *p++; 474 if (ttisp->tt_ttisstd != TRUE && 475 ttisp->tt_ttisstd != FALSE) 476 goto oops; 477 } 478 } 479 for (i = 0; i < sp->typecnt; ++i) { 480 register struct ttinfo * ttisp; 481 482 ttisp = &sp->ttis[i]; 483 if (ttisgmtcnt == 0) 484 ttisp->tt_ttisgmt = FALSE; 485 else { 486 ttisp->tt_ttisgmt = *p++; 487 if (ttisp->tt_ttisgmt != TRUE && 488 ttisp->tt_ttisgmt != FALSE) 489 goto oops; 490 } 491 } 492 /* 493 ** If this is an old file, we're done. 494 */ 495 if (up->tzhead.tzh_version[0] == '\0') 496 break; 497 nread -= p - up->buf; 498 for (i = 0; i < nread; ++i) 499 up->buf[i] = p[i]; 500 /* 501 ** If this is a signed narrow time_t system, we're done. 502 */ 503 if (TYPE_SIGNED(time_t) && stored >= (int) sizeof(time_t)) 504 break; 505 } 506 if (doextend && nread > 2 && 507 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 508 sp->typecnt + 2 <= TZ_MAX_TYPES) { 509 struct state * ts = malloc(sizeof *ts); 510 register int result; 511 512 if (ts == NULL) 513 goto oops; 514 515 up->buf[nread - 1] = '\0'; 516 result = tzparse(&up->buf[1], ts, FALSE); 517 if (result == 0 && ts->typecnt == 2 && 518 sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) { 519 for (i = 0; i < 2; ++i) 520 ts->ttis[i].tt_abbrind += 521 sp->charcnt; 522 for (i = 0; i < ts->charcnt; ++i) 523 sp->chars[sp->charcnt++] = 524 ts->chars[i]; 525 i = 0; 526 while (i < ts->timecnt && 527 ts->ats[i] <= 528 sp->ats[sp->timecnt - 1]) 529 ++i; 530 while (i < ts->timecnt && 531 sp->timecnt < TZ_MAX_TIMES) { 532 sp->ats[sp->timecnt] = 533 ts->ats[i]; 534 sp->types[sp->timecnt] = 535 sp->typecnt + 536 ts->types[i]; 537 ++sp->timecnt; 538 ++i; 539 } 540 sp->ttis[sp->typecnt++] = ts->ttis[0]; 541 sp->ttis[sp->typecnt++] = ts->ttis[1]; 542 } 543 free(ts); 544 } 545 if (sp->timecnt > 1) { 546 for (i = 1; i < sp->timecnt; ++i) 547 if (typesequiv(sp, sp->types[i], sp->types[0]) && 548 differ_by_repeat(sp->ats[i], sp->ats[0])) { 549 sp->goback = TRUE; 550 break; 551 } 552 for (i = sp->timecnt - 2; i >= 0; --i) 553 if (typesequiv(sp, sp->types[sp->timecnt - 1], 554 sp->types[i]) && 555 differ_by_repeat(sp->ats[sp->timecnt - 1], 556 sp->ats[i])) { 557 sp->goahead = TRUE; 558 break; 559 } 560 } 561 /* 562 ** If type 0 is is unused in transitions, 563 ** it's the type to use for early times. 564 */ 565 for (i = 0; i < sp->typecnt; ++i) 566 if (sp->types[i] == 0) 567 break; 568 i = (i >= sp->typecnt) ? 0 : -1; 569 /* 570 ** Absent the above, 571 ** if there are transition times 572 ** and the first transition is to a daylight time 573 ** find the standard type less than and closest to 574 ** the type of the first transition. 575 */ 576 if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) { 577 i = sp->types[0]; 578 while (--i >= 0) 579 if (!sp->ttis[i].tt_isdst) 580 break; 581 } 582 /* 583 ** If no result yet, find the first standard type. 584 ** If there is none, punt to type zero. 585 */ 586 if (i < 0) { 587 i = 0; 588 while (sp->ttis[i].tt_isdst) 589 if (++i >= sp->typecnt) { 590 i = 0; 591 break; 592 } 593 } 594 sp->defaulttype = i; 595#ifdef ALL_STATE 596 free(up); 597#endif /* defined ALL_STATE */ 598 return 0; 599oops: 600#ifdef ALL_STATE 601 free(up); 602#endif /* defined ALL_STATE */ 603 return -1; 604} 605 606static int 607typesequiv(const struct state *const sp, const int a, const int b) 608{ 609 register int result; 610 611 if (sp == NULL || 612 a < 0 || a >= sp->typecnt || 613 b < 0 || b >= sp->typecnt) 614 result = FALSE; 615 else { 616 register const struct ttinfo * ap = &sp->ttis[a]; 617 register const struct ttinfo * bp = &sp->ttis[b]; 618 result = ap->tt_gmtoff == bp->tt_gmtoff && 619 ap->tt_isdst == bp->tt_isdst && 620 ap->tt_ttisstd == bp->tt_ttisstd && 621 ap->tt_ttisgmt == bp->tt_ttisgmt && 622 strcmp(&sp->chars[ap->tt_abbrind], 623 &sp->chars[bp->tt_abbrind]) == 0; 624 } 625 return result; 626} 627 628static const int mon_lengths[2][MONSPERYEAR] = { 629 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 630 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 631}; 632 633static const int year_lengths[2] = { 634 DAYSPERNYEAR, DAYSPERLYEAR 635}; 636 637/* 638** Given a pointer into a time zone string, scan until a character that is not 639** a valid character in a zone name is found. Return a pointer to that 640** character. 641*/ 642 643static const char * 644getzname(register const char * strp) 645{ 646 register char c; 647 648 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 649 c != '+') 650 ++strp; 651 return strp; 652} 653 654/* 655** Given a pointer into an extended time zone string, scan until the ending 656** delimiter of the zone name is located. Return a pointer to the delimiter. 657** 658** As with getzname above, the legal character set is actually quite 659** restricted, with other characters producing undefined results. 660** We don't do any checking here; checking is done later in common-case code. 661*/ 662 663static const char * 664getqzname(register const char *strp, const int delim) 665{ 666 register int c; 667 668 while ((c = *strp) != '\0' && c != delim) 669 ++strp; 670 return strp; 671} 672 673/* 674** Given a pointer into a time zone string, extract a number from that string. 675** Check that the number is within a specified range; if it is not, return 676** NULL. 677** Otherwise, return a pointer to the first character not part of the number. 678*/ 679 680static const char * 681getnum(register const char * strp, int * const nump, const int min, const int max) 682{ 683 register char c; 684 register int num; 685 686 if (strp == NULL || !is_digit(c = *strp)) 687 return NULL; 688 num = 0; 689 do { 690 num = num * 10 + (c - '0'); 691 if (num > max) 692 return NULL; /* illegal value */ 693 c = *++strp; 694 } while (is_digit(c)); 695 if (num < min) 696 return NULL; /* illegal value */ 697 *nump = num; 698 return strp; 699} 700 701/* 702** Given a pointer into a time zone string, extract a number of seconds, 703** in hh[:mm[:ss]] form, from the string. 704** If any error occurs, return NULL. 705** Otherwise, return a pointer to the first character not part of the number 706** of seconds. 707*/ 708 709static const char * 710getsecs(register const char *strp, int_fast32_t *const secsp) 711{ 712 int num; 713 714 /* 715 ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like 716 ** "M10.4.6/26", which does not conform to Posix, 717 ** but which specifies the equivalent of 718 ** ``02:00 on the first Sunday on or after 23 Oct''. 719 */ 720 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 721 if (strp == NULL) 722 return NULL; 723 *secsp = num * (int_fast32_t) SECSPERHOUR; 724 if (*strp == ':') { 725 ++strp; 726 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 727 if (strp == NULL) 728 return NULL; 729 *secsp += num * SECSPERMIN; 730 if (*strp == ':') { 731 ++strp; 732 /* `SECSPERMIN' allows for leap seconds. */ 733 strp = getnum(strp, &num, 0, SECSPERMIN); 734 if (strp == NULL) 735 return NULL; 736 *secsp += num; 737 } 738 } 739 return strp; 740} 741 742/* 743** Given a pointer into a time zone string, extract an offset, in 744** [+-]hh[:mm[:ss]] form, from the string. 745** If any error occurs, return NULL. 746** Otherwise, return a pointer to the first character not part of the time. 747*/ 748 749static const char * 750getoffset(register const char *strp, int_fast32_t *const offsetp) 751{ 752 register int neg = 0; 753 754 if (*strp == '-') { 755 neg = 1; 756 ++strp; 757 } else if (*strp == '+') 758 ++strp; 759 strp = getsecs(strp, offsetp); 760 if (strp == NULL) 761 return NULL; /* illegal time */ 762 if (neg) 763 *offsetp = -*offsetp; 764 return strp; 765} 766 767/* 768** Given a pointer into a time zone string, extract a rule in the form 769** date[/time]. See POSIX section 8 for the format of "date" and "time". 770** If a valid rule is not found, return NULL. 771** Otherwise, return a pointer to the first character not part of the rule. 772*/ 773 774static const char * 775getrule(const char * strp, register struct rule * const rulep) 776{ 777 if (*strp == 'J') { 778 /* 779 ** Julian day. 780 */ 781 rulep->r_type = JULIAN_DAY; 782 ++strp; 783 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 784 } else if (*strp == 'M') { 785 /* 786 ** Month, week, day. 787 */ 788 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 789 ++strp; 790 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 791 if (strp == NULL) 792 return NULL; 793 if (*strp++ != '.') 794 return NULL; 795 strp = getnum(strp, &rulep->r_week, 1, 5); 796 if (strp == NULL) 797 return NULL; 798 if (*strp++ != '.') 799 return NULL; 800 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 801 } else if (is_digit(*strp)) { 802 /* 803 ** Day of year. 804 */ 805 rulep->r_type = DAY_OF_YEAR; 806 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 807 } else return NULL; /* invalid format */ 808 if (strp == NULL) 809 return NULL; 810 if (*strp == '/') { 811 /* 812 ** Time specified. 813 */ 814 ++strp; 815 strp = getoffset(strp, &rulep->r_time); 816 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 817 return strp; 818} 819 820/* 821** Given a year, a rule, and the offset from UT at the time that rule takes 822** effect, calculate the year-relative time that rule takes effect. 823*/ 824 825static int_fast32_t 826transtime(const int year, register const struct rule *const rulep, 827 const int_fast32_t offset) 828{ 829 register int leapyear; 830 register int_fast32_t value; 831 register int i; 832 int d, m1, yy0, yy1, yy2, dow; 833 834 INITIALIZE(value); 835 leapyear = isleap(year); 836 switch (rulep->r_type) { 837 838 case JULIAN_DAY: 839 /* 840 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 841 ** years. 842 ** In non-leap years, or if the day number is 59 or less, just 843 ** add SECSPERDAY times the day number-1 to the time of 844 ** January 1, midnight, to get the day. 845 */ 846 value = (rulep->r_day - 1) * SECSPERDAY; 847 if (leapyear && rulep->r_day >= 60) 848 value += SECSPERDAY; 849 break; 850 851 case DAY_OF_YEAR: 852 /* 853 ** n - day of year. 854 ** Just add SECSPERDAY times the day number to the time of 855 ** January 1, midnight, to get the day. 856 */ 857 value = rulep->r_day * SECSPERDAY; 858 break; 859 860 case MONTH_NTH_DAY_OF_WEEK: 861 /* 862 ** Mm.n.d - nth "dth day" of month m. 863 */ 864 865 /* 866 ** Use Zeller's Congruence to get day-of-week of first day of 867 ** month. 868 */ 869 m1 = (rulep->r_mon + 9) % 12 + 1; 870 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 871 yy1 = yy0 / 100; 872 yy2 = yy0 % 100; 873 dow = ((26 * m1 - 2) / 10 + 874 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 875 if (dow < 0) 876 dow += DAYSPERWEEK; 877 878 /* 879 ** "dow" is the day-of-week of the first day of the month. Get 880 ** the day-of-month (zero-origin) of the first "dow" day of the 881 ** month. 882 */ 883 d = rulep->r_day - dow; 884 if (d < 0) 885 d += DAYSPERWEEK; 886 for (i = 1; i < rulep->r_week; ++i) { 887 if (d + DAYSPERWEEK >= 888 mon_lengths[leapyear][rulep->r_mon - 1]) 889 break; 890 d += DAYSPERWEEK; 891 } 892 893 /* 894 ** "d" is the day-of-month (zero-origin) of the day we want. 895 */ 896 value = d * SECSPERDAY; 897 for (i = 0; i < rulep->r_mon - 1; ++i) 898 value += mon_lengths[leapyear][i] * SECSPERDAY; 899 break; 900 } 901 902 /* 903 ** "value" is the year-relative time of 00:00:00 UT on the day in 904 ** question. To get the year-relative time of the specified local 905 ** time on that day, add the transition time and the current offset 906 ** from UT. 907 */ 908 return value + rulep->r_time + offset; 909} 910 911/* 912** Given a POSIX section 8-style TZ string, fill in the rule tables as 913** appropriate. 914*/ 915 916static int 917tzparse(const char * name, register struct state * const sp, 918 const int lastditch) 919{ 920 const char * stdname; 921 const char * dstname; 922 size_t stdlen; 923 size_t dstlen; 924 int_fast32_t stdoffset; 925 int_fast32_t dstoffset; 926 register char * cp; 927 register int load_result; 928 static struct ttinfo zttinfo; 929 930 INITIALIZE(dstname); 931 stdname = name; 932 if (lastditch) { 933 stdlen = strlen(name); /* length of standard zone name */ 934 name += stdlen; 935 if (stdlen >= sizeof sp->chars) 936 stdlen = (sizeof sp->chars) - 1; 937 stdoffset = 0; 938 } else { 939 if (*name == '<') { 940 name++; 941 stdname = name; 942 name = getqzname(name, '>'); 943 if (*name != '>') 944 return (-1); 945 stdlen = name - stdname; 946 name++; 947 } else { 948 name = getzname(name); 949 stdlen = name - stdname; 950 } 951 if (*name == '\0') 952 return -1; 953 name = getoffset(name, &stdoffset); 954 if (name == NULL) 955 return -1; 956 } 957 load_result = tzload(TZDEFRULES, sp, FALSE); 958 if (load_result != 0) 959 sp->leapcnt = 0; /* so, we're off a little */ 960 if (*name != '\0') { 961 if (*name == '<') { 962 dstname = ++name; 963 name = getqzname(name, '>'); 964 if (*name != '>') 965 return -1; 966 dstlen = name - dstname; 967 name++; 968 } else { 969 dstname = name; 970 name = getzname(name); 971 dstlen = name - dstname; /* length of DST zone name */ 972 } 973 if (*name != '\0' && *name != ',' && *name != ';') { 974 name = getoffset(name, &dstoffset); 975 if (name == NULL) 976 return -1; 977 } else dstoffset = stdoffset - SECSPERHOUR; 978 if (*name == '\0' && load_result != 0) 979 name = TZDEFRULESTRING; 980 if (*name == ',' || *name == ';') { 981 struct rule start; 982 struct rule end; 983 register int year; 984 register int yearlim; 985 register int timecnt; 986 time_t janfirst; 987 988 ++name; 989 if ((name = getrule(name, &start)) == NULL) 990 return -1; 991 if (*name++ != ',') 992 return -1; 993 if ((name = getrule(name, &end)) == NULL) 994 return -1; 995 if (*name != '\0') 996 return -1; 997 sp->typecnt = 2; /* standard time and DST */ 998 /* 999 ** Two transitions per year, from EPOCH_YEAR forward. 1000 */ 1001 sp->ttis[0] = sp->ttis[1] = zttinfo; 1002 sp->ttis[0].tt_gmtoff = -dstoffset; 1003 sp->ttis[0].tt_isdst = 1; 1004 sp->ttis[0].tt_abbrind = stdlen + 1; 1005 sp->ttis[1].tt_gmtoff = -stdoffset; 1006 sp->ttis[1].tt_isdst = 0; 1007 sp->ttis[1].tt_abbrind = 0; 1008 timecnt = 0; 1009 janfirst = 0; 1010 yearlim = EPOCH_YEAR + YEARSPERREPEAT; 1011 for (year = EPOCH_YEAR; year < yearlim; year++) { 1012 int_fast32_t 1013 starttime = transtime(year, &start, stdoffset), 1014 endtime = transtime(year, &end, dstoffset); 1015 int_fast32_t 1016 yearsecs = (year_lengths[isleap(year)] 1017 * SECSPERDAY); 1018 int reversed = endtime < starttime; 1019 if (reversed) { 1020 int_fast32_t swap = starttime; 1021 starttime = endtime; 1022 endtime = swap; 1023 } 1024 if (reversed 1025 || (starttime < endtime 1026 && (endtime - starttime 1027 < (yearsecs 1028 + (stdoffset - dstoffset))))) { 1029 if (TZ_MAX_TIMES - 2 < timecnt) 1030 break; 1031 yearlim = year + YEARSPERREPEAT + 1; 1032 sp->ats[timecnt] = janfirst; 1033 if (increment_overflow_time 1034 (&sp->ats[timecnt], starttime)) 1035 break; 1036 sp->types[timecnt++] = reversed; 1037 sp->ats[timecnt] = janfirst; 1038 if (increment_overflow_time 1039 (&sp->ats[timecnt], endtime)) 1040 break; 1041 sp->types[timecnt++] = !reversed; 1042 } 1043 if (increment_overflow_time(&janfirst, yearsecs)) 1044 break; 1045 } 1046 sp->timecnt = timecnt; 1047 if (!timecnt) 1048 sp->typecnt = 1; /* Perpetual DST. */ 1049 } else { 1050 register int_fast32_t theirstdoffset; 1051 register int_fast32_t theirdstoffset; 1052 register int_fast32_t theiroffset; 1053 register int isdst; 1054 register int i; 1055 register int j; 1056 1057 if (*name != '\0') 1058 return -1; 1059 /* 1060 ** Initial values of theirstdoffset and theirdstoffset. 1061 */ 1062 theirstdoffset = 0; 1063 for (i = 0; i < sp->timecnt; ++i) { 1064 j = sp->types[i]; 1065 if (!sp->ttis[j].tt_isdst) { 1066 theirstdoffset = 1067 -sp->ttis[j].tt_gmtoff; 1068 break; 1069 } 1070 } 1071 theirdstoffset = 0; 1072 for (i = 0; i < sp->timecnt; ++i) { 1073 j = sp->types[i]; 1074 if (sp->ttis[j].tt_isdst) { 1075 theirdstoffset = 1076 -sp->ttis[j].tt_gmtoff; 1077 break; 1078 } 1079 } 1080 /* 1081 ** Initially we're assumed to be in standard time. 1082 */ 1083 isdst = FALSE; 1084 theiroffset = theirstdoffset; 1085 /* 1086 ** Now juggle transition times and types 1087 ** tracking offsets as you do. 1088 */ 1089 for (i = 0; i < sp->timecnt; ++i) { 1090 j = sp->types[i]; 1091 sp->types[i] = sp->ttis[j].tt_isdst; 1092 if (sp->ttis[j].tt_ttisgmt) { 1093 /* No adjustment to transition time */ 1094 } else { 1095 /* 1096 ** If summer time is in effect, and the 1097 ** transition time was not specified as 1098 ** standard time, add the summer time 1099 ** offset to the transition time; 1100 ** otherwise, add the standard time 1101 ** offset to the transition time. 1102 */ 1103 /* 1104 ** Transitions from DST to DDST 1105 ** will effectively disappear since 1106 ** POSIX provides for only one DST 1107 ** offset. 1108 */ 1109 if (isdst && !sp->ttis[j].tt_ttisstd) { 1110 sp->ats[i] += dstoffset - 1111 theirdstoffset; 1112 } else { 1113 sp->ats[i] += stdoffset - 1114 theirstdoffset; 1115 } 1116 } 1117 theiroffset = -sp->ttis[j].tt_gmtoff; 1118 if (sp->ttis[j].tt_isdst) 1119 theirdstoffset = theiroffset; 1120 else theirstdoffset = theiroffset; 1121 } 1122 /* 1123 ** Finally, fill in ttis. 1124 */ 1125 sp->ttis[0] = sp->ttis[1] = zttinfo; 1126 sp->ttis[0].tt_gmtoff = -stdoffset; 1127 sp->ttis[0].tt_isdst = FALSE; 1128 sp->ttis[0].tt_abbrind = 0; 1129 sp->ttis[1].tt_gmtoff = -dstoffset; 1130 sp->ttis[1].tt_isdst = TRUE; 1131 sp->ttis[1].tt_abbrind = stdlen + 1; 1132 sp->typecnt = 2; 1133 } 1134 } else { 1135 dstlen = 0; 1136 sp->typecnt = 1; /* only standard time */ 1137 sp->timecnt = 0; 1138 sp->ttis[0] = zttinfo; 1139 sp->ttis[0].tt_gmtoff = -stdoffset; 1140 sp->ttis[0].tt_isdst = 0; 1141 sp->ttis[0].tt_abbrind = 0; 1142 } 1143 sp->charcnt = stdlen + 1; 1144 if (dstlen != 0) 1145 sp->charcnt += dstlen + 1; 1146 if ((size_t) sp->charcnt > sizeof sp->chars) 1147 return -1; 1148 cp = sp->chars; 1149 (void) strncpy(cp, stdname, stdlen); 1150 cp += stdlen; 1151 *cp++ = '\0'; 1152 if (dstlen != 0) { 1153 (void) strncpy(cp, dstname, dstlen); 1154 *(cp + dstlen) = '\0'; 1155 } 1156 return 0; 1157} 1158 1159static void 1160gmtload(struct state * const sp) 1161{ 1162 if (tzload(gmt, sp, TRUE) != 0) 1163 (void) tzparse(gmt, sp, TRUE); 1164} 1165 1166#ifndef STD_INSPIRED 1167/* 1168** A non-static declaration of tzsetwall in a system header file 1169** may cause a warning about this upcoming static declaration... 1170*/ 1171static 1172#endif /* !defined STD_INSPIRED */ 1173void 1174tzsetwall(void) 1175{ 1176 if (lcl_is_set < 0) 1177 return; 1178 lcl_is_set = -1; 1179 1180#ifdef ALL_STATE 1181 if (lclptr == NULL) { 1182 lclptr = calloc(1, sizeof *lclptr); 1183 if (lclptr == NULL) { 1184 settzname(); /* all we can do */ 1185 return; 1186 } 1187 } 1188#endif /* defined ALL_STATE */ 1189 if (tzload(NULL, lclptr, TRUE) != 0) 1190 gmtload(lclptr); 1191 settzname(); 1192} 1193 1194#include <sys/system_properties.h> // For __system_property_get. 1195 1196static void 1197tzset_locked(void) 1198{ 1199 register const char * name = NULL; 1200 1201 name = getenv("TZ"); 1202 1203 // try the "persist.sys.timezone" system property first 1204 static char buf[PROP_VALUE_MAX]; 1205 if (name == NULL && __system_property_get("persist.sys.timezone", buf) > 0) { 1206 name = buf; 1207 } 1208 1209 if (name == NULL) { 1210 tzsetwall(); 1211 return; 1212 } 1213 1214 if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) 1215 return; 1216 lcl_is_set = strlen(name) < sizeof lcl_TZname; 1217 if (lcl_is_set) 1218 (void) strcpy(lcl_TZname, name); 1219 1220#ifdef ALL_STATE 1221 if (lclptr == NULL) { 1222 lclptr = calloc(1, sizeof *lclptr); 1223 if (lclptr == NULL) { 1224 settzname(); /* all we can do */ 1225 return; 1226 } 1227 } 1228#endif /* defined ALL_STATE */ 1229 if (*name == '\0') { 1230 /* 1231 ** User wants it fast rather than right. 1232 */ 1233 lclptr->leapcnt = 0; /* so, we're off a little */ 1234 lclptr->timecnt = 0; 1235 lclptr->typecnt = 0; 1236 lclptr->ttis[0].tt_isdst = 0; 1237 lclptr->ttis[0].tt_gmtoff = 0; 1238 lclptr->ttis[0].tt_abbrind = 0; 1239 (void) strcpy(lclptr->chars, gmt); 1240 } else if (tzload(name, lclptr, TRUE) != 0) 1241 if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) 1242 (void) gmtload(lclptr); 1243 settzname(); 1244} 1245 1246void 1247tzset(void) 1248{ 1249 _tzLock(); 1250 tzset_locked(); 1251 _tzUnlock(); 1252} 1253 1254/* 1255** The easy way to behave "as if no library function calls" localtime 1256** is to not call it--so we drop its guts into "localsub", which can be 1257** freely called. (And no, the PANS doesn't require the above behavior-- 1258** but it *is* desirable.) 1259** 1260** The unused offset argument is for the benefit of mktime variants. 1261*/ 1262 1263/*ARGSUSED*/ 1264static struct tm * 1265localsub(const time_t * const timep, const int_fast32_t offset, 1266 struct tm * const tmp, const struct state * sp) // android-changed: added sp. 1267{ 1268 register const struct ttinfo * ttisp; 1269 register int i; 1270 register struct tm * result; 1271 const time_t t = *timep; 1272 1273 // BEGIN android-changed: support user-supplied sp. 1274 if (sp == NULL) { 1275 sp = lclptr; 1276 } 1277 // END android-changed 1278#ifdef ALL_STATE 1279 if (sp == NULL) 1280 return gmtsub(timep, offset, tmp, sp); // android-changed: added sp. 1281#endif /* defined ALL_STATE */ 1282 if ((sp->goback && t < sp->ats[0]) || 1283 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1284 time_t newt = t; 1285 register time_t seconds; 1286 register time_t years; 1287 1288 if (t < sp->ats[0]) 1289 seconds = sp->ats[0] - t; 1290 else seconds = t - sp->ats[sp->timecnt - 1]; 1291 --seconds; 1292 years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT; 1293 seconds = years * AVGSECSPERYEAR; 1294 if (t < sp->ats[0]) 1295 newt += seconds; 1296 else newt -= seconds; 1297 if (newt < sp->ats[0] || 1298 newt > sp->ats[sp->timecnt - 1]) 1299 return NULL; /* "cannot happen" */ 1300 result = localsub(&newt, offset, tmp, sp); // android-changed: added sp. 1301 if (result == tmp) { 1302 register time_t newy; 1303 1304 newy = tmp->tm_year; 1305 if (t < sp->ats[0]) 1306 newy -= years; 1307 else newy += years; 1308 tmp->tm_year = newy; 1309 if (tmp->tm_year != newy) 1310 return NULL; 1311 } 1312 return result; 1313 } 1314 if (sp->timecnt == 0 || t < sp->ats[0]) { 1315 i = sp->defaulttype; 1316 } else { 1317 register int lo = 1; 1318 register int hi = sp->timecnt; 1319 1320 while (lo < hi) { 1321 register int mid = (lo + hi) >> 1; 1322 1323 if (t < sp->ats[mid]) 1324 hi = mid; 1325 else lo = mid + 1; 1326 } 1327 i = (int) sp->types[lo - 1]; 1328 } 1329 ttisp = &sp->ttis[i]; 1330 /* 1331 ** To get (wrong) behavior that's compatible with System V Release 2.0 1332 ** you'd replace the statement below with 1333 ** t += ttisp->tt_gmtoff; 1334 ** timesub(&t, 0L, sp, tmp); 1335 */ 1336 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); 1337 tmp->tm_isdst = ttisp->tt_isdst; 1338 tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; 1339#ifdef TM_ZONE 1340 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; 1341#endif /* defined TM_ZONE */ 1342 return result; 1343} 1344 1345struct tm * 1346localtime(const time_t * const timep) 1347{ 1348 return localtime_r(timep, &tmGlobal); 1349} 1350 1351/* 1352** Re-entrant version of localtime. 1353*/ 1354 1355struct tm * 1356localtime_r(const time_t * const timep, struct tm * tmp) 1357{ 1358 struct tm* result; 1359 1360 _tzLock(); 1361 tzset_locked(); 1362 result = localsub(timep, 0L, tmp, NULL); // android-changed: extra parameter. 1363 _tzUnlock(); 1364 1365 return result; 1366} 1367 1368/* 1369** gmtsub is to gmtime as localsub is to localtime. 1370*/ 1371 1372static struct tm * 1373gmtsub(const time_t * const timep, const int_fast32_t offset, 1374 struct tm *const tmp, const struct state * sp) // android-changed: added sp. 1375{ 1376 register struct tm * result; 1377 1378 (void) sp; // android-added: unused. 1379 1380 if (!gmt_is_set) { 1381 gmt_is_set = TRUE; 1382#ifdef ALL_STATE 1383 gmtptr = calloc(1, sizeof *gmtptr); 1384 if (gmtptr != NULL) 1385#endif /* defined ALL_STATE */ 1386 gmtload(gmtptr); 1387 } 1388 result = timesub(timep, offset, gmtptr, tmp); 1389#ifdef TM_ZONE 1390 /* 1391 ** Could get fancy here and deliver something such as 1392 ** "UT+xxxx" or "UT-xxxx" if offset is non-zero, 1393 ** but this is no time for a treasure hunt. 1394 */ 1395 if (offset != 0) 1396 tmp->TM_ZONE = wildabbr; 1397 else { 1398#ifdef ALL_STATE 1399 if (gmtptr == NULL) 1400 tmp->TM_ZONE = gmt; 1401 else tmp->TM_ZONE = gmtptr->chars; 1402#endif /* defined ALL_STATE */ 1403#ifndef ALL_STATE 1404 tmp->TM_ZONE = gmtptr->chars; 1405#endif /* State Farm */ 1406 } 1407#endif /* defined TM_ZONE */ 1408 return result; 1409} 1410 1411struct tm * 1412gmtime(const time_t * const timep) 1413{ 1414 return gmtime_r(timep, &tmGlobal); 1415} 1416 1417/* 1418* Re-entrant version of gmtime. 1419*/ 1420 1421struct tm * 1422gmtime_r(const time_t * const timep, struct tm * tmp) 1423{ 1424 struct tm* result; 1425 1426 _tzLock(); 1427 result = gmtsub(timep, 0L, tmp, NULL); // android-changed: extra parameter. 1428 _tzUnlock(); 1429 1430 return result; 1431} 1432 1433/* 1434** Return the number of leap years through the end of the given year 1435** where, to make the math easy, the answer for year zero is defined as zero. 1436*/ 1437 1438static int 1439leaps_thru_end_of(register const int y) 1440{ 1441 return (y >= 0) ? (y / 4 - y / 100 + y / 400) : 1442 -(leaps_thru_end_of(-(y + 1)) + 1); 1443} 1444 1445static struct tm * 1446timesub(const time_t *const timep, const int_fast32_t offset, 1447 register const struct state *const sp, 1448 register struct tm *const tmp) 1449{ 1450 register const struct lsinfo * lp; 1451 register time_t tdays; 1452 register int idays; /* unsigned would be so 2003 */ 1453 register int_fast64_t rem; 1454 int y; 1455 register const int * ip; 1456 register int_fast64_t corr; 1457 register int hit; 1458 register int i; 1459 1460 corr = 0; 1461 hit = 0; 1462#ifdef ALL_STATE 1463 i = (sp == NULL) ? 0 : sp->leapcnt; 1464#endif /* defined ALL_STATE */ 1465#ifndef ALL_STATE 1466 i = sp->leapcnt; 1467#endif /* State Farm */ 1468 while (--i >= 0) { 1469 lp = &sp->lsis[i]; 1470 if (*timep >= lp->ls_trans) { 1471 if (*timep == lp->ls_trans) { 1472 hit = ((i == 0 && lp->ls_corr > 0) || 1473 lp->ls_corr > sp->lsis[i - 1].ls_corr); 1474 if (hit) 1475 while (i > 0 && 1476 sp->lsis[i].ls_trans == 1477 sp->lsis[i - 1].ls_trans + 1 && 1478 sp->lsis[i].ls_corr == 1479 sp->lsis[i - 1].ls_corr + 1) { 1480 ++hit; 1481 --i; 1482 } 1483 } 1484 corr = lp->ls_corr; 1485 break; 1486 } 1487 } 1488 y = EPOCH_YEAR; 1489 tdays = *timep / SECSPERDAY; 1490 rem = *timep - tdays * SECSPERDAY; 1491 while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { 1492 int newy; 1493 register time_t tdelta; 1494 register int idelta; 1495 register int leapdays; 1496 1497 tdelta = tdays / DAYSPERLYEAR; 1498 if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta) 1499 && tdelta <= INT_MAX)) 1500 return NULL; 1501 idelta = tdelta; 1502 if (idelta == 0) 1503 idelta = (tdays < 0) ? -1 : 1; 1504 newy = y; 1505 if (increment_overflow(&newy, idelta)) 1506 return NULL; 1507 leapdays = leaps_thru_end_of(newy - 1) - 1508 leaps_thru_end_of(y - 1); 1509 tdays -= ((time_t) newy - y) * DAYSPERNYEAR; 1510 tdays -= leapdays; 1511 y = newy; 1512 } 1513 { 1514 register int_fast32_t seconds; 1515 1516 seconds = tdays * SECSPERDAY; 1517 tdays = seconds / SECSPERDAY; 1518 rem += seconds - tdays * SECSPERDAY; 1519 } 1520 /* 1521 ** Given the range, we can now fearlessly cast... 1522 */ 1523 idays = tdays; 1524 rem += offset - corr; 1525 while (rem < 0) { 1526 rem += SECSPERDAY; 1527 --idays; 1528 } 1529 while (rem >= SECSPERDAY) { 1530 rem -= SECSPERDAY; 1531 ++idays; 1532 } 1533 while (idays < 0) { 1534 if (increment_overflow(&y, -1)) 1535 return NULL; 1536 idays += year_lengths[isleap(y)]; 1537 } 1538 while (idays >= year_lengths[isleap(y)]) { 1539 idays -= year_lengths[isleap(y)]; 1540 if (increment_overflow(&y, 1)) 1541 return NULL; 1542 } 1543 tmp->tm_year = y; 1544 if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) 1545 return NULL; 1546 tmp->tm_yday = idays; 1547 /* 1548 ** The "extra" mods below avoid overflow problems. 1549 */ 1550 tmp->tm_wday = EPOCH_WDAY + 1551 ((y - EPOCH_YEAR) % DAYSPERWEEK) * 1552 (DAYSPERNYEAR % DAYSPERWEEK) + 1553 leaps_thru_end_of(y - 1) - 1554 leaps_thru_end_of(EPOCH_YEAR - 1) + 1555 idays; 1556 tmp->tm_wday %= DAYSPERWEEK; 1557 if (tmp->tm_wday < 0) 1558 tmp->tm_wday += DAYSPERWEEK; 1559 tmp->tm_hour = (int) (rem / SECSPERHOUR); 1560 rem %= SECSPERHOUR; 1561 tmp->tm_min = (int) (rem / SECSPERMIN); 1562 /* 1563 ** A positive leap second requires a special 1564 ** representation. This uses "... ??:59:60" et seq. 1565 */ 1566 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; 1567 ip = mon_lengths[isleap(y)]; 1568 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 1569 idays -= ip[tmp->tm_mon]; 1570 tmp->tm_mday = (int) (idays + 1); 1571 tmp->tm_isdst = 0; 1572#ifdef TM_GMTOFF 1573 tmp->TM_GMTOFF = offset; 1574#endif /* defined TM_GMTOFF */ 1575 return tmp; 1576} 1577 1578char * 1579ctime(const time_t * const timep) 1580{ 1581/* 1582** Section 4.12.3.2 of X3.159-1989 requires that 1583** The ctime function converts the calendar time pointed to by timer 1584** to local time in the form of a string. It is equivalent to 1585** asctime(localtime(timer)) 1586*/ 1587 return asctime(localtime(timep)); 1588} 1589 1590char * 1591ctime_r(const time_t * const timep, char * buf) 1592{ 1593 struct tm mytm; 1594 1595 return asctime_r(localtime_r(timep, &mytm), buf); 1596} 1597 1598/* 1599** Adapted from code provided by Robert Elz, who writes: 1600** The "best" way to do mktime I think is based on an idea of Bob 1601** Kridle's (so its said...) from a long time ago. 1602** It does a binary search of the time_t space. Since time_t's are 1603** just 32 bits, its a max of 32 iterations (even at 64 bits it 1604** would still be very reasonable). 1605*/ 1606 1607#ifndef WRONG 1608#define WRONG (-1) 1609#endif /* !defined WRONG */ 1610 1611/* 1612** Normalize logic courtesy Paul Eggert. 1613*/ 1614 1615static int 1616increment_overflow(int *const ip, int j) 1617{ 1618 register int const i = *ip; 1619 1620 /* 1621 ** If i >= 0 there can only be overflow if i + j > INT_MAX 1622 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 1623 ** If i < 0 there can only be overflow if i + j < INT_MIN 1624 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 1625 */ 1626 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 1627 return TRUE; 1628 *ip += j; 1629 return FALSE; 1630} 1631 1632static int 1633increment_overflow32(int_fast32_t *const lp, int const m) 1634{ 1635 register int_fast32_t const l = *lp; 1636 1637 if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) 1638 return TRUE; 1639 *lp += m; 1640 return FALSE; 1641} 1642 1643static int 1644increment_overflow_time(time_t *tp, int_fast32_t j) 1645{ 1646 /* 1647 ** This is like 1648 ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...', 1649 ** except that it does the right thing even if *tp + j would overflow. 1650 */ 1651 if (! (j < 0 1652 ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp) 1653 : *tp <= time_t_max - j)) 1654 return TRUE; 1655 *tp += j; 1656 return FALSE; 1657} 1658 1659static int 1660normalize_overflow(int *const tensptr, int *const unitsptr, const int base) 1661{ 1662 register int tensdelta; 1663 1664 tensdelta = (*unitsptr >= 0) ? 1665 (*unitsptr / base) : 1666 (-1 - (-1 - *unitsptr) / base); 1667 *unitsptr -= tensdelta * base; 1668 return increment_overflow(tensptr, tensdelta); 1669} 1670 1671static int 1672normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr, 1673 const int base) 1674{ 1675 register int tensdelta; 1676 1677 tensdelta = (*unitsptr >= 0) ? 1678 (*unitsptr / base) : 1679 (-1 - (-1 - *unitsptr) / base); 1680 *unitsptr -= tensdelta * base; 1681 return increment_overflow32(tensptr, tensdelta); 1682} 1683 1684static int 1685tmcomp(register const struct tm * const atmp, 1686 register const struct tm * const btmp) 1687{ 1688 register int result; 1689 1690 if (atmp->tm_year != btmp->tm_year) 1691 return atmp->tm_year < btmp->tm_year ? -1 : 1; 1692 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 1693 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 1694 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 1695 (result = (atmp->tm_min - btmp->tm_min)) == 0) 1696 result = atmp->tm_sec - btmp->tm_sec; 1697 return result; 1698} 1699 1700static time_t 1701time2sub(struct tm * const tmp, 1702 struct tm *(*const funcp)(const time_t*, int_fast32_t, struct tm*, const struct state*), 1703 const int_fast32_t offset, 1704 int * const okayp, 1705 const int do_norm_secs, const struct state * sp) // android-changed: added sp 1706{ 1707 register int dir; 1708 register int i, j; 1709 register int saved_seconds; 1710 register int_fast32_t li; 1711 register time_t lo; 1712 register time_t hi; 1713 int_fast32_t y; 1714 time_t newt; 1715 time_t t; 1716 struct tm yourtm, mytm; 1717 1718 *okayp = FALSE; 1719 yourtm = *tmp; 1720 if (do_norm_secs) { 1721 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, 1722 SECSPERMIN)) 1723 return WRONG; 1724 } 1725 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) 1726 return WRONG; 1727 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) 1728 return WRONG; 1729 y = yourtm.tm_year; 1730 if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) 1731 return WRONG; 1732 /* 1733 ** Turn y into an actual year number for now. 1734 ** It is converted back to an offset from TM_YEAR_BASE later. 1735 */ 1736 if (increment_overflow32(&y, TM_YEAR_BASE)) 1737 return WRONG; 1738 while (yourtm.tm_mday <= 0) { 1739 if (increment_overflow32(&y, -1)) 1740 return WRONG; 1741 li = y + (1 < yourtm.tm_mon); 1742 yourtm.tm_mday += year_lengths[isleap(li)]; 1743 } 1744 while (yourtm.tm_mday > DAYSPERLYEAR) { 1745 li = y + (1 < yourtm.tm_mon); 1746 yourtm.tm_mday -= year_lengths[isleap(li)]; 1747 if (increment_overflow32(&y, 1)) 1748 return WRONG; 1749 } 1750 for ( ; ; ) { 1751 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 1752 if (yourtm.tm_mday <= i) 1753 break; 1754 yourtm.tm_mday -= i; 1755 if (++yourtm.tm_mon >= MONSPERYEAR) { 1756 yourtm.tm_mon = 0; 1757 if (increment_overflow32(&y, 1)) 1758 return WRONG; 1759 } 1760 } 1761 if (increment_overflow32(&y, -TM_YEAR_BASE)) 1762 return WRONG; 1763 yourtm.tm_year = y; 1764 if (yourtm.tm_year != y) 1765 return WRONG; 1766 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 1767 saved_seconds = 0; 1768 else if (y + TM_YEAR_BASE < EPOCH_YEAR) { 1769 /* 1770 ** We can't set tm_sec to 0, because that might push the 1771 ** time below the minimum representable time. 1772 ** Set tm_sec to 59 instead. 1773 ** This assumes that the minimum representable time is 1774 ** not in the same minute that a leap second was deleted from, 1775 ** which is a safer assumption than using 58 would be. 1776 */ 1777 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) 1778 return WRONG; 1779 saved_seconds = yourtm.tm_sec; 1780 yourtm.tm_sec = SECSPERMIN - 1; 1781 } else { 1782 saved_seconds = yourtm.tm_sec; 1783 yourtm.tm_sec = 0; 1784 } 1785 /* 1786 ** Do a binary search (this works whatever time_t's type is). 1787 */ 1788 if (!TYPE_SIGNED(time_t)) { 1789 lo = 0; 1790 hi = lo - 1; 1791 } else { 1792 lo = 1; 1793 for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) 1794 lo *= 2; 1795 hi = -(lo + 1); 1796 } 1797 for ( ; ; ) { 1798 t = lo / 2 + hi / 2; 1799 if (t < lo) 1800 t = lo; 1801 else if (t > hi) 1802 t = hi; 1803 if ((*funcp)(&t, offset, &mytm, sp) == NULL) { // android-changed: added sp. 1804 /* 1805 ** Assume that t is too extreme to be represented in 1806 ** a struct tm; arrange things so that it is less 1807 ** extreme on the next pass. 1808 */ 1809 dir = (t > 0) ? 1 : -1; 1810 } else dir = tmcomp(&mytm, &yourtm); 1811 if (dir != 0) { 1812 if (t == lo) { 1813 if (t == time_t_max) 1814 return WRONG; 1815 ++t; 1816 ++lo; 1817 } else if (t == hi) { 1818 if (t == time_t_min) 1819 return WRONG; 1820 --t; 1821 --hi; 1822 } 1823 if (lo > hi) 1824 return WRONG; 1825 if (dir > 0) 1826 hi = t; 1827 else lo = t; 1828 continue; 1829 } 1830 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 1831 break; 1832 /* 1833 ** Right time, wrong type. 1834 ** Hunt for right time, right type. 1835 ** It's okay to guess wrong since the guess 1836 ** gets checked. 1837 */ 1838 // BEGIN android-changed: support user-supplied sp 1839 if (sp == NULL) { 1840 sp = (const struct state *) 1841 ((funcp == localsub) ? lclptr : gmtptr); 1842 } 1843 // END android-changed 1844#ifdef ALL_STATE 1845 if (sp == NULL) 1846 return WRONG; 1847#endif /* defined ALL_STATE */ 1848 for (i = sp->typecnt - 1; i >= 0; --i) { 1849 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 1850 continue; 1851 for (j = sp->typecnt - 1; j >= 0; --j) { 1852 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 1853 continue; 1854 newt = t + sp->ttis[j].tt_gmtoff - 1855 sp->ttis[i].tt_gmtoff; 1856 if ((*funcp)(&newt, offset, &mytm, sp) == NULL) // android-changed: added sp. 1857 continue; 1858 if (tmcomp(&mytm, &yourtm) != 0) 1859 continue; 1860 if (mytm.tm_isdst != yourtm.tm_isdst) 1861 continue; 1862 /* 1863 ** We have a match. 1864 */ 1865 t = newt; 1866 goto label; 1867 } 1868 } 1869 return WRONG; 1870 } 1871label: 1872 newt = t + saved_seconds; 1873 if ((newt < t) != (saved_seconds < 0)) 1874 return WRONG; 1875 t = newt; 1876 if ((*funcp)(&t, offset, tmp, sp)) // android-changed: added sp. 1877 *okayp = TRUE; 1878 return t; 1879} 1880 1881static time_t 1882time2(struct tm * const tmp, 1883 struct tm * (*const funcp)(const time_t *, int_fast32_t, struct tm *, const struct state *), // android-changed: added sp. 1884 const int_fast32_t offset, 1885 int *const okayp, const struct state* sp) // android-changed: added sp. 1886{ 1887 time_t t; 1888 1889 /* 1890 ** First try without normalization of seconds 1891 ** (in case tm_sec contains a value associated with a leap second). 1892 ** If that fails, try with normalization of seconds. 1893 */ 1894 t = time2sub(tmp, funcp, offset, okayp, FALSE, sp); 1895 return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp); 1896} 1897 1898static time_t 1899time1(struct tm * const tmp, 1900 struct tm * (* const funcp) (const time_t *, int_fast32_t, struct tm *, const struct state *), // android-changed: added sp. 1901 const int_fast32_t offset, const struct state * sp) // android-changed: added sp. 1902{ 1903 register time_t t; 1904 register int samei, otheri; 1905 register int sameind, otherind; 1906 register int i; 1907 register int nseen; 1908 int seen[TZ_MAX_TYPES]; 1909 int types[TZ_MAX_TYPES]; 1910 int okay; 1911 1912 if (tmp == NULL) { 1913 errno = EINVAL; 1914 return WRONG; 1915 } 1916 if (tmp->tm_isdst > 1) 1917 tmp->tm_isdst = 1; 1918 t = time2(tmp, funcp, offset, &okay, sp); // android-changed: added sp. 1919#ifdef PCTS 1920 /* 1921 ** PCTS code courtesy Grant Sullivan. 1922 */ 1923 if (okay) 1924 return t; 1925 if (tmp->tm_isdst < 0) 1926 tmp->tm_isdst = 0; /* reset to std and try again */ 1927#endif /* defined PCTS */ 1928#ifndef PCTS 1929 if (okay || tmp->tm_isdst < 0) 1930 return t; 1931#endif /* !defined PCTS */ 1932 /* 1933 ** We're supposed to assume that somebody took a time of one type 1934 ** and did some math on it that yielded a "struct tm" that's bad. 1935 ** We try to divine the type they started from and adjust to the 1936 ** type they need. 1937 */ 1938 // BEGIN android-changed: support user-supplied sp. 1939 if (sp == NULL) { 1940 sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr); 1941 } 1942 // BEGIN android-changed 1943#ifdef ALL_STATE 1944 if (sp == NULL) 1945 return WRONG; 1946#endif /* defined ALL_STATE */ 1947 for (i = 0; i < sp->typecnt; ++i) 1948 seen[i] = FALSE; 1949 nseen = 0; 1950 for (i = sp->timecnt - 1; i >= 0; --i) 1951 if (!seen[sp->types[i]]) { 1952 seen[sp->types[i]] = TRUE; 1953 types[nseen++] = sp->types[i]; 1954 } 1955 for (sameind = 0; sameind < nseen; ++sameind) { 1956 samei = types[sameind]; 1957 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 1958 continue; 1959 for (otherind = 0; otherind < nseen; ++otherind) { 1960 otheri = types[otherind]; 1961 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 1962 continue; 1963 tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - 1964 sp->ttis[samei].tt_gmtoff; 1965 tmp->tm_isdst = !tmp->tm_isdst; 1966 t = time2(tmp, funcp, offset, &okay, sp); // android-changed: added sp. 1967 if (okay) 1968 return t; 1969 tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - 1970 sp->ttis[samei].tt_gmtoff; 1971 tmp->tm_isdst = !tmp->tm_isdst; 1972 } 1973 } 1974 return WRONG; 1975} 1976 1977time_t 1978mktime(struct tm * const tmp) 1979{ 1980 _tzLock(); 1981 tzset_locked(); 1982 time_t result = time1(tmp, localsub, 0L, NULL); // android-changed: extra parameter. 1983 _tzUnlock(); 1984 return result; 1985} 1986 1987#ifdef STD_INSPIRED 1988 1989time_t 1990timelocal(struct tm * const tmp) 1991{ 1992 if (tmp != NULL) 1993 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 1994 return mktime(tmp); 1995} 1996 1997time_t 1998timegm(struct tm * const tmp) 1999{ 2000 time_t result; 2001 2002 if (tmp != NULL) 2003 tmp->tm_isdst = 0; 2004 _tzLock(); 2005 result = time1(tmp, gmtsub, 0L, NULL); // android-changed: extra parameter. 2006 _tzUnlock(); 2007 2008 return result; 2009} 2010 2011#endif /* defined STD_INSPIRED */ 2012 2013#ifdef CMUCS 2014 2015/* 2016** The following is supplied for compatibility with 2017** previous versions of the CMUCS runtime library. 2018*/ 2019 2020long 2021gtime(struct tm * const tmp) 2022{ 2023 const time_t t = mktime(tmp); 2024 2025 if (t == WRONG) 2026 return -1; 2027 return t; 2028} 2029 2030#endif /* defined CMUCS */ 2031 2032/* 2033** XXX--is the below the right way to conditionalize?? 2034*/ 2035 2036#ifdef STD_INSPIRED 2037 2038/* 2039** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599 2040** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 2041** is not the case if we are accounting for leap seconds. 2042** So, we provide the following conversion routines for use 2043** when exchanging timestamps with POSIX conforming systems. 2044*/ 2045 2046static int_fast64_t 2047leapcorr(time_t * timep) 2048{ 2049 register struct state * sp; 2050 register struct lsinfo * lp; 2051 register int i; 2052 2053 sp = lclptr; 2054 i = sp->leapcnt; 2055 while (--i >= 0) { 2056 lp = &sp->lsis[i]; 2057 if (*timep >= lp->ls_trans) 2058 return lp->ls_corr; 2059 } 2060 return 0; 2061} 2062 2063time_t 2064time2posix(time_t t) 2065{ 2066 tzset(); 2067 return t - leapcorr(&t); 2068} 2069 2070time_t 2071posix2time(time_t t) 2072{ 2073 time_t x; 2074 time_t y; 2075 2076 tzset(); 2077 /* 2078 ** For a positive leap second hit, the result 2079 ** is not unique. For a negative leap second 2080 ** hit, the corresponding time doesn't exist, 2081 ** so we return an adjacent second. 2082 */ 2083 x = t + leapcorr(&t); 2084 y = x - leapcorr(&x); 2085 if (y < t) { 2086 do { 2087 x++; 2088 y = x - leapcorr(&x); 2089 } while (y < t); 2090 if (t != y) 2091 return x - 1; 2092 } else if (y > t) { 2093 do { 2094 --x; 2095 y = x - leapcorr(&x); 2096 } while (y > t); 2097 if (t != y) 2098 return x + 1; 2099 } 2100 return x; 2101} 2102 2103#endif /* defined STD_INSPIRED */ 2104 2105// BEGIN android-added 2106 2107#include <assert.h> 2108#include <stdint.h> 2109#include <arpa/inet.h> // For ntohl(3). 2110 2111static int to_int(unsigned char* s) { 2112 return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; 2113} 2114 2115static int __bionic_open_tzdata_path(const char* path_prefix_variable, const char* path_suffix, 2116 const char* olson_id, int* data_size) { 2117 const char* path_prefix = getenv(path_prefix_variable); 2118 if (path_prefix == NULL) { 2119 fprintf(stderr, "%s: %s not set!\n", __FUNCTION__, path_prefix_variable); 2120 return -1; 2121 } 2122 size_t path_length = strlen(path_prefix) + 1 + strlen(path_suffix) + 1; 2123 char* path = malloc(path_length); 2124 if (path == NULL) { 2125 fprintf(stderr, "%s: couldn't allocate %zu-byte path\n", __FUNCTION__, path_length); 2126 return -1; 2127 } 2128 snprintf(path, path_length, "%s/%s", path_prefix, path_suffix); 2129 int fd = TEMP_FAILURE_RETRY(open(path, OPEN_MODE)); 2130 if (fd == -1) { 2131 XLOG(("%s: could not open \"%s\": %s\n", __FUNCTION__, path, strerror(errno))); 2132 free(path); 2133 return -2; // Distinguish failure to find any data from failure to find a specific id. 2134 } 2135 2136 // byte[12] tzdata_version -- "tzdata2012f\0" 2137 // int index_offset 2138 // int data_offset 2139 // int zonetab_offset 2140 struct bionic_tzdata_header { 2141 char tzdata_version[12]; 2142 int32_t index_offset; 2143 int32_t data_offset; 2144 int32_t zonetab_offset; 2145 } header; 2146 memset(&header, 0, sizeof(header)); 2147 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header))); 2148 if (bytes_read != sizeof(header)) { 2149 fprintf(stderr, "%s: could not read header of \"%s\": %s\n", 2150 __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read"); 2151 free(path); 2152 close(fd); 2153 return -1; 2154 } 2155 2156 if (strncmp(header.tzdata_version, "tzdata", 6) != 0 || header.tzdata_version[11] != 0) { 2157 fprintf(stderr, "%s: bad magic in \"%s\": \"%.6s\"\n", 2158 __FUNCTION__, path, header.tzdata_version); 2159 free(path); 2160 close(fd); 2161 return -1; 2162 } 2163 2164#if 0 2165 fprintf(stderr, "version: %s\n", header.tzdata_version); 2166 fprintf(stderr, "index_offset = %d\n", ntohl(header.index_offset)); 2167 fprintf(stderr, "data_offset = %d\n", ntohl(header.data_offset)); 2168 fprintf(stderr, "zonetab_offset = %d\n", ntohl(header.zonetab_offset)); 2169#endif 2170 2171 if (TEMP_FAILURE_RETRY(lseek(fd, ntohl(header.index_offset), SEEK_SET)) == -1) { 2172 fprintf(stderr, "%s: couldn't seek to index in \"%s\": %s\n", 2173 __FUNCTION__, path, strerror(errno)); 2174 free(path); 2175 close(fd); 2176 return -1; 2177 } 2178 2179 off_t specific_zone_offset = -1; 2180 ssize_t index_size = ntohl(header.data_offset) - ntohl(header.index_offset); 2181 char* index = malloc(index_size); 2182 if (index == NULL) { 2183 fprintf(stderr, "%s: couldn't allocate %zd-byte index for \"%s\"\n", 2184 __FUNCTION__, index_size, path); 2185 free(path); 2186 close(fd); 2187 return -1; 2188 } 2189 if (TEMP_FAILURE_RETRY(read(fd, index, index_size)) != index_size) { 2190 fprintf(stderr, "%s: could not read index of \"%s\": %s\n", 2191 __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read"); 2192 free(path); 2193 free(index); 2194 close(fd); 2195 return -1; 2196 } 2197 2198 static const size_t NAME_LENGTH = 40; 2199 struct index_entry_t { 2200 char buf[NAME_LENGTH]; 2201 int32_t start; 2202 int32_t length; 2203 int32_t raw_gmt_offset; 2204 }; 2205 2206 size_t id_count = (ntohl(header.data_offset) - ntohl(header.index_offset)) / sizeof(struct index_entry_t); 2207 struct index_entry_t* entry = (struct index_entry_t*) index; 2208 for (size_t i = 0; i < id_count; ++i) { 2209 char this_id[NAME_LENGTH + 1]; 2210 memcpy(this_id, entry->buf, NAME_LENGTH); 2211 this_id[NAME_LENGTH] = '\0'; 2212 2213 if (strcmp(this_id, olson_id) == 0) { 2214 specific_zone_offset = ntohl(entry->start) + ntohl(header.data_offset); 2215 *data_size = ntohl(entry->length); 2216 break; 2217 } 2218 2219 ++entry; 2220 } 2221 free(index); 2222 2223 if (specific_zone_offset == -1) { 2224 XLOG(("%s: couldn't find zone \"%s\"\n", __FUNCTION__, olson_id)); 2225 free(path); 2226 close(fd); 2227 return -1; 2228 } 2229 2230 if (TEMP_FAILURE_RETRY(lseek(fd, specific_zone_offset, SEEK_SET)) == -1) { 2231 fprintf(stderr, "%s: could not seek to %ld in \"%s\": %s\n", 2232 __FUNCTION__, specific_zone_offset, path, strerror(errno)); 2233 free(path); 2234 close(fd); 2235 return -1; 2236 } 2237 2238 // TODO: check that there's TZ_MAGIC at this offset, so we can fall back to the other file if not. 2239 2240 free(path); 2241 return fd; 2242} 2243 2244static int __bionic_open_tzdata(const char* olson_id, int* data_size) { 2245 int fd = __bionic_open_tzdata_path("ANDROID_DATA", "/misc/zoneinfo/tzdata", olson_id, data_size); 2246 if (fd < 0) { 2247 fd = __bionic_open_tzdata_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata", olson_id, data_size); 2248 if (fd == -2) { 2249 // The first thing that 'recovery' does is try to format the current time. It doesn't have 2250 // any tzdata available, so we must not abort here --- doing so breaks the recovery image! 2251 fprintf(stderr, "%s: couldn't find any tzdata when looking for %s!\n", __FUNCTION__, olson_id); 2252 } 2253 } 2254 return fd; 2255} 2256 2257// Caches the most recent timezone (http://b/8270865). 2258static int __bionic_tzload_cached(const char* name, struct state* const sp, const int doextend) { 2259 _tzLock(); 2260 2261 // Our single-item cache. 2262 static char* g_cached_time_zone_name; 2263 static struct state g_cached_time_zone; 2264 2265 // Do we already have this timezone cached? 2266 if (g_cached_time_zone_name != NULL && strcmp(name, g_cached_time_zone_name) == 0) { 2267 *sp = g_cached_time_zone; 2268 _tzUnlock(); 2269 return 0; 2270 } 2271 2272 // Can we load it? 2273 int rc = tzload(name, sp, doextend); 2274 if (rc == 0) { 2275 // Update the cache. 2276 free(g_cached_time_zone_name); 2277 g_cached_time_zone_name = strdup(name); 2278 g_cached_time_zone = *sp; 2279 } 2280 2281 _tzUnlock(); 2282 return rc; 2283} 2284 2285// Non-standard API: mktime(3) but with an explicit timezone parameter. 2286time_t mktime_tz(struct tm* const tmp, const char* tz) { 2287 struct state* st = malloc(sizeof(*st)); 2288 time_t return_value; 2289 2290 if (st == NULL) 2291 return 0; 2292 if (__bionic_tzload_cached(tz, st, TRUE) != 0) { 2293 // TODO: not sure what's best here, but for now, we fall back to gmt. 2294 gmtload(st); 2295 } 2296 2297 return_value = time1(tmp, localsub, 0L, st); 2298 free(st); 2299 return return_value; 2300} 2301 2302// Non-standard API: localtime(3) but with an explicit timezone parameter. 2303void localtime_tz(const time_t* const timep, struct tm* tmp, const char* tz) { 2304 struct state* st = malloc(sizeof(*st)); 2305 2306 if (st == NULL) 2307 return; 2308 if (__bionic_tzload_cached(tz, st, TRUE) != 0) { 2309 // TODO: not sure what's best here, but for now, we fall back to gmt. 2310 gmtload(st); 2311 } 2312 localsub(timep, 0L, tmp, st); 2313 free(st); 2314} 2315 2316// END android-added 2317