Update from Gnulib

This incorporates:
2018-09-10 timespec: fix resolution confusion
2018-09-09 mktime: simplify in prep for glibc merge
2018-09-07 intprops: minor clarification of code
2018-09-06 stddef: Override max_align_t on NetBSD 8.0/x86
2018-09-06 fcntl: Fix F_DUPFD_CLOEXEC behaviour on Haiku
2018-09-06 strtoll, strtoull: Rely on limits-h module
2018-09-06 limits-h: Provide numerical limits macros
2018-09-06 fcntl: Don't access nonexistent optional argument
2018-09-02 mktime: fix unlikely race+overflow bug
2018-08-31 mktime, timegm: simplify glibc time64_t
2018-08-31 mktime, timegm: simplify merge to glibc
* build-aux/config.guess, build-aux/config.sub:
* lib/dtotimespec.c, lib/fcntl.c, lib/intprops.h:
* lib/limits.in.h, lib/mktime-internal.h, lib/mktime.c:
* lib/stat-time.h, lib/strtol.c, lib/timegm.c:
* lib/timespec-add.c, lib/timespec-sub.c, lib/timespec.h:
* lib/utimens.c, m4/limits-h.m4, m4/stddef_h.m4:
Copy from Gnulib.
This commit is contained in:
Paul Eggert 2018-09-10 21:16:03 -07:00
parent 0407733ef3
commit fc389d3a83
17 changed files with 814 additions and 640 deletions

View file

@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2018 Free Software Foundation, Inc.
timestamp='2018-08-02'
timestamp='2018-08-29'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -838,7 +838,7 @@ EOF
*:BSD/OS:*:*)
echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
exit ;;
arm*:FreeBSD:*:*)
arm:FreeBSD:*:*)
UNAME_PROCESSOR=`uname -p`
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \

916
build-aux/config.sub vendored

File diff suppressed because it is too large Load diff

View file

