proposed tz changes: 1997-06 leap second, core dump if TZ=Europe, etc.

Paul Eggert eggert at twinsun.com
Thu Feb 27 23:17:27 UTC 1997


   Date: Thu, 27 Feb 97 10:36:47 GMT
   From: peter at memex.co.uk (Peter Ilieve)

   there will be a leap second on 30 June 1997.
   See ftp://hpvlbi.obspm.fr/iers/bul/bulc/bulletinc.13

Here is a proposed patch for that new leap second,
plus the following other issues:

  * A localtime bug can lead to a core dump, e.g. when TZ=Europe.
    (Thanks to Garrett Wollman for this fix.)
  * mkdirs complains when run in parallel.
    (I adapted fixes from Ken Pizzini and Ulrich Drepper for this; thanks.)
  * mkdirs uses the constant 0755, which isn't portable POSIX.
  * The location of Dumont-d'Urville is incorrect.
  * The URLs in tzselect.ksh are out of date.
  * The bash bug noted in tzselect.ksh is fixed in recent bash versions.
  * Recent GCC snapshots issue the following diagnostics for the code:
    redo declarations and add casts to avoid this.

localtime.c:888: warning: comparison between signed and unsigned
scheck.c:16: warning: no previous prototype for `scheck'
ialloc.c:84: warning: no previous prototype for `icfree'
zdump.c:181: warning: comparison between signed and unsigned
zdump.c:272: warning: `hunt' was used with no prototype before its definition
zdump.c:308: warning: `delta' was used with no prototype before its definition
zdump.c:333: warning: `show' was used with no prototype before its definition
zdump.c:357: warning: `abbr' was used with no prototype before its definition

===================================================================
RCS file: RCS/antarctica,v
retrieving revision 1997.1
retrieving revision 1997.1.1.1
diff -c -r1997.1 -r1997.1.1.1
*** antarctica	1997/01/21 14:11:10	1997.1
--- antarctica	1997/02/27 21:11:39	1997.1.1.1
***************
*** 79,85 ****
  			5:00	-	TFT	# ISO code TF Time
  #
  # year-round base in the main continent
! # Dumont-d'Urville, Terre Adelie (Adelie Land), -6040+14001, since 1956-11
  #
  # Another base at Port-Martin, 50km east, began operation in 1947.
  # It was destroyed by fire on 1952-01-14.
--- 79,85 ----
  			5:00	-	TFT	# ISO code TF Time
  #
  # year-round base in the main continent
! # Dumont-d'Urville, Terre Adelie (Adelie Land), -6640+14001, since 1956-11
  #
  # Another base at Port-Martin, 50km east, began operation in 1947.
  # It was destroyed by fire on 1952-01-14.
===================================================================
RCS file: RCS/ialloc.c,v
retrieving revision 1995.3
retrieving revision 1995.3.1.1
diff -c -r1995.3 -r1995.3.1.1
*** ialloc.c	1995/03/11 17:55:48	1995.3
--- ialloc.c	1997/02/27 22:16:47	1995.3.1.1
***************
*** 10,22 ****
  
  #define nonzero(n)	(((n) == 0) ? 1 : (n))
  
- char *	icalloc P((int nelem, int elsize));
- char *	icatalloc P((char * old, const char * new));
- char *	icpyalloc P((const char * string));
- char *	imalloc P((int n));
- void *	irealloc P((void * pointer, int size));
- void	ifree P((char * pointer));
- 
  char *
  imalloc(n)
  const int	n;
--- 10,15 ----
===================================================================
RCS file: RCS/leapseconds,v
retrieving revision 1995.1
retrieving revision 1995.1.1.1
diff -c -r1995.1 -r1995.1.1.1
*** leapseconds	1995/07/08 22:02:34	1995.1
--- leapseconds	1997/02/27 21:11:39	1995.1.1.1
***************
*** 40,42 ****
--- 40,43 ----
  Leap	1993	Jun	30	23:59:60	+	S
  Leap	1994	Jun	30	23:59:60	+	S
  Leap	1995	Dec	31	23:59:60	+	S
