X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Ftime%2F__tz.c;h=c34b3eb755a54b38efa8f8e4b39e0bfb1e23b406;hb=269d193820342dc109f39909d78fb30f4c978f76;hp=8b84b9bd12cf9091268105357c0158357d6ab82f;hpb=c13f2af1fe1856e36dd1b2773cac05d5d72641dc;p=musl diff --git a/src/time/__tz.c b/src/time/__tz.c index 8b84b9bd..c34b3eb7 100644 --- a/src/time/__tz.c +++ b/src/time/__tz.c @@ -3,7 +3,16 @@ #include #include #include +#include +#include #include "libc.h" +#include "lock.h" +#include "fork_impl.h" + +#define malloc __libc_malloc +#define calloc undef +#define realloc undef +#define free undef long __timezone = 0; int __daylight = 0; @@ -15,7 +24,7 @@ weak_alias(__tzname, tzname); static char std_name[TZNAME_MAX+1]; static char dst_name[TZNAME_MAX+1]; -const char __gmt[] = "GMT"; +const char __utc[] = "UTC"; static int dst_off; static int r0[5], r1[5]; @@ -27,7 +36,8 @@ static char old_tz_buf[32]; static char *old_tz = old_tz_buf; static size_t old_tz_size = sizeof old_tz_buf; -static volatile int lock[2]; +static volatile int lock[1]; +volatile int *const __timezone_lockptr = lock; static int getint(const char **p) { @@ -84,15 +94,15 @@ static void getname(char *d, const char **p) int i; if (**p == '<') { ++*p; - for (i=0; **p!='>' && i PATH_MAX+1) s = __gmt, i = 3; + if (i > PATH_MAX+1) s = __utc, i = 3; if (i >= old_tz_size) { old_tz_size *= 2; if (i >= old_tz_size) old_tz_size = i+1; @@ -145,10 +155,21 @@ static void do_tzset() } if (old_tz) memcpy(old_tz, s, i+1); + int posix_form = 0; + if (*s != ':') { + p = s; + char dummy_name[TZNAME_MAX+1]; + getname(dummy_name, &p); + if (p!=s && (*p == '+' || *p == '-' || isdigit(*p) + || !strcmp(dummy_name, "UTC") + || !strcmp(dummy_name, "GMT"))) + posix_form = 1; + } + /* Non-suid can use an absolute tzfile pathname or a relative * pathame beginning with "."; in secure mode, only the * standard path will be searched. */ - if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) { + if (!posix_form) { if (*s == ':') s++; if (*s == '/' || *s == '.') { if (!libc.secure || !strcmp(s, "/etc/localtime")) @@ -165,18 +186,18 @@ static void do_tzset() } } } - if (!map) s = __gmt; + if (!map) s = __utc; } if (map && (map_size < 44 || memcmp(map, "TZif", 4))) { __munmap((void *)map, map_size); map = 0; - s = __gmt; + s = __utc; } zi = map; if (map) { int scale = 2; - if (sizeof(time_t) > 4 && map[4]=='2') { + if (map[4]!='1') { size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6); trans = zi+skip+44+44; scale++; @@ -194,7 +215,6 @@ static void do_tzset() const unsigned char *p; __tzname[0] = __tzname[1] = 0; __daylight = __timezone = dst_off = 0; - for (i=0; i<5; i++) r0[i] = r1[i] = 0; for (p=types; p>scale; if (a == n-1) return -1; if (a == 0) { - x = zi_read32(trans + (a<= t0 && t < t1) goto dst; goto std; } else { - if (!local) { - t1 += __timezone; - t0 += dst_off; - } if (t >= t1 && t < t0) goto std; goto dst; } @@ -403,7 +417,7 @@ dst: UNLOCK(lock); } -void __tzset() +static void __tzset() { LOCK(lock); do_tzset(); @@ -417,7 +431,7 @@ const char *__tm_to_tzname(const struct tm *tm) const void *p = tm->__tm_zone; LOCK(lock); do_tzset(); - if (p != __gmt && p != __tzname[0] && p != __tzname[1] && + if (p != __utc && p != __tzname[0] && p != __tzname[1] && (!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs)) p = ""; UNLOCK(lock);