patches to zdump.c and date.c for Posix-compliant tzset behavior
Paul Eggert
eggert at twinsun.com
Tue Dec 6 17:49:50 UTC 1994
date.c and zdump.c currently use the trick of temporarily setting
`environ' to modify "TZ", then calling tzset(), then restoring
`environ', then calling `localtime' to get the effect of the
temporarily modified "TZ". But this trick doesn't work if `ctime',
`localtime', `mktime', and `strftime' inspect "TZ" every time they are
invoked, as required by Posix 1003.1b-1993 section 8.1.1 page 192
lines 54-56. The following patch fixes date.c and zdump.c to set
`environ' permanently; this should work regardless of whether tzset
has the Posix-required behavior or the old tz behavior. (I've already
sent a patch to fix the old tz behavior -- I can resend this to
whoever's interested.)
===================================================================
RCS file: RCS/date.c,v
retrieving revision 1994.6.1.2
retrieving revision 1994.6.1.3
diff -c -r1994.6.1.2 -r1994.6.1.3
*** date.c 1994/05/09 09:47:28 1994.6.1.2
--- date.c 1994/12/06 17:13:55 1994.6.1.3
***************
*** 299,312 ****
static void
dogmt()
{
! register char ** saveenv;
! static char TZ_GMT0[] = "TZ=GMT0";
! static char * fakeenv[] = { TZ_GMT0, NULL };
! saveenv = environ;
! environ = fakeenv;
! tzset();
! environ = saveenv;
}
#ifdef OLD_TIME
--- 299,320 ----
static void
dogmt()
{
! static char **fakeenv;
! if (!fakeenv) {
! register int i, j;
! for (i = 0; environ[i]; i++)
! continue;
! if (!(fakeenv = (char **) malloc((i + 2) * sizeof(char *)))) {
! (void) perror("Memory exhausted");
! errensure();
! (void) exit(retval);
! }
! fakeenv[0] = "TZ=GMT0";
! for (i = 0, j = 1; (fakeenv[j] = environ[i]) != 0; i++)
! j += strncmp(fakeenv[j], "TZ=", 3) != 0;
! environ = fakeenv;
! }
}
#ifdef OLD_TIME
===================================================================
RCS file: RCS/zdump.c,v
retrieving revision 1994.6.1.1
retrieving revision 1994.6.1.2
diff -c -r1994.6.1.1 -r1994.6.1.2
*** zdump.c 1994/05/05 16:24:49 1994.6.1.1
--- zdump.c 1994/12/06 17:13:55 1994.6.1.2
***************
*** 41,47 ****
/* localtime.c */
extern char * tzname[];
- extern void tzset P((void));
#ifndef MAX_STRING_LENGTH
#define MAX_STRING_LENGTH 1024
--- 41,46 ----
***************
*** 116,121 ****
--- 115,121 ----
register char * cutoff;
register int cutyear;
register long cuttime;
+ char ** fakeenv;
time_t now;
time_t t, newt;
time_t hibit;
***************
*** 154,178 ****
longest = strlen(argv[i]);
for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
continue;
for (i = optind; i < argc; ++i) {
- register char ** saveenv;
static char buf[MAX_STRING_LENGTH];
- char * fakeenv[2];
! if (strlen(argv[i]) + 4 > sizeof buf) {
! (void) fflush(stdout);
! (void) fprintf(stderr, "%s: argument too long -- %s\n",
! progname, argv[i]);
! (void) exit(EXIT_FAILURE);
! }
! (void) strcpy(buf, "TZ=");
! (void) strcat(buf, argv[i]);
! fakeenv[0] = buf;
! fakeenv[1] = NULL;
! saveenv = environ;
! environ = fakeenv;
! (void) tzset();
! environ = saveenv;
show(argv[i], now, FALSE);
if (!vflag)
continue;
--- 154,176 ----
longest = strlen(argv[i]);
for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
continue;
+
+ for (i = 0; environ[i]; i++)
+ continue;
+ if (!(fakeenv = (char **) malloc((i + 2) * sizeof(char *)))
+ || !(fakeenv[0] = malloc(longest + 4))) {
+ (void) perror(progname);
+ (void) exit(EXIT_FAILURE);
+ }
+ (void) strcpy(fakeenv[0], "TZ=");
+ for (i = 0, c = 1; (fakeenv[c] = environ[i]) != 0; i++)
+ c += strncmp(fakeenv[c], "TZ=", 3) != 0;
+ environ = fakeenv;
+
for (i = optind; i < argc; ++i) {
static char buf[MAX_STRING_LENGTH];
! (void) strcpy(fakeenv[0] + 3, argv[i]);
show(argv[i], now, FALSE);
if (!vflag)
continue;
More information about the tz
mailing list