X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fgettimeofday.c;h=e17812c6861e73613683b81b17236206ca7e3000;hb=66f5e6513c46dffcb40b216e3709b84ab5fbc392;hp=e0afa49cf30c9be49ad3ac8056ca3fc965109530;hpb=e5ba383c5c9684ed2abe901d35485b86725fbea8;p=gnulib.git diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c index e0afa49cf..e17812c68 100644 --- a/lib/gettimeofday.c +++ b/lib/gettimeofday.c @@ -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-2012 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 @@ -19,26 +13,37 @@ 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 . */ /* written by Jim Meyering */ #include /* Specification. */ -#include "gettimeofday.h" +#include -#include -#include +#include #if HAVE_SYS_TIMEB_H # include #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 }