1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 04:10:54 -08:00

Add gnulib files to support higher-resolution time stamps.

Fixes: debbugs:9000
This commit is contained in:
Paul Eggert 2012-06-22 14:26:37 -07:00
parent 36cec983d4
commit c8fff86301
24 changed files with 2734 additions and 0 deletions

69
lib/dtotimespec.c Normal file
View file

@ -0,0 +1,69 @@
/* Convert double to timespec.
Copyright (C) 2011-2012 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
/* written by Paul Eggert */
/* Convert the double value SEC to a struct timespec. Round toward
positive infinity. On overflow, return an extremal value. */
#include <config.h>
#include "timespec.h"
#include "intprops.h"
struct timespec
dtotimespec (double sec)
{
enum { BILLION = 1000 * 1000 * 1000 };
double min_representable = TYPE_MINIMUM (time_t);
double max_representable =
((TYPE_MAXIMUM (time_t) * (double) BILLION + (BILLION - 1))
/ BILLION);
struct timespec r;
if (! (min_representable < sec))
{
r.tv_sec = TYPE_MINIMUM (time_t);
r.tv_nsec = 0;
}
else if (! (sec < max_representable))
{
r.tv_sec = TYPE_MAXIMUM (time_t);
r.tv_nsec = BILLION - 1;
}
else
{
time_t s = sec;
double frac = BILLION * (sec - s);
long ns = frac;
ns += ns < frac;
s += ns / BILLION;
ns %= BILLION;
if (ns < 0)
{
s--;
ns += BILLION;
}
r.tv_sec = s;
r.tv_nsec = ns;
}
return r;
}

48
lib/gettime.c Normal file
View file

@ -0,0 +1,48 @@
/* gettime -- get the system clock
Copyright (C) 2002, 2004-2007, 2009-2012 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
#include <config.h>
#include "timespec.h"
#include <sys/time.h>
/* Get the system time into *TS. */
void
gettime (struct timespec *ts)
{
#if HAVE_NANOTIME
nanotime (ts);
#else
# if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME
if (clock_gettime (CLOCK_REALTIME, ts) == 0)
return;
# endif
{
struct timeval tv;
gettimeofday (&tv, NULL);
ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec * 1000;
}
#endif
}

154
lib/gettimeofday.c Normal file
View file

@ -0,0 +1,154 @@
/* Provide gettimeofday for systems that don't have it or for which it's broken.
Copyright (C) 2001-2003, 2005-2007, 2009-2012 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 3, 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, see <http://www.gnu.org/licenses/>. */
/* written by Jim Meyering */
#include <config.h>
/* Specification. */
#include <sys/time.h>
#include <time.h>
#if HAVE_SYS_TIMEB_H
# include <sys/timeb.h>
#endif
#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
/* Work around the bug in some systems whereby gettimeofday clobbers
the static buffer that localtime uses for its return value. The
gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
this problem. The tzset replacement is necessary for at least
Solaris 2.5, 2.5.1, and 2.6. */
static struct tm tm_zero_buffer;
static struct tm *localtime_buffer_addr = &tm_zero_buffer;
# undef localtime
extern struct tm *localtime (time_t const *);
# undef gmtime
extern struct tm *gmtime (time_t const *);
/* This is a wrapper for localtime. It is used only on systems for which
gettimeofday clobbers the static buffer used for localtime's result.
On the first call, record the address of the static buffer that
localtime uses for its result. */
struct tm *
rpl_localtime (time_t const *timep)
{
struct tm *tm = localtime (timep);
if (localtime_buffer_addr == &tm_zero_buffer)
localtime_buffer_addr = tm;
return tm;
}
/* Same as above, since gmtime and localtime use the same buffer. */
struct tm *
rpl_gmtime (time_t const *timep)
{
struct tm *tm = gmtime (timep);
if (localtime_buffer_addr == &tm_zero_buffer)
localtime_buffer_addr = tm;
return tm;
}
#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */
#if TZSET_CLOBBERS_LOCALTIME
# undef tzset
extern void tzset (void);
/* This is a wrapper for tzset, for systems on which tzset may clobber
the static buffer used for localtime's result. */
void
rpl_tzset (void)
{
/* Save and restore the contents of the buffer used for localtime's
result around the call to tzset. */
struct tm save = *localtime_buffer_addr;
tzset ();
*localtime_buffer_addr = save;
}
#endif
/* This is a wrapper for gettimeofday. It is used only on systems
that lack this function, or whose implementation of this function
causes problems. */
int
gettimeofday (struct timeval *restrict tv, void *restrict tz)
{
#undef gettimeofday
#if HAVE_GETTIMEOFDAY
# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
/* Save and restore the contents of the buffer used for localtime's
result around the call to gettimeofday. */
struct tm save = *localtime_buffer_addr;
# endif
# if defined timeval /* 'struct timeval' overridden by gnulib? */
# undef timeval
struct timeval otv;
int result = gettimeofday (&otv, (struct timezone *) tz);
if (result == 0)
{
tv->tv_sec = otv.tv_sec;
tv->tv_usec = otv.tv_usec;
}
# else
int result = gettimeofday (tv, (struct timezone *) tz);
# endif
# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
*localtime_buffer_addr = save;
# endif
return result;
#else
# if HAVE__FTIME
struct _timeb timebuf;
_ftime (&timebuf);
tv->tv_sec = timebuf.time;
tv->tv_usec = timebuf.millitm * 1000;
# else
# if !defined OK_TO_USE_1S_CLOCK
# error "Only 1-second nominal clock resolution found. Is that intended?" \
"If so, compile with the -DOK_TO_USE_1S_CLOCK option."
# endif
tv->tv_sec = time (NULL);
tv->tv_usec = 0;
# endif
return 0;
#endif
}

76
lib/pselect.c Normal file
View file

@ -0,0 +1,76 @@
/* pselect - synchronous I/O multiplexing
Copyright 2011-2012 Free Software Foundation, Inc.
This file is part of gnulib.
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.
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, see <http://www.gnu.org/licenses/>. */
/* written by Paul Eggert */
#include <config.h>
#include <sys/select.h>
#include <errno.h>
#include <signal.h>
/* Examine the size-NFDS file descriptor sets in RFDS, WFDS, and XFDS
to see whether some of their descriptors are ready for reading,
ready for writing, or have exceptions pending. Wait for at most
TIMEOUT seconds, and use signal mask SIGMASK while waiting. A null
pointer parameter stands for no descriptors, an infinite timeout,
or an unaffected signal mask. */
int
pselect (int nfds, fd_set *restrict rfds,
fd_set *restrict wfds, fd_set *restrict xfds,
struct timespec const *restrict timeout,
sigset_t const *restrict sigmask)
{
int select_result;
sigset_t origmask;
struct timeval tv, *tvp;
if (timeout)
{
if (! (0 <= timeout->tv_nsec && timeout->tv_nsec < 1000000000))
{
errno = EINVAL;
return -1;
}
tv.tv_sec = timeout->tv_sec;
tv.tv_usec = (timeout->tv_nsec + 999) / 1000;
tvp = &tv;
}
else
tvp = NULL;
/* Signal mask munging should be atomic, but this is the best we can
do in this emulation. */
if (sigmask)
pthread_sigmask (SIG_SETMASK, sigmask, &origmask);
select_result = select (nfds, rfds, wfds, xfds, tvp);
if (sigmask)
{
int select_errno = errno;
pthread_sigmask (SIG_SETMASK, &origmask, NULL);
errno = select_errno;
}
return select_result;
}

189
lib/stat-time.h Normal file
View file

@ -0,0 +1,189 @@
/* stat-related time functions.
Copyright (C) 2005, 2007, 2009-2012 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
#ifndef STAT_TIME_H
#define STAT_TIME_H 1
#include <sys/stat.h>
#include <time.h>
/* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type
struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST,
ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST,
if available. ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim
for access, status change, data modification, or birth (creation)
time respectively.
These macros are private to stat-time.h. */
#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
# ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC
# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
# else
# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec)
# endif
#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec)
#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC
# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec)
#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC
# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec)
#endif
/* Return the nanosecond component of *ST's access time. */
static inline long int
get_stat_atime_ns (struct stat const *st)
{
# if defined STAT_TIMESPEC
return STAT_TIMESPEC (st, st_atim).tv_nsec;
# elif defined STAT_TIMESPEC_NS
return STAT_TIMESPEC_NS (st, st_atim);
# else
return 0;
# endif
}
/* Return the nanosecond component of *ST's status change time. */
static inline long int
get_stat_ctime_ns (struct stat const *st)
{
# if defined STAT_TIMESPEC
return STAT_TIMESPEC (st, st_ctim).tv_nsec;
# elif defined STAT_TIMESPEC_NS
return STAT_TIMESPEC_NS (st, st_ctim);
# else
return 0;
# endif
}
/* Return the nanosecond component of *ST's data modification time. */
static inline long int
get_stat_mtime_ns (struct stat const *st)
{
# if defined STAT_TIMESPEC
return STAT_TIMESPEC (st, st_mtim).tv_nsec;
# elif defined STAT_TIMESPEC_NS
return STAT_TIMESPEC_NS (st, st_mtim);
# else
return 0;
# endif
}
/* Return the nanosecond component of *ST's birth time. */
static inline long int
get_stat_birthtime_ns (struct stat const *st)
{
# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
return STAT_TIMESPEC (st, st_birthtim).tv_nsec;
# elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
return STAT_TIMESPEC_NS (st, st_birthtim);
# else
/* Avoid a "parameter unused" warning. */
(void) st;
return 0;
# endif
}
/* Return *ST's access time. */
static inline struct timespec
get_stat_atime (struct stat const *st)
{
#ifdef STAT_TIMESPEC
return STAT_TIMESPEC (st, st_atim);
#else
struct timespec t;
t.tv_sec = st->st_atime;
t.tv_nsec = get_stat_atime_ns (st);
return t;
#endif
}
/* Return *ST's status change time. */
static inline struct timespec
get_stat_ctime (struct stat const *st)
{
#ifdef STAT_TIMESPEC
return STAT_TIMESPEC (st, st_ctim);
#else
struct timespec t;
t.tv_sec = st->st_ctime;
t.tv_nsec = get_stat_ctime_ns (st);
return t;
#endif
}
/* Return *ST's data modification time. */
static inline struct timespec
get_stat_mtime (struct stat const *st)
{
#ifdef STAT_TIMESPEC
return STAT_TIMESPEC (st, st_mtim);
#else
struct timespec t;
t.tv_sec = st->st_mtime;
t.tv_nsec = get_stat_mtime_ns (st);
return t;
#endif
}
/* Return *ST's birth time, if available; otherwise return a value
with tv_sec and tv_nsec both equal to -1. */
static inline struct timespec
get_stat_birthtime (struct stat const *st)
{
struct timespec t;
#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
|| defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC)
t = STAT_TIMESPEC (st, st_birthtim);
#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
t.tv_sec = st->st_birthtime;
t.tv_nsec = st->st_birthtimensec;
#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
/* Native Windows platforms (but not Cygwin) put the "file creation
time" in st_ctime (!). See
<http://msdn2.microsoft.com/de-de/library/14h5k7ff(VS.80).aspx>. */
t.tv_sec = st->st_ctime;
t.tv_nsec = 0;
#else
/* Birth time is not supported. */
t.tv_sec = -1;
t.tv_nsec = -1;
/* Avoid a "parameter unused" warning. */
(void) st;
#endif
#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
|| defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \
|| defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
/* FreeBSD and NetBSD sometimes signal the absence of knowledge by
using zero. Attempt to work around this problem. Alas, this can
report failure even for valid time stamps. Also, NetBSD
sometimes returns junk in the birth time fields; work around this
bug if it is detected. */
if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000))
{
t.tv_sec = -1;
t.tv_nsec = -1;
}
#endif
return t;
}
#endif

