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