@ -32,20 +32,20 @@ dtotimespec (double sec)
if (! (TYPE_MINIMUM (time_t) < sec))
return make_timespec (TYPE_MINIMUM (time_t), 0);
else if (! (sec < 1.0 + TYPE_MAXIMUM (time_t)))
return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_RESOLUTION - 1);
return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1);
else
{
time_t s = sec;
double frac = TIMESPEC_RESOLUTION * (sec - s);
double frac = TIMESPEC_HZ * (sec - s);
long ns = frac;
ns += ns < frac;
s += ns / TIMESPEC_RESOLUTION;
ns %= TIMESPEC_RESOLUTION;
s += ns / TIMESPEC_HZ;
ns %= TIMESPEC_HZ;
if (ns < 0)
{
s--;
ns += TIMESPEC_RESOLUTION;
ns += TIMESPEC_HZ;
}
return make_timespec (s, ns);

View file

@ -329,6 +329,12 @@ rpl_fcntl (int fd, int action, /* arg */...)
result = dupfd (fd, target, O_CLOEXEC);
break;
#else /* HAVE_FCNTL */
# if defined __HAIKU__
/* On Haiku, the system fcntl (fd, F_DUPFD_CLOEXEC, target) sets
the FD_CLOEXEC flag on fd, not on target. Therefore avoid the
system fcntl in this case. */
# define have_dupfd_cloexec -1
# else
/* Try the system call first, if the headers claim it exists
(that is, if GNULIB_defined_F_DUPFD_CLOEXEC is 0), since we
may be running with a glibc that has the macro but with an
@ -343,10 +349,10 @@ rpl_fcntl (int fd, int action, /* arg */...)
if (0 <= result || errno != EINVAL)
{
have_dupfd_cloexec = 1;
# if REPLACE_FCHDIR
# if REPLACE_FCHDIR
if (0 <= result)
result = _gl_register_dup (fd, result);
# endif
# endif
}
else
{
@ -357,6 +363,7 @@ rpl_fcntl (int fd, int action, /* arg */...)
}
}
else
# endif
result = rpl_fcntl (fd, F_DUPFD, target);
if (0 <= result && have_dupfd_cloexec == -1)
{
@ -405,8 +412,183 @@ rpl_fcntl (int fd, int action, /* arg */...)
default:
{
#if HAVE_FCNTL
void *p = va_arg (arg, void *);
result = fcntl (fd, action, p);
switch (action)
{
#ifdef F_BARRIERFSYNC /* macOS */
case F_BARRIERFSYNC:
#endif
#ifdef F_CHKCLEAN /* macOS */
case F_CHKCLEAN:
#endif
#ifdef F_CLOSEM /* NetBSD, HP-UX */
case F_CLOSEM:
#endif
#ifdef F_FLUSH_DATA /* macOS */
case F_FLUSH_DATA:
#endif
#ifdef F_FREEZE_FS /* macOS */
case F_FREEZE_FS:
#endif
#ifdef F_FULLFSYNC /* macOS */
case F_FULLFSYNC:
#endif
#ifdef F_GETCONFINED /* macOS */
case F_GETCONFINED:
#endif
#ifdef F_GETDEFAULTPROTLEVEL /* macOS */
case F_GETDEFAULTPROTLEVEL:
#endif
#ifdef F_GETFD /* POSIX */
case F_GETFD:
#endif
#ifdef F_GETFL /* POSIX */
case F_GETFL:
#endif
#ifdef F_GETLEASE /* Linux */
case F_GETLEASE:
#endif
#ifdef F_GETNOSIGPIPE /* macOS */
case F_GETNOSIGPIPE:
#endif
#ifdef F_GETOWN /* POSIX */
case F_GETOWN:
#endif
#ifdef F_GETPIPE_SZ /* Linux */
case F_GETPIPE_SZ:
#endif
#ifdef F_GETPROTECTIONCLASS /* macOS */
case F_GETPROTECTIONCLASS:
#endif
#ifdef F_GETPROTECTIONLEVEL /* macOS */
case F_GETPROTECTIONLEVEL:
#endif
#ifdef F_GET_SEALS /* Linux */
case F_GET_SEALS:
#endif
#ifdef F_GETSIG /* Linux */
case F_GETSIG:
#endif
#ifdef F_MAXFD /* NetBSD */
case F_MAXFD:
#endif
#ifdef F_RECYCLE /* macOS */
case F_RECYCLE:
#endif
#ifdef F_SETFIFOENH /* HP-UX */
case F_SETFIFOENH:
#endif
#ifdef F_THAW_FS /* macOS */
case F_THAW_FS:
#endif
/* These actions take no argument. */
result = fcntl (fd, action);
break;
#ifdef F_ADD_SEALS /* Linux */
case F_ADD_SEALS:
#endif
#ifdef F_BADFD /* Solaris */
case F_BADFD:
#endif
#ifdef F_CHECK_OPENEVT /* macOS */
case F_CHECK_OPENEVT:
#endif
#ifdef F_DUP2FD /* FreeBSD, AIX, Solaris */
case F_DUP2FD:
#endif
#ifdef F_DUP2FD_CLOEXEC /* FreeBSD, Solaris */
case F_DUP2FD_CLOEXEC:
#endif
#ifdef F_DUP2FD_CLOFORK /* Solaris */
case F_DUP2FD_CLOFORK:
#endif
#ifdef F_DUPFD /* POSIX */
case F_DUPFD:
#endif
#ifdef F_DUPFD_CLOEXEC /* POSIX */
case F_DUPFD_CLOEXEC:
#endif
#ifdef F_DUPFD_CLOFORK /* Solaris */
case F_DUPFD_CLOFORK:
#endif
#ifdef F_GETXFL /* Solaris */
case F_GETXFL:
#endif
#ifdef F_GLOBAL_NOCACHE /* macOS */
case F_GLOBAL_NOCACHE:
#endif
#ifdef F_MAKECOMPRESSED /* macOS */
case F_MAKECOMPRESSED:
#endif
#ifdef F_MOVEDATAEXTENTS /* macOS */
case F_MOVEDATAEXTENTS:
#endif
#ifdef F_NOCACHE /* macOS */
case F_NOCACHE:
#endif
#ifdef F_NODIRECT /* macOS */
case F_NODIRECT:
#endif
#ifdef F_NOTIFY /* Linux */
case F_NOTIFY:
#endif
#ifdef F_OPLKACK /* IRIX */
case F_OPLKACK:
#endif
#ifdef F_OPLKREG /* IRIX */
case F_OPLKREG:
#endif
#ifdef F_RDAHEAD /* macOS */
case F_RDAHEAD:
#endif
#ifdef F_SETBACKINGSTORE /* macOS */
case F_SETBACKINGSTORE:
#endif
#ifdef F_SETCONFINED /* macOS */
case F_SETCONFINED:
#endif
#ifdef F_SETFD /* POSIX */
case F_SETFD:
#endif
#ifdef F_SETFL /* POSIX */
case F_SETFL:
#endif
#ifdef F_SETLEASE /* Linux */
case F_SETLEASE:
#endif
#ifdef F_SETNOSIGPIPE /* macOS */
case F_SETNOSIGPIPE:
#endif
#ifdef F_SETOWN /* POSIX */
case F_SETOWN:
#endif
#ifdef F_SETPIPE_SZ /* Linux */
case F_SETPIPE_SZ:
#endif
#ifdef F_SETPROTECTIONCLASS /* macOS */
case F_SETPROTECTIONCLASS:
#endif
#ifdef F_SETSIG /* Linux */
case F_SETSIG:
#endif
#ifdef F_SINGLE_WRITER /* macOS */
case F_SINGLE_WRITER:
#endif
/* These actions take an 'int' argument. */
{
int x = va_arg (arg, int);
result = fcntl (fd, action, x);
}
break;
default:
/* Other actions take a pointer argument. */
{
void *p = va_arg (arg, void *);
result = fcntl (fd, action, p);
}
break;
}
#else
errno = EINVAL;
#endif

View file

@ -342,8 +342,8 @@
Arguments should be free of side effects. */
#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \
op_result_overflow (a, b, \
_GL_INT_MINIMUM ((1 ? 0 : (b)) + (a)), \
_GL_INT_MAXIMUM ((1 ? 0 : (b)) + (a)))
_GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
_GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))
/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.
Return 1 if the result overflows. See above for restrictions. */

