Most of the files under libc/time/ were copied from older version
of musl than the musl/ folder and never changed since:
- gmtime.c
- gmtime_r.c
- localtime.c
- localtime_r.c
- mktime.c
- strftime.c
- timegm.c
- __time.h
- __tm_to_time.c

Following files were changed at some point to
support different way of locking and default UTC timezone:
- __time_to_tm.c
- tzset.c

So this patch replaces most of the files under libc/time
with their musl copies via makefile. Also this patch drops
some files (__time.h, __time_to_tm.c, __tm_to_time.c, __tm_to_time.c)
and adds many new ones (__map_file.c, __month_to_secs.c, __secs_to_tm.c,
__tm_to_secs.c, __year_to_secs.c, time_impl.h) via makefile.

Please note that __tz.c is actually copied as is from musl src/time/
and then modified in following ways:
- adjust locking logic to use mutex_t
- use UTC instead of GMT as a default timezone (this is fixed in the
  newer version of musl we will be upgrading to)
- fix one of the bugs when parsing timezone data (this was manually
  applied from newer version of musl than we have in musl/ now)

Please note this patch effectively follows the changes made
to original musl sources with this commit - 
https://git.musl-libc.org/cgit/musl/commit/?id=1cc81f5cb0df2b66a795ff0c26d7bbc4d16e13c6.
New logic also supports reading timezone data
from directories like /usr/share/zoneinfo. That is a reason
we add some of these file to the test image from host to
accomodate some of the unit tests in tst-time.cc.

Finally, we could have waited with this update until upgrade to new musl,
but I think that eliminating most files from libc/time/ now
is actually going to make easier to do eventual updgrade in future as the
structure of this directory has not changed fundamentally in
future versions of musl.

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
---
 Makefile                        |  25 +++--
 libc/aliases.ld                 |   4 +
 libc/locale/strftime_l.c        |  11 --
 libc/syscall_to_function.h      |   4 +-
 libc/time/__time.h              |   9 --
 libc/time/__time_to_tm.c        |  88 ----------------
 libc/time/__tm_to_time.c        |  33 ------
 libc/time/__tz.c                |  16 +--
 libc/time/gmtime.c              |  11 --
 libc/time/gmtime_r.c            |  10 --
 libc/time/localtime.c           |  12 ---
 libc/time/localtime_r.c         |  11 --
 libc/time/mktime.c              |  24 -----
 libc/time/strftime.c            | 172 -------------------------------
 libc/time/time_impl.h           |   1 +
 libc/time/timegm.c              |   9 --
 libc/time/tzset.c               | 173 --------------------------------
 modules/tests/Makefile          |   2 +-
 modules/tests/usr.manifest.skel |   4 +
 19 files changed, 36 insertions(+), 583 deletions(-)
 delete mode 100644 libc/locale/strftime_l.c
 delete mode 100644 libc/time/__time.h
 delete mode 100644 libc/time/__time_to_tm.c
 delete mode 100644 libc/time/__tm_to_time.c
 delete mode 100644 libc/time/gmtime.c
 delete mode 100644 libc/time/gmtime_r.c
 delete mode 100644 libc/time/localtime.c
 delete mode 100644 libc/time/localtime_r.c
 delete mode 100644 libc/time/mktime.c
 delete mode 100644 libc/time/strftime.c
 create mode 120000 libc/time/time_impl.h
 delete mode 100644 libc/time/timegm.c
 delete mode 100644 libc/time/tzset.c

diff --git a/Makefile b/Makefile
index c123d05b..6d39e5bf 100644
--- a/Makefile
+++ b/Makefile
@@ -1046,7 +1046,6 @@ musl += locale/strcasecmp_l.o
 musl += locale/strcoll.o
 musl += locale/strerror_l.o
 musl += locale/strfmon.o
-libc += locale/strftime_l.o
 musl += locale/strncasecmp_l.o
 libc += locale/strtod_l.o
 libc += locale/strtof_l.o