298
lib/sys_select.in.h Normal file
View file

@ -0,0 +1,298 @@
/* Substitute for <sys/select.h>.
Copyright (C) 2007-2012 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 3, 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, see <http://www.gnu.org/licenses/>. */
# if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
# endif
@PRAGMA_COLUMNS@
/* On OSF/1, <sys/types.h> and <sys/time.h> include <sys/select.h>.
Simply delegate to the system's header in this case. */
#if @HAVE_SYS_SELECT_H@ && defined __osf__ && (defined _SYS_TYPES_H_ && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H) && defined _OSF_SOURCE
# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
#elif @HAVE_SYS_SELECT_H@ && defined __osf__ && (defined _SYS_TIME_H_ && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H) && defined _OSF_SOURCE
# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
/* On IRIX 6.5, <sys/timespec.h> includes <sys/types.h>, which includes
<sys/bsd_types.h>, which includes <sys/select.h>. At this point we cannot
include <signal.h>, because that includes <internal/signal_core.h>, which
gives a syntax error because <sys/timespec.h> has not been completely
processed. Simply delegate to the system's header in this case. */
#elif @HAVE_SYS_SELECT_H@ && defined __sgi && (defined _SYS_BSD_TYPES_H && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H)
# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
/* On OpenBSD 5.0, <pthread.h> includes <sys/types.h>, which includes
<sys/select.h>. At this point we cannot include <signal.h>, because that
includes gnulib's pthread.h override, which gives a syntax error because
/usr/include/pthread.h has not been completely processed. Simply delegate
to the system's header in this case. */
#elif @HAVE_SYS_SELECT_H@ && defined __OpenBSD__ && (defined _PTHREAD_H_ && !defined PTHREAD_MUTEX_INITIALIZER)
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
#else
#ifndef _@GUARD_PREFIX@_SYS_SELECT_H
/* On many platforms, <sys/select.h> assumes prior inclusion of
<sys/types.h>. Also, mingw defines sigset_t there, instead of
in <signal.h> where it belongs. */
#include <sys/types.h>
#if @HAVE_SYS_SELECT_H@
/* On OSF/1 4.0, <sys/select.h> provides only a forward declaration
of 'struct timeval', and no definition of this type.
Also, Mac OS X, AIX, HP-UX, IRIX, Solaris, Interix declare select()
in <sys/time.h>.
But avoid namespace pollution on glibc systems. */
# ifndef __GLIBC__
# include <sys/time.h>
# endif
/* On AIX 7 and Solaris 10, <sys/select.h> provides an FD_ZERO implementation
that relies on memset(), but without including <string.h>.
But in any case avoid namespace pollution on glibc systems. */
# if (defined __OpenBSD__ || defined _AIX || defined __sun || defined __osf__ || defined __BEOS__) \
&& ! defined __GLIBC__
# include <string.h>
# endif
/* The include_next requires a split double-inclusion guard. */
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
#endif
/* Get definition of 'sigset_t'.
But avoid namespace pollution on glibc systems.
Do this after the include_next (for the sake of OpenBSD 5.0) but before
the split double-inclusion guard (for the sake of Solaris). */
#if !(defined __GLIBC__ && !defined __UCLIBC__)
# include <signal.h>
#endif
#ifndef _@GUARD_PREFIX@_SYS_SELECT_H
#define _@GUARD_PREFIX@_SYS_SELECT_H
#if !@HAVE_SYS_SELECT_H@
/* A platform that lacks <sys/select.h>. */
/* Get the 'struct timeval' and 'fd_set' types and the FD_* macros
on most platforms. */
# include <sys/time.h>
/* On HP-UX 11, <sys/time.h> provides an FD_ZERO implementation
that relies on memset(), but without including <string.h>. */
# if defined __hpux
# include <string.h>
# endif
/* On native Windows platforms:
Get the 'fd_set' type.
Get the close() declaration before we override it. */
# if @HAVE_WINSOCK2_H@
# if !defined _GL_INCLUDING_WINSOCK2_H
# define _GL_INCLUDING_WINSOCK2_H
# include <winsock2.h>
# undef _GL_INCLUDING_WINSOCK2_H
# endif
# include <io.h>
# endif
#endif
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
/* The definition of _GL_WARN_ON_USE is copied here. */
/* Fix some definitions from <winsock2.h>. */
#if @HAVE_WINSOCK2_H@
# if !GNULIB_defined_rpl_fd_isset
/* Re-define FD_ISSET to avoid a WSA call while we are not using
network sockets. */
static inline int
rpl_fd_isset (SOCKET fd, fd_set * set)
{
u_int i;
if (set == NULL)
return 0;
for (i = 0; i < set->fd_count; i++)
if (set->fd_array[i] == fd)
return 1;
return 0;
}
# define GNULIB_defined_rpl_fd_isset 1
# endif
# undef FD_ISSET
# define FD_ISSET(fd, set) rpl_fd_isset(fd, set)
#endif
/* Hide some function declarations from <winsock2.h>. */
#if @HAVE_WINSOCK2_H@
# if !defined _@GUARD_PREFIX@_UNISTD_H
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef close
# define close close_used_without_including_unistd_h
# else
_GL_WARN_ON_USE (close,
"close() used without including <unistd.h>");
# endif
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef gethostname
# define gethostname gethostname_used_without_including_unistd_h
# else
_GL_WARN_ON_USE (gethostname,
"gethostname() used without including <unistd.h>");
# endif
# endif
# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef socket
# define socket socket_used_without_including_sys_socket_h
# undef connect
# define connect connect_used_without_including_sys_socket_h
# undef accept
# define accept accept_used_without_including_sys_socket_h
# undef bind
# define bind bind_used_without_including_sys_socket_h
# undef getpeername
# define getpeername getpeername_used_without_including_sys_socket_h
# undef getsockname
# define getsockname getsockname_used_without_including_sys_socket_h
# undef getsockopt
# define getsockopt getsockopt_used_without_including_sys_socket_h
# undef listen
# define listen listen_used_without_including_sys_socket_h
# undef recv
# define recv recv_used_without_including_sys_socket_h
# undef send
# define send send_used_without_including_sys_socket_h
# undef recvfrom
# define recvfrom recvfrom_used_without_including_sys_socket_h
# undef sendto
# define sendto sendto_used_without_including_sys_socket_h
# undef setsockopt
# define setsockopt setsockopt_used_without_including_sys_socket_h
# undef shutdown
# define shutdown shutdown_used_without_including_sys_socket_h
# else
_GL_WARN_ON_USE (socket,
"socket() used without including <sys/socket.h>");
_GL_WARN_ON_USE (connect,
"connect() used without including <sys/socket.h>");
_GL_WARN_ON_USE (accept,
"accept() used without including <sys/socket.h>");
_GL_WARN_ON_USE (bind,
"bind() used without including <sys/socket.h>");
_GL_WARN_ON_USE (getpeername,
"getpeername() used without including <sys/socket.h>");
_GL_WARN_ON_USE (getsockname,
"getsockname() used without including <sys/socket.h>");
_GL_WARN_ON_USE (getsockopt,
"getsockopt() used without including <sys/socket.h>");
_GL_WARN_ON_USE (listen,
"listen() used without including <sys/socket.h>");
_GL_WARN_ON_USE (recv,
"recv() used without including <sys/socket.h>");
_GL_WARN_ON_USE (send,
"send() used without including <sys/socket.h>");
_GL_WARN_ON_USE (recvfrom,
"recvfrom() used without including <sys/socket.h>");
_GL_WARN_ON_USE (sendto,
"sendto() used without including <sys/socket.h>");
_GL_WARN_ON_USE (setsockopt,
"setsockopt() used without including <sys/socket.h>");
_GL_WARN_ON_USE (shutdown,
"shutdown() used without including <sys/socket.h>");
# endif
# endif
#endif
#if @GNULIB_PSELECT@
# if @REPLACE_PSELECT@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef pselect
# define pselect rpl_pselect
# endif
_GL_FUNCDECL_RPL (pselect, int,
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
struct timespec const *restrict, const sigset_t *restrict));
_GL_CXXALIAS_RPL (pselect, int,
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
struct timespec const *restrict, const sigset_t *restrict));
# else
# if !@HAVE_PSELECT@
_GL_FUNCDECL_SYS (pselect, int,
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
struct timespec const *restrict, const sigset_t *restrict));
# endif
_GL_CXXALIAS_SYS (pselect, int,
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
struct timespec const *restrict, const sigset_t *restrict));
# endif
_GL_CXXALIASWARN (pselect);
#elif defined GNULIB_POSIXCHECK
# undef pselect
# if HAVE_RAW_DECL_PSELECT
_GL_WARN_ON_USE (pselect, "pselect is not portable - "
"use gnulib module pselect for portability");
# endif
#endif
#if @GNULIB_SELECT@
# if @REPLACE_SELECT@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef select
# define select rpl_select
# endif
_GL_FUNCDECL_RPL (select, int,
(int, fd_set *, fd_set *, fd_set *, struct timeval *));
_GL_CXXALIAS_RPL (select, int,
(int, fd_set *, fd_set *, fd_set *, struct timeval *));
# else
_GL_CXXALIAS_SYS (select, int,
(int, fd_set *, fd_set *, fd_set *, struct timeval *));
# endif
_GL_CXXALIASWARN (select);
#elif @HAVE_WINSOCK2_H@
# undef select
# define select select_used_without_requesting_gnulib_module_select
#elif defined GNULIB_POSIXCHECK
# undef select
# if HAVE_RAW_DECL_SELECT
_GL_WARN_ON_USE (select, "select is not always POSIX compliant - "
"use gnulib module select for portability");
# endif
#endif
#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */
#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */
#endif /* OSF/1 */