+ Leap	1997	Jun	30	23:59:60	+	S
===================================================================
RCS file: RCS/localtime.c,v
retrieving revision 1997.1
retrieving revision 1997.1.1.2
diff -c -r1997.1 -r1997.1.1.2
*** localtime.c	1997/01/21 14:11:10	1997.1
--- localtime.c	1997/02/27 22:16:47	1997.1.1.2
***************
*** 708,722 ****
  		name += stdlen;
  		if (stdlen >= sizeof sp->chars)
  			stdlen = (sizeof sp->chars) - 1;
  	} else {
  		name = getzname(name);
  		stdlen = name - stdname;
  		if (stdlen < 3)
  			return -1;
! 	}
! 	if (*name == '\0')
! 		return -1;	/* was "stdoffset = 0;" */
! 	else {
  		name = getoffset(name, &stdoffset);
  		if (name == NULL)
  			return -1;
--- 708,721 ----
  		name += stdlen;
  		if (stdlen >= sizeof sp->chars)
  			stdlen = (sizeof sp->chars) - 1;
+ 		stdoffset = 0;
  	} else {
  		name = getzname(name);
  		stdlen = name - stdname;
  		if (stdlen < 3)
  			return -1;
! 		if (*name == '\0')
! 			return -1;
  		name = getoffset(name, &stdoffset);
  		if (name == NULL)
  			return -1;
***************
*** 885,891 ****
  	sp->charcnt = stdlen + 1;
  	if (dstlen != 0)
  		sp->charcnt += dstlen + 1;
! 	if (sp->charcnt > sizeof sp->chars)
  		return -1;
  	cp = sp->chars;
  	(void) strncpy(cp, stdname, stdlen);
--- 884,890 ----
  	sp->charcnt = stdlen + 1;
  	if (dstlen != 0)
  		sp->charcnt += dstlen + 1;
! 	if ((size_t) sp->charcnt > sizeof sp->chars)
  		return -1;
  	cp = sp->chars;
  	(void) strncpy(cp, stdname, stdlen);
===================================================================
RCS file: RCS/private.h,v
retrieving revision 1996.13
retrieving revision 1996.13.1.1
diff -c -r1996.13 -r1996.13.1.1
*** private.h	1996/11/05 18:50:08	1996.13
--- private.h	1997/02/27 22:16:47	1996.13.1.1
***************
*** 173,178 ****
--- 173,191 ----
  #endif /* !defined errno */
  
  /*
+ ** Private function declarations.
+ */
+ char *	icalloc P((int nelem, int elsize));
+ char *	icatalloc P((char * old, const char * new));
+ char *	icpyalloc P((const char * string));
+ char *	imalloc P((int n));
+ void *	irealloc P((void * pointer, int size));
+ void	icfree P((char * pointer));
+ void	ifree P((char * pointer));
+ char *  scheck P((const char *string, char *format));
+ 
+ 
+ /*
  ** Finally, some convenience items.
  */
  
===================================================================
RCS file: RCS/scheck.c,v
retrieving revision 1995.7
retrieving revision 1995.7.1.1
diff -c -r1995.7 -r1995.7.1.1
*** scheck.c	1995/10/30 15:20:12	1995.7
--- scheck.c	1997/02/27 22:16:47	1995.7.1.1
***************
*** 8,16 ****
  
  #include "private.h"
  
- extern char *	imalloc P((int n));
- extern void	ifree P((char * p));
- 
  char *
  scheck(string, format)
  const char * const	string;
--- 8,13 ----
===================================================================
RCS file: RCS/tzselect.ksh,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -c -r1.1 -r1.1.1.1
*** tzselect.ksh	1996/09/03 23:48:46	1.1
--- tzselect.ksh	1997/02/27 21:11:39	1.1.1.1
***************
*** 11,33 ****
  # you can use either of the following free programs instead:
  #
  #	Bourne-Again shell (bash)
! #	<URL:ftp://prep.ai.mit.edu:/pub/gnu/bash-1.14.7.tar.gz>
! #	(or any later version)
  #
  #	Public domain ksh
! #	<URL:ftp://ftp.cs.mun.ca:/pub/pdksh/pdksh.tar.gz>
  #
  # This script also uses several features of modern awk programs.
  # If your host lacks awk, or has an old awk that does not conform to Posix.2,
  # you can use either of the following free programs instead:
  #
  #	GNU awk (gawk)
! #	<URL:ftp://prep.ai.mit.edu:/pub/gnu/gawk-3.0.0.tar.gz>
! #	(or any later version)
  #
  #	mawk
! #	<URL:ftp://oxy.edu/public/mawk1.2.2.tar.gz>
! #	(or any later version)
  
  
  # Specify default values for environment variables if they are unset.
--- 11,30 ----
  # you can use either of the following free programs instead:
  #
  #	Bourne-Again shell (bash)
! #	<URL:ftp://ftp.gnu.ai.mit.edu/pub/gnu/>
  #
  #	Public domain ksh
! #	<URL:ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz>
  #
  # This script also uses several features of modern awk programs.
  # If your host lacks awk, or has an old awk that does not conform to Posix.2,
  # you can use either of the following free programs instead:
  #
  #	GNU awk (gawk)
! #	<URL:ftp://ftp.gnu.ai.mit.edu/pub/gnu/>
  #
  #	mawk
! #	<URL:ftp://ftp.whidbey.net/pub/brennan/>
  
  
  # Specify default values for environment variables if they are unset.
***************
*** 57,63 ****
  IFS=$newline
  
  
! # Work around a bash bug, where $PS3 is sent to stdout.
  case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in
  ?*) PS3=
  esac
