~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/time/unix/time.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * 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)
 
39
static apr_int32_t server_gmt_offset;
 
40
#define NO_GMTOFF_IN_STRUCT_TM
 
41
#endif          
 
42
 
 
43
static 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) {
 
56
        return server_gmt_offset + daylightOffset;
 
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
 
 
66
APR_DECLARE(apr_status_t) apr_time_ansi_put(apr_time_t *result,
 
67
                                            time_t input)
 
68
{
 
69
    *result = (apr_time_t)input * APR_USEC_PER_SEC;
 
70
    return APR_SUCCESS;
 
71
}
 
72
 
 
73
/* NB NB NB NB This returns GMT!!!!!!!!!! */
 
74
APR_DECLARE(apr_time_t) apr_time_now(void)
 
75
{
 
76
    struct timeval tv;
 
77
    gettimeofday(&tv, NULL);
 
78
    return tv.tv_sec * APR_USEC_PER_SEC + tv.tv_usec;
 
79
}
 
80
 
 
81
static void explode_time(apr_time_exp_t *xt, apr_time_t t,
 
82
                         apr_int32_t offset, int use_localtime)
 
83
{
 
84
    struct tm tm;
 
85
    time_t tt = (t / APR_USEC_PER_SEC) + offset;
 
86
    xt->tm_usec = t % APR_USEC_PER_SEC;
 
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
 
 
112
APR_DECLARE(apr_status_t) apr_time_exp_tz(apr_time_exp_t *result,
 
113
                                          apr_time_t input, apr_int32_t offs)
 
114
{
 
115
    explode_time(result, input, offs, 0);
 
116
    result->tm_gmtoff = offs;
 
117
    return APR_SUCCESS;
 
118
}
 
119
 
 
120
APR_DECLARE(apr_status_t) apr_time_exp_gmt(apr_time_exp_t *result,
 
121
                                           apr_time_t input)
 
122
{
 
123
    return apr_time_exp_tz(result, input, 0);
 
124
}
 
125
 
 
126
APR_DECLARE(apr_status_t) apr_time_exp_lt(apr_time_exp_t *result,
 
127
                                                apr_time_t input)
 
128
{
 
129
#if defined(__EMX__)
 
130
    /* EMX gcc (OS/2) has a timezone global we can use */
 
131
    return apr_time_exp_tz(result, input, -timezone);
 
132
#else
 
133
    explode_time(result, input, 0, 1);
 
134
    return APR_SUCCESS;
 
135
#endif /* __EMX__ */
 
136
}
 
137
 
 
138
APR_DECLARE(apr_status_t) apr_time_exp_get(apr_time_t *t, apr_time_exp_t *xt)
 
139
{
 
140
    apr_time_t year = xt->tm_year;
 
141
    apr_time_t days;
 
142
    static const int dayoffset[12] =
 
143
    {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
 
144
 
 
145
    /* shift new year to 1st March in order to make leap year calc easy */
 
146
 
 
147
    if (xt->tm_mon < 2)
 
148
        year--;
 
149
 
 
150
    /* Find number of days since 1st March 1900 (in the Gregorian calendar). */
 
151
 
 
152
    days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
 
153
    days += dayoffset[xt->tm_mon] + xt->tm_mday - 1;
 
154
    days -= 25508;              /* 1 jan 1970 is 25508 days since 1 mar 1900 */
 
155
    days = ((days * 24 + xt->tm_hour) * 60 + xt->tm_min) * 60 + xt->tm_sec;
 
156
 
 
157
    if (days < 0) {
 
158
        return APR_EBADDATE;
 
159
    }
 
160
    *t = days * APR_USEC_PER_SEC + xt->tm_usec;
 
161
    return APR_SUCCESS;
 
162
}
 
163
 
 
164
APR_DECLARE(apr_status_t) apr_time_exp_gmt_get(apr_time_t *t, 
 
165
                                               apr_time_exp_t *xt)
 
166
{
 
167
    apr_status_t status = apr_time_exp_get(t, xt);
 
168
    if (status == APR_SUCCESS)
 
169
        *t -= (apr_time_t) xt->tm_gmtoff * APR_USEC_PER_SEC;
 
170
    return status;
 
171
}
 
172
 
 
173
APR_DECLARE(apr_status_t) apr_os_imp_time_get(apr_os_imp_time_t **ostime,
 
174
                                              apr_time_t *aprtime)
 
175
{
 
176
    (*ostime)->tv_usec = *aprtime % APR_USEC_PER_SEC;
 
177
    (*ostime)->tv_sec = *aprtime / APR_USEC_PER_SEC;
 
178
    return APR_SUCCESS;
 
179
}
 
180
 
 
181
APR_DECLARE(apr_status_t) apr_os_exp_time_get(apr_os_exp_time_t **ostime,
 
182
                                              apr_time_exp_t *aprtime)
 
183
{
 
184
    (*ostime)->tm_sec  = aprtime->tm_sec;
 
185
    (*ostime)->tm_min  = aprtime->tm_min;
 
186
    (*ostime)->tm_hour = aprtime->tm_hour;
 
187
    (*ostime)->tm_mday = aprtime->tm_mday;
 
188
    (*ostime)->tm_mon  = aprtime->tm_mon;
 
189
    (*ostime)->tm_year = aprtime->tm_year;
 
190
    (*ostime)->tm_wday = aprtime->tm_wday;
 
191
    (*ostime)->tm_yday = aprtime->tm_yday;
 
192
    (*ostime)->tm_isdst = aprtime->tm_isdst;
 
193
 
 
194
#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
 
195
    (*ostime)->tm_gmtoff = aprtime->tm_gmtoff;
 
196
#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
 
197
    (*ostime)->__tm_gmtoff = aprtime->tm_gmtoff;
 
198
#endif
 
199
 
 
200
    return APR_SUCCESS;
 
201
}
 
202
 
 
203
APR_DECLARE(apr_status_t) apr_os_imp_time_put(apr_time_t *aprtime,
 
204
                                              apr_os_imp_time_t **ostime,
 
205
                                              apr_pool_t *cont)
 
206
{
 
207
    *aprtime = (*ostime)->tv_sec * APR_USEC_PER_SEC + (*ostime)->tv_usec;
 
208
    return APR_SUCCESS;
 
209
}
 
210
 
 
211
APR_DECLARE(apr_status_t) apr_os_exp_time_put(apr_time_exp_t *aprtime,
 
212
                                              apr_os_exp_time_t **ostime,
 
213
                                              apr_pool_t *cont)
 
214
{
 
215
    aprtime->tm_sec = (*ostime)->tm_sec;
 
216
    aprtime->tm_min = (*ostime)->tm_min;
 
217
    aprtime->tm_hour = (*ostime)->tm_hour;
 
218
    aprtime->tm_mday = (*ostime)->tm_mday;
 
219
    aprtime->tm_mon = (*ostime)->tm_mon;
 
220
    aprtime->tm_year = (*ostime)->tm_year;
 
221
    aprtime->tm_wday = (*ostime)->tm_wday;
 
222
    aprtime->tm_yday = (*ostime)->tm_yday;
 
223
    aprtime->tm_isdst = (*ostime)->tm_isdst;
 
224
 
 
225
#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
 
226
    aprtime->tm_gmtoff = (*ostime)->tm_gmtoff;
 
227
#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
 
228
    aprtime->tm_gmtoff = (*ostime)->__tm_gmtoff;
 
229
#endif
 
230
 
 
231
    return APR_SUCCESS;
 
232
}
 
233
 
 
234
APR_DECLARE(void) apr_sleep(apr_interval_time_t t)
 
235
{
 
236
#ifdef OS2
 
237
    DosSleep(t/1000);
 
238
#elif defined(BEOS)
 
239
    snooze(t);
 
240
#elif defined(NETWARE)
 
241
    delay(t/1000);
 
242
#else
 
243
    struct timeval tv;
 
244
    tv.tv_usec = t % APR_USEC_PER_SEC;
 
245
    tv.tv_sec = t / APR_USEC_PER_SEC;
 
246
    select(0, NULL, NULL, NULL, &tv);
 
247
#endif
 
248
}
 
249
 
 
250
#ifdef OS2
 
251
APR_DECLARE(apr_status_t) apr_os2_time_to_apr_time(apr_time_t *result,
 
252
                                                   FDATE os2date,
 
253
                                                   FTIME os2time)
 
254
{
 
255
  struct tm tmpdate;
 
256
 
 
257
  memset(&tmpdate, 0, sizeof(tmpdate));
 
258
  tmpdate.tm_hour  = os2time.hours;
 
259
  tmpdate.tm_min   = os2time.minutes;
 
260
  tmpdate.tm_sec   = os2time.twosecs * 2;
 
261
 
 
262
  tmpdate.tm_mday  = os2date.day;
 
263
  tmpdate.tm_mon   = os2date.month - 1;
 
264
  tmpdate.tm_year  = os2date.year + 80;
 
265
  tmpdate.tm_isdst = -1;
 
266
 
 
267
  *result = mktime(&tmpdate) * APR_USEC_PER_SEC;
 
268
  return APR_SUCCESS;
 
269
}
 
270
 
 
271
APR_DECLARE(apr_status_t) apr_apr_time_to_os2_time(FDATE *os2date,
 
272
                                                   FTIME *os2time,
 
273
                                                   apr_time_t aprtime)
 
274
{
 
275
    time_t ansitime = aprtime / APR_USEC_PER_SEC;
 
276
    struct tm *lt;
 
277
    lt = localtime(&ansitime);
 
278
    os2time->hours    = lt->tm_hour;
 
279
    os2time->minutes  = lt->tm_min;
 
280
    os2time->twosecs  = lt->tm_sec / 2;
 
281
 
 
282
    os2date->day      = lt->tm_mday;
 
283
    os2date->month    = lt->tm_mon + 1;
 
284
    os2date->year     = lt->tm_year - 80;
 
285
    return APR_SUCCESS;
 
286
}
 
287
#endif
 
288
 
 
289
#ifdef NETWARE
 
290
APR_DECLARE(void) apr_netware_setup_time(void)
 
291
{
 
292
    tzset();
 
293
    server_gmt_offset = -TZONE;
 
294
}
 
295
#else
 
296
APR_DECLARE(void) apr_unix_setup_time(void)
 
297
{
 
298
#ifdef NO_GMTOFF_IN_STRUCT_TM
 
299
    /* Precompute the offset from GMT on systems where it's not
 
300
       in struct tm.
 
301
 
 
302
       Note: This offset is normalized to be independent of daylight
 
303
       savings time; if the calculation happens to be done in a
 
304
       time/place where a daylight savings adjustment is in effect,
 
305
       the returned offset has the same value that it would have
 
306
       in the same location if daylight savings were not in effect.
 
307
       The reason for this is that the returned offset can be
 
308
       applied to a past or future timestamp in explode_time(),
 
309
       so the DST adjustment obtained from the current time won't
 
310
       necessarily be applicable.
 
311
 
 
312
       mktime() is the inverse of localtime(); so, presumably,
 
313
       passing in a struct tm made by gmtime() let's us calculate
 
314
       the true GMT offset. However, there's a catch: if daylight
 
315
       savings is in effect, gmtime()will set the tm_isdst field
 
316
       and confuse mktime() into returning a time that's offset
 
317
       by one hour. In that case, we must adjust the calculated GMT
 
318
       offset.
 
319
 
 
320
     */
 
321
 
 
322
    struct timeval now;
 
323
    time_t t1, t2;
 
324
    struct tm t;
 
325
 
 
326
    gettimeofday(&now, NULL);
 
327
    t1 = now.tv_sec;
 
328
    t2 = 0;
 
329
 
 
330
#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
 
331
    gmtime_r(&t1, &t);
 
332
#else
 
333
    t = *gmtime(&t1);
 
334
#endif
 
335
    t.tm_isdst = 0; /* we know this GMT time isn't daylight-savings */
 
336
    t2 = mktime(&t);
 
337
    server_gmt_offset = (apr_int32_t) difftime(t1, t2);
 
338
#endif /* NO_GMTOFF_IN_STRUCT_TM */
 
339
}
 
340
 
 
341
#endif
 
342
 
 
343
/* A noop on all known Unix implementations */
 
344
APR_DECLARE(void) apr_time_clock_hires(apr_pool_t *p)
 
345
{
 
346
    return;
 
347
}
 
348
 
 
349