View file

@ -28,15 +28,32 @@
#ifndef _@GUARD_PREFIX@_LIMITS_H
#define _@GUARD_PREFIX@_LIMITS_H
/* For HP-UX 11.31. */
#if defined LONG_LONG_MIN && !defined LLONG_MIN
# define LLONG_MIN LONG_LONG_MIN
#ifndef LLONG_MIN
# if defined LONG_LONG_MIN /* HP-UX 11.31 */
# define LLONG_MIN LONG_LONG_MIN
# elif defined LONGLONG_MIN /* IRIX 6.5 */
# define LLONG_MIN LONGLONG_MIN
# elif defined __GNUC__
# define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL)
# endif
#endif
#if defined LONG_LONG_MAX && !defined LLONG_MAX
# define LLONG_MAX LONG_LONG_MAX
#ifndef LLONG_MAX
# if defined LONG_LONG_MAX /* HP-UX 11.31 */
# define LLONG_MAX LONG_LONG_MAX
# elif defined LONGLONG_MAX /* IRIX 6.5 */
# define LLONG_MAX LONGLONG_MAX
# elif defined __GNUC__
# define LLONG_MAX __LONG_LONG_MAX__
# endif
#endif
#if defined ULONG_LONG_MAX && !defined ULLONG_MAX
# define ULLONG_MAX ULONG_LONG_MAX
#ifndef ULLONG_MAX
# if defined ULONG_LONG_MAX /* HP-UX 11.31 */
# define ULLONG_MAX ULONG_LONG_MAX
# elif defined ULONGLONG_MAX /* IRIX 6.5 */
# define ULLONG_MAX ULONGLONG_MAX
# elif defined __GNUC__
# define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)
# endif
#endif
/* The number of usable bits in an unsigned or signed integer type
@ -53,6 +70,19 @@
#define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n))
#define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1))
#ifndef WORD_BIT
/* Assume 'int' is 32 bits wide. */
# define WORD_BIT 32
#endif
#ifndef LONG_BIT
/* Assume 'long' is 32 or 64 bits wide. */
# if LONG_MAX == INT_MAX
# define LONG_BIT 32
# else
# define LONG_BIT 64
# endif
#endif
/* Macros specified by ISO/IEC TS 18661-1:2014. */
#if (! defined ULLONG_WIDTH \