@@ -1645,24 +1644,28 @@ musl += temp/mkostemp.o
 musl += temp/mkostemps.o
 
 libc += time/__asctime.o
-libc += time/__time_to_tm.o
-libc += time/__tm_to_time.o
+musl += time/__map_file.o
+$(out)/musl/src/time/__map_file.o: CFLAGS += --include 
libc/syscall_to_function.h
+musl += time/__month_to_secs.o
+musl += time/__secs_to_tm.o
+musl += time/__tm_to_secs.o
+libc += time/__tz.o
+musl += time/__year_to_secs.o
 musl += time/asctime.o
 musl += time/asctime_r.o
 musl += time/ctime.o
 musl += time/ctime_r.o
 musl += time/difftime.o
 musl += time/getdate.o
-libc += time/gmtime.o
-libc += time/gmtime_r.o
-libc += time/localtime.o
-libc += time/localtime_r.o
-libc += time/mktime.o
-libc += time/strftime.o
+musl += time/gmtime.o
+musl += time/gmtime_r.o
+musl += time/localtime.o
+musl += time/localtime_r.o
+musl += time/mktime.o
+musl += time/strftime.o
 musl += time/strptime.o
 musl += time/time.o
-libc += time/timegm.o
-libc += time/tzset.o
+musl += time/timegm.o
 libc += time/wcsftime.o
 libc += time/ftime.o # verbatim copy of the file as in 4b15d9f46a2b@musl
 $(out)/libc/time/ftime.o: CFLAGS += -Ilibc/include
diff --git a/libc/aliases.ld b/libc/aliases.ld
index 0bc91597..e2e2e73c 100644
--- a/libc/aliases.ld
+++ b/libc/aliases.ld
@@ -31,6 +31,10 @@ __setlocale = setlocale;
 /* multibyte */
 __mbrlen = mbrlen;
 
+/* memory */
+__munmap = munmap;
+__mmap = mmap;
+
 /* stdio */
 __dup3 = dup3;
 
diff --git a/libc/locale/strftime_l.c b/libc/locale/strftime_l.c
deleted file mode 100644
index 0193866e..00000000
--- a/libc/locale/strftime_l.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <locale.h>
-#include <time.h>
-#include "libc.h"
-
-size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const 
struct tm *restrict tm, locale_t l)
-{
-       return strftime(s, n, f, tm);
-}
-
-/* OSv local: a libstdc++ build against glibc wants the __ version */
-weak_alias(__strftime_l, strftime_l);
diff --git a/libc/syscall_to_function.h b/libc/syscall_to_function.h
index 08d7ce93..a58b4222 100644
--- a/libc/syscall_to_function.h
+++ b/libc/syscall_to_function.h
@@ -1,7 +1,7 @@
 #include <bits/syscall.h>
 #include <unistd.h>
 
-#define __OSV_TO_FUNCTION_SYS_open(filename, flags, perm) (open(filename, 
flags, perm))
+#define __OSV_TO_FUNCTION_SYS_open(filename, flags, ...) (open(filename, flags 
__VA_OPT__(,) __VA_ARGS__))
 
 #define __OSV_TO_FUNCTION_SYS_close(fd) (close(fd))
 
@@ -15,6 +15,8 @@
 
 #define __OSV_TO_FUNCTION_SYS_ioctl(fd, cmd, args) (ioctl(fd, cmd, args))
 
+#define __OSV_TO_FUNCTION_SYS_fstat(fd, st) (fstat(fd, st))
+
 #define __OSV_TO_FUNCTION_SYS_unlink(path) (unlink(path))
 
 #define __OSV_TO_FUNCTION_SYS_rmdir(path) (rmdir(path))
