Updated to fedora-glibc-20080613T1601 fedora-glibc-2_8_90-7
authorjakub <jakub>
Fri, 13 Jun 2008 16:16:15 +0000 (16:16 +0000)
committerjakub <jakub>
Fri, 13 Jun 2008 16:16:15 +0000 (16:16 +0000)
13 files changed:
ChangeLog
fedora/branch.mk
fedora/glibc.spec.in
nscd/cache.c
nscd/connections.c
nscd/nscd.h
resolv/nss_dns/dns-host.c
sysdeps/powerpc/powerpc32/fpu/s_lround.S
sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S
sysdeps/powerpc/powerpc64/fpu/s_llround.S
sysdeps/powerpc/powerpc64/fpu/s_llroundf.S
sysdeps/unix/sysv/linux/Makefile
time/strftime_l.c

index fe655a4..1b01c4a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,47 @@
 2008-06-12  Ulrich Drepper  <drepper@redhat.com>
 
+       * time/strftime.c: Pass reference to tzset_called around to handle
+       recursive calls.
+
+       [BZ #6612]
+       * time/strftime.c (__strftime_internal): Call tzset() only
+       when printing timezone-dependent values.
+       Based on a patch by Petr Baudis <pasky@suse.cz>.
+
+       * resolv/nss_dns/dns-host.c (gaih_getanswer): Don't
+       unconditionally use second gaih_getanswer_slice result.
+
+       * sysdeps/posix/getaddrinfo.c (gai_inet): Remove unnecessary test.
+       (getaddrinfo): RES must always be non-NULL.
+
+2008-06-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/powerpc/powerpc64/fpu/s_llround.S (__llround): Avoid using
+       cr[34] registers.
+       * sysdeps/powerpc/powerpc64/fpu/s_llroundf.S (__llroundf): Likewise.
+       * sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S (__llround):
+       Likewise.
+       * sysdeps/powerpc/powerpc32/fpu/s_lround.S (__lround): Avoid using cr3
+       register.
+
+2008-06-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * nscd/nscd.h (struct database_dyn): Add inotify_descr and clear_cache
+       fields.
+       * nscd/connections.c (inotify_fd): New variable.
+       (nscd_init): Try to open an inotify descriptor.
+       If successful, watch files for databases using inotify instead of
+       having prune threads stat the files.
+       (nscd_run_prune): Recognize clear_cache flag being set and call
+       prune_cache appropriately.
+       (main_loop_poll): Add inotify descriptor to wait set and handle the
+       reported changes.
+       (main_loop_epoll): Likewise.
+       * nscd/cache.c (prune_cache): Don't stat files for databases if
+       inotify is used.
+       * sysdeps/unix/sysv/linux/Makefile [subdir=nscd]
+       (CFLAGS-connections.c): Add -DHAVE_INOTIFY.
+
        * nscd/grpcache.c (cache_addgr): Correctly compute size of
        fixed-size portion of the record.
        * nscd/servicescache.c (cache_addserv): Likewise.
index 6d65ef0..b4011fc 100644 (file)
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-f8
-fedora-sync-date := 2008-06-12 16:19 UTC
-fedora-sync-tag := fedora-glibc-20080612T1619
+fedora-sync-date := 2008-06-13 16:01 UTC
+fedora-sync-tag := fedora-glibc-20080613T1601
index 38ccd97..c7b2d20 100644 (file)
@@ -19,7 +19,7 @@
 Summary: The GNU libc libraries
 Name: glibc
 Version: @glibcversion@
-Release: 6
+Release: 7
 # GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries.
 # Things that are linked directly into dynamically linked programs
 # and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional
@@ -976,6 +976,12 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Fri Jun 13 2008 Jakub Jelinek <jakub@redhat.com> 2.8.90-7
+- update from trunk
+  - avoid *lround* on ppc* clobbering cr3/cr4 registers (#450790)
+  - further nscd fixes (#450704)
+  - use inotify in nscd to watch files
+
 * Thu Jun 12 2008 Jakub Jelinek <jakub@redhat.com> 2.8.90-6
 - update from trunk
   - nscd fixes (#450704)
index 2faaf34..cd6e6b4 100644 (file)
@@ -274,7 +274,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
 
   /* If we check for the modification of the underlying file we invalidate
      the entries also in this case.  */
-  if (table->check_file && now != LONG_MAX)
+  if (table->inotify_descr < 0 && table->check_file && now != LONG_MAX)
     {
       struct stat64 st;
 
index e6a2c94..bef1c16 100644 (file)
@@ -35,6 +35,9 @@
 #ifdef HAVE_EPOLL
 # include <sys/epoll.h>
 #endif
+#ifdef HAVE_INOTIFY
+# include <sys/inotify.h>
+#endif
 #include <sys/mman.h>
 #include <sys/param.h>
 #include <sys/poll.h>
@@ -222,6 +225,11 @@ int max_nthreads = 32;
 /* Socket for incoming connections.  */
 static int sock;
 
+#ifdef HAVE_INOTIFY
+/* Inotify descriptor.  */
+static int inotify_fd = -1;
+#endif
+
 /* Number of times clients had to wait.  */
 unsigned long int client_queued;
 
@@ -503,6 +511,13 @@ nscd_init (void)
     /* No configuration for this value, assume a default.  */
     nthreads = 4;
 
+#ifdef HAVE_INOTIFY
+  /* Use inotify to recognize changed files.  */
+  inotify_fd = inotify_init ();
+  if (inotify_fd != -1)
+    fcntl (inotify_fd, F_SETFL, O_NONBLOCK);
+#endif
+
   for (size_t cnt = 0; cnt < lastdb; ++cnt)
     if (dbs[cnt].enabled)
       {
@@ -805,20 +820,30 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
            assert (dbs[cnt].ro_fd == -1);
          }
 
+       dbs[cnt].inotify_descr = -1;
        if (dbs[cnt].check_file)
          {
-           /* We need the modification date of the file.  */
-           struct stat64 st;
-
-           if (stat64 (dbs[cnt].filename, &st) < 0)
+#ifdef HAVE_INOTIFY
+           if (inotify_fd == -1
+               || (dbs[cnt].inotify_descr
+                   = inotify_add_watch (inotify_fd, dbs[cnt].filename,
+                                        IN_DELETE_SELF | IN_MODIFY)) < 0)
+             /* We cannot notice changes in the main thread.  */
+#endif
              {
-               /* We cannot stat() the file, disable file checking.  */
-               dbg_log (_("cannot stat() file `%s': %s"),
-                        dbs[cnt].filename, strerror (errno));
-               dbs[cnt].check_file = 0;
+               /* We need the modification date of the file.  */
+               struct stat64 st;
+
+               if (stat64 (dbs[cnt].filename, &st) < 0)
+                 {
+                   /* We cannot stat() the file, disable file checking.  */
+                   dbg_log (_("cannot stat() file `%s': %s"),
+                            dbs[cnt].filename, strerror (errno));
+                   dbs[cnt].check_file = 0;
+                 }
+               else
+                 dbs[cnt].file_mtime = st.st_mtime;
              }
-           else
-             dbs[cnt].file_mtime = st.st_mtime;
          }
       }
 
@@ -1428,12 +1453,15 @@ nscd_run_prune (void *p)
   while (1)
     {
       /* Wait, but not forever.  */
-      int e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
+      int e = 0;
+      if (! dbs[my_number].clear_cache)
+       e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
       assert (__builtin_expect (e == 0 || e == ETIMEDOUT, 1));
 
       time_t next_wait;
       now = time (NULL);
-      if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time)
+      if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time
+         || dbs[my_number].clear_cache)
        {
          /* We will determine the new timout values based on the
             cache content.  Should there be concurrent additions to
@@ -1446,9 +1474,13 @@ nscd_run_prune (void *p)
          else
            dbs[my_number].wakeup_time = INT_MAX;
 
+         /* Unconditionally reset the flag.  */
+         time_t prune_now = dbs[my_number].clear_cache ? LONG_MAX : now;
+         dbs[my_number].clear_cache = 0;
+
          pthread_mutex_unlock (prune_lock);
 
-         next_wait = prune_cache (&dbs[my_number], now, -1);
+         next_wait = prune_cache (&dbs[my_number], prune_now, -1);
 
          next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
          /* If clients cannot determine for sure whether nscd is running
@@ -1703,6 +1735,16 @@ main_loop_poll (void)
   size_t nused = 1;
   size_t firstfree = 1;
 
+#ifdef HAVE_INOTIFY
+  if (inotify_fd != -1)
+    {
+      conns[1].fd = inotify_fd;
+      conns[1].events = POLLRDNORM;
+      nused = 2;
+      firstfree = 2;
+    }
+#endif
+
   while (1)
     {
       /* Wait for any event.  We wait at most a couple of seconds so
@@ -1750,7 +1792,42 @@ main_loop_poll (void)
              --n;
            }
 
-         for (size_t cnt = 1; cnt < nused && n > 0; ++cnt)
+         size_t first = 1;
+#ifdef HAVE_INOTIFY
+         if (conns[1].fd == inotify_fd)
+           {
+             if (conns[1].revents != 0)
+               {
+                 union
+                 {
+                   struct inotify_event i;
+                   char buf[100];
+                 } inev;
+
+                 while (TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
+                                                  sizeof (inev)))
+                        >= sizeof (struct inotify_event))
+                   {
+                     /* Check which of the files changed.  */
+                     for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
+                       if (inev.i.wd == dbs[dbcnt].inotify_descr)
+                         {
+                           pthread_mutex_trylock (&dbs[dbcnt].prune_lock);
+                           dbs[dbcnt].clear_cache = 1;
+                           pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
+                           pthread_cond_signal (&dbs[dbcnt].prune_cond);
+                           break;
+                         }
+                   }
+
+                 --n;
+               }
+
+             first = 2;
+           }
+#endif
+
+         for (size_t cnt = first; cnt < nused && n > 0; ++cnt)
            if (conns[cnt].revents != 0)
              {
                fd_ready (conns[cnt].fd);
@@ -1816,6 +1893,18 @@ main_loop_epoll (int efd)
     /* We cannot use epoll.  */
     return;
 
+#ifdef HAVE_INOTIFY
+  if (inotify_fd != -1)
+    {
+      ev.events = EPOLLRDNORM;
+      ev.data.fd = inotify_fd;
+      if (epoll_ctl (efd, EPOLL_CTL_ADD, inotify_fd, &ev) == -1)
+       /* We cannot use epoll.  */
+       return;
+      nused = 2;
+    }
+#endif
+
   while (1)
     {
       struct epoll_event revs[100];
@@ -1852,6 +1941,32 @@ main_loop_epoll (int efd)
                  }
              }
          }