205
lib/sys_time.in.h Normal file
View file

@ -0,0 +1,205 @@
/* Provide a more complete sys/time.h.
Copyright (C) 2007-2012 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 3, 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, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
#endif
@PRAGMA_COLUMNS@
#if defined _@GUARD_PREFIX@_SYS_TIME_H
/* Simply delegate to the system's header, without adding anything. */
# if @HAVE_SYS_TIME_H@
# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@
# endif
#else
# define _@GUARD_PREFIX@_SYS_TIME_H
# if @HAVE_SYS_TIME_H@
# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@
# else
# include <time.h>
# endif
/* On native Windows with MSVC, get the 'struct timeval' type.
Also, on native Windows with a 64-bit time_t, where we are overriding the
'struct timeval' type, get all declarations of system functions whose
signature contains 'struct timeval'. */
# if (defined _MSC_VER || @REPLACE_STRUCT_TIMEVAL@) && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H
# define _GL_INCLUDING_WINSOCK2_H
# include <winsock2.h>
# undef _GL_INCLUDING_WINSOCK2_H
# endif
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
/* The definition of _GL_ARG_NONNULL is copied here. */
/* The definition of _GL_WARN_ON_USE is copied here. */
# ifdef __cplusplus
extern "C" {
# endif
# if !@HAVE_STRUCT_TIMEVAL@ || @REPLACE_STRUCT_TIMEVAL@
# if @REPLACE_STRUCT_TIMEVAL@
# define timeval rpl_timeval
# endif
# if !GNULIB_defined_struct_timeval
struct timeval
{
time_t tv_sec;
long int tv_usec;
};
# define GNULIB_defined_struct_timeval 1
# endif
# endif
# ifdef __cplusplus
}
# endif
# if @GNULIB_GETTIMEOFDAY@
# if @REPLACE_GETTIMEOFDAY@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef gettimeofday
# define gettimeofday rpl_gettimeofday
# endif
_GL_FUNCDECL_RPL (gettimeofday, int,
(struct timeval *restrict, void *restrict)
_GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL (gettimeofday, int,
(struct timeval *restrict, void *restrict));
# else
# if !@HAVE_GETTIMEOFDAY@
_GL_FUNCDECL_SYS (gettimeofday, int,
(struct timeval *restrict, void *restrict)
_GL_ARG_NONNULL ((1)));
# endif
/* Need to cast, because on glibc systems, by default, the second argument is
struct timezone *. */
_GL_CXXALIAS_SYS_CAST (gettimeofday, int,
(struct timeval *restrict, void *restrict));
# endif
_GL_CXXALIASWARN (gettimeofday);
# elif defined GNULIB_POSIXCHECK
# undef gettimeofday
# if HAVE_RAW_DECL_GETTIMEOFDAY
_GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - "
"use gnulib module gettimeofday for portability");
# endif
# endif
/* Hide some function declarations from <winsock2.h>. */
# if defined _MSC_VER && @HAVE_WINSOCK2_H@
# if !defined _@GUARD_PREFIX@_UNISTD_H
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef close
# define close close_used_without_including_unistd_h
# else
_GL_WARN_ON_USE (close,
"close() used without including <unistd.h>");
# endif
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef gethostname
# define gethostname gethostname_used_without_including_unistd_h
# else
_GL_WARN_ON_USE (gethostname,
"gethostname() used without including <unistd.h>");
# endif
# endif
# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef socket
# define socket socket_used_without_including_sys_socket_h
# undef connect
# define connect connect_used_without_including_sys_socket_h
# undef accept
# define accept accept_used_without_including_sys_socket_h
# undef bind
# define bind bind_used_without_including_sys_socket_h
# undef getpeername
# define getpeername getpeername_used_without_including_sys_socket_h
# undef getsockname
# define getsockname getsockname_used_without_including_sys_socket_h
# undef getsockopt
# define getsockopt getsockopt_used_without_including_sys_socket_h
# undef listen
# define listen listen_used_without_including_sys_socket_h
# undef recv
# define recv recv_used_without_including_sys_socket_h
# undef send
# define send send_used_without_including_sys_socket_h
# undef recvfrom
# define recvfrom recvfrom_used_without_including_sys_socket_h
# undef sendto
# define sendto sendto_used_without_including_sys_socket_h
# undef setsockopt
# define setsockopt setsockopt_used_without_including_sys_socket_h
# undef shutdown
# define shutdown shutdown_used_without_including_sys_socket_h
# else
_GL_WARN_ON_USE (socket,
"socket() used without including <sys/socket.h>");
_GL_WARN_ON_USE (connect,
"connect() used without including <sys/socket.h>");
_GL_WARN_ON_USE (accept,
"accept() used without including <sys/socket.h>");
_GL_WARN_ON_USE (bind,
"bind() used without including <sys/socket.h>");
_GL_WARN_ON_USE (getpeername,
"getpeername() used without including <sys/socket.h>");
_GL_WARN_ON_USE (getsockname,
"getsockname() used without including <sys/socket.h>");
_GL_WARN_ON_USE (getsockopt,
"getsockopt() used without including <sys/socket.h>");
_GL_WARN_ON_USE (listen,
"listen() used without including <sys/socket.h>");
_GL_WARN_ON_USE (recv,
"recv() used without including <sys/socket.h>");
_GL_WARN_ON_USE (send,
"send() used without including <sys/socket.h>");
_GL_WARN_ON_USE (recvfrom,
"recvfrom() used without including <sys/socket.h>");
_GL_WARN_ON_USE (sendto,
"sendto() used without including <sys/socket.h>");
_GL_WARN_ON_USE (setsockopt,
"setsockopt() used without including <sys/socket.h>");
_GL_WARN_ON_USE (shutdown,
"shutdown() used without including <sys/socket.h>");
# endif
# endif
# if !defined _@GUARD_PREFIX@_SYS_SELECT_H
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef select
# define select select_used_without_including_sys_select_h
# else
_GL_WARN_ON_USE (select,
"select() used without including <sys/select.h>");
# endif
# endif
# endif
#endif /* _@GUARD_PREFIX@_SYS_TIME_H */

71
lib/timespec-add.c Normal file
View file

@ -0,0 +1,71 @@
/* Add two struct timespec values.
Copyright (C) 2011-2012 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
/* 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 <= 999999999. */
#include <config.h>
#include "timespec.h"
#include "intprops.h"
struct timespec
timespec_add (struct timespec a, struct timespec b)
{
struct timespec r;
time_t rs = a.tv_sec;
time_t bs = b.tv_sec;
int ns = a.tv_nsec + b.tv_nsec;
int nsd = ns - 1000000000;
int rns = ns;
if (0 <= nsd)
{
rns = nsd;
if (rs == TYPE_MAXIMUM (time_t))
{
if (0 <= bs)
goto high_overflow;
bs++;
}
else
rs++;
}
if (INT_ADD_OVERFLOW (rs, bs))
{
if (rs < 0)
{
rs = TYPE_MINIMUM (time_t);
rns = 0;
}
else
{
high_overflow:
rs = TYPE_MAXIMUM (time_t);
rns = 999999999;
}
}
else
rs += bs;
r.tv_sec = rs;
r.tv_nsec = rns;
return r;
}

72
lib/timespec-sub.c Normal file
View file

@ -0,0 +1,72 @@
/* Subtract two struct timespec values.
Copyright (C) 2011-2012 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
/* Return the difference between two timespec values A and B. On
overflow, return an extremal value. This assumes 0 <= tv_nsec <=
999999999. */
#include <config.h>
#include <config.h>
#include "timespec.h"
#include "intprops.h"
struct timespec
timespec_sub (struct timespec a, struct timespec b)
{
struct timespec r;
time_t rs = a.tv_sec;
time_t bs = b.tv_sec;
int ns = a.tv_nsec - b.tv_nsec;
int rns = ns;
if (ns < 0)
{
rns = ns + 1000000000;
if (rs == TYPE_MINIMUM (time_t))
{
if (bs <= 0)
goto low_overflow;
bs--;
}
else
rs--;
}
if (INT_SUBTRACT_OVERFLOW (rs, bs))
{
if (rs < 0)
{
low_overflow:
rs = TYPE_MINIMUM (time_t);
rns = 0;
}
else
{
rs = TYPE_MAXIMUM (time_t);
rns = 999999999;
}
}
else
rs -= bs;
r.tv_sec = rs;
r.tv_nsec = rns;
return r;
}

