fix fesetenv(FE_DFL_ENV) on mips
[musl] / src / time / __tz.c
index fbe3d49..4ce2025 100644 (file)
@@ -36,19 +36,16 @@ 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);
@@ -57,7 +54,7 @@ static int getoff(const char **p)
                        off += getint(p);
                }
        }
-       return off;
+       return neg ? -off : off;
 }
 
 static void getrule(const char **p, int rule[5])
@@ -128,7 +125,7 @@ static void do_tzset()
                "/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;
 
@@ -153,7 +150,8 @@ static void do_tzset()
        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, '.')) {
@@ -166,6 +164,12 @@ static void do_tzset()
                                }
                        }
                }
+               if (!map) s = __gmt;
+       }
+       if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
+               __munmap((void *)map, map_size);
+               map = 0;
+               s = __gmt;
        }
 
        zi = map;