* 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
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,
{
register struct tm *ptm = &__time_tm;
- tzset();
+ /* In this implementation, tzset() is called by localtime_r(). */
localtime_r(timer, ptm); /* Can return NULL... */
/* 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 */
};
+/* Note: timezone locking is done by localtime_r. */
+
static int tm_isdst(register const struct tm *__restrict ptm)
{
register rule_struct *r = _time_tzinfo;
++r;
} while (++i < 2);
}
+
return (isdst & 1);
}
long offset;
int days, dst;
+ TZLOCK;
+
+ tzset();
+
dst = 0;
do {
days = -7;
++dst;
} while ((result->tm_isdst = tm_isdst(result)) != 0);
+ TZUNLOCK;
+
return result;
}
goto OUTPUT;
}
+ TZLOCK;
+
rsp = _time_tzinfo;
if (timeptr->tm_isdst > 0) {
++rsp;
}
#endif
o_count = SIZE_MAX;
+ TZUNLOCK;
goto OUTPUT;
} else { /* z */
*s = '+';
tzo = -tzo;
*s = '-';
}
+ TZUNLOCK;
++s;
--count;
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)
int n, count, f;
char c;
+ TZLOCK;
+
if (!(e = getenv(TZ)) || !*e) { /* Not set or set to empty string. */
ILLEGAL: /* TODO: Clean up the following... */
s = _time_tzinfo[0].tzname;
tzname[1] = _time_tzinfo[1].tzname;
daylight = !!new_rules[1].tzname[0];
timezone = new_rules[0].gmt_offset;
+
+ TZUNLOCK;
}
#endif
/* TODO - check */
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;
}
secs += (days * 86400L);
#else
+ TZLOCK;
d = p[5] - 1;
d = -719163L + d*365 + (d/4) - (d/100) + (d/400);
secs = p[0]
+ 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)
) {