--- 54,60 ----
  IFS=$newline
  
  
! # Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
  case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in
  ?*) PS3=
  esac
===================================================================
RCS file: RCS/zdump.c,v
retrieving revision 1997.1
retrieving revision 1997.1.1.1
diff -c -r1997.1 -r1997.1.1.1
*** zdump.c	1997/01/21 00:02:25	1997.1
--- zdump.c	1997/02/27 22:16:47	1997.1.1.1
***************
*** 111,129 ****
  #define TZ_DOMAIN "tz"
  #endif /* !defined TZ_DOMAIN */
  
  extern char **	environ;
! extern int	getopt();
  extern char *	optarg;
  extern int	optind;
- extern time_t	time();
- extern char *	tzname[2];
  
! static char *	abbr();
! static long	delta();
! static time_t	hunt();
! static int	longest;
  static char *	progname;
! static void	show();
  
  int
  main(argc, argv)
--- 111,137 ----
  #define TZ_DOMAIN "tz"
  #endif /* !defined TZ_DOMAIN */
  
+ #ifndef P
+ #ifdef __STDC__
+ #define P(x)	x
+ #endif /* defined __STDC__ */
+ #ifndef __STDC__
+ #define P(x)	()
+ #endif /* !defined __STDC__ */
+ #endif /* !defined P */
+ 
  extern char **	environ;
! extern int	getopt P((int argc, char * const argv[],
! 			  const char * options));
  extern char *	optarg;
  extern int	optind;
  
! static char *	abbr P((struct tm * tmp));
! static long	delta P((struct tm * newp, struct tm * oldp));
! static time_t	hunt P((char * name, time_t lot, time_t	hit));
! static size_t	longest;
  static char *	progname;
! static void	show P((char * zone, time_t t, int v));
  
  int
  main(argc, argv)
***************
*** 191,198 ****
  		fakeenv = (char **) malloc((size_t) ((i + 2) *
  			sizeof *fakeenv));
  		if (fakeenv == NULL ||
! 			(fakeenv[0] = (char *) malloc((size_t) (longest +
! 				4))) == NULL) {
  					(void) perror(progname);
  					(void) exit(EXIT_FAILURE);
  		}
--- 199,205 ----
  		fakeenv = (char **) malloc((size_t) ((i + 2) *
  			sizeof *fakeenv));
  		if (fakeenv == NULL ||
! 			(fakeenv[0] = (char *) malloc(longest + 4)) == NULL) {
  					(void) perror(progname);
  					(void) exit(EXIT_FAILURE);
  		}
***************
*** 326,333 ****
  	return result;
  }
  
- extern struct tm *	localtime();
- 
  static void
  show(zone, t, v)
  char *	zone;
