|
@@ -69,8 +69,6 @@
|
|
|
* TODO - Implement getdate? tzfile? struct tm extensions?
|
|
|
*
|
|
|
* TODO - Rework _time_mktime to remove the dependency on long long.
|
|
|
- *
|
|
|
- * TODO - Make tzset and _time_tzinfo refs threadsafe.
|
|
|
*/
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
@@ -120,6 +118,22 @@ typedef struct {
|
|
|
char tzname[TZNAME_MAX+1];
|
|
|
} rule_struct;
|
|
|
|
|
|
+#ifdef __UCLIBC_HAS_THREADS__
|
|
|
+
|
|
|
+#include <pthread.h>
|
|
|
+
|
|
|
+extern pthread_mutex_t _time_tzlock;
|
|
|
+
|
|
|
+#define TZLOCK pthread_mutex_lock(&_time_tzlock)
|
|
|
+#define TZUNLOCK pthread_mutex_unlock(&_time_tzlock)
|
|
|
+
|
|
|
+#else
|
|
|
+
|
|
|
+#define TZLOCK ((void) 0)
|
|
|
+#define TZUNLOCK ((void) 0)
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
extern rule_struct _time_tzinfo[2];
|
|
|
|
|
|
extern struct tm *_time_t2tm(const time_t *__restrict timer,
|
|
@@ -409,7 +423,7 @@ struct tm *localtime(const time_t *timer)
|
|
|
{
|
|
|
register struct tm *ptm = &__time_tm;
|
|
|
|
|
|
- tzset();
|
|
|
+
|
|
|
|
|
|
localtime_r(timer, ptm);
|
|
|
|
|
@@ -426,6 +440,8 @@ static const unsigned char day_cor[] = {
|
|
|
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
static int tm_isdst(register const struct tm *__restrict ptm)
|
|
|
{
|
|
|
register rule_struct *r = _time_tzinfo;
|
|
@@ -494,6 +510,7 @@ static int tm_isdst(register const struct tm *__restrict ptm)
|
|
|
++r;
|
|
|
} while (++i < 2);
|
|
|
}
|
|
|
+
|
|
|
return (isdst & 1);
|
|
|
}
|
|
|
|
|
@@ -504,6 +521,10 @@ struct tm *localtime_r(register const time_t *__restrict timer,
|
|
|
long offset;
|
|
|
int days, dst;
|
|
|
|
|
|
+ TZLOCK;
|
|
|
+
|
|
|
+ tzset();
|
|
|
+
|
|
|
dst = 0;
|
|
|
do {
|
|
|
days = -7;
|
|
@@ -523,6 +544,8 @@ struct tm *localtime_r(register const time_t *__restrict timer,
|
|
|
++dst;
|
|
|
} while ((result->tm_isdst = tm_isdst(result)) != 0);
|
|
|
|
|
|
+ TZUNLOCK;
|
|
|
+
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -849,6 +872,8 @@ size_t strftime(char *__restrict s, size_t maxsize,
|
|
|
goto OUTPUT;
|
|
|
}
|
|
|
|
|
|
+ TZLOCK;
|
|
|
+
|
|
|
rsp = _time_tzinfo;
|
|
|
if (timeptr->tm_isdst > 0) {
|
|
|
++rsp;
|
|
@@ -863,6 +888,7 @@ size_t strftime(char *__restrict s, size_t maxsize,
|
|
|
}
|
|
|
#endif
|
|
|
o_count = SIZE_MAX;
|
|
|
+ TZUNLOCK;
|
|
|
goto OUTPUT;
|
|
|
} else {
|
|
|
*s = '+';
|
|
@@ -870,6 +896,7 @@ size_t strftime(char *__restrict s, size_t maxsize,
|
|
|
tzo = -tzo;
|
|
|
*s = '-';
|
|
|
}
|
|
|
+ TZUNLOCK;
|
|
|
++s;
|
|
|
--count;
|
|
|
|
|
@@ -1378,6 +1405,10 @@ int daylight = 0;
|
|
|
long timezone = 0;
|
|
|
char *tzname[2] = { (char *) UTC, (char *) (UTC-1) };
|
|
|
|
|
|
+#ifdef __UCLIBC_HAS_THREADS__
|
|
|
+pthread_mutex_t _time_tzlock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
|
|
+#endif
|
|
|
+
|
|
|
rule_struct _time_tzinfo[2];
|
|
|
|
|
|
static const char *getoffset(register const char *e, long *pn)
|
|
@@ -1451,6 +1482,8 @@ void tzset(void)
|
|
|
int n, count, f;
|
|
|
char c;
|
|
|
|
|
|
+ TZLOCK;
|
|
|
+
|
|
|
if (!(e = getenv(TZ)) || !*e) {
|
|
|
ILLEGAL:
|
|
|
s = _time_tzinfo[0].tzname;
|
|
@@ -1583,6 +1616,8 @@ void tzset(void)
|
|
|
tzname[1] = _time_tzinfo[1].tzname;
|
|
|
daylight = !!new_rules[1].tzname[0];
|
|
|
timezone = new_rules[0].gmt_offset;
|
|
|
+
|
|
|
+ TZUNLOCK;
|
|
|
}
|
|
|
|
|
|
#endif
|
|
@@ -1823,8 +1858,8 @@ time_t _time_mktime(struct tm *timeptr, int store_on_success)
|
|
|
|
|
|
d = p[5] - 1;
|
|
|
days = -719163L + d*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]);
|
|
|
- secs = p[0] + 60*( p[1] + 60*((long)(p[2])) );
|
|
|
-
|
|
|
+ secs = p[0] + 60*( p[1] + 60*((long)(p[2])) )
|
|
|
+ + _time_tzinfo[timeptr->tm_isdst > 0].gmt_offset;
|
|
|
if (secs < 0) {
|
|
|
secs += 120009600L;
|
|
|
days -= 1389;
|
|
@@ -1834,6 +1869,7 @@ time_t _time_mktime(struct tm *timeptr, int store_on_success)
|
|
|
}
|
|
|
secs += (days * 86400L);
|
|
|
#else
|
|
|
+ TZLOCK;
|
|
|
d = p[5] - 1;
|
|
|
d = -719163L + d*365 + (d/4) - (d/100) + (d/400);
|
|
|
secs = p[0]
|
|
@@ -1842,6 +1878,7 @@ time_t _time_mktime(struct tm *timeptr, int store_on_success)
|
|
|
+ 60*(p[2]
|
|
|
+ 24*(((146073L * ((long long)(p[6])) + d)
|
|
|
+ p[3]) + p[7])));
|
|
|
+ TZUNLOCK;
|
|
|
if (((unsigned long long)(secs - LONG_MIN))
|
|
|
> (((unsigned long long)LONG_MAX) - LONG_MIN)
|
|
|
) {
|