Home | History | Annotate | Line # | Download | only in lib
gettimeofday.c revision 1.2
      1  1.1  christos /* Work around the bug in some systems whereby gettimeofday clobbers the
      2  1.1  christos    static buffer that localtime uses for it's return value.  The gettimeofday
      3  1.1  christos    function from Mac OS X 10.0.4, i.e. Darwin 1.3.7 has this problem.
      4  1.1  christos    The tzset replacement is necessary for at least Solaris 2.5, 2.5.1, and 2.6.
      5  1.1  christos    Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 2, or (at your option)
     10  1.1  christos    any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program; if not, write to the Free Software Foundation,
     19  1.1  christos    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
     20  1.2  christos #include <sys/cdefs.h>
     21  1.2  christos __RCSID("$NetBSD: gettimeofday.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
     22  1.2  christos 
     23  1.1  christos 
     24  1.1  christos /* written by Jim Meyering */
     25  1.1  christos 
     26  1.1  christos #ifdef HAVE_CONFIG_H
     27  1.1  christos # include <config.h>
     28  1.1  christos #endif
     29  1.1  christos 
     30  1.1  christos /* Disable the definitions of these functions (from config.h)
     31  1.1  christos    so we can use the library versions here.  */
     32  1.1  christos #undef gettimeofday
     33  1.1  christos #undef gmtime
     34  1.1  christos #undef localtime
     35  1.1  christos #undef tzset
     36  1.1  christos 
     37  1.1  christos #include <sys/types.h>
     38  1.1  christos 
     39  1.1  christos #if TIME_WITH_SYS_TIME
     40  1.1  christos # include <sys/time.h>
     41  1.1  christos # include <time.h>
     42  1.1  christos #else
     43  1.1  christos # if HAVE_SYS_TIME_H
     44  1.1  christos #  include <sys/time.h>
     45  1.1  christos # else
     46  1.1  christos #  include <time.h>
     47  1.1  christos # endif
     48  1.1  christos #endif
     49  1.1  christos 
     50  1.1  christos #include <stdlib.h>
     51  1.1  christos 
     52  1.1  christos static struct tm *localtime_buffer_addr;
     53  1.1  christos 
     54  1.1  christos /* This is a wrapper for localtime.  It is used only on systems for which
     55  1.1  christos    gettimeofday clobbers the static buffer used for localtime's result.
     56  1.1  christos 
     57  1.1  christos    On the first call, record the address of the static buffer that
     58  1.1  christos    localtime uses for its result.  */
     59  1.1  christos 
     60  1.1  christos struct tm *
     61  1.1  christos rpl_localtime (const time_t *timep)
     62  1.1  christos {
     63  1.1  christos   struct tm *tm = localtime (timep);
     64  1.1  christos 
     65  1.1  christos   if (! localtime_buffer_addr)
     66  1.1  christos     localtime_buffer_addr = tm;
     67  1.1  christos 
     68  1.1  christos   return tm;
     69  1.1  christos }
     70  1.1  christos 
     71  1.1  christos /* Same as above, since gmtime and localtime use the same buffer.  */
     72  1.1  christos struct tm *
     73  1.1  christos rpl_gmtime (const time_t *timep)
     74  1.1  christos {
     75  1.1  christos   struct tm *tm = gmtime (timep);
     76  1.1  christos 
     77  1.1  christos   if (! localtime_buffer_addr)
     78  1.1  christos     localtime_buffer_addr = tm;
     79  1.1  christos 
     80  1.1  christos   return tm;
     81  1.1  christos }
     82  1.1  christos 
     83  1.1  christos /* This is a wrapper for gettimeofday.  It is used only on systems for which
     84  1.1  christos    gettimeofday clobbers the static buffer used for localtime's result.
     85  1.1  christos 
     86  1.1  christos    Save and restore the contents of the buffer used for localtime's result
     87  1.1  christos    around the call to gettimeofday.  */
     88  1.1  christos 
     89  1.1  christos int
     90  1.1  christos rpl_gettimeofday (struct timeval *tv, struct timezone *tz)
     91  1.1  christos {
     92  1.1  christos   struct tm save;
     93  1.1  christos   int result;
     94  1.1  christos 
     95  1.1  christos   if (! localtime_buffer_addr)
     96  1.1  christos     {
     97  1.1  christos       time_t t = 0;
     98  1.1  christos       localtime_buffer_addr = localtime (&t);
     99  1.1  christos     }
    100  1.1  christos 
    101  1.1  christos   save = *localtime_buffer_addr;
    102  1.1  christos   result = gettimeofday (tv, tz);
    103  1.1  christos   *localtime_buffer_addr = save;
    104  1.1  christos 
    105  1.1  christos   return result;
    106  1.1  christos }
    107  1.1  christos 
    108  1.1  christos /* This is a wrapper for tzset. It is used only on systems for which
    109  1.1  christos    tzset may clobber the static buffer used for localtime's result.
    110  1.1  christos    Save and restore the contents of the buffer used for localtime's
    111  1.1  christos    result around the call to tzset.  */
    112  1.1  christos void
    113  1.1  christos rpl_tzset (void)
    114  1.1  christos {
    115  1.1  christos   struct tm save;
    116  1.1  christos 
    117  1.1  christos   if (! localtime_buffer_addr)
    118  1.1  christos     {
    119  1.1  christos       time_t t = 0;
    120  1.1  christos       localtime_buffer_addr = localtime (&t);
    121  1.1  christos     }
    122  1.1  christos 
    123  1.1  christos   save = *localtime_buffer_addr;
    124  1.1  christos   tzset ();
    125  1.1  christos   *localtime_buffer_addr = save;
    126  1.1  christos }
    127