Clean up struct tm handling. Instead of calling gmtime/localtime
authorray <ray@openbsd.org>
Fri, 23 Jul 2010 09:11:10 +0000 (09:11 +0000)
committerray <ray@openbsd.org>
Fri, 23 Jul 2010 09:11:10 +0000 (09:11 +0000)
and making copies (among other weird dances), use reentrant versions.

Not being able to tell the time is a fatal error, so die if that
happens.

Diff originally from nicm.

OK nicm xsa

usr.bin/cvs/date.y

index 6e30f6e..93da811 100644 (file)
@@ -1,5 +1,5 @@
 %{
-/*     $OpenBSD: date.y,v 1.18 2008/02/16 01:00:00 cnst Exp $  */
+/*     $OpenBSD: date.y,v 1.19 2010/07/23 09:11:10 ray Exp $   */
 
 /*
 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
@@ -807,39 +807,24 @@ difftm(struct tm *a, struct tm *b)
 time_t
 cvs_date_parse(const char *p)
 {
-       struct tm       gmt, *gmt_ptr, *tm;
-       struct timeb    ftz, *now;
-       time_t          Start, tod, nowtime;
+       struct tm       gmt, tm;
+       time_t          Start, tod, nowtime, tz;
 
        yyInput = p;
 
-       now = &ftz;
-       (void)time(&nowtime);
+       if (time(&nowtime) == -1 || !gmtime_r(&nowtime, &gmt) ||
+           !localtime_r(&nowtime, &tm))
+               fatal("cvs_date_parse failed");
 
-       gmt_ptr = gmtime(&nowtime);
-       if (gmt_ptr != NULL) {
-               /* Make a copy, in case localtime modifies *tm (I think
-                * that comment now applies to *gmt_ptr, but I am too
-                * lazy to dig into how gmtime and locatime allocate the
-                * structures they return pointers to).
-                */
-               gmt = *gmt_ptr;
-       }
-
-       if (!(tm = localtime(&nowtime)))
-               return (-1);
-
-       if (gmt_ptr != NULL)
-               ftz.timezone = difftm(&gmt, tm) / 60;
+       tz = difftm(&gmt, &tm) / 60;
 
-       if (tm->tm_isdst)
-               ftz.timezone += 60;
+       if (tm.tm_isdst)
+               tz += 60;
 
-       tm = localtime(&nowtime);
-       yyYear = tm->tm_year + 1900;
-       yyMonth = tm->tm_mon + 1;
-       yyDay = tm->tm_mday;
-       yyTimezone = now->timezone;
+       yyYear = tm.tm_year + 1900;
+       yyMonth = tm.tm_mon + 1;
+       yyDay = tm.tm_mday;
+       yyTimezone = tz;
        yyDSTmode = DSTmaybe;
        yyHour = 0;
        yyMinutes = 0;
@@ -865,8 +850,8 @@ cvs_date_parse(const char *p)
        } else {
                Start = nowtime;
                if (!yyHaveRel)
-                       Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) +
-                           tm->tm_sec;
+                       Start -= ((tm.tm_hour * 60L + tm.tm_min) * 60L) +
+                           tm.tm_sec;
        }
 
        Start += yyRelSeconds;