summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>1999-07-06 05:05:39 +0000
committerobrien <obrien@FreeBSD.org>1999-07-06 05:05:39 +0000
commitca1b97c691756d726e676f30689ce2f0938c2df3 (patch)
treecce5a7f6a865ca740275ee69d697981112120829 /lib
parent14d7c61e551e53a36546654bc000ec233e65f467 (diff)
downloadFreeBSD-src-ca1b97c691756d726e676f30689ce2f0938c2df3.zip
FreeBSD-src-ca1b97c691756d726e676f30689ce2f0938c2df3.tar.gz
Make the new %Z addition thread-safe.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdtime/strptime.c68
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;
}
OpenPOWER on IntegriCloud