82
lib/timespec.h Normal file
View file

@ -0,0 +1,82 @@
/* timespec -- System time interface
Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2012 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
#if ! defined TIMESPEC_H
# define TIMESPEC_H
# include <time.h>
/* Return negative, zero, positive if A < B, A == B, A > B, respectively.
For each time stamp T, this code assumes that either:
* T.tv_nsec is in the range 0..999999999; or
* T.tv_sec corresponds to a valid leap second on a host that supports
leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or
* T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or
T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000.
This allows for special struct timespec values that are less or
greater than all possible valid time stamps.
In all these cases, it is safe to subtract two tv_nsec values and
convert the result to integer without worrying about overflow on
any platform of interest to the GNU project, since all such
platforms have 32-bit int or wider.
Replacing "(int) (a.tv_nsec - b.tv_nsec)" with something like
"a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause
this function to work in some cases where the above assumption is
violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2,
b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the
extra instructions. Using a subtraction has the advantage of
detecting some invalid cases on platforms that detect integer
overflow.
The (int) cast avoids a gcc -Wconversion warning. */
static inline int
timespec_cmp (struct timespec a, struct timespec b)
{
return (a.tv_sec < b.tv_sec ? -1
: a.tv_sec > b.tv_sec ? 1
: (int) (a.tv_nsec - b.tv_nsec));
}
/* Return -1, 0, 1, depending on the sign of A. A.tv_nsec must be
nonnegative. */
static inline int
timespec_sign (struct timespec a)
{
return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec;
}
struct timespec timespec_add (struct timespec, struct timespec);
struct timespec timespec_sub (struct timespec, struct timespec);
struct timespec dtotimespec (double);
/* Return an approximation to A, of type 'double'. */
static inline double
timespectod (struct timespec a)
{
return a.tv_sec + a.tv_nsec / 1e9;
}
void gettime (struct timespec *);
int settime (struct timespec const *);
#endif

533
lib/utimens.c Normal file
View file

