This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
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 <jakub@redhat.com> * 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
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |