Make the new %Z addition thread-safe.

This commit is contained in:
David E. O'Brien 1999-07-06 05:05:39 +00:00
parent 473ac4479f
commit cb7a4779cb
1 changed files with 51 additions and 21 deletions

View File

@ -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"
static char * _strptime(const char *, const char *, struct tm *);
#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;
#define asizeof(a) (sizeof (a) / sizeof ((a)[0]))
static int got_GMT = 0;
char *
strptime(const char *buf, const char *fmt, struct tm *tm)
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;
}
}
if (got_GMT) {
time_t t = timegm(tm);
localtime_r(&t, tm);
}
return (char *)buf;
}
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);
got_GMT = 0;
}
#ifdef _THREAD_SAFE
pthread_mutex_unlock(&gotgmt_mutex);
#endif
return ret;
}