static char *old_tz = old_tz_buf;
static size_t old_tz_size = sizeof old_tz_buf;
-static int lock[2];
+static volatile int lock[2];
static int getint(const char **p)
{
return x;
}
-static int getsigned(const char **p)
+static int getoff(const char **p)
{
+ int neg = 0;
if (**p == '-') {
++*p;
- return -getint(p);
+ neg = 1;
+ } else if (**p == '+') {
+ ++*p;
}
- if (**p == '+') ++*p;
- return getint(p);
-}
-
-static int getoff(const char **p)
-{
- int off = 3600*getsigned(p);
+ int off = 3600*getint(p);
if (**p == ':') {
++*p;
off += 60*getint(p);
off += getint(p);
}
}
- return off;
+ return neg ? -off : off;
}
static void getrule(const char **p, int rule[5])
"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
s = getenv("TZ");
- if (!s || !*s) s = __gmt;
+ if (!s || !*s) s = "/etc/localtime";
if (old_tz && !strcmp(s, old_tz)) return;
if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) {
if (*s == ':') s++;
if (*s == '/' || *s == '.') {
- if (!libc.secure) map = __map_file(s, &map_size);
+ if (!libc.secure || !strcmp(s, "/etc/localtime"))
+ map = __map_file(s, &map_size);
} else {
size_t l = strlen(s);
if (l <= NAME_MAX && !strchr(s, '.')) {
}
if (!map) s = __gmt;
}
+ if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
+ __munmap((void *)map, map_size);
+ map = 0;
+ s = __gmt;
+ }
zi = map;
if (map) {