@ -0,0 +1,533 @@
/* Set file access and modification times.
Copyright (C) 2003-2012 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 3 of the License, or 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, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
/* derived from a function in touch.c */
#include <config.h>
#include "utimens.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include "stat-time.h"
#include "timespec.h"
#if HAVE_UTIME_H
# include <utime.h>
#endif
/* Some systems (even some that do have <utime.h>) don't declare this
structure anywhere. */
#ifndef HAVE_STRUCT_UTIMBUF
struct utimbuf
{
long actime;
long modtime;
};
#endif
/* Avoid recursion with rpl_futimens or rpl_utimensat. */
#undef futimens
#undef utimensat
/* Solaris 9 mistakenly succeeds when given a non-directory with a
trailing slash. Force the use of rpl_stat for a fix. */
#ifndef REPLACE_FUNC_STAT_FILE
# define REPLACE_FUNC_STAT_FILE 0
#endif
#if HAVE_UTIMENSAT || HAVE_FUTIMENS
/* Cache variables for whether the utimensat syscall works; used to
avoid calling the syscall if we know it will just fail with ENOSYS,
and to avoid unnecessary work in massaging timestamps if the
syscall will work. Multiple variables are needed, to distinguish
between the following scenarios on Linux:
utimensat doesn't exist, or is in glibc but kernel 2.6.18 fails with ENOSYS
kernel 2.6.22 and earlier rejects AT_SYMLINK_NOFOLLOW
kernel 2.6.25 and earlier reject UTIME_NOW/UTIME_OMIT with non-zero tv_sec
kernel 2.6.32 used with xfs or ntfs-3g fail to honor UTIME_OMIT
utimensat completely works
For each cache variable: 0 = unknown, 1 = yes, -1 = no. */
static int utimensat_works_really;
static int lutimensat_works_really;
#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
/* Validate the requested timestamps. Return 0 if the resulting
timespec can be used for utimensat (after possibly modifying it to
work around bugs in utimensat). Return a positive value if the
timespec needs further adjustment based on stat results: 1 if any
adjustment is needed for utimes, and 2 if any adjustment is needed
for Linux utimensat. Return -1, with errno set to EINVAL, if
timespec is out of range. */
static int
validate_timespec (struct timespec timespec[2])
{
int result = 0;
int utime_omit_count = 0;
assert (timespec);
if ((timespec[0].tv_nsec != UTIME_NOW
&& timespec[0].tv_nsec != UTIME_OMIT
&& (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec))
|| (timespec[1].tv_nsec != UTIME_NOW
&& timespec[1].tv_nsec != UTIME_OMIT
&& (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec)))
{
errno = EINVAL;
return -1;
}
/* Work around Linux kernel 2.6.25 bug, where utimensat fails with
EINVAL if tv_sec is not 0 when using the flag values of tv_nsec.
Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT
fails to bump ctime. */
if (timespec[0].tv_nsec == UTIME_NOW
|| timespec[0].tv_nsec == UTIME_OMIT)
{
timespec[0].tv_sec = 0;
result = 1;
if (timespec[0].tv_nsec == UTIME_OMIT)
utime_omit_count++;
}
if (timespec[1].tv_nsec == UTIME_NOW
|| timespec[1].tv_nsec == UTIME_OMIT)
{
timespec[1].tv_sec = 0;
result = 1;
if (timespec[1].tv_nsec == UTIME_OMIT)
utime_omit_count++;
}
return result + (utime_omit_count == 1);
}
/* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat
buffer STATBUF to obtain the current timestamps of the file. If
both times are UTIME_NOW, set *TS to NULL (as this can avoid some
permissions issues). If both times are UTIME_OMIT, return true
(nothing further beyond the prior collection of STATBUF is
necessary); otherwise return false. */
static bool
update_timespec (struct stat const *statbuf, struct timespec *ts[2])
{
struct timespec *timespec = *ts;
if (timespec[0].tv_nsec == UTIME_OMIT
&& timespec[1].tv_nsec == UTIME_OMIT)
return true;
if (timespec[0].tv_nsec == UTIME_NOW
&& timespec[1].tv_nsec == UTIME_NOW)
{
*ts = NULL;
return false;
}
if (timespec[0].tv_nsec == UTIME_OMIT)
timespec[0] = get_stat_atime (statbuf);
else if (timespec[0].tv_nsec == UTIME_NOW)
gettime (&timespec[0]);
if (timespec[1].tv_nsec == UTIME_OMIT)
timespec[1] = get_stat_mtime (statbuf);
else if (timespec[1].tv_nsec == UTIME_NOW)
gettime (&timespec[1]);
return false;
}
/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
TIMESPEC[0] and TIMESPEC[1], respectively.
FD must be either negative -- in which case it is ignored --
or a file descriptor that is open on FILE.
If FD is nonnegative, then FILE can be NULL, which means
use just futimes (or equivalent) instead of utimes (or equivalent),
and fail if on an old system without futimes (or equivalent).
If TIMESPEC is null, set the time stamps to the current time.
Return 0 on success, -1 (setting errno) on failure. */
int
fdutimens (int fd, char const *file, struct timespec const timespec[2])
{
struct timespec adjusted_timespec[2];
struct timespec *ts = timespec ? adjusted_timespec : NULL;
int adjustment_needed = 0;
struct stat st;
if (ts)
{
adjusted_timespec[0] = timespec[0];
adjusted_timespec[1] = timespec[1];
adjustment_needed = validate_timespec (ts);
}
if (adjustment_needed < 0)
return -1;
/* Require that at least one of FD or FILE are potentially valid, to avoid
a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather
than failing. */
if (fd < 0 && !file)
{
errno = EBADF;
return -1;
}
/* Some Linux-based NFS clients are buggy, and mishandle time stamps
of files in NFS file systems in some cases. We have no
configure-time test for this, but please see
<http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to
some of the problems with Linux 2.6.16. If this affects you,
compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to
help in some cases, albeit at a cost in performance. But you
really should upgrade your kernel to a fixed version, since the
problem affects many applications. */
#if HAVE_BUGGY_NFS_TIME_STAMPS
if (fd < 0)
sync ();
else
fsync (fd);
#endif
/* POSIX 2008 added two interfaces to set file timestamps with
nanosecond resolution; newer Linux implements both functions via
a single syscall. We provide a fallback for ENOSYS (for example,
compiling against Linux 2.6.25 kernel headers and glibc 2.7, but
running on Linux 2.6.18 kernel). */
#if HAVE_UTIMENSAT || HAVE_FUTIMENS
if (0 <= utimensat_works_really)
{
int result;
# if __linux__
/* As recently as Linux kernel 2.6.32 (Dec 2009), several file
systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
but work if both times are either explicitly specified or
UTIME_NOW. Work around it with a preparatory [f]stat prior
to calling futimens/utimensat; fortunately, there is not much
timing impact due to the extra syscall even on file systems
where UTIME_OMIT would have worked. FIXME: Simplify this in
2012, when file system bugs are no longer common. */
if (adjustment_needed == 2)
{
if (fd < 0 ? stat (file, &st) : fstat (fd, &st))
return -1;
if (ts[0].tv_nsec == UTIME_OMIT)
ts[0] = get_stat_atime (&st);
else if (ts[1].tv_nsec == UTIME_OMIT)
ts[1] = get_stat_mtime (&st);
/* Note that st is good, in case utimensat gives ENOSYS. */
adjustment_needed++;
}
# endif /* __linux__ */
# if HAVE_UTIMENSAT
if (fd < 0)
{
result = utimensat (AT_FDCWD, file, ts, 0);
# ifdef __linux__
/* Work around a kernel bug:
http://bugzilla.redhat.com/442352
http://bugzilla.redhat.com/449910
It appears that utimensat can mistakenly return 280 rather
than -1 upon ENOSYS failure.
FIXME: remove in 2010 or whenever the offending kernels
are no longer in common use. */
if (0 < result)
errno = ENOSYS;
# endif /* __linux__ */
if (result == 0 || errno != ENOSYS)
{
utimensat_works_really = 1;
return result;
}
}
# endif /* HAVE_UTIMENSAT */
# if HAVE_FUTIMENS
if (0 <= fd)
{
result = futimens (fd, ts);
# ifdef __linux__
/* Work around the same bug as above. */
if (0 < result)
errno = ENOSYS;
# endif /* __linux__ */
if (result == 0 || errno != ENOSYS)
{
utimensat_works_really = 1;
return result;
}
}
# endif /* HAVE_FUTIMENS */
}
utimensat_works_really = -1;
lutimensat_works_really = -1;
#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
/* The platform lacks an interface to set file timestamps with
nanosecond resolution, so do the best we can, discarding any
fractional part of the timestamp. */
if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0))
{
if (adjustment_needed != 3
&& (fd < 0 ? stat (file, &st) : fstat (fd, &st)))
return -1;
if (ts && update_timespec (&st, &ts))
return 0;
}
{
#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
struct timeval timeval[2];
struct timeval *t;
if (ts)
{
timeval[0].tv_sec = ts[0].tv_sec;
timeval[0].tv_usec = ts[0].tv_nsec / 1000;
timeval[1].tv_sec = ts[1].tv_sec;
timeval[1].tv_usec = ts[1].tv_nsec / 1000;
t = timeval;
}
else
t = NULL;
if (fd < 0)
{
# if HAVE_FUTIMESAT
return futimesat (AT_FDCWD, file, t);
# endif
}
else
{
/* If futimesat or futimes fails here, don't try to speed things
up by returning right away. glibc can incorrectly fail with
errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0
in high security mode doesn't allow ordinary users to read
/proc/self, so glibc incorrectly fails with errno == EACCES.
If errno == EIO, EPERM, or EROFS, it's probably safe to fail
right away, but these cases are rare enough that they're not
worth optimizing, and who knows what other messed-up systems
are out there? So play it safe and fall back on the code
below. */
# if (HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) || HAVE_FUTIMES
# if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG
# undef futimes
# define futimes(fd, t) futimesat (fd, NULL, t)
# endif
if (futimes (fd, t) == 0)
{
# if __linux__ && __GLIBC__
/* Work around a longstanding glibc bug, still present as
of 2010-12-27. On older Linux kernels that lack both
utimensat and utimes, glibc's futimes rounds instead of
truncating when falling back on utime. The same bug
occurs in futimesat with a null 2nd arg. */
if (t)
{
bool abig = 500000 <= t[0].tv_usec;
bool mbig = 500000 <= t[1].tv_usec;
if ((abig | mbig) && fstat (fd, &st) == 0)
{
/* If these two subtractions overflow, they'll
track the overflows inside the buggy glibc. */
time_t adiff = st.st_atime - t[0].tv_sec;
time_t mdiff = st.st_mtime - t[1].tv_sec;
struct timeval *tt = NULL;
struct timeval truncated_timeval[2];
truncated_timeval[0] = t[0];
truncated_timeval[1] = t[1];
if (abig && adiff == 1 && get_stat_atime_ns (&st) == 0)
{
tt = truncated_timeval;
tt[0].tv_usec = 0;
}
if (mbig && mdiff == 1 && get_stat_mtime_ns (&st) == 0)
{
tt = truncated_timeval;
tt[1].tv_usec = 0;
}
if (tt)
futimes (fd, tt);
}
}
# endif
return 0;
}
# endif
}
#endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
if (!file)
{
#if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) \
|| (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
errno = ENOSYS;
#endif
return -1;
}
#if HAVE_WORKING_UTIMES
return utimes (file, t);
#else
{
struct utimbuf utimbuf;
struct utimbuf *ut;
if (ts)
{
utimbuf.actime = ts[0].tv_sec;
utimbuf.modtime = ts[1].tv_sec;
ut = &utimbuf;
}
else
ut = NULL;
return utime (file, ut);
}
#endif /* !HAVE_WORKING_UTIMES */
}
}
/* Set the access and modification time stamps of FILE to be
TIMESPEC[0] and TIMESPEC[1], respectively. */
int
utimens (char const *file, struct timespec const timespec[2])
{
return fdutimens (-1, file, timespec);
}
/* Set the access and modification time stamps of FILE to be
TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
symlinks. Fail with ENOSYS if the platform does not support
changing symlink timestamps, but FILE was a symlink. */
int
lutimens (char const *file, struct timespec const timespec[2])
{
struct timespec adjusted_timespec[2];
struct timespec *ts = timespec ? adjusted_timespec : NULL;
int adjustment_needed = 0;
struct stat st;
if (ts)
{
adjusted_timespec[0] = timespec[0];
adjusted_timespec[1] = timespec[1];
adjustment_needed = validate_timespec (ts);
}
if (adjustment_needed < 0)
return -1;
/* The Linux kernel did not support symlink timestamps until
utimensat, in version 2.6.22, so we don't need to mimic
fdutimens' worry about buggy NFS clients. But we do have to
worry about bogus return values. */
#if HAVE_UTIMENSAT
if (0 <= lutimensat_works_really)
{
int result;
# if __linux__
/* As recently as Linux kernel 2.6.32 (Dec 2009), several file
systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
but work if both times are either explicitly specified or
UTIME_NOW. Work around it with a preparatory lstat prior to
calling utimensat; fortunately, there is not much timing
impact due to the extra syscall even on file systems where
UTIME_OMIT would have worked. FIXME: Simplify this in 2012,
when file system bugs are no longer common. */
if (adjustment_needed == 2)
{
if (lstat (file, &st))
return -1;
if (ts[0].tv_nsec == UTIME_OMIT)
ts[0] = get_stat_atime (&st);
else if (ts[1].tv_nsec == UTIME_OMIT)
ts[1] = get_stat_mtime (&st);
/* Note that st is good, in case utimensat gives ENOSYS. */
adjustment_needed++;
}
# endif /* __linux__ */
result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
# ifdef __linux__
/* Work around a kernel bug:
http://bugzilla.redhat.com/442352
http://bugzilla.redhat.com/449910
It appears that utimensat can mistakenly return 280 rather
than -1 upon ENOSYS failure.
FIXME: remove in 2010 or whenever the offending kernels
are no longer in common use. */
if (0 < result)
errno = ENOSYS;
# endif
if (result == 0 || errno != ENOSYS)
{
utimensat_works_really = 1;
lutimensat_works_really = 1;
return result;
}
}
lutimensat_works_really = -1;
#endif /* HAVE_UTIMENSAT */
/* The platform lacks an interface to set file timestamps with
nanosecond resolution, so do the best we can, discarding any
fractional part of the timestamp. */
if (adjustment_needed || REPLACE_FUNC_STAT_FILE)
{
if (adjustment_needed != 3 && lstat (file, &st))
return -1;
if (ts && update_timespec (&st, &ts))
return 0;
}
/* On Linux, lutimes is a thin wrapper around utimensat, so there is
no point trying lutimes if utimensat failed with ENOSYS. */
#if HAVE_LUTIMES && !HAVE_UTIMENSAT
{
struct timeval timeval[2];
struct timeval *t;
int result;
if (ts)
{
timeval[0].tv_sec = ts[0].tv_sec;
timeval[0].tv_usec = ts[0].tv_nsec / 1000;
timeval[1].tv_sec = ts[1].tv_sec;
timeval[1].tv_usec = ts[1].tv_nsec / 1000;
t = timeval;
}
else
t = NULL;
result = lutimes (file, t);
if (result == 0 || errno != ENOSYS)
return result;
}
#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */
/* Out of luck for symlinks, but we still handle regular files. */
if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))
return -1;
if (!S_ISLNK (st.st_mode))
return fdutimens (-1, file, ts);
errno = ENOSYS;
return -1;
}

19
lib/utimens.h Normal file
View file

@ -0,0 +1,19 @@
#include <time.h>
int fdutimens (int, char const *, struct timespec const [2]);
int utimens (char const *, struct timespec const [2]);
int lutimens (char const *, struct timespec const [2]);
#if GNULIB_FDUTIMENSAT
# include <fcntl.h>
# include <sys/stat.h>
int fdutimensat (int fd, int dir, char const *name, struct timespec const [2],
int atflag);
/* Using this function makes application code slightly more readable. */
static inline int
lutimensat (int dir, char const *file, struct timespec const times[2])
{
return utimensat (dir, file, times, AT_SYMLINK_NOFOLLOW);
}
#endif

31
m4/clock_time.m4 Normal file
View file

@ -0,0 +1,31 @@
# clock_time.m4 serial 10
dnl Copyright (C) 2002-2006, 2009-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# Check for clock_gettime and clock_settime, and set LIB_CLOCK_GETTIME.
# For a program named, say foo, you should add a line like the following
# in the corresponding Makefile.am file:
# foo_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
AC_DEFUN([gl_CLOCK_TIME],
[
dnl Persuade glibc and Solaris <time.h> to declare these functions.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
# Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
# Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4.
# Save and restore LIBS so e.g., -lrt, isn't added to it. Otherwise, *all*
# programs in the package would end up linked with that potentially-shared
# library, inducing unnecessary run-time overhead.
LIB_CLOCK_GETTIME=
AC_SUBST([LIB_CLOCK_GETTIME])
gl_saved_libs=$LIBS
AC_SEARCH_LIBS([clock_gettime], [rt posix4],
[test "$ac_cv_search_clock_gettime" = "none required" ||
LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
AC_CHECK_FUNCS([clock_gettime clock_settime])
LIBS=$gl_saved_libs
])

13
m4/gettime.m4 Normal file
View file

@ -0,0 +1,13 @@
# gettime.m4 serial 8
dnl Copyright (C) 2002, 2004-2006, 2009-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_GETTIME],
[
dnl Prerequisites of lib/gettime.c.
AC_REQUIRE([gl_CLOCK_TIME])
AC_REQUIRE([gl_TIMESPEC])
AC_CHECK_FUNCS_ONCE([gettimeofday nanotime])
])

