From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30882 invoked by alias); 11 Aug 2004 16:15:07 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 30849 invoked from network); 11 Aug 2004 16:15:06 -0000 Received: from unknown (HELO sunsite.ms.mff.cuni.cz) (195.113.15.26) by sourceware.org with SMTP; 11 Aug 2004 16:15:06 -0000 Received: from sunsite.ms.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8) with ESMTP id i7BDw73j017562; Wed, 11 Aug 2004 15:58:07 +0200 Received: (from jakub@localhost) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8/Submit) id i7BDw7Fr017560; Wed, 11 Aug 2004 15:58:07 +0200 Date: Wed, 11 Aug 2004 16:15:00 -0000 From: Jakub Jelinek To: Ulrich Drepper , Roland McGrath Cc: Glibc hackers Subject: [PATCH] Fix tzfile.c Message-ID: <20040811135807.GW30497@sunsite.ms.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i X-SW-Source: 2004-08/txt/msg00033.txt.bz2 Hi! The recent tzfile.c changes broke any program which calls tzset or strftime* or mktime* more than once. Although the second __tzfile_read set __use_tzfile to 1, transitions was NULL. The patch below fixes this. Still, I wonder if it is a good idea to fopen /etc/localtime every time strfime, strftime_l or mktime is called or if it wouldn't be enough to use the old behaviour of tzset (where if $TZ is unset and was previously unset too, nothing will happen) when called from these functions and only do the slow path if tzset () is called by the user program. E.g. rpm -qia call results in almost 15000 openings of /etc/localtime, which is IMHO a lot. 2004-08-11 Jakub Jelinek * time/tzfile.c (__tzfile_read): Free transitions only if it will not be reused. --- libc/time/tzfile.c.jj 2004-08-11 17:27:33.000000000 +0200 +++ libc/time/tzfile.c 2004-08-11 17:47:20.654952554 +0200 @@ -104,16 +104,12 @@ __tzfile_read (const char *file, size_t __use_tzfile = 0; - if (transitions != NULL) - free ((void *) transitions); - transitions = NULL; - if (file == NULL) /* No user specification; use the site-wide default. */ file = TZDEFAULT; else if (*file == '\0') /* User specified the empty string; use UTC with no leap seconds. */ - return; + goto ret_free_transitions; else { /* We must not allow to read an arbitrary file in a setuid @@ -127,7 +123,7 @@ __tzfile_read (const char *file, size_t || strstr (file, "../") != NULL)) /* This test is certainly a bit too restrictive but it should catch all critical cases. */ - return; + goto ret_free_transitions; } if (*file != '/') @@ -156,14 +152,14 @@ __tzfile_read (const char *file, size_t disabled. */ f = fopen (file, "rc"); if (f == NULL) - return; + goto ret_free_transitions; /* Get information about the file. */ struct stat64 st; if (fstat64 (fileno (f), &st) != 0) { fclose (f); - return; + goto ret_free_transitions; } if (was_using_tzfile && tzfile_ino == st.st_ino && tzfile_dev == st.st_dev) { @@ -173,6 +169,9 @@ __tzfile_read (const char *file, size_t return; } + free ((void *) transitions); + transitions = NULL; + /* Remember the inode and device number. */ tzfile_dev = st.st_dev; tzfile_ino = st.st_ino; @@ -381,6 +380,9 @@ __tzfile_read (const char *file, size_t lose: fclose (f); + ret_free_transitions: + free ((void *) transitions); + transitions = NULL; } /* The user specified a hand-made timezone, but not its DST rules. Jakub