+#ifdef HAVE_INOTIFY
+       else if (revs[cnt].data.fd == inotify_fd)
+         {
+           union
+           {
+             struct inotify_event i;
+             char buf[100];
+           } inev;
+
+           while (TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
+                                            sizeof (inev)))
+                  >= sizeof (struct inotify_event))
+             {
+               /* Check which of the files changed.  */
+               for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
+                 if (inev.i.wd == dbs[dbcnt].inotify_descr)
+                   {
+                     pthread_mutex_trylock (&dbs[dbcnt].prune_lock);
+                     dbs[dbcnt].clear_cache = 1;
+                     pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
+                     pthread_cond_signal (&dbs[dbcnt].prune_cond);
+                     break;
+                   }
+             }
+         }
+#endif
        else
          {
            /* Remove the descriptor from the epoll descriptor.  */
index b07256d..5c77dd3 100644 (file)
@@ -73,6 +73,8 @@ struct database_dyn
 
   int enabled;
   int check_file;
+  int inotify_descr;
+  int clear_cache;
   int persistent;
   int shared;
   int propagate;
index f99db1c..cae0774 100644 (file)
@@ -1097,11 +1097,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
 
          if (__builtin_expect (buflen < sizeof (struct gaih_addrtuple),
                                0))
-           {
-             *errnop = ERANGE;
-             *h_errnop = NETDB_INTERNAL;
-             return NSS_STATUS_TRYAGAIN;
-           }
+           goto too_small;
 
          *pat = (struct gaih_addrtuple *) buffer;
          buffer += sizeof (struct gaih_addrtuple);
@@ -1175,11 +1171,17 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
                                  &pat, &buffer, &buflen,
                                  errnop, h_errnop, ttlp,
                                  &first);
