Apache HTTPD
time.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr_portable.h"
18#include "apr_time.h"
19#include "apr_lib.h"
20#include "apr_private.h"
21#include "apr_strings.h"
22
23/* private APR headers */
24#include "apr_arch_internal_time.h"
25
26/* System Headers required for time library */
27#if APR_HAVE_SYS_TIME_H
28#include <sys/time.h>
29#endif
30#if APR_HAVE_UNISTD_H
31#include <unistd.h>
32#endif
33#ifdef HAVE_TIME_H
34#include <time.h>
35#endif
36/* End System Headers */
37
38#if !defined(HAVE_STRUCT_TM_TM_GMTOFF) && !defined(HAVE_STRUCT_TM___TM_GMTOFF)
40#define NO_GMTOFF_IN_STRUCT_TM
41#endif
42
43static apr_int32_t get_offset(struct tm *tm)
44{
45#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
46 return tm->tm_gmtoff;
47#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
48 return tm->__tm_gmtoff;
49#else
50#ifdef NETWARE
51 /* Need to adjust the global variable each time otherwise
52 the web server would have to be restarted when daylight
53 savings changes.
54 */
55 if (daylightOnOff) {
57 }
58#else
59 if (tm->tm_isdst)
60 return server_gmt_offset + 3600;
61#endif
62 return server_gmt_offset;
63#endif
64}
65
72
73/* NB NB NB NB This returns GMT!!!!!!!!!! */
75{
76 struct timeval tv;
78 return tv.tv_sec * (apr_time_t)APR_USEC_PER_SEC + (apr_time_t)tv.tv_usec;
79}
80
83{
84 struct tm tm;
87
88#if APR_HAS_THREADS && defined (_POSIX_THREAD_SAFE_FUNCTIONS)
89 if (use_localtime)
90 localtime_r(&tt, &tm);
91 else
92 gmtime_r(&tt, &tm);
93#else
94 if (use_localtime)
95 tm = *localtime(&tt);
96 else
97 tm = *gmtime(&tt);
98#endif
99
100 xt->tm_sec = tm.tm_sec;
101 xt->tm_min = tm.tm_min;
102 xt->tm_hour = tm.tm_hour;
103 xt->tm_mday = tm.tm_mday;
104 xt->tm_mon = tm.tm_mon;
105 xt->tm_year = tm.tm_year;
106 xt->tm_wday = tm.tm_wday;
107 xt->tm_yday = tm.tm_yday;
108 xt->tm_isdst = tm.tm_isdst;
109 xt->tm_gmtoff = get_offset(&tm);
110}
111
114{
116 result->tm_gmtoff = offs;
117 return APR_SUCCESS;
118}
119
122{
123 return apr_time_exp_tz(result, input, 0);
124}
125
128{
129#if defined(__EMX__)
130 /* EMX gcc (OS/2) has a timezone global we can use */
132#else
133 explode_time(result, input, 0, 1);
134 return APR_SUCCESS;
135#endif /* __EMX__ */
136}
137
139{
140 apr_time_t year = xt->tm_year;
142 static const int dayoffset[12] =
143 {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
144
145 if (xt->tm_mon < 0 || xt->tm_mon >= 12)
146 return APR_EBADDATE;
147
148 /* shift new year to 1st March in order to make leap year calc easy */
149
150 if (xt->tm_mon < 2)
151 year--;
152
153 /* Find number of days since 1st March 1900 (in the Gregorian calendar). */
154
155 days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
156 days += dayoffset[xt->tm_mon] + xt->tm_mday - 1;
157 days -= 25508; /* 1 jan 1970 is 25508 days since 1 mar 1900 */
158 days = ((days * 24 + xt->tm_hour) * 60 + xt->tm_min) * 60 + xt->tm_sec;
159
160 if (days < 0) {
161 return APR_EBADDATE;
162 }
163 *t = days * APR_USEC_PER_SEC + xt->tm_usec;
164 return APR_SUCCESS;
165}
166
168 apr_time_exp_t *xt)
169{
171 if (status == APR_SUCCESS)
173 return status;
174}
175
178{
179 (*ostime)->tv_usec = *aprtime % APR_USEC_PER_SEC;
180 (*ostime)->tv_sec = *aprtime / APR_USEC_PER_SEC;
181 return APR_SUCCESS;
182}
183
186{
187 (*ostime)->tm_sec = aprtime->tm_sec;
188 (*ostime)->tm_min = aprtime->tm_min;
189 (*ostime)->tm_hour = aprtime->tm_hour;
190 (*ostime)->tm_mday = aprtime->tm_mday;
191 (*ostime)->tm_mon = aprtime->tm_mon;
192 (*ostime)->tm_year = aprtime->tm_year;
193 (*ostime)->tm_wday = aprtime->tm_wday;
194 (*ostime)->tm_yday = aprtime->tm_yday;
195 (*ostime)->tm_isdst = aprtime->tm_isdst;
196
197#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
198 (*ostime)->tm_gmtoff = aprtime->tm_gmtoff;
199#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
200 (*ostime)->__tm_gmtoff = aprtime->tm_gmtoff;
201#endif
202
203 return APR_SUCCESS;
204}
205
209{
210 *aprtime = (*ostime)->tv_sec * APR_USEC_PER_SEC + (*ostime)->tv_usec;
211 return APR_SUCCESS;
212}
213
217{
218 aprtime->tm_sec = (*ostime)->tm_sec;
219 aprtime->tm_min = (*ostime)->tm_min;
220 aprtime->tm_hour = (*ostime)->tm_hour;
221 aprtime->tm_mday = (*ostime)->tm_mday;
222 aprtime->tm_mon = (*ostime)->tm_mon;
223 aprtime->tm_year = (*ostime)->tm_year;
224 aprtime->tm_wday = (*ostime)->tm_wday;
225 aprtime->tm_yday = (*ostime)->tm_yday;
226 aprtime->tm_isdst = (*ostime)->tm_isdst;
227
228#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
229 aprtime->tm_gmtoff = (*ostime)->tm_gmtoff;
230#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
231 aprtime->tm_gmtoff = (*ostime)->__tm_gmtoff;
232#endif
233
234 return APR_SUCCESS;
235}
236
238{
239#ifdef OS2
240 DosSleep(t/1000);
241#elif defined(BEOS)
242 snooze(t);
243#elif defined(NETWARE)
244 delay(t/1000);
245#else
246 struct timeval tv;
247 tv.tv_usec = t % APR_USEC_PER_SEC;
248 tv.tv_sec = t / APR_USEC_PER_SEC;
249 select(0, NULL, NULL, NULL, &tv);
250#endif
251}
252
253#ifdef OS2
257{
258 struct tm tmpdate;
259
260 memset(&tmpdate, 0, sizeof(tmpdate));
261 tmpdate.tm_hour = os2time.hours;
262 tmpdate.tm_min = os2time.minutes;
263 tmpdate.tm_sec = os2time.twosecs * 2;
264
265 tmpdate.tm_mday = os2date.day;
266 tmpdate.tm_mon = os2date.month - 1;
267 tmpdate.tm_year = os2date.year + 80;
268 tmpdate.tm_isdst = -1;
269
271 return APR_SUCCESS;
272}
273
275 FTIME *os2time,
277{
279 struct tm *lt;
281 os2time->hours = lt->tm_hour;
282 os2time->minutes = lt->tm_min;
283 os2time->twosecs = lt->tm_sec / 2;
284
285 os2date->day = lt->tm_mday;
286 os2date->month = lt->tm_mon + 1;
287 os2date->year = lt->tm_year - 80;
288 return APR_SUCCESS;
289}
290#endif
291
292#ifdef NETWARE
294{
295 tzset();
297}
298#else
300{
301#ifdef NO_GMTOFF_IN_STRUCT_TM
302 /* Precompute the offset from GMT on systems where it's not
303 in struct tm.
304
305 Note: This offset is normalized to be independent of daylight
306 savings time; if the calculation happens to be done in a
307 time/place where a daylight savings adjustment is in effect,
308 the returned offset has the same value that it would have
309 in the same location if daylight savings were not in effect.
310 The reason for this is that the returned offset can be
311 applied to a past or future timestamp in explode_time(),
312 so the DST adjustment obtained from the current time won't
313 necessarily be applicable.
314
315 mktime() is the inverse of localtime(); so, presumably,
316 passing in a struct tm made by gmtime() let's us calculate
317 the true GMT offset. However, there's a catch: if daylight
318 savings is in effect, gmtime()will set the tm_isdst field
319 and confuse mktime() into returning a time that's offset
320 by one hour. In that case, we must adjust the calculated GMT
321 offset.
322
323 */
324
325 struct timeval now;
326 time_t t1, t2;
327 struct tm t;
328
330 t1 = now.tv_sec;
331 t2 = 0;
332
333#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
334 gmtime_r(&t1, &t);
335#else
336 t = *gmtime(&t1);
337#endif
338 t.tm_isdst = 0; /* we know this GMT time isn't daylight-savings */
339 t2 = mktime(&t);
341#endif /* NO_GMTOFF_IN_STRUCT_TM */
342}
343
344#endif
345
346/* A noop on all known Unix implementations */
348{
349 return;
350}
351
352
#define select
APR general purpose library routines.
APR Portability Routines.
APR Strings library.
APR Time Library.
#define APR_EBADDATE
Definition apr_errno.h:293
apr_size_t size
const char * input
Definition apr_cstr.h:93
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_seek_where_t apr_off_t * offset
apr_array_header_t ** result
apr_pool_t * cont
Definition apr_getopt.h:103
APR_DECLARE(void)
Definition time.c:237
apr_interval_time_t t
struct tm apr_os_exp_time_t
struct timeval apr_os_imp_time_t
apr_time_exp_t * aprtime
apr_os_imp_time_t ** ostime
int int status
apr_size_t apr_size_t const char apr_time_exp_t * tm
Definition apr_time.h:221
apr_time_t apr_int32_t offs
Definition apr_time.h:142
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
#define APR_USEC_PER_SEC
Definition apr_time.h:60
apr_int64_t apr_time_t
Definition apr_time.h:45
apr_pool_t * p
Definition md_event.c:32
return NULL
Definition mod_so.c:359
void apr_netware_setup_time(void)
#define TZONE
apr_status_t apr_os2_time_to_apr_time(apr_time_t *result, FDATE os2date, FTIME os2time)
apr_status_t apr_apr_time_to_os2_time(FDATE *os2date, FTIME *os2time, apr_time_t aprtime)
apr_int32_t tm_gmtoff
Definition apr_time.h:119
apr_int32_t tm_sec
Definition apr_time.h:101
apr_int32_t tm_hour
Definition apr_time.h:105
apr_int32_t tm_year
Definition apr_time.h:111
apr_int32_t tm_isdst
Definition apr_time.h:117
apr_int32_t tm_min
Definition apr_time.h:103
apr_int32_t tm_wday
Definition apr_time.h:113
apr_int32_t tm_mday
Definition apr_time.h:107
apr_int32_t tm_mon
Definition apr_time.h:109
apr_int32_t tm_yday
Definition apr_time.h:115
apr_int32_t tm_usec
Definition apr_time.h:99
static apr_table_t * t1
Definition testtable.c:34
static apr_time_t now
Definition testtime.c:33
void apr_unix_setup_time(void)
static apr_int32_t server_gmt_offset
Definition time.c:39
static void explode_time(apr_time_exp_t *xt, apr_time_t t, apr_int32_t offset, int use_localtime)
Definition time.c:81
static apr_int32_t get_offset(struct tm *tm)
Definition time.c:43