1 /* Provide gettimeofday
2 1. for systems that don't have it,
3 2. for some systems where gettimeofday clobbers the static buffer that
4 localtime uses for it's return value. The gettimeofday function from
5 Mac OS X 10.0.4, i.e. Darwin 1.3.7 has this problem.
6 The tzset replacement is necessary for at least Solaris 2.5, 2.5.1, and
9 Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
25 /* written by Jim Meyering */
30 #include "gettimeofday.h"
32 #include <sys/types.h>
36 # include <sys/timeb.h>
39 #if GETTIMEOFDAY_CLOBBERS_LOCALTIME
41 static struct tm *localtime_buffer_addr;
43 /* This is a wrapper for localtime. It is used only on systems for which
44 gettimeofday clobbers the static buffer used for localtime's result.
46 On the first call, record the address of the static buffer that
47 localtime uses for its result. */
50 localtime (const time_t *timep)
53 extern struct tm *localtime (const time_t *);
54 struct tm *tm = localtime (timep);
56 if (! localtime_buffer_addr)
57 localtime_buffer_addr = tm;
62 /* Same as above, since gmtime and localtime use the same buffer. */
64 gmtime (const time_t *timep)
67 extern struct tm *gmtime (const time_t *);
68 struct tm *tm = gmtime (timep);
70 if (! localtime_buffer_addr)
71 localtime_buffer_addr = tm;
76 /* This is a wrapper for tzset. It is used only on systems for which
77 tzset may clobber the static buffer used for localtime's result.
78 Save and restore the contents of the buffer used for localtime's
79 result around the call to tzset. */
84 extern struct tm *localtime (const time_t *);
85 extern void tzset (void);
88 if (! localtime_buffer_addr)
91 localtime_buffer_addr = localtime (&t);
94 save = *localtime_buffer_addr;
96 *localtime_buffer_addr = save;
101 /* This is a wrapper for gettimeofday.
102 It is used only on systems that lack this function, or for whose
103 implementation of this function causes problems. */
106 gettimeofday (struct timeval *restrict tv, void *restrict tz)
109 #if HAVE_GETTIMEOFDAY
110 extern int gettimeofday (/* unspecified arguments */);
111 # if GETTIMEOFDAY_CLOBBERS_LOCALTIME
112 extern struct tm *localtime (const time_t *);
114 /* Save and restore the contents of the buffer used for localtime's result
115 around the call to gettimeofday. */
119 if (! localtime_buffer_addr)
122 localtime_buffer_addr = localtime (&t);
125 save = *localtime_buffer_addr;
126 result = gettimeofday (tv, tz);
127 *localtime_buffer_addr = save;
133 return gettimeofday (tv, tz);
138 /* The clock does not have microsecond resolution, so get the maximum
139 possible value for the current time that is consistent with the
140 reported clock. That way, files are not considered to be in the
141 future merely because their time stamps have higher resolution
142 than the clock resolution. */
146 struct _timeb timebuf;
149 tv->tv_sec = timebuf.time;
150 tv->tv_usec = timebuf.millitm * 1000 + 999;
156 time_t t = time (NULL);
158 if (t == (time_t) -1)
161 tv->tv_usec = 999999;