-  if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
+  if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
+       || status == NSS_STATUS_TRYAGAIN)
       && answer2 != NULL && anslen2 > 0)
-    status = gaih_getanswer_slice(answer2, anslen2, qname,
-                                 &pat, &buffer, &buflen,
-                                 errnop, h_errnop, ttlp, &first);
+    {
+      enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
+                                                    &pat, &buffer, &buflen,
+                                                    errnop, h_errnop, ttlp,
+                                                    &first);
+      if (status != NSS_STATUS_SUCCESS)
+       status = status2;
+    }
 
   return status;
 }
index ebacccc..d73749e 100644 (file)
@@ -1,5 +1,5 @@
 /* lround function.  PowerPC32 version.
-   Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -65,10 +65,10 @@ ENTRY (__lround)
        fabs    fp2, fp1        /* Get the absolute value of x.  */
        fsub    fp12,fp10,fp10  /* Compute 0.0.  */
        fcmpu   cr6, fp2, fp10  /* if |x| < 0.5  */
-       fcmpu   cr3, fp1, fp12  /* x is negative? x < 0.0  */
+       fcmpu   cr7, fp1, fp12  /* x is negative? x < 0.0  */
        blt-    cr6,.Lretzero
        fadd    fp3,fp2,fp10    /* |x|+=0.5 bias to prepare to round.  */
