From: Waldemar Kozaczuk <[email protected]>
Committer: Nadav Har'El <[email protected]>
Branch: master

libc: replaced most libc/time/ files with their musl copies

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 <[email protected]>
Message-Id: <[email protected]>

---
diff --git a/Makefile b/Makefile
--- 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
--- 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
--- a/libc/locale/strftime_l.c
+++ b/libc/locale/strftime_l.c
@@ -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
--- 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
--- a/libc/time/__time.h
+++ b/libc/time/__time.h
@@ -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
--- a/libc/time/__time_to_tm.c
+++ b/libc/time/__time_to_tm.c
@@ -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
--- a/libc/time/__tm_to_time.c
+++ b/libc/time/__tm_to_time.c
@@ -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
--- 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
--- a/libc/time/gmtime.c
+++ b/libc/time/gmtime.c
@@ -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
--- a/libc/time/gmtime_r.c
+++ b/libc/time/gmtime_r.c
@@ -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
--- a/libc/time/localtime.c
+++ b/libc/time/localtime.c
@@ -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
--- a/libc/time/localtime_r.c
+++ b/libc/time/localtime_r.c
@@ -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
--- a/libc/time/mktime.c
+++ b/libc/time/mktime.c
@@ -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
--- a/libc/time/strftime.c
+++ b/libc/time/strftime.c
@@ -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
--- a/libc/time/time_impl.h
+++ 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
--- a/libc/time/timegm.c
+++ b/libc/time/timegm.c
@@ -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
--- a/libc/time/tzset.c
+++ b/libc/time/tzset.c
@@ -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
--- 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
--- 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/**

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/000000000000a6ca4d05adc3a608%40google.com.

Reply via email to