diff --git a/libc/time/__time.h b/libc/time/__time.h
deleted file mode 100644
index 967e5180..00000000
--- a/libc/time/__time.h
+++ /dev/null
@@ -1,9 +0,0 @@
-time_t __tm_to_time(struct tm *);
-struct tm *__time_to_tm(time_t, struct tm *);
-void __tzset(void);
-struct tm *__dst_adjust(struct tm *tm);
-
-extern long __timezone;
-extern int __daylight;
-extern int __dst_offset;
-extern char *__tzname[2];
diff --git a/libc/time/__time_to_tm.c b/libc/time/__time_to_tm.c
deleted file mode 100644
index 48ea1f75..00000000
--- a/libc/time/__time_to_tm.c
+++ /dev/null
@@ -1,88 +0,0 @@
-#include <time.h>
-
-/* C defines the rounding for division in a nonsensical way */
-#define Q(a,b) ((a)>0 ? (a)/(b) : -(((b)-(a)-1)/(b)))
-
-#define DAYS_PER_400Y (365*400 + 97)
-#define DAYS_PER_100Y (365*100 + 24)
-#define DAYS_PER_4Y   (365*4   + 1)
-
-/* FIXME: use lldiv once it's fixed to compute quot,rem together */
-struct tm *__time_to_tm(time_t t, struct tm *tm)
-{
-       /* months are march-based */
-       static const int days_thru_month[] = 
{31,61,92,122,153,184,214,245,275,306,337,366};
-       long long bigday;
-       unsigned int day, year4, year100;
-       int year, year400;
-       int month;
-       int leap;
-       int hour, min, sec;
-       int wday, mday, yday;
-
-       /* start from 2000-03-01 (multiple of 400 years) */
-       t += -946684800 - 86400*(31+29);
-
-       bigday = Q(t, 86400);
-       sec = t-bigday*86400;
-
-       hour = sec/3600;
-       sec -= hour*3600;
-       min = sec/60;
-       sec -= min*60;
-
-       /* 2000-03-01 was a wednesday */
-       wday = (3+bigday)%7;
-       if (wday < 0) wday += 7;
-
-       t = -946684800LL - 86400*(31+29) + 9000000;
-       
-       year400 = Q(bigday, DAYS_PER_400Y);
-       day = bigday-year400*DAYS_PER_400Y;
-
-       year100 = day/DAYS_PER_100Y;
-       if (year100 == 4) year100--;
-       day -= year100*DAYS_PER_100Y;
-
-       year4 = day/DAYS_PER_4Y;
-       if (year4 == 25) year4--;
-       day -= year4*DAYS_PER_4Y;
-
-       year = day/365;
-       if (year == 4) year--;
-       day -= year*365;
-
-       leap = !year && (year4 || !year100);
-       yday = day + 31+28 + leap;
-       if (yday >= 365+leap) yday -= 365+leap;
-
-       year += 4*year4 + 100*year100 + 400*year400 + 2000-1900;
-
-       for (month=0; days_thru_month[month] <= day; month++);
-       if (month) day -= days_thru_month[month-1];
-       month += 2;
-       if (month >= 12) {
-               month -= 12;
-               year++;
-       }
-
-       mday = day+1;
-
-       tm->tm_sec = sec;
-       tm->tm_min = min;
-       tm->tm_hour= hour;
-       tm->tm_mday= mday;
-       tm->tm_mon = month;
-       tm->tm_year= year;
-       tm->tm_wday= wday;
-       tm->tm_yday= yday;
-#ifdef __USE_BSD
-    tm->tm_zone = "GMT";
-    tm->tm_gmtoff = 0;
-#else
-    tm->__tm_zone = "GMT";
-    tm->__tm_gmtoff = 0;
-#endif
-
-       return tm;
-}
diff --git a/libc/time/__tm_to_time.c b/libc/time/__tm_to_time.c
deleted file mode 100644
index 9f11805d..00000000
--- a/libc/time/__tm_to_time.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <time.h>
-
-/* C defines the rounding for division in a nonsensical way */
-#define Q(a,b) ((a)>0 ? (a)/(b) : -(((b)-(a)-1)/(b)))
-
-time_t __tm_to_time(struct tm *tm)
-{
-       time_t year  = tm->tm_year + -100;
-       int    month = tm->tm_mon;
-       int    day   = tm->tm_mday;
-       int z4, z100, z400;
-
-       /* normalize month */
-       if (month >= 12) {
-               year += month/12;
-               month %= 12;
-       } else if (month < 0) {
-               year += month/12;
-               month %= 12;
-               if (month) {
-                       month += 12;
-                       year--;
-               }
-       }
-       z4 = Q(year - (month < 2), 4);
-       z100 = Q(z4, 25);
-       z400 = Q(z100, 4);
-       day += year*365 + z4 - z100 + z400 +
-               month[(const int 
[]){0,31,59,90,120,151,181,212,243,273,304,334}];
-       return (long long)day*86400
-               + tm->tm_hour*3600 + tm->tm_min*60 + tm->tm_sec
-               - -946684800; /* the dawn of time :) */
-}
diff --git a/libc/time/__tz.c b/libc/time/__tz.c
index a76a7b48..cadece11 100644
--- a/libc/time/__tz.c
+++ b/libc/time/__tz.c
@@ -2,6 +2,7 @@
 #include <stdint.h>
 #include <limits.h>
 #include <stdlib.h>
