POSIX-TZ without rules

Paul Eggert eggert at twinsun.com
Thu May 6 19:39:14 UTC 1999

[This is a slightly revised version of a message that I sent to the tz
mailing list on April 29, when the mailing list wasn't working.]

   From:	Guido Flohr [SMTP:gufl0000 at stud.uni-sb.de]
   Sent:	Monday, April 26, 1999 9:46 PM

   for testing purposes I set the envariable TZ to "CET-1CEST-2",
   i. e. a valid POSIX-style string but without explicit rules.
   I also uninstalled the database for that test.

   Under these circumstances tzparse() in localtime.c will return an error
   because it fails to open a default rules file.  From what I remember I
   would say that POSIX demands that the US rules should be applied instead.

POSIX.1 is not US-centric here; it says that the behavior in this case
is implementation-defined.  The rationale (POSIX 1003.1-1996 section
B.8.1.1 page 493 lines 5609-5612) says ``An implementation may provide
those rules [i.e. the DST rules not explicitly specified by the user]
in any way it sees fit, as long as the constraints implied by the TZ
string as provided by the user are met.  Specifically, the
implementation may use the string as an index into a table, which may
reside either on disk or in memory.''  So the implementation is
allowed to do the right thing with "CET-1CEST-2".

   Anyway, "CET-1CEST-2" is perfectly POSIX-compliant and the library should
   not return an error then.

Yes.  My reading of POSIX.1 is that the implementation is allowed to
guess the DST rules, but it shouldn't ignore this TZ string entirely.

   The GNU libc handles this case by assuming an implicit rule of
   "M4.1.0,M10.5.0" (commented as "US Federal Law").  My solution is somewhat
   different: I generated a header "new_york.h"

Both solutions are suboptimal.  The first mishandles old dates; the
second assumes the New York City DST rules, whereas it'd be better to
assume only the US rules.  But clearly something should be done to the
tz code to fix the problem, and either solution is acceptable.

Going to your other point:

   In zic.c, the analysis of the return value of
   system("yearistype ...") assumes a certain structure of that return value.

I see how to fix this bug; here's a patch.

1999-04-29  Paul Eggert  <eggert at twinsun.com>

	* zic.c (yearistype): Check exit status portably.
	* private.h (HAVE_SYS_WAIT_H, WIFEXITED, WEXITSTATUS): New macros.
	* Makefile: Comment about HAVE_SYS_WAIT_H.

RCS file: RCS/private.h,v
retrieving revision 1998.7
retrieving revision 1998.7.1.1
diff -u -r1998.7 -r1998.7.1.1
--- private.h	1998/09/24 14:46:42	1998.7
+++ private.h	1999/04/29 23:34:11	1998.7.1.1
@@ -50,6 +50,10 @@
 #define HAVE_SYMLINK		1
 #endif /* !defined HAVE_SYMLINK */
+#ifndef HAVE_SYS_WAIT_H
+#define HAVE_SYS_WAIT_H		1
+#endif /* !defined HAVE_SYS_WAIT_H */
 #ifndef HAVE_UNISTD_H
 #define HAVE_UNISTD_H		1
 #endif /* !defined HAVE_UNISTD_H */
@@ -78,6 +82,17 @@
 #include "libintl.h"
 #endif /* HAVE_GETTEXT - 0 */
+#if HAVE_SYS_WAIT_H - 0
+#include <sys/wait.h>	/* for WIFEXITED and WEXITSTATUS */
+#endif /* HAVE_SYS_WAIT_H - 0 */
+#ifndef WIFEXITED
+#define WIFEXITED(status)	(((status) & 0xff) == 0)
+#endif /* !defined WIFEXITED */
+#define WEXITSTATUS(status)	(((status) >> 8) & 0xff)
+#endif /* !defined WEXITSTATUS */
 #if HAVE_UNISTD_H - 0
 #include "unistd.h"	/* for F_OK and R_OK */
 #endif /* HAVE_UNISTD_H - 0 */
RCS file: RCS/Makefile,v
retrieving revision 1999.4
retrieving revision 1999.4.1.1
diff -u -r1999.4 -r1999.4.1.1
--- Makefile	1999/03/30 16:27:50	1999.4
+++ Makefile	1999/04/29 23:34:11	1999.4.1.1
@@ -92,6 +92,7 @@
 #  -DHAVE_SETTIMEOFDAY=3 if settimeofday ignores 2nd arg (4.4BSD)
 #  -DHAVE_STRERROR=1 if `strerror' works
 #  -DHAVE_SYMLINK=0 if your system lacks the symlink function
+#  -DHAVE_SYS_WAIT_H=0 if your compiler lacks a "sys/wait.h"
 #  -DLOCALE_HOME=\"path\" if locales are in "path", not "/usr/lib/locale"
 #  -DHAVE_UNISTD_H=0 if your compiler lacks a "unistd.h" (Microsoft C++ 7?)
 #  -DHAVE_UTMPX_H=1 if your compiler has a "utmpx.h"
RCS file: RCS/zic.c,v
retrieving revision 1999.2
retrieving revision 1999.2.1.1
diff -u -r1999.2 -r1999.2.1.1
--- zic.c	1999/02/01 22:51:44	1999.2
+++ zic.c	1999/04/29 23:34:11	1999.2.1.1
@@ -1906,10 +1906,12 @@
 	buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type)));
 	(void) sprintf(buf, "%s %d %s", yitcommand, year, type);
 	result = system(buf);
-	if (result == 0)
-		return TRUE;
-	if (result == (1 << 8))
-		return FALSE;
+	if (WIFEXITED(result)) switch (WEXITSTATUS(result)) {
+		case 0:
+			return TRUE;
+		case 1:
+			return FALSE;
+	}
 	error(_("Wild result from command execution"));
 	(void) fprintf(stderr, _("%s: command was '%s', result was %d\n"),
 		progname, buf, result);

More information about the tz mailing list