View file

@ -35,3 +35,19 @@ typedef int mktime_offset_t;
time_t mktime_internal (struct tm *,
struct tm * (*) (time_t const *, struct tm *),
mktime_offset_t *);
/* Although glibc source code uses leading underscores, Gnulib wants
ordinary names.
Portable standalone applications should supply a <time.h> that
declares a POSIX-compliant localtime_r, for the benefit of older
implementations that lack localtime_r or have a nonstandard one.
Similarly for gmtime_r. See the gnulib time_r module for one way
to implement this. */
#undef __gmtime_r
#undef __localtime_r
#define __gmtime_r gmtime_r
#define __localtime_r localtime_r
#define __mktime_internal mktime_internal

View file

@ -28,6 +28,8 @@
Macro/expression Which gnulib module This compilation unit
should define
_LIBC (glibc proper) mktime
NEED_MKTIME_WORKING mktime rpl_mktime
|| NEED_MKTIME_WINDOWS
@ -51,25 +53,70 @@
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <intprops.h>
#include <verify.h>
#if DEBUG_MKTIME
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
/* Make it work even if the system's libc has its own mktime routine. */
# undef mktime
# define mktime my_mktime
#endif /* DEBUG_MKTIME */
#ifndef NEED_MKTIME_INTERNAL
# define NEED_MKTIME_INTERNAL 0
#endif
#ifndef NEED_MKTIME_WINDOWS
# define NEED_MKTIME_WINDOWS 0
#endif
#ifndef NEED_MKTIME_WORKING
# define NEED_MKTIME_WORKING DEBUG_MKTIME
#endif
#if NEED_MKTIME_WINDOWS /* on native Windows */
# include <stdlib.h>
# include <string.h>
#include "mktime-internal.h"
#ifndef _LIBC
static void
my_tzset (void)
{
# if NEED_MKTIME_WINDOWS
/* Rectify the value of the environment variable TZ.
There are four possible kinds of such values:
- Traditional US time zone names, e.g. "PST8PDT". Syntax: see
<https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
- Time zone names based on geography, that contain one or more
slashes, e.g. "Europe/Moscow".
- Time zone names based on geography, without slashes, e.g.
"Singapore".
- Time zone names that contain explicit DST rules. Syntax: see
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
The Microsoft CRT understands only the first kind. It produces incorrect
results if the value of TZ is of the other kinds.
But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
of the second kind for most geographies, or of the first kind in a few
other geographies. If it is of the second kind, neutralize it. For the
Microsoft CRT, an absent or empty TZ means the time zone that the user
has set in the Windows Control Panel.
If the value of TZ is of the third or fourth kind -- Cygwin programs
understand these syntaxes as well --, it does not matter whether we
neutralize it or not, since these values occur only when a Cygwin user
has set TZ explicitly; this case is 1. rare and 2. under the user's
responsibility. */
const char *tz = getenv ("TZ");
if (tz != NULL && strchr (tz, '/') != NULL)
_putenv ("TZ=");
# elif HAVE_TZSET
tzset ();
# endif
}
# undef __tzset
# define __tzset() my_tzset ()
#endif
#if NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL || DEBUG_MKTIME
#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL
/* A signed type that can represent an integer number of years
multiplied by three times the number of seconds in a year. It is
@ -150,19 +197,6 @@ const unsigned short int __mon_yday[2][13] =
};
#ifdef _LIBC
typedef time_t mktime_offset_t;
#else
/* Portable standalone applications should supply a <time.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. */
# undef __localtime_r
# define __localtime_r localtime_r
# define __mktime_internal mktime_internal
# include "mktime-internal.h"
#endif
/* Do the values A and B differ according to the rules for tm_isdst?
A and B differ if one is zero and the other positive. */
static bool
@ -304,6 +338,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
return r;
}
/* Convert *TP to a time_t value, inverting
the monotonic and mostly-unit-linear conversion function CONVERT.
Use *OFFSET to keep track of a guess at the offset of the result,
@ -355,6 +390,7 @@ __mktime_internal (struct tm *tp,
long_int lmday = mday;
long_int yday = mon_yday + lmday;
mktime_offset_t off = *offset;
int negative_offset_guess;
int sec_requested = sec;
@ -372,7 +408,7 @@ __mktime_internal (struct tm *tp,
/* Invert CONVERT by probing. First assume the same offset as last
time. */
INT_SUBTRACT_WRAPV (0, *offset, &negative_offset_guess);
INT_SUBTRACT_WRAPV (0, off, &negative_offset_guess);
t0 = ydhms_diff (year, yday, hour, min, sec,
EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, negative_offset_guess);
@ -478,64 +514,28 @@ __mktime_internal (struct tm *tp,
return t;
}
#endif /* NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL || DEBUG_MKTIME */
#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */
#if NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS || DEBUG_MKTIME
# if NEED_MKTIME_WORKING || DEBUG_MKTIME
static mktime_offset_t localtime_offset;
# endif
#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
/* Convert *TP to a time_t value. */
time_t
mktime (struct tm *tp)
{
# if NEED_MKTIME_WINDOWS
/* Rectify the value of the environment variable TZ.
There are four possible kinds of such values:
- Traditional US time zone names, e.g. "PST8PDT". Syntax: see
<https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
- Time zone names based on geography, that contain one or more
slashes, e.g. "Europe/Moscow".
- Time zone names based on geography, without slashes, e.g.
"Singapore".
- Time zone names that contain explicit DST rules. Syntax: see
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
The Microsoft CRT understands only the first kind. It produces incorrect
results if the value of TZ is of the other kinds.
But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
of the second kind for most geographies, or of the first kind in a few
other geographies. If it is of the second kind, neutralize it. For the
Microsoft CRT, an absent or empty TZ means the time zone that the user
has set in the Windows Control Panel.
If the value of TZ is of the third or fourth kind -- Cygwin programs
understand these syntaxes as well --, it does not matter whether we
neutralize it or not, since these values occur only when a Cygwin user
has set TZ explicitly; this case is 1. rare and 2. under the user's
responsibility. */
const char *tz = getenv ("TZ");
if (tz != NULL && strchr (tz, '/') != NULL)
_putenv ("TZ=");
# endif
# if NEED_MKTIME_WORKING || DEBUG_MKTIME
# ifdef _LIBC
/* POSIX.1 8.1.1 requires that whenever mktime() is called, the
time zone names contained in the external variable 'tzname' shall
be set as if the tzset() function had been called. */
__tzset ();
# elif HAVE_TZSET
tzset ();
# endif
# if defined __LIBC || NEED_MKTIME_WORKING
static mktime_offset_t localtime_offset;
return __mktime_internal (tp, __localtime_r, &localtime_offset);
# else
# undef mktime
return mktime (tp);
# endif
}
#endif /* NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS || DEBUG_MKTIME */
#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
#ifdef weak_alias
weak_alias (mktime, timelocal)