140
m4/gettimeofday.m4 Normal file
View file

@ -0,0 +1,140 @@
# serial 20
# Copyright (C) 2001-2003, 2005, 2007, 2009-2012 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
dnl From Jim Meyering.
AC_DEFUN([gl_FUNC_GETTIMEOFDAY],
[
AC_REQUIRE([AC_C_RESTRICT])
AC_REQUIRE([gl_HEADER_SYS_TIME_H])
AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
AC_CHECK_FUNCS_ONCE([gettimeofday])
gl_gettimeofday_timezone=void
if test $ac_cv_func_gettimeofday != yes; then
HAVE_GETTIMEOFDAY=0
else
gl_FUNC_GETTIMEOFDAY_CLOBBER
AC_CACHE_CHECK([for gettimeofday with POSIX signature],
[gl_cv_func_gettimeofday_posix_signature],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <sys/time.h>
struct timeval c;
int gettimeofday (struct timeval *restrict, void *restrict);
]],
[[/* glibc uses struct timezone * rather than the POSIX void *
if _GNU_SOURCE is defined. However, since the only portable
use of gettimeofday uses NULL as the second parameter, and
since the glibc definition is actually more typesafe, it is
not worth wrapping this to get a compliant signature. */
int (*f) (struct timeval *restrict, void *restrict)
= gettimeofday;
int x = f (&c, 0);
return !(x | c.tv_sec | c.tv_usec);
]])],
[gl_cv_func_gettimeofday_posix_signature=yes],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <sys/time.h>
int gettimeofday (struct timeval *restrict, struct timezone *restrict);
]])],
[gl_cv_func_gettimeofday_posix_signature=almost],
[gl_cv_func_gettimeofday_posix_signature=no])])])
if test $gl_cv_func_gettimeofday_posix_signature = almost; then
gl_gettimeofday_timezone='struct timezone'
elif test $gl_cv_func_gettimeofday_posix_signature != yes; then
REPLACE_GETTIMEOFDAY=1
fi
dnl If we override 'struct timeval', we also have to override gettimeofday.
if test $REPLACE_STRUCT_TIMEVAL = 1; then
REPLACE_GETTIMEOFDAY=1
fi
m4_ifdef([gl_FUNC_TZSET_CLOBBER], [
gl_FUNC_TZSET_CLOBBER
case "$gl_cv_func_tzset_clobber" in
*yes)
REPLACE_GETTIMEOFDAY=1
gl_GETTIMEOFDAY_REPLACE_LOCALTIME
AC_DEFINE([tzset], [rpl_tzset],
[Define to rpl_tzset if the wrapper function should be used.])
AC_DEFINE([TZSET_CLOBBERS_LOCALTIME], [1],
[Define if tzset clobbers localtime's static buffer.])
;;
esac
])
fi
AC_DEFINE_UNQUOTED([GETTIMEOFDAY_TIMEZONE], [$gl_gettimeofday_timezone],
[Define this to 'void' or 'struct timezone' to match the system's
declaration of the second argument to gettimeofday.])
])
dnl See if gettimeofday clobbers the static buffer that localtime uses
dnl for its return value. The gettimeofday function from Mac OS X 10.0.4
dnl (i.e., Darwin 1.3.7) has this problem.
dnl
dnl If it does, then arrange to use gettimeofday and localtime only via
dnl the wrapper functions that work around the problem.
AC_DEFUN([gl_FUNC_GETTIMEOFDAY_CLOBBER],
[
AC_REQUIRE([gl_HEADER_SYS_TIME_H])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_CACHE_CHECK([whether gettimeofday clobbers localtime buffer],
[gl_cv_func_gettimeofday_clobber],
[AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
]],
[[
time_t t = 0;
struct tm *lt;
struct tm saved_lt;
struct timeval tv;
lt = localtime (&t);
saved_lt = *lt;
gettimeofday (&tv, NULL);
return memcmp (lt, &saved_lt, sizeof (struct tm)) != 0;
]])],
[gl_cv_func_gettimeofday_clobber=no],
[gl_cv_func_gettimeofday_clobber=yes],
[# When cross-compiling:
case "$host_os" in
# Guess all is fine on glibc systems.
*-gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;;
# If we don't know, assume the worst.
*) gl_cv_func_gettimeofday_clobber="guessing yes" ;;
esac
])])
case "$gl_cv_func_gettimeofday_clobber" in
*yes)
REPLACE_GETTIMEOFDAY=1
gl_GETTIMEOFDAY_REPLACE_LOCALTIME
AC_DEFINE([GETTIMEOFDAY_CLOBBERS_LOCALTIME], [1],
[Define if gettimeofday clobbers the localtime buffer.])
;;
esac
])
AC_DEFUN([gl_GETTIMEOFDAY_REPLACE_LOCALTIME], [
AC_DEFINE([gmtime], [rpl_gmtime],
[Define to rpl_gmtime if the replacement function should be used.])
AC_DEFINE([localtime], [rpl_localtime],
[Define to rpl_localtime if the replacement function should be used.])
])
# Prerequisites of lib/gettimeofday.c.
AC_DEFUN([gl_PREREQ_GETTIMEOFDAY], [
AC_CHECK_HEADERS([sys/timeb.h])
AC_CHECK_FUNCS([_ftime])
])

31
m4/pselect.m4 Normal file
View file

@ -0,0 +1,31 @@
# pselect.m4
dnl Copyright (C) 2011-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_PSELECT],
[
AC_REQUIRE([gl_HEADER_SYS_SELECT])
AC_REQUIRE([AC_C_RESTRICT])
AC_CHECK_FUNCS_ONCE([pselect])
if test $ac_cv_func_pselect = yes; then
AC_CACHE_CHECK([whether signature of pselect conforms to POSIX],
gl_cv_sig_pselect,
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <sys/select.h>
]],
[[int (*p) (int, fd_set *, fd_set *, fd_set *restrict,
struct timespec const *restrict,
sigset_t const *restrict) = pselect;
return !p;]])],
[gl_cv_sig_pselect=yes],
[gl_cv_sig_pselect=no])])
fi
if test $ac_cv_func_pselect = no || test $gl_cv_sig_pselect = no; then
REPLACE_PSELECT=1
fi
])

85
m4/stat-time.m4 Normal file
View file