--- 333,338 ----
***************
*** 336,342 ****
  {
  	struct tm *	tmp;
  
! 	(void) printf("%-*s  ", longest, zone);
  	if (v)
  		(void) printf("%.24s GMT = ", asctime(gmtime(&t)));
  	tmp = localtime(&t);
--- 341,347 ----
  {
  	struct tm *	tmp;
  
! 	(void) printf("%-*s  ", (int) longest, zone);
  	if (v)
  		(void) printf("%.24s GMT = ", asctime(gmtime(&t)));
  	tmp = localtime(&t);
===================================================================
RCS file: RCS/zic.c,v
retrieving revision 1997.1
retrieving revision 1997.1.1.1
diff -c -r1997.1 -r1997.1.1.1
*** zic.c	1997/01/21 00:02:25	1997.1
--- zic.c	1997/02/27 22:16:47	1997.1.1.1
***************
*** 79,93 ****
  
  extern int	getopt P((int argc, char * const argv[],
  			const char * options));
- extern char *	icatalloc P((char * old, const char * new));
- extern char *	icpyalloc P((const char * string));
- extern void	ifree P((char * p));
- extern char *	imalloc P((int n));
- extern void *	irealloc P((void * old, int n));
  extern int	link P((const char * fromname, const char * toname));
  extern char *	optarg;
  extern int	optind;
- extern char *	scheck P((const char * string, const char * format));
  
  static void	addtt P((time_t starttime, int type));
  static int	addtype P((long gmtoff, const char * abbr, int isdst,
--- 79,87 ----
***************
*** 2126,2140 ****
  		if (!itsdir(name)) {
  			/*
  			** It doesn't seem to exist, so we try to create it.
  			*/
! 			if (mkdir(name, 0755) != 0) {
! 				const char *e = strerror(errno);
  
  				(void) fprintf(stderr,
  				    _("%s: Can't create directory %s: %s\n"),
! 				    progname, name, e);
  				ifree(name);
  				return -1;
  			}
  		}
  		*cp = '/';
--- 2120,2139 ----
  		if (!itsdir(name)) {
  			/*
  			** It doesn't seem to exist, so we try to create it.
+ 			** But don't complain if the attempt to creation fails
+ 			** because it already exists -- this just means that
+ 			** some other process just created the directory.
  			*/
! 			if (mkdir(name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) {
! 			    int mkdir_errno = errno;
  
+ 			    if (mkdir_errno != EEXIST || !itsdir(name)) {
  				(void) fprintf(stderr,
  				    _("%s: Can't create directory %s: %s\n"),
! 				    progname, name, strerror(mkdir_errno));
  				ifree(name);
  				return -1;
+ 			    }
  			}
  		}
  		*cp = '/';
===================================================================
RCS file: RCS/zone.tab,v
retrieving revision 1.2.1.1
retrieving revision 1.2.1.2
diff -c -r1.2.1.1 -r1.2.1.2
*** zone.tab	1997/01/21 04:03:37	1.2.1.1
--- zone.tab	1997/02/27 21:11:39	1.2.1.2
***************
*** 34,40 ****
  AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
  AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
  AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
! AQ	-6040+14001	Antarctica/DumontDUrville	Dumont-d'Urville Base, Terre Adelie
  AR	-3436-05827	America/Buenos_Aires	E Argentina (BA, DF, SC, TF)
  AR	-3257-06040	America/Rosario	NE Argentina (SF, ER, CN, MN, CC, FM, LP, CH)
  AR	-3124-06411	America/Cordoba	W Argentina (CB, SA, TM, LR, SJ, SL, NQ, RN)
--- 34,40 ----
  AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
  AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
  AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
! AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Base, Terre Adelie
  AR	-3436-05827	America/Buenos_Aires	E Argentina (BA, DF, SC, TF)
  AR	-3257-06040	America/Rosario	NE Argentina (SF, ER, CN, MN, CC, FM, LP, CH)
  AR	-3124-06411	America/Cordoba	W Argentina (CB, SA, TM, LR, SJ, SL, NQ, RN)



More information about the tz mailing list