View file

@ -213,7 +213,7 @@ stat_time_normalize (int result, struct stat *st _GL_UNUSED)
#if defined __sun && defined STAT_TIMESPEC
if (result == 0)
{
long int timespec_resolution = 1000000000;
long int timespec_hz = 1000000000;
short int const ts_off[] = { offsetof (struct stat, st_atim),
offsetof (struct stat, st_mtim),
offsetof (struct stat, st_ctim) };
@ -221,11 +221,11 @@ stat_time_normalize (int result, struct stat *st _GL_UNUSED)
for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++)
{
struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]);
long int q = ts->tv_nsec / timespec_resolution;
long int r = ts->tv_nsec % timespec_resolution;
long int q = ts->tv_nsec / timespec_hz;
long int r = ts->tv_nsec % timespec_hz;
if (r < 0)
{
r += timespec_resolution;
r += timespec_hz;
q--;
}
ts->tv_nsec = r;

View file

@ -117,35 +117,6 @@
# define STRTOL_LONG_MIN LLONG_MIN
# define STRTOL_LONG_MAX LLONG_MAX
# define STRTOL_ULONG_MAX ULLONG_MAX
/* The extra casts in the following macros work around compiler bugs,
e.g., in Cray C 5.0.3.0. */
/* True if the arithmetic type T is signed. */
# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
/* Minimum and maximum values for integer types.
These macros have undefined behavior for signed types that either
have padding bits or do not use two's complement. If this is a
problem for you, please let us know how to fix it for your host. */
/* The maximum and minimum values for the integer type T. */
# define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
# define TYPE_MAXIMUM(t) \
((t) (! TYPE_SIGNED (t) \
? (t) -1 \
: ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
# ifndef ULLONG_MAX
# define ULLONG_MAX TYPE_MAXIMUM (unsigned long long)
# endif
# ifndef LLONG_MAX
# define LLONG_MAX TYPE_MAXIMUM (long long int)
# endif
# ifndef LLONG_MIN
# define LLONG_MIN TYPE_MINIMUM (long long int)
# endif
# if __GNUC__ == 2 && __GNUC_MINOR__ < 7
/* Work around gcc bug with using this constant. */
static const unsigned long long int maxquad = ULLONG_MAX;

View file

@ -1,20 +1,21 @@
/* Convert UTC calendar time to simple time. Like mktime but assumes UTC.
Copyright (C) 1994, 1997, 2003-2004, 2006-2007, 2009-2018 Free Software
Foundation, Inc. This file is part of the GNU C Library.
Copyright (C) 1994-2018 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
The GNU C Library 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 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
The GNU C Library 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.
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, see <https://www.gnu.org/licenses/>. */
You should have received a copy of the GNU General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _LIBC
# include <config.h>
@ -22,14 +23,7 @@
#include <time.h>
#ifdef _LIBC
typedef time_t mktime_offset_t;
#else
# undef __gmtime_r
# define __gmtime_r gmtime_r
# define __mktime_internal mktime_internal
# include "mktime-internal.h"
#endif
#include "mktime-internal.h"
time_t
timegm (struct tm *tmp)

View file

@ -18,7 +18,7 @@
/* Written by Paul Eggert. */
/* Return the sum of two timespec values A and B. On overflow, return
an extremal value. This assumes 0 <= tv_nsec < TIMESPEC_RESOLUTION. */
an extremal value. This assumes 0 <= tv_nsec < TIMESPEC_HZ. */
#include <config.h>
#include "timespec.h"
@ -31,7 +31,7 @@ timespec_add (struct timespec a, struct timespec b)
time_t rs = a.tv_sec;
time_t bs = b.tv_sec;
int ns = a.tv_nsec + b.tv_nsec;
int nsd = ns - TIMESPEC_RESOLUTION;
int nsd = ns - TIMESPEC_HZ;
int rns = ns;
time_t tmin = TYPE_MINIMUM (time_t);
time_t tmax = TYPE_MAXIMUM (time_t);
@ -63,7 +63,7 @@ timespec_add (struct timespec a, struct timespec b)
{
high_overflow:
rs = tmax;
rns = TIMESPEC_RESOLUTION - 1;
rns = TIMESPEC_HZ - 1;
}
}

View file

@ -19,7 +19,7 @@
/* Return the difference between two timespec values A and B. On
overflow, return an extremal value. This assumes 0 <= tv_nsec <
TIMESPEC_RESOLUTION. */
TIMESPEC_HZ. */
#include <config.h>
#include "timespec.h"
@ -38,7 +38,7 @@ timespec_sub (struct timespec a, struct timespec b)
if (ns < 0)
{
rns = ns + TIMESPEC_RESOLUTION;
rns = ns + TIMESPEC_HZ;
if (bs < tmax)
bs++;
else if (- TYPE_SIGNED (time_t) < rs)
@ -63,7 +63,7 @@ timespec_sub (struct timespec a, struct timespec b)
else
{
rs = tmax;
rns = TIMESPEC_RESOLUTION - 1;
rns = TIMESPEC_HZ - 1;
}
}

View file

@ -35,11 +35,17 @@ extern "C" {
#include "verify.h"
/* Resolution of timespec timestamps (in units per second), and log
base 10 of the resolution. */
/* Inverse resolution of timespec timestamps (in units per second),
and log base 10 of the inverse resolution. */
enum { TIMESPEC_RESOLUTION = 1000000000 };
enum { LOG10_TIMESPEC_RESOLUTION = 9 };
enum { TIMESPEC_HZ = 1000000000 };
enum { LOG10_TIMESPEC_HZ = 9 };
/* Obsolescent names for backward compatibility.
They are misnomers, because TIMESPEC_RESOLUTION is not a resolution. */
enum { TIMESPEC_RESOLUTION = TIMESPEC_HZ };
enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ };
/* Return a timespec with seconds S and nanoseconds NS. */
@ -88,8 +94,8 @@ timespec_cmp (struct timespec a, struct timespec b)
/* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02). See:
https://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html */
assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_HZ);
assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_HZ);
return a.tv_nsec - b.tv_nsec;
}

