+2003-09-06 Paul Eggert <eggert@twinsun.com>
+
+ * MODULES.html.sh (func_all_modules): Add time_r.
+ * modules/time_r: New file.
+ * modules/mktime, modules/strftime, modules/timegm: Depend on time_r.
+ * modules/timegm: Depend on mktime. Change maintainer to "all, glibc".
+
2003-08-31 Simon Josefsson <jas@extundo.com>
* modules/timegm: New file.
func_module readlink
func_module stat
func_module lstat
+ func_module time_r
func_module timespec
func_module nanosleep
func_module regex
+2003-09-06 Paul Eggert <eggert@twinsun.com>
+
+ * time_r.c, time_r.h: New files.
+
+ * mktime.c (my_mktime_localtime_r): Remove; all uses changed to
+ __localtime_r.
+ (__localtime_r) [!defined _LIBC]: New macro. Include <time_r.h>.
+ (__mktime_internal) [!defined _LIBC]: Now extern, not static.
+
+ * strftime.c (my_strftime_gmtime_r): Remove; all uses changed to
+ __gmtime_r.
+ (my_strftime_localtime_r): Remove; all uses changed to __localtime_r.
+ (__gtime_r, __localtime_r) [!HAVE_TM_GMTOFF]: New macros.
+ Include <time_r.h>.
+
+ * timegm.c: Switch to glibc implementation, with the following changes:
+ [defined HAVE_CONFIG_H]: Include <config.h>.
+ [!defined _LIBC]: Include "timegm.h" rather than <time.h>.
+ (__mktime_internal) [!defined _LIBC]: New decl.
+ (__gmtime_r) [!defined _LIBC]: New macro and function.
+ (timegm): Use a prototype, since gnulib assumes C89.
+ Do not bother declaring tmp to be const, as it's not really usefu.
+ * timegm.h: Hoist "#include <time.h>" out of #ifdef.
+ (timegm): Declare only if HAVE_DECL_TIMEGM.
+
2003-09-03 Paul Eggert <eggert@twinsun.com>
* human.c (human_readable): Fix bug that rounded 10501 to 10k.
};
-#ifdef _LIBC
-# define my_mktime_localtime_r __localtime_r
-#else
-/* If we're a mktime substitute in a GNU program, then prefer
- localtime to localtime_r, since many localtime_r implementations
- are buggy. */
-static struct tm *
-my_mktime_localtime_r (const time_t *t, struct tm *tp)
-{
- struct tm *l = localtime (t);
- if (! l)
- return 0;
- *tp = *l;
- return tp;
-}
-#endif /* ! _LIBC */
+#ifndef _LIBC
+/* Portable standalone applications should supply a "time_r.h" that
+ declares a POSIX-compliant localtime_r, for the benefit of older
+ implementations that lack localtime_r or have a nonstandard one.
+ See the gnulib time_r module for one way to implement this. */
+# include "time_r.h"
+# undef __localtime_r
+# define __localtime_r localtime_r
+#endif
/* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
(YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
Use *OFFSET to keep track of a guess at the offset of the result,
compared to what the result would be for UTC without leap seconds.
If *OFFSET's guess is correct, only one CONVERT call is needed. */
-#ifndef _LIBC
-static
-#endif
time_t
__mktime_internal (struct tm *tp,
struct tm *(*convert) (const time_t *, struct tm *),
__tzset ();
#endif
- return __mktime_internal (tp, my_mktime_localtime_r, &localtime_offset);
+ return __mktime_internal (tp, __localtime_r, &localtime_offset);
}
#ifdef weak_alias
#ifdef _LIBC
-# define my_strftime_gmtime_r __gmtime_r
-# define my_strftime_localtime_r __localtime_r
# define tzname __tzname
# define tzset __tzset
-#else
-
-/* If we're a strftime substitute in a GNU program, then prefer gmtime
- to gmtime_r, since many gmtime_r implementations are buggy.
- Similarly for localtime_r. */
-
-# if ! HAVE_TM_GMTOFF
-static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
-static struct tm *
-my_strftime_gmtime_r (t, tp)
- const time_t *t;
- struct tm *tp;
-{
- struct tm *l = gmtime (t);
- if (! l)
- return 0;
- *tp = *l;
- return tp;
-}
+#endif
-static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
-static struct tm *
-my_strftime_localtime_r (t, tp)
- const time_t *t;
- struct tm *tp;
-{
- struct tm *l = localtime (t);
- if (! l)
- return 0;
- *tp = *l;
- return tp;
-}
-# endif /* ! HAVE_TM_GMTOFF */
-#endif /* ! defined _LIBC */
+#if !HAVE_TM_GMTOFF
+/* Portable standalone applications should supply a "time_r.h" that
+ declares a POSIX-compliant localtime_r, for the benefit of older
+ implementations that lack localtime_r or have a nonstandard one.
+ See the gnulib time_r module for one way to implement this. */
+# include "time_r.h"
+# undef __gmtime_r
+# undef __localtime_r
+# define __gmtime_r gmtime_r
+# define __localtime_r localtime_r
+#endif
#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
occurred. */
struct tm tm;
- if (! my_strftime_localtime_r (<, &tm)
+ if (! __localtime_r (<, &tm)
|| ((ltm.tm_sec ^ tm.tm_sec)
| (ltm.tm_min ^ tm.tm_min)
| (ltm.tm_hour ^ tm.tm_hour)
break;
}
- if (! my_strftime_gmtime_r (<, >m))
+ if (! __gmtime_r (<, >m))
break;
diff = tm_diff (<m, >m);
--- /dev/null
+/* Reentrant time functions like localtime_r.
+
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "time_r.h"
+
+#include <string.h>
+
+static char *
+copy_string_result (char *dest, char const *src)
+{
+ if (! src)
+ return 0;
+ return strcpy (dest, src);
+}
+
+static struct tm *
+copy_tm_result (struct tm *dest, struct tm const *src)
+{
+ if (! src)
+ return 0;
+ *dest = *src;
+ return dest;
+}
+
+
+char *
+asctime_r (struct tm const * restrict tm, char * restrict buf)
+{
+ return copy_string_result (buf, asctime (tm));
+}
+
+char *
+ctime_r (time_t const *t, char *buf)
+{
+ return copy_string_result (buf, ctime (t));
+}
+
+struct tm *
+gmtime_r (time_t const * restrict t, struct tm * restrict tp)
+{
+ return copy_tm_result (gmtime (t));
+}
+
+struct tm *
+localtime_r (time_t const * restrict t, struct tm * restrict tp)
+{
+ return copy_tm_result (localtime (t));
+}
--- /dev/null
+/* Reentrant time functions like localtime_r.
+
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#ifndef _TIME_R_H
+#define _TIME_R_H
+
+/* Include <time.h> first, since it may declare these functions with
+ signatures that disagree with POSIX, and we don't want to rename
+ those declarations. */
+#include <time.h>
+
+#if !HAVE_TIME_R_POSIX
+# undef asctime_r
+# undef ctime_r
+# undef gmtime_r
+# undef localtime_r
+
+# define asctime_r rpl_asctime_r
+# define ctime_r rpl_ctime_r
+# define gmtime_r rpl_gmtime_r
+# define localtime_r rpl_localtime_r
+
+char *asctime_r (struct tm const * restrict, char * restrict);
+char *ctime_r (time_t const *, char *);
+struct tm *gmtime_r (time_t const * restrict, struct tm * restrict);
+struct tm *localtime_r (time_t const * restrict, struct tm * restrict);
+#endif
+
+#endif
-/* Convert calendar time to simple time, inverse of mktime.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2003
- Free Software Foundation, Inc.
+/* Convert UTC calendar time to simple time. Like mktime but assumes UTC.
+
+ Copyright (C) 1994, 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
-/* Specification. Get mktime and gmtime declarations. */
-#include "timegm.h"
-
-/* 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. */
+#ifdef _LIBC
+# include <time.h>
+#else
+# include "timegm.h"
+# include <time_r.h>
+# undef __gmtime_r
+# define __gmtime_r gmtime_r
+time_t __mktime_internal (struct tm *,
+ struct tm * (*) (time_t const *, struct tm *),
+ time_t *);
+#endif
time_t
-timegm (struct tm *tm)
+timegm (struct tm *tmp)
{
- time_t tl, tb;
- struct tm *tg;
-
- tl = mktime (tm);
- if (tl == (time_t) -1)
- {
- tm->tm_hour--;
- tl = mktime (tm);
- if (tl == (time_t) -1)
- return (time_t) -1;
- tl += 3600;
- }
-#if HAVE_GMTIME_R && HAVE_DECL_GMTIME_R
- tg = gmtime_r (&tl, tg);
-#else
- tg = gmtime (&tl);
-#endif
- tg->tm_isdst = 0;
- tb = mktime (tg);
- if (tb == (time_t) -1)
- {
- tg->tm_hour--;
- tb = mktime (tg);
- if (tb == (time_t) -1)
- return (time_t) -1;
- tb += 3600;
- }
- return (tl - (tb - tl));
+ static time_t gmtime_offset;
+ tmp->tm_isdst = 0;
+ return __mktime_internal (tmp, __gmtime_r, &gmtime_offset);
}
-/* Convert calendar time to simple time, inverse of mktime.
+/* Convert UTC calendar time to simple time. Like mktime but assumes UTC.
+
Copyright (C) 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ifdef HAVE_TIMEGM
-
-/* Get timegm declaration. */
-#include <time.h>
-
-#else
-
-/* Get time_t and struct tm. */
#include <time.h>
-/* Convert calendar time to simple time, inverse of mktime. */
-extern time_t timegm (struct tm *tm);
-
+#ifndef HAVE_DECL_TIMEGM
+time_t timegm (struct tm *tm);
#endif
+2003-09-06 Paul Eggert <eggert@twinsun.com>
+
+ * time_4.m4: New file.
+ * mktime.m4 (gl_PREREQ_MKTIME): Remove check for limits.h.
+ * timegm.m4 (gl_FUNC_TIMEGM): Assume that timegm is buggy if mktime is.
+ Check for timegm declaration.
+ (gl_PREREQ_TIMEGM): Require gl_FUNC_MKTIME.
+ Do not check for gmtime_r.
+ Replace mktime if __mktime_internal does not exist and if mktime
+ hasn't been replaced already.
+
2003-08-31 Simon Josefsson <jas@extundo.com>
* timegm.m4: New file.
-# mktime.m4 serial 2
+# mktime.m4 serial 3
dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc.
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
# Prerequisites of lib/mktime.c.
AC_DEFUN([gl_PREREQ_MKTIME], [
AC_REQUIRE([AC_HEADER_STDC])
- AC_CHECK_HEADERS_ONCE(limits.h)
])
--- /dev/null
+dnl Reentrant time functions like localtime_r.
+
+dnl Copyright (C) 2003 Free Software Foundation, Inc.
+
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+dnl Written by Paul Eggert.
+
+AC_DEFUN([gl_TIME_R],
+[
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([gl_C_RESTRICT])
+
+ AC_CACHE_CHECK([whether localtime_r is compatible with its POSIX signature],
+ [gl_cv_time_r_posix],
+ [AC_TRY_COMPILE(
+ [#include <time.h>],
+ [/* We don't need to append 'restrict's to the argument types,
+ even though the POSIX signature has the 'restrict's,
+ since C99 says they can't affect type compatibility. */
+ struct tm * (*ptr) (time_t const *, struct tm *) = localtime_r;],
+ [gl_cv_time_r_posix=yes],
+ [gl_cv_time_r_posix=no])])
+ if test $gl_cv_time_r_posix = yes; then
+ AC_DEFINE([HAVE_TIME_R_POSIX], 1,
+ [Define to 1 if localtime_r, etc. have the type signatures that
+ POSIX requires.])
+ else
+ AC_LIBOBJ([time_r])
+ gl_PREREQ_TIME_R
+ fi
+])
+
+# Prerequisites of lib/time_r.c.
+AC_DEFUN([gl_PREREQ_TIME_R], [
+ :
+])
-# timegm.m4 serial 1
+# timegm.m4 serial 2
dnl Copyright (C) 2003 Free Software Foundation, Inc.
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
AC_DEFUN([gl_FUNC_TIMEGM],
[
- AC_REPLACE_FUNCS(timegm)
+ AC_REQUIRE([gl_FUNC_MKTIME])
+ if test $ac_cv_func_working_mktime = no; then
+ # Assume that timegm is buggy if mktime is.
+ AC_LIBOBJ([timegm])
+ ac_cv_func_timegm=no
+ else
+ AC_REPLACE_FUNCS(timegm)
+ fi
if test $ac_cv_func_timegm = no; then
gl_PREREQ_TIMEGM
fi
+
+ AC_CHECK_DECLS([timegm], , , [#include <time.h>])
])
# Prerequisites of lib/timegm.c.
AC_DEFUN([gl_PREREQ_TIMEGM], [
- AC_CHECK_DECLS(gmtime_r,,,[
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-])
- AC_CHECK_FUNCS(gmtime_r)
+ AC_REQUIRE([gl_TIME_R])
+ AC_REQUIRE([gl_FUNC_MKTIME])
+ if test $ac_cv_func_working_mktime = yes; then
+ AC_CHECK_FUNC(__mktime_internal, ,
+ [# mktime works but it doesn't export __mktime_internal,
+ # so we need to substitute our own mktime implementation.
+ AC_LIBOBJ([mktime])
+ AC_DEFINE([mktime], [rpl_mktime],
+ [Define to rpl_mktime if the replacement function should be used.])
+ gl_PREREQ_MKTIME])
+ fi
])
m4/mktime.m4
Depends-on:
+time_r
configure.ac:
gl_FUNC_MKTIME
m4/strftime.m4
Depends-on:
+time_r
tzset
configure.ac:
--- /dev/null
+Description:
+Reentrant time functions like localtime_r.
+
+Files:
+lib/time_r.c
+lib/time_r.h
+m4/time_r.m4
+
+Depends-on:
+extensions
+
+configure.ac:
+gl_TIME_R
+
+Makefile.am:
+lib_SOURCES += time_r.h
+
+Include:
+<time_r.h>
+
+Maintainer:
+Paul Eggert
+
m4/timegm.m4
Depends-on:
+mktime
+time_r
configure.ac:
gl_FUNC_TIMEGM
"timegm.h"
Maintainer:
-Simon Josefsson
+all, glibc