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