Bug 3330205 Thread safe strptime implementation

Change-Id: I03e72b0253a7a2e015455ab81dbf155ed1e574d2
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 1f481c9..0567aa4 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -89,29 +89,31 @@
 #define _LEGAL_ALT(x)       { if (alt_format & ~(x)) return (0); }
 
 
+struct century_relyear {
+    int century;
+    int relyear;
+};
 static  int _conv_num(const unsigned char **, int *, int, int);
-static  unsigned char *_strptime(const unsigned char *, const char *, struct tm *, int);
+static  unsigned char *_strptime(const unsigned char *, const char *, struct tm *,
+        struct century_relyear *);
 
 
 char *
 strptime(const char *buf, const char *fmt, struct tm *tm)
 {
-    return (char*)(_strptime((const unsigned char*)buf, fmt, tm, 1));
+    struct century_relyear cr;
+    cr.century = TM_YEAR_BASE;
+    cr.relyear = -1;
+    return (char*)(_strptime((const unsigned char*)buf, fmt, tm, &cr));
 }
 
 static unsigned char *
-_strptime(const unsigned char *buf, const char *fmt, struct tm *tm, int initialize)
+_strptime(const unsigned char *buf, const char *fmt, struct tm *tm, struct century_relyear *cr)
 {
     unsigned char c;
     const unsigned char *bp;
     size_t len = 0;
     int alt_format, i;
-    static int century, relyear;
-
-    if (initialize) {
-        century = TM_YEAR_BASE;
-        relyear = -1;
-    }
 
     bp = (unsigned char *)buf;
     while ((c = *fmt) != '\0') {
@@ -158,43 +160,43 @@
          */
         case 'c':   /* Date and time, using the locale's format. */
             _LEGAL_ALT(_ALT_E);
-            if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0)))
+            if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, cr)))
                 return (NULL);
             break;
 
         case 'D':   /* The date as "%m/%d/%y". */
             _LEGAL_ALT(0);
-            if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0)))
+            if (!(bp = _strptime(bp, "%m/%d/%y", tm, cr)))
                 return (NULL);
             break;
     
         case 'R':   /* The time as "%H:%M". */
             _LEGAL_ALT(0);
-            if (!(bp = _strptime(bp, "%H:%M", tm, 0)))
+            if (!(bp = _strptime(bp, "%H:%M", tm, cr)))
                 return (NULL);
             break;
 
         case 'r':   /* The time as "%I:%M:%S %p". */
             _LEGAL_ALT(0);
-            if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0)))
+            if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, cr)))
                 return (NULL);
             break;
 
         case 'T':   /* The time as "%H:%M:%S". */
             _LEGAL_ALT(0);
-            if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0)))
+            if (!(bp = _strptime(bp, "%H:%M:%S", tm, cr)))
                 return (NULL);
             break;
 
         case 'X':   /* The time, using the locale's format. */
             _LEGAL_ALT(_ALT_E);
-            if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0)))
+            if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, cr)))
                 return (NULL);
             break;
 
         case 'x':   /* The date, using the locale's format. */
             _LEGAL_ALT(_ALT_E);
-            if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0)))
+            if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, cr)))
                 return (NULL);
             break;
 
@@ -253,7 +255,7 @@
             if (!(_conv_num(&bp, &i, 0, 99)))
                 return (NULL);
 
-            century = i * 100;
+            cr->century = i * 100;
             break;
 
         case 'd':   /* The day of month. */
@@ -359,13 +361,13 @@
             if (!(_conv_num(&bp, &i, 0, 9999)))
                 return (NULL);
 
-            relyear = -1;
+            cr->relyear = -1;
             tm->tm_year = i - TM_YEAR_BASE;
             break;
 
         case 'y':   /* The year within the century (2 digits). */
             _LEGAL_ALT(_ALT_E | _ALT_O);
-            if (!(_conv_num(&bp, &relyear, 0, 99)))
+            if (!(_conv_num(&bp, &cr->relyear, 0, 99)))
                 return (NULL);
             break;
 
@@ -391,14 +393,14 @@
      * We need to evaluate the two digit year spec (%y)
      * last as we can get a century spec (%C) at any time.
      */
-    if (relyear != -1) {
-        if (century == TM_YEAR_BASE) {
-            if (relyear <= 68)
-                tm->tm_year = relyear + 2000 - TM_YEAR_BASE;
+    if (cr->relyear != -1) {
+        if (cr->century == TM_YEAR_BASE) {
+            if (cr->relyear <= 68)
+                tm->tm_year = cr->relyear + 2000 - TM_YEAR_BASE;
             else
-                tm->tm_year = relyear + 1900 - TM_YEAR_BASE;
+                tm->tm_year = cr->relyear + 1900 - TM_YEAR_BASE;
         } else {
-            tm->tm_year = relyear + century - TM_YEAR_BASE;
+            tm->tm_year = cr->relyear + cr->century - TM_YEAR_BASE;
         }
     }