[svn] Check for timegm and use it where available.

This commit is contained in:
hniksic 2005-06-27 06:22:30 -07:00
parent 0561a866c3
commit bb8a5f2eb9
5 changed files with 81 additions and 71 deletions

View File

@ -204,7 +204,7 @@ dnl
AC_FUNC_ALLOCA
AC_FUNC_MMAP
AC_FUNC_FSEEKO
AC_CHECK_FUNCS(strptime snprintf vsnprintf)
AC_CHECK_FUNCS(strptime timegm snprintf vsnprintf)
AC_CHECK_FUNCS(usleep ftello sigblock sigsetjmp symlink)
dnl We expect to have these functions on Unix-like systems configure

View File

@ -1,3 +1,9 @@
2005-06-27 Hrvoje Niksic <hniksic@xemacs.org>
* http.c (mktime_from_utc): Renamed to timegm and moved to cmpt.c.
Don't compile it if GNU timegm is available.
(http_atotm): Use timegm.
2005-06-27 Hrvoje Niksic <hniksic@xemacs.org>
* http.c (http_atotm): Correctly query the old locale value.

View File

@ -1222,3 +1222,71 @@ fnmatch (const char *pattern, const char *string, int flags)
}
#endif /* not SYSTEM_FNMATCH */
#ifndef HAVE_TIMEGM
/* timegm is a GNU extension typically unavailable on non-glibc-based
platforms. */
/* Inverse of gmtime: converts struct tm to time_t, assuming the data
in tm is UTC rather than local timezone.
mktime is similar but assumes struct tm, also known as the
"broken-down" form of time, is in local time zone. This
implementation of timegm uses mktime to make the conversion
understanding that an offset will be introduced by the local time
assumption.
timegm then measures the introduced offset by applying gmtime to
the initial result and applying mktime to the resulting
"broken-down" form. The difference between the two mktime results
is the measured offset which is then subtracted from the initial
mktime result to yield a calendar time which is the value returned.
tm_isdst in struct tm is set to 0 to force mktime to introduce a
consistent offset (the non DST offset) since tm and tm+o might be
on opposite sides of a DST change.
Some implementations of mktime return -1 for the nonexistent
localtime hour at the beginning of DST. In this event, use
mktime(tm - 1hr) + 3600.
Schematically
mktime(tm) --> t+o
gmtime(t+o) --> tm+o
mktime(tm+o) --> t+2o
t+o - (t+2o - t+o) = t
Contributed by Roger Beeman <beeman@cisco.com>, with the help of
Mark Baushke <mdb@cisco.com> and other experts at CISCO. Further
improved by Roger with assistance from Edward J. Sabol based on
input by Jamie Zawinski. */
time_t
timegm (struct tm *t)
{
time_t tl, tb;
struct tm *tg;
tl = mktime (t);
if (tl == -1)
{
t->tm_hour--;
tl = mktime (t);
if (tl == -1)
return -1; /* can't deal with contents of T */
tl += 3600;
}
tg = gmtime (&tl);
tg->tm_isdst = 0;
tb = mktime (tg);
if (tb == -1)
{
tg->tm_hour--;
tb = mktime (tg);
if (tb == -1)
return -1; /* can't deal with output from gmtime */
tb += 3600;
}
return (tl - (tb - tl));
}
#endif /* HAVE_TIMEGM */

View File

@ -2501,74 +2501,6 @@ The sizes do not match (local %s) -- retrieving.\n"),
return TRYLIMEXC;
}
/* Converts struct tm to time_t, assuming the data in tm is UTC rather
than local timezone.
mktime is similar but assumes struct tm, also known as the
"broken-down" form of time, is in local time zone. mktime_from_utc
uses mktime to make the conversion understanding that an offset
will be introduced by the local time assumption.
mktime_from_utc then measures the introduced offset by applying
gmtime to the initial result and applying mktime to the resulting
"broken-down" form. The difference between the two mktime results
is the measured offset which is then subtracted from the initial
mktime result to yield a calendar time which is the value returned.
tm_isdst in struct tm is set to 0 to force mktime to introduce a
consistent offset (the non DST offset) since tm and tm+o might be
on opposite sides of a DST change.
Some implementations of mktime return -1 for the nonexistent
localtime hour at the beginning of DST. In this event, use
mktime(tm - 1hr) + 3600.
Schematically
mktime(tm) --> t+o
gmtime(t+o) --> tm+o
mktime(tm+o) --> t+2o
t+o - (t+2o - t+o) = t
Note that glibc contains a function of the same purpose named
`timegm' (reverse of gmtime). But obviously, it is not universally
available, and unfortunately it is not straightforwardly
extractable for use here. Perhaps configure should detect timegm
and use it where available.
Contributed by Roger Beeman <beeman@cisco.com>, with the help of
Mark Baushke <mdb@cisco.com> and the rest of the Gurus at CISCO.
Further improved by Roger with assistance from Edward J. Sabol
based on input by Jamie Zawinski. */
static time_t
mktime_from_utc (struct tm *t)
{
time_t tl, tb;
struct tm *tg;
tl = mktime (t);
if (tl == -1)
{
t->tm_hour--;
tl = mktime (t);
if (tl == -1)
return -1; /* can't deal with output from strptime */
tl += 3600;
}
tg = gmtime (&tl);
tg->tm_isdst = 0;
tb = mktime (tg);
if (tb == -1)
{
tg->tm_hour--;
tb = mktime (tg);
if (tb == -1)
return -1; /* can't deal with output from gmtime */
tb += 3600;
}
return (tl - (tb - tl));
}
/* Check whether the result of strptime() indicates success.
strptime() returns the pointer to how far it got to in the string.
The processing has been successful if the string is at `GMT' or
@ -2652,12 +2584,12 @@ http_atotm (const char *time_string)
/* Some versions of strptime use the existing contents of struct
tm to recalculate the date according to format. Zero it out
to prevent garbage from the stack influencing strptime. */
to prevent stack garbage from influencing strptime. */
xzero (t);
if (check_end (strptime (time_string, time_formats[i], &t)))
{
ret = mktime_from_utc (&t);
ret = timegm (&t);
break;
}
}

View File

@ -131,6 +131,10 @@ int strncasecmp ();
#ifndef HAVE_STRPTIME
char *strptime ();
#endif
#ifndef HAVE_TIMEGM
# include <time.h>
time_t timegm (struct tm *);
#endif
/* These are defined in snprintf.c. It would be nice to have an
snprintf.h, though. */