-       bge     cr3,.Lconvert   /* x is positive so don't negate x.  */
+       bge     cr7,.Lconvert   /* x is positive so don't negate x.  */
        fnabs   fp3,fp3         /* -(|x|+=0.5)  */ 
 .Lconvert:
        fctiwz  fp4,fp3         /* Convert to Integer word lround toward 0.  */
index 4b1691e..e10a379 100644 (file)
@@ -1,5 +1,5 @@
 /* llround function.  PowerPC32 on PowerPC64 version.
-   Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -75,12 +75,12 @@ ENTRY (__llround)
        fabs    fp2,fp1         /* Get the absolute value of x.  */
        fsub    fp12,fp10,fp10  /* Compute 0.0 into fpr12.  */
        fcmpu   cr6,fp2,fp10    /* if |x| < 0.5  */
-       fcmpu   cr4,fp2,fp9     /* if |x| >= 2^52  */
-       fcmpu   cr3,fp1,fp12    /* x is negative? x < 0.0  */
+       fcmpu   cr7,fp2,fp9     /* if |x| >= 2^52  */
+       fcmpu   cr1,fp1,fp12    /* x is negative? x < 0.0  */
        blt-    cr6,.Lretzero   /* 0.5 > x < -0.5 so just return 0.  */
-       bge-    cr4,.Lnobias    /* 2^52 > x < -2^52 just convert with no bias.  */
+       bge-    cr7,.Lnobias    /* 2^52 > x < -2^52 just convert with no bias.  */
        fadd    fp3,fp2,fp10    /* |x|+=0.5 bias to prepare to round.  */
-       bge     cr3,.Lconvert   /* x is positive so don't negate x.  */
+       bge     cr1,.Lconvert   /* x is positive so don't negate x.  */
        fnabs   fp3,fp3         /* -(|x|+=0.5)  */
 .Lconvert:
        fctidz  fp4,fp3         /* Convert to Integer double word round toward 0.  */
index 4134847..cdfdd02 100644 (file)
@@ -1,5 +1,5 @@
 /* llround function.  PowerPC64 version.
-   Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -52,12 +52,12 @@ ENTRY (__llround)
        fabs    fp2,fp1         /* Get the absolute value of x.  */
        fsub    fp12,fp10,fp10  /* Compute 0.0 into fp12.  */
        fcmpu   cr6,fp2,fp10    /* if |x| < 0.5  */
-       fcmpu   cr4,fp2,fp9     /* if |x| >= 2^52  */
-       fcmpu   cr3,fp1,fp12    /* x is negative? x < 0.0  */
+       fcmpu   cr7,fp2,fp9     /* if |x| >= 2^52  */
+       fcmpu   cr1,fp1,fp12    /* x is negative? x < 0.0  */
        blt-    cr6,.Lretzero   /* 0.5 > x < -0.5 so just return 0.  */
-       bge-    cr4,.Lnobias    /* 2^52 > x < -2^52 just convert with no bias.  */
+       bge-    cr7,.Lnobias    /* 2^52 > x < -2^52 just convert with no bias.  */
        fadd    fp3,fp2,fp10    /* |x|+=0.5 bias to prepare to round.  */
-       bge     cr3,.Lconvert   /* x is positive so don't negate x.  */
+       bge     cr1,.Lconvert   /* x is positive so don't negate x.  */
        fnabs   fp3,fp3         /* -(|x|+=0.5)  */
 .Lconvert:
        fctidz  fp4,fp3         /* Convert to Integer double word round toward 0.  */
index a211879..e617bca 100644 (file)
@@ -1,5 +1,5 @@
 /* llroundf function.  PowerPC64 version.
-   Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -51,12 +51,12 @@ ENTRY (__llroundf)
        fabs    fp2,fp1         /* Get the absolute value of x.  */
        fsub    fp12,fp10,fp10  /* Compute 0.0 into fp12.  */
        fcmpu   cr6,fp2,fp10    /* if |x| < 0.5  */