@ -0,0 +1,85 @@
# Checks for stat-related time functions.
# Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2012 Free Software
# Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
dnl From Paul Eggert.
# st_atim.tv_nsec - Linux, Solaris, Cygwin
# st_atimespec.tv_nsec - FreeBSD, NetBSD, if ! defined _POSIX_SOURCE
# st_atimensec - FreeBSD, NetBSD, if defined _POSIX_SOURCE
# st_atim.st__tim.tv_nsec - UnixWare (at least 2.1.2 through 7.1)
# st_birthtimespec - FreeBSD, NetBSD (hidden on OpenBSD 3.9, anyway)
# st_birthtim - Cygwin 1.7.0+
AC_DEFUN([gl_STAT_TIME],
[
AC_REQUIRE([AC_C_INLINE])
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_HEADERS_ONCE([sys/time.h])
AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec],
[AC_CACHE_CHECK([whether struct stat.st_atim is of type struct timespec],
[ac_cv_typeof_struct_stat_st_atim_is_struct_timespec],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <time.h>
struct timespec ts;
struct stat st;
]],
[[
st.st_atim = ts;
]])],
[ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=yes],
[ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=no])])
if test $ac_cv_typeof_struct_stat_st_atim_is_struct_timespec = yes; then
AC_DEFINE([TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC], [1],
[Define to 1 if the type of the st_atim member of a struct stat is
struct timespec.])
fi],
[AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec], [],
[AC_CHECK_MEMBERS([struct stat.st_atimensec], [],
[AC_CHECK_MEMBERS([struct stat.st_atim.st__tim.tv_nsec], [], [],
[#include <sys/types.h>
#include <sys/stat.h>])],
[#include <sys/types.h>
#include <sys/stat.h>])],
[#include <sys/types.h>
#include <sys/stat.h>])],
[#include <sys/types.h>
#include <sys/stat.h>])
])
# Check for st_birthtime, a feature from UFS2 (FreeBSD, NetBSD, OpenBSD, etc.)
# and NTFS (Cygwin).
# There was a time when this field was named st_createtime (21 June
# 2002 to 16 July 2002) But that window is very small and applied only
# to development code, so systems still using that configuration are
# not supported. See revisions 1.10 and 1.11 of FreeBSD's
# src/sys/ufs/ufs/dinode.h.
#
AC_DEFUN([gl_STAT_BIRTHTIME],
[
AC_REQUIRE([AC_C_INLINE])
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_HEADERS_ONCE([sys/time.h])
AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec], [],
[AC_CHECK_MEMBERS([struct stat.st_birthtimensec], [],
[AC_CHECK_MEMBERS([struct stat.st_birthtim.tv_nsec], [], [],
[#include <sys/types.h>
#include <sys/stat.h>])],
[#include <sys/types.h>
#include <sys/stat.h>])],
[#include <sys/types.h>
#include <sys/stat.h>])
])

95
m4/sys_select_h.m4 Normal file
View file

@ -0,0 +1,95 @@
# sys_select_h.m4 serial 20
dnl Copyright (C) 2006-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_HEADER_SYS_SELECT],
[
AC_REQUIRE([AC_C_RESTRICT])
AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
AC_CACHE_CHECK([whether <sys/select.h> is self-contained],
[gl_cv_header_sys_select_h_selfcontained],
[
dnl Test against two bugs:
dnl 1. On many platforms, <sys/select.h> assumes prior inclusion of
dnl <sys/types.h>.
dnl 2. On OSF/1 4.0, <sys/select.h> provides only a forward declaration
dnl of 'struct timeval', and no definition of this type.
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/select.h>]],
[[struct timeval b;]])],
[gl_cv_header_sys_select_h_selfcontained=yes],
[gl_cv_header_sys_select_h_selfcontained=no])
dnl Test against another bug:
dnl 3. On Solaris 10, <sys/select.h> provides an FD_ZERO implementation
dnl that relies on memset(), but without including <string.h>.
if test $gl_cv_header_sys_select_h_selfcontained = yes; then
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#include <sys/select.h>]],
[[int memset; int bzero;]])
],
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[#include <sys/select.h>]], [[
#undef memset
#define memset nonexistent_memset
extern
#ifdef __cplusplus
"C"
#endif
void *memset (void *, int, unsigned long);
#undef bzero
#define bzero nonexistent_bzero
extern
#ifdef __cplusplus
"C"
#endif
void bzero (void *, unsigned long);
fd_set fds;
FD_ZERO (&fds);
]])
],
[],
[gl_cv_header_sys_select_h_selfcontained=no])
])
fi
])
dnl <sys/select.h> is always overridden, because of GNULIB_POSIXCHECK.
gl_CHECK_NEXT_HEADERS([sys/select.h])
if test $ac_cv_header_sys_select_h = yes; then
HAVE_SYS_SELECT_H=1
else
HAVE_SYS_SELECT_H=0
fi
AC_SUBST([HAVE_SYS_SELECT_H])
gl_PREREQ_SYS_H_WINSOCK2
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use.
gl_WARN_ON_USE_PREPARE([[
/* Some systems require prerequisite headers. */
#include <sys/types.h>
#if !(defined __GLIBC__ && !defined __UCLIBC__) && HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/select.h>
]], [pselect select])
])
AC_DEFUN([gl_SYS_SELECT_MODULE_INDICATOR],
[
dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
AC_DEFUN([gl_SYS_SELECT_H_DEFAULTS],
[
GNULIB_PSELECT=0; AC_SUBST([GNULIB_PSELECT])
GNULIB_SELECT=0; AC_SUBST([GNULIB_SELECT])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_PSELECT=1; AC_SUBST([HAVE_PSELECT])
REPLACE_PSELECT=0; AC_SUBST([REPLACE_PSELECT])
REPLACE_SELECT=0; AC_SUBST([REPLACE_SELECT])
])

177
m4/sys_socket_h.m4 Normal file
View file

@ -0,0 +1,177 @@
# sys_socket_h.m4 serial 22
dnl Copyright (C) 2005-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Simon Josefsson.
AC_DEFUN([gl_HEADER_SYS_SOCKET],
[
AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_C_INLINE])
dnl On OSF/1, the functions recv(), send(), recvfrom(), sendto() have
dnl old-style declarations (with return type 'int' instead of 'ssize_t')
dnl unless _POSIX_PII_SOCKET is defined.
case "$host_os" in
osf*)
AC_DEFINE([_POSIX_PII_SOCKET], [1],
[Define to 1 in order to get the POSIX compatible declarations
of socket functions.])
;;
esac
AC_CACHE_CHECK([whether <sys/socket.h> is self-contained],
[gl_cv_header_sys_socket_h_selfcontained],
[
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]], [[]])],
[gl_cv_header_sys_socket_h_selfcontained=yes],
[gl_cv_header_sys_socket_h_selfcontained=no])
])
if test $gl_cv_header_sys_socket_h_selfcontained = yes; then
dnl If the shutdown function exists, <sys/socket.h> should define
dnl SHUT_RD, SHUT_WR, SHUT_RDWR.
AC_CHECK_FUNCS([shutdown])
if test $ac_cv_func_shutdown = yes; then
AC_CACHE_CHECK([whether <sys/socket.h> defines the SHUT_* macros],
[gl_cv_header_sys_socket_h_shut],
[
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#include <sys/socket.h>]],
[[int a[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };]])],
[gl_cv_header_sys_socket_h_shut=yes],
[gl_cv_header_sys_socket_h_shut=no])
])
if test $gl_cv_header_sys_socket_h_shut = no; then
SYS_SOCKET_H='sys/socket.h'
fi
fi
fi
# We need to check for ws2tcpip.h now.
gl_PREREQ_SYS_H_SOCKET
AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[
/* sys/types.h is not needed according to POSIX, but the
sys/socket.h in i386-unknown-freebsd4.10 and
powerpc-apple-darwin5.5 required it. */
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
])
if test $ac_cv_type_struct_sockaddr_storage = no; then
HAVE_STRUCT_SOCKADDR_STORAGE=0
fi
if test $ac_cv_type_sa_family_t = no; then
HAVE_SA_FAMILY_T=0
fi
if test $ac_cv_type_struct_sockaddr_storage != no; then
AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family],
[],
[HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=0],
[#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
])
fi
if test $HAVE_STRUCT_SOCKADDR_STORAGE = 0 || test $HAVE_SA_FAMILY_T = 0 \
|| test $HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = 0; then
SYS_SOCKET_H='sys/socket.h'
fi
gl_PREREQ_SYS_H_WINSOCK2
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use.
gl_WARN_ON_USE_PREPARE([[
/* Some systems require prerequisite headers. */
#include <sys/types.h>
#include <sys/socket.h>
]], [socket connect accept bind getpeername getsockname getsockopt
listen recv send recvfrom sendto setsockopt shutdown accept4])
])
AC_DEFUN([gl_PREREQ_SYS_H_SOCKET],
[
dnl Check prerequisites of the <sys/socket.h> replacement.
AC_REQUIRE([gl_CHECK_SOCKET_HEADERS])
gl_CHECK_NEXT_HEADERS([sys/socket.h])
if test $ac_cv_header_sys_socket_h = yes; then
HAVE_SYS_SOCKET_H=1
HAVE_WS2TCPIP_H=0
else
HAVE_SYS_SOCKET_H=0
if test $ac_cv_header_ws2tcpip_h = yes; then
HAVE_WS2TCPIP_H=1
else
HAVE_WS2TCPIP_H=0
fi
fi
AC_SUBST([HAVE_SYS_SOCKET_H])
AC_SUBST([HAVE_WS2TCPIP_H])
])
# Common prerequisites of the <sys/socket.h> replacement and of the
# <sys/select.h> replacement.
# Sets and substitutes HAVE_WINSOCK2_H.
AC_DEFUN([gl_PREREQ_SYS_H_WINSOCK2],
[
m4_ifdef([gl_UNISTD_H_DEFAULTS], [AC_REQUIRE([gl_UNISTD_H_DEFAULTS])])
m4_ifdef([gl_SYS_IOCTL_H_DEFAULTS], [AC_REQUIRE([gl_SYS_IOCTL_H_DEFAULTS])])
AC_CHECK_HEADERS_ONCE([sys/socket.h])
if test $ac_cv_header_sys_socket_h != yes; then
dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make
dnl the check for those headers unconditional; yet cygwin reports
dnl that the headers are present but cannot be compiled (since on
dnl cygwin, all socket information should come from sys/socket.h).
AC_CHECK_HEADERS([winsock2.h])
fi
if test "$ac_cv_header_winsock2_h" = yes; then
HAVE_WINSOCK2_H=1
UNISTD_H_HAVE_WINSOCK2_H=1
SYS_IOCTL_H_HAVE_WINSOCK2_H=1
else
HAVE_WINSOCK2_H=0
fi
AC_SUBST([HAVE_WINSOCK2_H])
])
AC_DEFUN([gl_SYS_SOCKET_MODULE_INDICATOR],
[
dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS])
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS],
[
GNULIB_SOCKET=0; AC_SUBST([GNULIB_SOCKET])
GNULIB_CONNECT=0; AC_SUBST([GNULIB_CONNECT])
GNULIB_ACCEPT=0; AC_SUBST([GNULIB_ACCEPT])
GNULIB_BIND=0; AC_SUBST([GNULIB_BIND])
GNULIB_GETPEERNAME=0; AC_SUBST([GNULIB_GETPEERNAME])
GNULIB_GETSOCKNAME=0; AC_SUBST([GNULIB_GETSOCKNAME])
GNULIB_GETSOCKOPT=0; AC_SUBST([GNULIB_GETSOCKOPT])
GNULIB_LISTEN=0; AC_SUBST([GNULIB_LISTEN])
GNULIB_RECV=0; AC_SUBST([GNULIB_RECV])
GNULIB_SEND=0; AC_SUBST([GNULIB_SEND])
GNULIB_RECVFROM=0; AC_SUBST([GNULIB_RECVFROM])
GNULIB_SENDTO=0; AC_SUBST([GNULIB_SENDTO])
GNULIB_SETSOCKOPT=0; AC_SUBST([GNULIB_SETSOCKOPT])
GNULIB_SHUTDOWN=0; AC_SUBST([GNULIB_SHUTDOWN])
GNULIB_ACCEPT4=0; AC_SUBST([GNULIB_ACCEPT4])
HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE])
HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1;
AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY])
HAVE_SA_FAMILY_T=1; AC_SUBST([HAVE_SA_FAMILY_T])
HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4])
])

106
m4/sys_time_h.m4 Normal file
View file