View file

@ -91,11 +91,11 @@ validate_timespec (struct timespec timespec[2])
if ((timespec[0].tv_nsec != UTIME_NOW
&& timespec[0].tv_nsec != UTIME_OMIT
&& ! (0 <= timespec[0].tv_nsec
&& timespec[0].tv_nsec < TIMESPEC_RESOLUTION))
&& timespec[0].tv_nsec < TIMESPEC_HZ))
|| (timespec[1].tv_nsec != UTIME_NOW
&& timespec[1].tv_nsec != UTIME_OMIT
&& ! (0 <= timespec[1].tv_nsec
&& timespec[1].tv_nsec < TIMESPEC_RESOLUTION)))
&& timespec[1].tv_nsec < TIMESPEC_HZ)))
{
errno = EINVAL;
return -1;

View file

@ -11,14 +11,18 @@ AC_DEFUN_ONCE([gl_LIMITS_H],
[
gl_CHECK_NEXT_HEADERS([limits.h])
AC_CACHE_CHECK([whether limits.h has ULLONG_WIDTH etc.],
AC_CACHE_CHECK([whether limits.h has LLONG_MAX, WORD_BIT, ULLONG_WIDTH etc.],
[gl_cv_header_limits_width],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
#define __STDC_WANT_IEC_60559_BFP_EXT__ 1
#endif
#include <limits.h>
int ullw = ULLONG_WIDTH;]])],
[AC_LANG_PROGRAM(
[[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
#define __STDC_WANT_IEC_60559_BFP_EXT__ 1
#endif
#include <limits.h>
long long llm = LLONG_MAX;
int wb = WORD_BIT;
int ullw = ULLONG_WIDTH;
]])],
[gl_cv_header_limits_width=yes],
[gl_cv_header_limits_width=no])])
if test "$gl_cv_header_limits_width" = yes; then

