diff options
author | obrien <obrien@FreeBSD.org> | 1999-07-06 05:05:39 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 1999-07-06 05:05:39 +0000 |
commit | ca1b97c691756d726e676f30689ce2f0938c2df3 (patch) | |
tree | cce5a7f6a865ca740275ee69d697981112120829 /lib/libc | |
parent | 14d7c61e551e53a36546654bc000ec233e65f467 (diff) | |
download | FreeBSD-src-ca1b97c691756d726e676f30689ce2f0938c2df3.zip FreeBSD-src-ca1b97c691756d726e676f30689ce2f0938c2df3.tar.gz |
Make the new %Z addition thread-safe.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/stdtime/strptime.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/lib/libc/stdtime/strptime.c b/lib/libc/stdtime/strptime.c index 34da06e..a96cefc 100644 --- a/lib/libc/stdtime/strptime.c +++ b/lib/libc/stdtime/strptime.c @@ -67,14 +67,24 @@ static char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; #include <time.h> #include <ctype.h> #include <string.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #include "timelocal.h" -#define asizeof(a) (sizeof (a) / sizeof ((a)[0])) +static char * _strptime(const char *, const char *, struct tm *); -static int got_GMT = 0; +#ifdef _THREAD_SAFE +static struct pthread_mutex _gotgmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; +static pthread_mutex_t gotgmt_mutex = &_gotgmt_mutexd; +#endif +static int got_GMT; -char * -strptime(const char *buf, const char *fmt, struct tm *tm) +#define asizeof(a) (sizeof (a) / sizeof ((a)[0])) + +static char * +_strptime(const char *buf, const char *fmt, struct tm *tm) { char c; const char *ptr; @@ -106,49 +116,49 @@ strptime(const char *buf, const char *fmt, struct tm *tm) break; case 'C': - buf = strptime(buf, Locale->date_fmt, tm); + buf = _strptime(buf, Locale->date_fmt, tm); if (buf == 0) return 0; break; case 'c': - buf = strptime(buf, "%x %X", tm); + buf = _strptime(buf, "%x %X", tm); if (buf == 0) return 0; break; case 'D': - buf = strptime(buf, "%m/%d/%y", tm); + buf = _strptime(buf, "%m/%d/%y", tm); if (buf == 0) return 0; break; case 'R': - buf = strptime(buf, "%H:%M", tm); + buf = _strptime(buf, "%H:%M", tm); if (buf == 0) return 0; break; case 'r': - buf = strptime(buf, "%I:%M:%S %p", tm); + buf = _strptime(buf, "%I:%M:%S %p", tm); if (buf == 0) return 0; break; case 'T': - buf = strptime(buf, "%H:%M:%S", tm); + buf = _strptime(buf, "%H:%M:%S", tm); if (buf == 0) return 0; break; case 'X': - buf = strptime(buf, Locale->X_fmt, tm); + buf = _strptime(buf, Locale->X_fmt, tm); if (buf == 0) return 0; break; case 'x': - buf = strptime(buf, Locale->x_fmt, tm); + buf = _strptime(buf, Locale->x_fmt, tm); if (buf == 0) return 0; break; @@ -359,13 +369,13 @@ strptime(const char *buf, const char *fmt, struct tm *tm) zonestr[cp - buf] = '\0'; tzset(); if (0 == strcmp(zonestr, "GMT")) { - got_GMT = 1; + got_GMT = 1; } else if (0 == strcmp(zonestr, tzname[0])) { - tm->tm_isdst = 0; + tm->tm_isdst = 0; } else if (0 == strcmp(zonestr, tzname[1])) { - tm->tm_isdst = 1; + tm->tm_isdst = 1; } else { - return 0; + return 0; } buf += cp - buf; } @@ -373,10 +383,30 @@ strptime(const char *buf, const char *fmt, struct tm *tm) break; } } + return (char *)buf; +} + - if (got_GMT) { +char * +strptime(const char *buf, const char *fmt, struct tm *tm) +{ + char *ret; + +#ifdef _THREAD_SAFE + pthread_mutex_lock(&gotgmt_mutex); +#endif + + got_GMT = 0; + ret = _strptime(buf, fmt, tm); + if (ret && got_GMT) { time_t t = timegm(tm); - localtime_r(&t, tm); + localtime_r(&t, tm); + got_GMT = 0; } - return (char *)buf; + +#ifdef _THREAD_SAFE + pthread_mutex_unlock(&gotgmt_mutex); +#endif + + return ret; } |