+#undef _BSD_SOURCE // avoid conflict of static index variable with index() 
function in include/api/strings.h
 #include <string.h>
 #include "libc.h"
 
@@ -15,6 +16,7 @@ weak_alias(__tzname, tzname);
 
 static char std_name[TZNAME_MAX+1];
 static char dst_name[TZNAME_MAX+1];
+const char __utc[] = "UTC";
 
 static int dst_off;
 static int r0[5], r1[5];
@@ -26,7 +28,7 @@ static char old_tz_buf[32];
 static char *old_tz = old_tz_buf;
 static size_t old_tz_size = sizeof old_tz_buf;
 
-static int lock[2];
+static mutex_t lock;
 
 static int getint(const char **p)
 {
@@ -127,7 +129,7 @@ static void do_tzset()
                "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
 
        s = getenv("TZ");
-       if (!s) s = "";
+       if (!s) s = __utc;
 
        if (old_tz && !strcmp(s, old_tz)) return;
 
@@ -137,7 +139,7 @@ static void do_tzset()
         * free so as not to pull it into static programs. Growth
         * strategy makes it so free would have minimal benefit anyway. */
        i = strlen(s);
-       if (i > PATH_MAX+1) s = "", i = 0;
+       if (i > PATH_MAX+1) s = __utc, i = 0;
        if (i >= old_tz_size) {
                old_tz_size *= 2;
                if (i >= old_tz_size) old_tz_size = i+1;
@@ -152,7 +154,7 @@ static void do_tzset()
         * pathame beginning with "."; in secure mode, only the
         * standard path will be searched. */
        if (*s == '/' || *s == '.') {
-               if (!libc.secure) map = __map_file(s, &map_size);
+               map = __map_file(s, &map_size);
        } else {
                for (i=0; s[i] && s[i]!=','; i++) {
                        if (s[i]=='/') {
@@ -175,8 +177,8 @@ static void do_tzset()
        if (map) {
                int scale = 2;
                if (sizeof(time_t) > 4 && map[4]=='2') {
-                       size_t skip = zi_dotprod(zi, VEC(1,1,8,5,6,1), 6);
-                       trans = zi+skip+44+20;
+                       size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6);
+                       trans = zi+skip+44+44;
                        scale++;
                } else {
                        trans = zi+44;
@@ -192,7 +194,7 @@ static void do_tzset()
                }
        }
 
-       if (!s) s = "GMT0";
+       if (!s) s = __utc;
        getname(std_name, &s);
        __tzname[0] = std_name;
        __timezone = getoff(&s);
diff --git a/libc/time/gmtime.c b/libc/time/gmtime.c
deleted file mode 100644
index d4d5d1f1..00000000
--- a/libc/time/gmtime.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <time.h>
-
-#include "__time.h"
-
-struct tm *gmtime(const time_t *t)
-{
-       static struct tm tm;
-       __time_to_tm(*t, &tm);
-       tm.tm_isdst = 0;
-       return &tm;
-}
diff --git a/libc/time/gmtime_r.c b/libc/time/gmtime_r.c
deleted file mode 100644
index 13a2548f..00000000
--- a/libc/time/gmtime_r.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <time.h>
-
-#include "__time.h"
-
-struct tm *gmtime_r(const time_t *restrict t, struct tm *restrict result)
-{
-       __time_to_tm(*t, result);
-       result->tm_isdst = 0;
-       return result;
-}
diff --git a/libc/time/localtime.c b/libc/time/localtime.c
deleted file mode 100644
index abd5e84d..00000000
--- a/libc/time/localtime.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <time.h>
-
-#include "__time.h"
-
-struct tm *localtime(const time_t *t)
-{
-       static struct tm tm;
-       __tzset();
-       __time_to_tm(*t - __timezone, &tm);
-       tm.tm_isdst = -1;
-       return __dst_adjust(&tm);
-}
diff --git a/libc/time/localtime_r.c b/libc/time/localtime_r.c
deleted file mode 100644
index 389a5917..00000000
--- a/libc/time/localtime_r.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <time.h>
-
-#include "__time.h"
-
-struct tm *localtime_r(const time_t *restrict t, struct tm *restrict result)
-{
-       __tzset();
-       __time_to_tm(*t - __timezone, result);
-       result->tm_isdst = -1;
-       return __dst_adjust(result);
-}
diff --git a/libc/time/mktime.c b/libc/time/mktime.c
deleted file mode 100644
index 858cd50d..00000000
--- a/libc/time/mktime.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <time.h>
-
-#include "__time.h"
-
-time_t mktime(struct tm *tm)
-{
-       int isdst = tm->tm_isdst;
-       time_t t, lt;
-
-       __tzset();
-
-       tm->tm_sec += __timezone;
-       if (isdst > 0) tm->tm_sec += __dst_offset;
-
-       t = __tm_to_time(tm);
-       
-       lt = t - __timezone;
-       if (isdst > 0) lt -= __dst_offset;
-       __time_to_tm(lt, tm);
-
-       __dst_adjust(tm);
-       
-       return t;
-}
diff --git a/libc/time/strftime.c b/libc/time/strftime.c
deleted file mode 100644
index b69a83a4..00000000
--- a/libc/time/strftime.c
+++ /dev/null
@@ -1,172 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <langinfo.h>
-#include <time.h>
-#include "__time.h"
-
-// FIXME: integer overflows
-
-const char *__langinfo(nl_item);
-
-size_t strftime(char *restrict s, size_t n, const char *restrict f, const 
struct tm *restrict tm)
-{
-       nl_item item;
-       int val;
-       const char *fmt;
-       size_t l;
-       for (l=0; *f && l<n; f++) {
-               if (*f == '%') {
-do_fmt:
-               switch (*++f) {
-               case '%':
-                       goto literal;
-               case 'E':
-               case 'O':
-                       goto do_fmt;
-               case 'a':
-                       item = ABDAY_1 + tm->tm_wday;
-                       goto nl_strcat;
-               case 'A':
-                       item = DAY_1 + tm->tm_wday;
-                       goto nl_strcat;
-               case 'h':
-               case 'b':
-                       item = ABMON_1 + tm->tm_mon;
-                       goto nl_strcat;
-               case 'B':
-                       item = MON_1 + tm->tm_mon;
-                       goto nl_strcat;
-               case 'c':
-                       item = D_T_FMT;
-                       goto nl_strftime;
-               case 'C':
-                       val = (1900+tm->tm_year) / 100;
-                       fmt = "%02d";
-                       goto number;
-               case 'd':
-                       val = tm->tm_mday;
-                       fmt = "%02d";
-                       goto number;
-               case 'D':
-                       fmt = "%m/%d/%y";
-                       goto recu_strftime;
-               case 'e':
-                       val = tm->tm_mday;
-                       fmt = "%2d";
-                       goto number;
-               case 'F':
-                       fmt = "%Y-%m-%d";
-                       goto recu_strftime;
-               case 'g':
-                       // FIXME
-                       val = 0; //week_based_year(tm)%100;
-                       fmt = "%02d";
-                       goto number;
-               case 'G':
-                       // FIXME
-                       val = 0; //week_based_year(tm);
-                       fmt = "%04d";
-                       goto number;
-               case 'H':
-                       val = tm->tm_hour;
-                       fmt = "%02d";
-                       goto number;
-               case 'I':
-                       val = tm->tm_hour;
-                       if (!val) val = 12;
-                       else if (val > 12) val -= 12;
-                       fmt = "%02d";
-                       goto number;
-               case 'j':
-                       val = tm->tm_yday+1;
-                       fmt = "%03d";
-                       goto number;
-               case 'm':
-                       val = tm->tm_mon+1;
-                       fmt = "%02d";
-                       goto number;
-               case 'M':
-                       val = tm->tm_min;
-                       fmt = "%02d";
-                       goto number;
-               case 'n':
-                       s[l++] = '\n';
-                       continue;
-               case 'p':
-                       item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
-                       goto nl_strcat;
-               case 'r':
-                       item = T_FMT_AMPM;
-                       goto nl_strftime;
-               case 'R':
-                       fmt = "%H:%M";
-                       goto recu_strftime;
-               case 'S':
-                       val = tm->tm_sec;
-                       fmt = "%02d";
-                       goto number;
-               case 't':
-                       s[l++] = '\t';
-                       continue;
-               case 'T':
-                       fmt = "%H:%M:%S";
-                       goto recu_strftime;
-               case 'u':
-                       val = tm->tm_wday ? tm->tm_wday : 7;
-                       fmt = "%d";
-                       goto number;
-               case 'U':
-               case 'V':
-               case 'W':
-                       // FIXME: week number mess..
-                       continue;
-               case 'w':
-                       val = tm->tm_wday;
-                       fmt = "%d";
-                       goto number;
-               case 'x':
-                       item = D_FMT;
-                       goto nl_strftime;
-               case 'X':
-                       item = T_FMT;
-                       goto nl_strftime;
-               case 'y':
-                       val = tm->tm_year % 100;
-                       fmt = "%02d";
-                       goto number;
-               case 'Y':
-                       val = tm->tm_year + 1900;
-                       fmt = "%04d";
-                       goto number;
-               case 'z':
-                       if (tm->tm_isdst < 0) continue;
-                       val = -__timezone - (tm->tm_isdst ? __dst_offset : 0);
-                       l += snprintf(s+l, n-l, "%+.2d%.2d", val/3600, 
abs(val%3600)/60);
-                       continue;
-               case 'Z':
-                       if (tm->tm_isdst < 0 || !__tzname[0] || !__tzname[0][0])
-                               continue;
-                       l += snprintf(s+l, n-l, "%s", __tzname[!!tm->tm_isdst]);
-                       continue;
-               default:
-                       return 0;
-               }
-               }
-literal:
-               s[l++] = *f;
-               continue;
-number:
-               l += snprintf(s+l, n-l, fmt, val);
-               continue;
-nl_strcat:
-               l += snprintf(s+l, n-l, "%s", __langinfo(item));
-               continue;
-nl_strftime:
-               fmt = __langinfo(item);
-recu_strftime:
-               l += strftime(s+l, n-l, fmt, tm);
-       }
-       if (l >= n) return 0;
-       s[l] = 0;
-       return l;
-}
diff --git a/libc/time/time_impl.h b/libc/time/time_impl.h
new file mode 120000
index 00000000..c4f1d67b
--- /dev/null
+++ b/libc/time/time_impl.h
@@ -0,0 +1 @@
+../../musl/src/time/time_impl.h
\ No newline at end of file
diff --git a/libc/time/timegm.c b/libc/time/timegm.c
deleted file mode 100644
index 6d08917e..00000000
--- a/libc/time/timegm.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#define _GNU_SOURCE
-#include <time.h>
-
-#include "__time.h"
-
-time_t timegm(struct tm *tm)
-{
-       return __tm_to_time(tm);
-}
diff --git a/libc/time/tzset.c b/libc/time/tzset.c
deleted file mode 100644
index 3b2c9313..00000000
--- a/libc/time/tzset.c
+++ /dev/null
@@ -1,173 +0,0 @@
-#include <time.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include "libc.h"
-
-#include "__time.h"
-
-long  __timezone = 0;
-int   __daylight = 0;
-char *__tzname[2] = { 0, 0 };
-int   __dst_offset = 0;
-
-weak_alias(__timezone, timezone);
-weak_alias(__daylight, daylight);
-weak_alias(__tzname, tzname);
-
-static char std_name[TZNAME_MAX+1];
-static char dst_name[TZNAME_MAX+1];
-
-/* all elements are zero-based */
-static struct rule {
-       signed char month;
-       signed char week;
-       short day;
-       int time;
-} __dst_start, __dst_end;
-
-static void zname(char *d, char **s)
-{
-       int i;
-       for (i=0; i<TZNAME_MAX && isalpha(d[i]=**s); i++, (*s)++);
-       d[i] = 0;
-}
-
-static int hhmmss(char **s)
-{
-       int ofs = strtol(*s, s, 10)*3600;
-       if (ofs >= 0) {
-               if (**s == ':') ofs += strtol(*s+1, s, 10)*60;
-               if (**s == ':') ofs += strtol(*s+1, s, 10);
-       } else {
-               if (**s == ':') ofs -= strtol(*s+1, s, 10)*60;
-               if (**s == ':') ofs -= strtol(*s+1, s, 10);
-       }
-       return ofs;
-}
-
-static int dstrule(struct rule *rule, char **s)
-{
-       if (**s != ',') return -1;
-       switch (*++*s) {
-       case 'J':
-               rule->month = 'J';
-               rule->day = strtol(*s+1, s, 10)-1;
-               break;
-       case 'M':
-               rule->month = strtol(*s+1, s, 10)-1;
-               if (**s != '.' || rule->month < 0 || rule->month > 11)
-                       return -1;
-               rule->week = strtol(*s+1, s, 10)-1;
-               if (**s != '.' || rule->week < 0 || rule->week > 4)
-                       return -1;
-               rule->day = strtol(*s+1, s, 10);
-               if (rule->day < 0 || rule->day > 6)
-                       return -1;
-               break;
-       default:
-               rule->month = 'L';
-               rule->day = strtol(*s+1, s, 10);
-               break;
-       }
-       if (**s == '/') {
-               (*s)++;
-               rule->time = hhmmss(s);
-       } else rule->time = 7200;
-       return 0;
-}
-
-void tzset(void)
-{
-       char *z, *a;
-       
-       strcpy(std_name, "UTC");
-       strcpy(dst_name, "UTC");
-       __tzname[0] = std_name;
-       __tzname[1] = dst_name;
-       __timezone = 0;
-       __daylight = 0;
-       
-       if (!(z = getenv("TZ")) || !isalpha(*z)) return;
-
-       zname(std_name, &z);
-       __timezone = hhmmss(&z);
-
-       zname(dst_name, &z);
-       if (dst_name[0]) __daylight=1;
-       a = z;
-       __dst_offset = hhmmss(&z) - __timezone;
-       if (z==a) __dst_offset = -3600;
-
-       if (dstrule(&__dst_start, &z) || dstrule(&__dst_end, &z))
-               __daylight = 0;
-}
-
-void __tzset(void)
-{
-       static mutex_t lock;
-       static int init;
-       if (init) return;
-       LOCK(lock);
-       if (!init) tzset();
-       init=1;
-       UNLOCK(lock);
-}
-
-static int is_leap(int year)
-{
-       year -= 100;
-       return !(year&3) && ((year%100) || !(year%400));
-}
-
-static int cutoff_yday(struct tm *tm, struct rule *rule)
-{
-       static const char days_in_month[] = 
{31,28,31,30,31,30,31,31,30,31,30,31};
-       static const int first_day[] = 
{0,31,59,90,120,151,181,212,243,273,304,335};
-       int yday, mday, leap;
-       
-       switch (rule->month) {
-       case 'J':
-               return rule->day + (tm->tm_mon > 1 && is_leap(tm->tm_year));
-       case 'L':
-               return rule->day;
-       default:
-               yday = first_day[rule->month];
-               leap = is_leap(tm->tm_year);
-               if (rule->month > 1 && leap) yday++;
-               mday = (rule->day - (yday + tm->tm_wday - tm->tm_yday) + 
1400)%7 + 7*rule->week;
-               if (mday >= days_in_month[rule->month] + (leap && rule->month 
== 1))
-                       mday -= 7;
-               return mday + yday;
-       }
-}
-
-struct tm *__dst_adjust(struct tm *tm)
-{
-       time_t t;
-       int start, end, secs;
-       int after_start, before_end;
-
-       if (tm->tm_isdst >= 0) return tm;
-       if (!__daylight) {
-               tm->tm_isdst = 0;
-               return tm;
-       }
-       
-       secs = tm->tm_hour*3600 + tm->tm_min*60 + tm->tm_sec;
-       start = cutoff_yday(tm, &__dst_start);
-       end = cutoff_yday(tm, &__dst_end);
-
-       after_start = (tm->tm_yday > start || (tm->tm_yday == start && secs >= 
__dst_start.time));
-       before_end = (tm->tm_yday < end || (tm->tm_yday == end && secs < 
__dst_end.time));
-
-       if ((after_start && before_end) || ((end < start) && (after_start || 
before_end))) {
-               tm->tm_sec -= __dst_offset;
-               tm->tm_isdst = 1;
-               t = __tm_to_time(tm);
-               return __time_to_tm(t, tm);
-       } else tm->tm_isdst = 0;
-
-       return tm;
-}
diff --git a/modules/tests/Makefile b/modules/tests/Makefile
index 78f215e6..be89e531 100644
--- a/modules/tests/Makefile
+++ b/modules/tests/Makefile
@@ -246,7 +246,7 @@ common-boost-tests := tst-vfs.so tst-libc-locking.so 
misc-fs-stress.so \
        tst-bsd-tcp1-zsndrcv.so tst-async.so tst-rcu-list.so tst-tcp-listen.so \
        tst-poll.so tst-bitset-iter.so tst-timer-set.so tst-clock.so \
        tst-rcu-hashtable.so tst-unordered-ring-mpsc.so \
-       tst-seek.so tst-ctype.so tst-wctype.so tst-string.so
+       tst-seek.so tst-ctype.so tst-wctype.so tst-string.so tst-time.so
 
 boost-tests := $(common-boost-tests)
 
diff --git a/modules/tests/usr.manifest.skel b/modules/tests/usr.manifest.skel
index 8f2c824c..9b768150 100644
--- a/modules/tests/usr.manifest.skel
+++ b/modules/tests/usr.manifest.skel
@@ -1 +1,5 @@
 /testrunner.so: ./tests/testrunner.so
+/usr/share/zoneinfo/America/**: /usr/share/zoneinfo/America/**
+/usr/share/zoneinfo/Europe/**: /usr/share/zoneinfo/Europe/**
+/usr/share/zoneinfo/Pacific/**: /usr/share/zoneinfo/Pacific/**
+/usr/share/zoneinfo/Asia/**: /usr/share/zoneinfo/Asia/**
-- 
2.26.2

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20200826035356.201786-4-jwkozaczuk%40gmail.com.

Reply via email to