@ -0,0 +1,106 @@
# Configure a replacement for <sys/time.h>.
# serial 8
# Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Written by Paul Eggert and Martin Lambers.
AC_DEFUN([gl_HEADER_SYS_TIME_H],
[
dnl Use AC_REQUIRE here, so that the REPLACE_GETTIMEOFDAY=0 statement
dnl below is expanded once only, before all REPLACE_GETTIMEOFDAY=1
dnl statements that occur in other macros.
AC_REQUIRE([gl_HEADER_SYS_TIME_H_BODY])
])
AC_DEFUN([gl_HEADER_SYS_TIME_H_BODY],
[
AC_REQUIRE([AC_C_RESTRICT])
AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
AC_CHECK_HEADERS_ONCE([sys/time.h])
gl_CHECK_NEXT_HEADERS([sys/time.h])
if test $ac_cv_header_sys_time_h != yes; then
HAVE_SYS_TIME_H=0
fi
dnl On native Windows with MSVC, 'struct timeval' is defined in <winsock2.h>
dnl only. So include that header in the list.
gl_PREREQ_SYS_H_WINSOCK2
AC_CACHE_CHECK([for struct timeval], [gl_cv_sys_struct_timeval],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <time.h>
#if HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
]],
[[static struct timeval x; x.tv_sec = x.tv_usec;]])],
[gl_cv_sys_struct_timeval=yes],
[gl_cv_sys_struct_timeval=no])
])
if test $gl_cv_sys_struct_timeval != yes; then
HAVE_STRUCT_TIMEVAL=0
else
dnl On native Windows with a 64-bit 'time_t', 'struct timeval' is defined
dnl (in <sys/time.h> and <winsock2.h> for mingw64, in <winsock2.h> only
dnl for MSVC) with a tv_sec field of type 'long' (32-bit!), which is
dnl smaller than the 'time_t' type mandated by POSIX.
AC_CACHE_CHECK([for correct struct timeval.tv_sec member],
[gl_cv_sys_struct_timeval_tv_sec],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <time.h>
#if HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
]],
[[static struct timeval x;
typedef int verify_tv_sec_type[sizeof (x.tv_sec) == sizeof (time_t) ? 1 : -1];
]])],
[gl_cv_sys_struct_timeval_tv_sec=yes],
[gl_cv_sys_struct_timeval_tv_sec=no])
])
if test $gl_cv_sys_struct_timeval_tv_sec != yes; then
REPLACE_STRUCT_TIMEVAL=1
fi
fi
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use.
gl_WARN_ON_USE_PREPARE([[
#if HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <time.h>
]], [gettimeofday])
])
AC_DEFUN([gl_SYS_TIME_MODULE_INDICATOR],
[
dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
AC_DEFUN([gl_HEADER_SYS_TIME_H_DEFAULTS],
[
GNULIB_GETTIMEOFDAY=0; AC_SUBST([GNULIB_GETTIMEOFDAY])
dnl Assume POSIX behavior unless another module says otherwise.
HAVE_GETTIMEOFDAY=1; AC_SUBST([HAVE_GETTIMEOFDAY])
HAVE_STRUCT_TIMEVAL=1; AC_SUBST([HAVE_STRUCT_TIMEVAL])
HAVE_SYS_TIME_H=1; AC_SUBST([HAVE_SYS_TIME_H])
REPLACE_GETTIMEOFDAY=0; AC_SUBST([REPLACE_GETTIMEOFDAY])
REPLACE_STRUCT_TIMEVAL=0; AC_SUBST([REPLACE_STRUCT_TIMEVAL])
])

15
m4/timespec.m4 Normal file
View file

@ -0,0 +1,15 @@
#serial 14
# Copyright (C) 2000-2001, 2003-2007, 2009-2012 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
dnl From Jim Meyering
AC_DEFUN([gl_TIMESPEC],
[
dnl Prerequisites of lib/timespec.h.
AC_REQUIRE([AC_C_INLINE])
])

39
m4/utimbuf.m4 Normal file
View file

@ -0,0 +1,39 @@
# serial 9
# Copyright (C) 1998-2001, 2003-2004, 2007, 2009-2012 Free Software Foundation,
# Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
dnl From Jim Meyering
dnl Define HAVE_STRUCT_UTIMBUF if 'struct utimbuf' is declared --
dnl usually in <utime.h>.
dnl Some systems have utime.h but don't declare the struct anywhere.
AC_DEFUN([gl_CHECK_TYPE_STRUCT_UTIMBUF],
[
AC_CHECK_HEADERS_ONCE([sys/time.h utime.h])
AC_CACHE_CHECK([for struct utimbuf], [gl_cv_sys_struct_utimbuf],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <time.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
]],
[[static struct utimbuf x; x.actime = x.modtime;]])],
[gl_cv_sys_struct_utimbuf=yes],
[gl_cv_sys_struct_utimbuf=no])])
if test $gl_cv_sys_struct_utimbuf = yes; then
AC_DEFINE([HAVE_STRUCT_UTIMBUF], [1],
[Define if struct utimbuf is declared -- usually in <utime.h>.
Some systems have utime.h but don't declare the struct anywhere. ])
fi
])

50
m4/utimens.m4 Normal file
View file

@ -0,0 +1,50 @@
dnl Copyright (C) 2003-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl serial 7
AC_DEFUN([gl_UTIMENS],
[
dnl Prerequisites of lib/utimens.c.
AC_REQUIRE([gl_FUNC_UTIMES])
AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC])
AC_REQUIRE([gl_CHECK_TYPE_STRUCT_UTIMBUF])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_CHECK_FUNCS_ONCE([futimes futimesat futimens utimensat lutimes])
if test $ac_cv_func_futimens = no && test $ac_cv_func_futimesat = yes; then
dnl FreeBSD 8.0-rc2 mishandles futimesat(fd,NULL,time). It is not
dnl standardized, but Solaris implemented it first and uses it as
dnl its only means to set fd time.
AC_CACHE_CHECK([whether futimesat handles NULL file],
[gl_cv_func_futimesat_works],
[touch conftest.file
AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <stddef.h>
#include <sys/times.h>
#include <fcntl.h>
]], [[ int fd = open ("conftest.file", O_RDWR);
if (fd < 0) return 1;
if (futimesat (fd, NULL, NULL)) return 2;
]])],
[gl_cv_func_futimesat_works=yes],
[gl_cv_func_futimesat_works=no],
[case "$host_os" in
# Guess yes on glibc systems.
*-gnu*) gl_cv_func_futimesat_works="guessing yes" ;;
# If we don't know, assume the worst.
*) gl_cv_func_futimesat_works="guessing no" ;;
esac
])
rm -f conftest.file])
case "$gl_cv_func_futimesat_works" in
*yes) ;;
*)
AC_DEFINE([FUTIMESAT_NULL_BUG], [1],
[Define to 1 if futimesat mishandles a NULL file name.])
;;
esac
fi
])

136
m4/utimes.m4 Normal file
View file

@ -0,0 +1,136 @@
# Detect some bugs in glibc's implementation of utimes.
# serial 3
dnl Copyright (C) 2003-2005, 2009-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# See if we need to work around bugs in glibc's implementation of
# utimes from 2003-07-12 to 2003-09-17.
# First, there was a bug that would make utimes set mtime
# and atime to zero (1970-01-01) unconditionally.
# Then, there was code to round rather than truncate.
# Then, there was an implementation (sparc64, Linux-2.4.28, glibc-2.3.3)
# that didn't honor the NULL-means-set-to-current-time semantics.
# Finally, there was also a version of utimes that failed on read-only
# files, while utime worked fine (linux-2.2.20, glibc-2.2.5).
#
# From Jim Meyering, with suggestions from Paul Eggert.
AC_DEFUN([gl_FUNC_UTIMES],
[
AC_CACHE_CHECK([whether the utimes function works],
[gl_cv_func_working_utimes],
[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <utime.h>
static int
inorder (time_t a, time_t b, time_t c)
{
return a <= b && b <= c;
}
int
main ()
{
int result = 0;
char const *file = "conftest.utimes";
static struct timeval timeval[2] = {{9, 10}, {999999, 999999}};
/* Test whether utimes() essentially works. */
{
struct stat sbuf;
FILE *f = fopen (file, "w");
if (f == NULL)
result |= 1;
else if (fclose (f) != 0)
result |= 1;
else if (utimes (file, timeval) != 0)
result |= 2;
else if (lstat (file, &sbuf) != 0)
result |= 1;
else if (!(sbuf.st_atime == timeval[0].tv_sec
&& sbuf.st_mtime == timeval[1].tv_sec))
result |= 4;
if (unlink (file) != 0)
result |= 1;
}
/* Test whether utimes() with a NULL argument sets the file's timestamp
to the current time. Use 'fstat' as well as 'time' to
determine the "current" time, to accommodate NFS file systems
if there is a time skew between the host and the NFS server. */
{
int fd = open (file, O_WRONLY|O_CREAT, 0644);
if (fd < 0)
result |= 1;
else
{
time_t t0, t2;
struct stat st0, st1, st2;
if (time (&t0) == (time_t) -1)
result |= 1;
else if (fstat (fd, &st0) != 0)
result |= 1;
else if (utimes (file, timeval) != 0)
result |= 2;
else if (utimes (file, NULL) != 0)
result |= 8;
else if (fstat (fd, &st1) != 0)
result |= 1;
else if (write (fd, "\n", 1) != 1)
result |= 1;
else if (fstat (fd, &st2) != 0)
result |= 1;
else if (time (&t2) == (time_t) -1)
result |= 1;
else
{
int m_ok_POSIX = inorder (t0, st1.st_mtime, t2);
int m_ok_NFS = inorder (st0.st_mtime, st1.st_mtime, st2.st_mtime);
if (! (st1.st_atime == st1.st_mtime))
result |= 16;
if (! (m_ok_POSIX || m_ok_NFS))
result |= 32;
}
if (close (fd) != 0)
result |= 1;
}
if (unlink (file) != 0)
result |= 1;
}
/* Test whether utimes() with a NULL argument works on read-only files. */
{
int fd = open (file, O_WRONLY|O_CREAT, 0444);
if (fd < 0)
result |= 1;
else if (close (fd) != 0)
result |= 1;
else if (utimes (file, NULL) != 0)
result |= 64;
if (unlink (file) != 0)
result |= 1;
}
return result;
}
]])],
[gl_cv_func_working_utimes=yes],
[gl_cv_func_working_utimes=no],
[gl_cv_func_working_utimes=no])])
if test $gl_cv_func_working_utimes = yes; then
AC_DEFINE([HAVE_WORKING_UTIMES], [1], [Define if utimes works properly. ])
fi
])