View file

@ -1,5 +1,5 @@
dnl A placeholder for <stddef.h>, for platforms that have issues.
# stddef_h.m4 serial 5
# stddef_h.m4 serial 6
dnl Copyright (C) 2009-2018 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -10,13 +10,33 @@ AC_DEFUN([gl_STDDEF_H],
AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
AC_REQUIRE([gt_TYPE_WCHAR_T])
STDDEF_H=
AC_CHECK_TYPE([max_align_t], [], [HAVE_MAX_ALIGN_T=0; STDDEF_H=stddef.h],
[[#include <stddef.h>
]])
dnl Test whether the type max_align_t exists and whether its alignment
dnl "is as great as is supported by the implementation in all contexts".
AC_CACHE_CHECK([for good max_align_t],
[gl_cv_type_max_align_t],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stddef.h>
unsigned int s = sizeof (max_align_t);
#if defined __GNUC__ || defined __IBM__ALIGNOF__
int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) - 1];
int check2[2 * (__alignof__ (long double) <= __alignof__ (max_align_t)) - 1];
#endif
]])],
[gl_cv_type_max_align_t=yes],
[gl_cv_type_max_align_t=no])
])
if test $gl_cv_type_max_align_t = no; then
HAVE_MAX_ALIGN_T=0
STDDEF_H=stddef.h
fi
if test $gt_cv_c_wchar_t = no; then
HAVE_WCHAR_T=0
STDDEF_H=stddef.h
fi
AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],
[gl_cv_decl_null_works],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>
@ -28,6 +48,7 @@ AC_DEFUN([gl_STDDEF_H],
REPLACE_NULL=1
STDDEF_H=stddef.h
fi
AC_SUBST([STDDEF_H])
AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"])
if test -n "$STDDEF_H"; then