r3077 - in trunk/varnish-cache: . bin/varnishd lib/libvarnish

phk at projects.linpro.no phk at projects.linpro.no
Mon Aug 11 11:15:27 CEST 2008


Author: phk
Date: 2008-08-11 11:15:27 +0200 (Mon, 11 Aug 2008)
New Revision: 3077

Modified:
   trunk/varnish-cache/bin/varnishd/varnishd.c
   trunk/varnish-cache/configure.ac
   trunk/varnish-cache/lib/libvarnish/time.c
Log:
Be much more explicit about the string->time conversion disaster
visited upon us by the brilliant minds behind POSIX.

Parts from:	Solaris patch from Theo Schlossnagle



Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2008-08-11 08:31:08 UTC (rev 3076)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2008-08-11 09:15:27 UTC (rev 3077)
@@ -429,7 +429,13 @@
 	setbuf(stdout, NULL);
 	setbuf(stderr, NULL);
 
-	AZ(setenv("TZ", "GMT", 1));
+	/*
+	 * Run in UTC timezone, on the off-chance that this operating
+	 * system does not have a timegm() function, and translates
+	 * timestamps on the local timescale.
+	 * See lib/libvarnish/time.c
+	 */
+	AZ(setenv("TZ", "UTC", 1));
 	tzset();
 
 	memset(cli, 0, sizeof cli);

Modified: trunk/varnish-cache/configure.ac
===================================================================
--- trunk/varnish-cache/configure.ac	2008-08-11 08:31:08 UTC (rev 3076)
+++ trunk/varnish-cache/configure.ac	2008-08-11 09:15:27 UTC (rev 3077)
@@ -101,6 +101,7 @@
 AC_CHECK_FUNCS([fmtcheck])
 AC_CHECK_FUNCS([getdtablesize])
 AC_CHECK_FUNCS([abort2])
+AC_CHECK_FUNCS([timegm])
 
 save_LIBS="${LIBS}"
 LIBS="${PTHREAD_LIBS}"

Modified: trunk/varnish-cache/lib/libvarnish/time.c
===================================================================
--- trunk/varnish-cache/lib/libvarnish/time.c	2008-08-11 08:31:08 UTC (rev 3076)
+++ trunk/varnish-cache/lib/libvarnish/time.c	2008-08-11 09:15:27 UTC (rev 3077)
@@ -112,18 +112,70 @@
 time_t
 TIM_parse(const char *p)
 {
+	time_t t;
 	struct tm tm;
 	const char **r;
 
 	for (r = fmts; *r != NULL; r++) {
 		memset(&tm, 0, sizeof tm);
-		if (strptime(p, *r, &tm) != NULL)
-			return (mktime(&tm));
+		if (strptime(p, *r, &tm) != NULL) {
+			/*
+			 * Make sure this is initialized on the off-chance
+			 * that some raving loonie would apply DST to UTC.
+			 */
+			tm.tm_isdst = -1;
+#if defined(HAVE_TIMEGM)
+			t = timegm(&tm);
+#else
+			/*
+			 * Ahh, another POSIX_STUPIDITY, how unexpected.
+			 * Instead of, as would have been logical, to have
+			 * tm_timezone element, mktime() is standardized as
+			 * always working in localtime.  This brilliant idea
+			 * came from the same people who said "leap-seconds ?
+			 * Naah, screw it!".
+			 *
+			 * On broken systems without a working timegm(),
+			 * it is the responsibility of the calling program
+			 * to set the timezone to UTC.  We check that.
+			 */
+			t = mktime(&tm);
+			assert(!strcmp(tzname[0], "UTC"));
+#endif
+			return (t);
+		}
 	}
 	return (0);
 }
 
 #ifdef TEST_DRIVER
+
+#include <stdlib.h>
+
+/*
+ * Compile with:
+ *  cc -o foo -DTEST_DRIVER -I../.. -I../../include time.c assert.c
+ * Test with:
+ *  env TZ=UTC ./foo
+ *  env TZ=CET ./foo
+ */
+
+static void
+tst(const char *s, time_t good)
+{
+	time_t t;
+	char buf[BUFSIZ];
+
+	t = TIM_parse(s);
+	TIM_format(t, buf);
+	printf("%-30s -> %12jd -> %s\n", s, (intmax_t)t, buf);
+	if (t != good) {
+		printf("Parse error! Got: %jd should have %jd diff %jd\n",
+		    (intmax_t)t, (intmax_t)good, (intmax_t)(t - good));
+		exit (2);
+	}
+}
+
 int
 main(int argc, char **argv)
 {
@@ -136,9 +188,9 @@
 	printf("scan = %d <%s>\n", TIM_parse(buf), buf);
 
 	/* Examples from RFC2616 section 3.3.1 */
-	printf("scan = %d\n", TIM_parse("Sun, 06 Nov 1994 08:49:37 GMT"));
-	printf("scan = %d\n", TIM_parse("Sunday, 06-Nov-94 08:49:37 GMT"));
-	printf("scan = %d\n", TIM_parse("Sun Nov  6 08:49:37 1994"));
+	tst("Sun, 06 Nov 1994 08:49:37 GMT", 784111777);
+	tst("Sunday, 06-Nov-94 08:49:37 GMT", 784111777);
+	tst("Sun Nov  6 08:49:37 1994", 784111777);
 
 	return (0);
 }




More information about the varnish-commit mailing list