maint: update copyright
[gnulib.git] / lib / gettimeofday.c
index e0afa49..aa8cbee 100644 (file)
@@ -1,12 +1,6 @@
-/* Provide gettimeofday
-   1. for systems that don't have it,
-   2. for some systems where gettimeofday clobbers the static buffer that
-      localtime uses for it's return value.  The gettimeofday function from
-      Mac OS X 10.0.4, i.e. Darwin 1.3.7 has this problem.
-      The tzset replacement is necessary for at least Solaris 2.5, 2.5.1, and
-      2.6.
+/* Provide gettimeofday for systems that don't have it or for which it's broken.
 
-   Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2005-2007, 2009-2014 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 /* written by Jim Meyering */
 
 #include <config.h>
 
 /* Specification.  */
-#include "gettimeofday.h"
+#include <sys/time.h>
 
-#include <sys/types.h>
-#include <stdlib.h>
+#include <time.h>
 
 #if HAVE_SYS_TIMEB_H
 # include <sys/timeb.h>
 #endif
 
-#if GETTIMEOFDAY_CLOBBERS_LOCALTIME
+#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
 
-static struct tm *localtime_buffer_addr;
+/* Work around the bug in some systems whereby gettimeofday clobbers
+   the static buffer that localtime uses for its return value.  The
+   gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
+   this problem.  The tzset replacement is necessary for at least
+   Solaris 2.5, 2.5.1, and 2.6.  */
+
+static struct tm tm_zero_buffer;
+static struct tm *localtime_buffer_addr = &tm_zero_buffer;
+
+# undef localtime
+extern struct tm *localtime (time_t const *);
+
+# undef gmtime
+extern struct tm *gmtime (time_t const *);
 
 /* This is a wrapper for localtime.  It is used only on systems for which
    gettimeofday clobbers the static buffer used for localtime's result.
@@ -47,13 +52,11 @@ static struct tm *localtime_buffer_addr;
    localtime uses for its result.  */
 
 struct tm *
-localtime (const time_t *timep)
-#undef localtime
+rpl_localtime (time_t const *timep)
 {
-  extern struct tm *localtime (const time_t *);
   struct tm *tm = localtime (timep);
 
-  if (! localtime_buffer_addr)
+  if (localtime_buffer_addr == &tm_zero_buffer)
     localtime_buffer_addr = tm;
 
   return tm;
@@ -61,96 +64,91 @@ localtime (const time_t *timep)
 
 /* Same as above, since gmtime and localtime use the same buffer.  */
 struct tm *
-gmtime (const time_t *timep)
-#undef gmtime
+rpl_gmtime (time_t const *timep)
 {
-  extern struct tm *gmtime (const time_t *);
   struct tm *tm = gmtime (timep);
 
-  if (! localtime_buffer_addr)
+  if (localtime_buffer_addr == &tm_zero_buffer)
     localtime_buffer_addr = tm;
 
   return tm;
 }
 
-/* This is a wrapper for tzset. It is used only on systems for which
-   tzset may clobber the static buffer used for localtime's result.
-   Save and restore the contents of the buffer used for localtime's
-   result around the call to tzset.  */
-void
-tzset (void)
-#undef tzset
-{
-  extern struct tm *localtime (const time_t *);
-  extern void tzset (void);
-  struct tm save;
+#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */
 
-  if (! localtime_buffer_addr)
-    {
-      time_t t = 0;
-      localtime_buffer_addr = localtime (&t);
-    }
+#if TZSET_CLOBBERS_LOCALTIME
 
-  save = *localtime_buffer_addr;
+# undef tzset
+extern void tzset (void);
+
+/* This is a wrapper for tzset, for systems on which tzset may clobber
+   the static buffer used for localtime's result.  */
+void
+rpl_tzset (void)
+{
+  /* Save and restore the contents of the buffer used for localtime's
+     result around the call to tzset.  */
+  struct tm save = *localtime_buffer_addr;
   tzset ();
   *localtime_buffer_addr = save;
 }
-
 #endif
 
-/* This is a wrapper for gettimeofday.  
-   It is used only on systems that lack this function, or for whose 
-   implementation of this function causes problems. */
+/* This is a wrapper for gettimeofday.  It is used only on systems
+   that lack this function, or whose implementation of this function
+   causes problems.  */
 
 int
 gettimeofday (struct timeval *restrict tv, void *restrict tz)
-#undef gettimeofday
 {
+#undef gettimeofday
 #if HAVE_GETTIMEOFDAY
 # if GETTIMEOFDAY_CLOBBERS_LOCALTIME
-  extern struct tm *localtime (const time_t *);
-  extern int gettimeofday (/* unspecified arguments */);
-
-  /* Save and restore the contents of the buffer used for localtime's result
-     around the call to gettimeofday. */
-  struct tm save;
-  int result;
+  /* Save and restore the contents of the buffer used for localtime's
+     result around the call to gettimeofday.  */
+  struct tm save = *localtime_buffer_addr;
+# endif
 
-  if (! localtime_buffer_addr)
+# if defined timeval /* 'struct timeval' overridden by gnulib?  */
+#  undef timeval
+  struct timeval otv;
+  int result = gettimeofday (&otv, (struct timezone *) tz);
+  if (result == 0)
     {
-      time_t t = 0;
-      localtime_buffer_addr = localtime (&t);
+      tv->tv_sec = otv.tv_sec;
+      tv->tv_usec = otv.tv_usec;
     }
+# else
+  int result = gettimeofday (tv, (struct timezone *) tz);
+# endif
 
-  save = *localtime_buffer_addr;
-  result = gettimeofday (tv, tz);
+# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
   *localtime_buffer_addr = save;
+# endif
 
   return result;
 
-# endif
 #else
+
 # if HAVE__FTIME
 
   struct _timeb timebuf;
-  
   _ftime (&timebuf);
   tv->tv_sec = timebuf.time;
   tv->tv_usec = timebuf.millitm * 1000;
 
-  return 0;
-
 # else
 
-  time_t t = time (NULL);
-  
-  if (t == (time_t) -1)
-    return -1;
-  tv->tv_sec = t;
+#  if !defined OK_TO_USE_1S_CLOCK
+#   error "Only 1-second nominal clock resolution found.  Is that intended?" \
+          "If so, compile with the -DOK_TO_USE_1S_CLOCK option."
+#  endif
+  tv->tv_sec = time (NULL);
   tv->tv_usec = 0;
 
+# endif
+
   return 0;
 
-# endif
 #endif
 }