-       fcmpu   cr4,fp2,fp9     /* if |x| >= 2^23  */
-       fcmpu   cr3,fp1,fp12    /* x is negative? x < 0.0  */
+       fcmpu   cr7,fp2,fp9     /* if |x| >= 2^23  */
+       fcmpu   cr1,fp1,fp12    /* x is negative? x < 0.0  */
        blt-    cr6,.Lretzero   /* 0.5 > x < -0.5 so just return 0.  */
-       bge-    cr4,.Lnobias    /* 2^23 > x < -2^23 just convert with no bias.  */
+       bge-    cr7,.Lnobias    /* 2^23 > x < -2^23 just convert with no bias.  */
        fadd    fp3,fp2,fp10    /* |x|+=0.5 bias to prepare to round.  */
-       bge     cr3,.Lconvert   /* x is positive so don't negate x.  */
+       bge     cr1,.Lconvert   /* x is positive so don't negate x.  */
        fnabs   fp3,fp3         /* -(|x|+=0.5)  */
 .Lconvert:
        fctidz  fp4,fp3         /* Convert to Integer double word round toward 0.  */
index ddbb4f6..c93538c 100644 (file)
@@ -154,7 +154,7 @@ CFLAGS-mq_receive.c += -fexceptions
 endif
 
 ifeq ($(subdir),nscd)
-CFLAGS-connections.c += -DHAVE_EPOLL -DHAVE_SENDFILE
+CFLAGS-connections.c += -DHAVE_EPOLL -DHAVE_SENDFILE -DHAVE_INOTIFY
 CFLAGS-pwdcache.c += -DHAVE_SENDFILE
 CFLAGS-grpcache.c += -DHAVE_SENDFILE
 CFLAGS-hstcache.c += -DHAVE_SENDFILE
index 4a57b15..f1d3303 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2004, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -455,7 +455,8 @@ static CHAR_T const month_name[][10] =
 #endif
 
 static size_t __strftime_internal (CHAR_T *, size_t, const CHAR_T *,
-                                  const struct tm *, bool ut_argument_spec_iso
+                                  const struct tm *, bool *
+                                  ut_argument_spec_iso
                                   LOCALE_PARAM_PROTO) __THROW;
 
 /* Write information from TP into S according to the format
@@ -481,7 +482,8 @@ my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
   tmcopy = *tp;
   tp = &tmcopy;
 #endif
-  return __strftime_internal (s, maxsize, format, tp, false
+  bool tzset_called = false;
+  return __strftime_internal (s, maxsize, format, tp, &tzset_called
                              ut_argument LOCALE_ARG);
 }
 #ifdef _LIBC
@@ -495,7 +497,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
       size_t maxsize;
       const CHAR_T *format;
       const struct tm *tp;
-      bool tzset_called;
+      bool *tzset_called;
       ut_argument_spec
       LOCALE_PARAM_DECL
 {
@@ -563,16 +565,6 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
       if (! (zone && *zone))
        zone = "GMT";
     }
-  else
-    {
-      /* POSIX.1 requires that local time zone information is used as
-        though strftime called tzset.  */
-# if HAVE_TZSET
-      if (!tzset_called)
-       tzset ();
-      tzset_called = true;
-# endif
-    }
 #endif
 
   if (hour12 > 12)
@@ -1325,7 +1317,18 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
 #if HAVE_TZNAME
          /* The tzset() call might have changed the value.  */
          if (!(zone && *zone) && tp->tm_isdst >= 0)
-           zone = tzname[tp->tm_isdst];
+           {
+             /* POSIX.1 requires that local time zone information is used as
+                though strftime called tzset.  */
+# if HAVE_TZSET
+             if (!*tzset_called)
+               {
+                 tzset ();
+                 *tzset_called = true;
+               }
+# endif
+             zone = tzname[tp->tm_isdst];
+           }
 #endif
          if (! zone)
            zone = "";
@@ -1361,6 +1364,16 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
                struct tm ltm;
                time_t lt;
 
+               /* POSIX.1 requires that local time zone information is used as
+                  though strftime called tzset.  */
+# if HAVE_TZSET
+               if (!*tzset_called)
+                 {
+                   tzset ();
+                   *tzset_called = true;
+                 }
+# endif
+
                ltm = *tp;
                lt = mktime (&ltm);