diff options
| author | Paul Eggert | 2012-06-22 14:26:37 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-06-22 14:26:37 -0700 |
| commit | c8fff8630133fea7c4e279458d10d825e5028c62 (patch) | |
| tree | f8b8261fdf3596e1306a3d072e13ec572c9e3e65 | |
| parent | 36cec983d4e680e28e7066fda505910cd549f509 (diff) | |
| download | emacs-c8fff8630133fea7c4e279458d10d825e5028c62.tar.gz emacs-c8fff8630133fea7c4e279458d10d825e5028c62.zip | |
Add gnulib files to support higher-resolution time stamps.
Fixes: debbugs:9000
| -rw-r--r-- | lib/dtotimespec.c | 69 | ||||
| -rw-r--r-- | lib/gettime.c | 48 | ||||
| -rw-r--r-- | lib/gettimeofday.c | 154 | ||||
| -rw-r--r-- | lib/pselect.c | 76 | ||||
| -rw-r--r-- | lib/stat-time.h | 189 | ||||
| -rw-r--r-- | lib/sys_select.in.h | 298 | ||||
| -rw-r--r-- | lib/sys_time.in.h | 205 | ||||
| -rw-r--r-- | lib/timespec-add.c | 71 | ||||
| -rw-r--r-- | lib/timespec-sub.c | 72 | ||||
| -rw-r--r-- | lib/timespec.h | 82 | ||||
| -rw-r--r-- | lib/utimens.c | 533 | ||||
| -rw-r--r-- | lib/utimens.h | 19 | ||||
| -rw-r--r-- | m4/clock_time.m4 | 31 | ||||
| -rw-r--r-- | m4/gettime.m4 | 13 | ||||
| -rw-r--r-- | m4/gettimeofday.m4 | 140 | ||||
| -rw-r--r-- | m4/pselect.m4 | 31 | ||||
| -rw-r--r-- | m4/stat-time.m4 | 85 | ||||
| -rw-r--r-- | m4/sys_select_h.m4 | 95 | ||||
| -rw-r--r-- | m4/sys_socket_h.m4 | 177 | ||||
| -rw-r--r-- | m4/sys_time_h.m4 | 106 | ||||
| -rw-r--r-- | m4/timespec.m4 | 15 | ||||
| -rw-r--r-- | m4/utimbuf.m4 | 39 | ||||
| -rw-r--r-- | m4/utimens.m4 | 50 | ||||
| -rw-r--r-- | m4/utimes.m4 | 136 |
24 files changed, 2734 insertions, 0 deletions
diff --git a/lib/dtotimespec.c b/lib/dtotimespec.c new file mode 100644 index 00000000000..f30fa075077 --- /dev/null +++ b/lib/dtotimespec.c | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | /* Convert double to timespec. | ||
| 2 | |||
| 3 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* written by Paul Eggert */ | ||
| 19 | |||
| 20 | /* Convert the double value SEC to a struct timespec. Round toward | ||
| 21 | positive infinity. On overflow, return an extremal value. */ | ||
| 22 | |||
| 23 | #include <config.h> | ||
| 24 | |||
| 25 | #include "timespec.h" | ||
| 26 | |||
| 27 | #include "intprops.h" | ||
| 28 | |||
| 29 | struct timespec | ||
| 30 | dtotimespec (double sec) | ||
| 31 | { | ||
| 32 | enum { BILLION = 1000 * 1000 * 1000 }; | ||
| 33 | double min_representable = TYPE_MINIMUM (time_t); | ||
| 34 | double max_representable = | ||
| 35 | ((TYPE_MAXIMUM (time_t) * (double) BILLION + (BILLION - 1)) | ||
| 36 | / BILLION); | ||
| 37 | struct timespec r; | ||
| 38 | |||
| 39 | if (! (min_representable < sec)) | ||
| 40 | { | ||
| 41 | r.tv_sec = TYPE_MINIMUM (time_t); | ||
| 42 | r.tv_nsec = 0; | ||
| 43 | } | ||
| 44 | else if (! (sec < max_representable)) | ||
| 45 | { | ||
| 46 | r.tv_sec = TYPE_MAXIMUM (time_t); | ||
| 47 | r.tv_nsec = BILLION - 1; | ||
| 48 | } | ||
| 49 | else | ||
| 50 | { | ||
| 51 | time_t s = sec; | ||
| 52 | double frac = BILLION * (sec - s); | ||
| 53 | long ns = frac; | ||
| 54 | ns += ns < frac; | ||
| 55 | s += ns / BILLION; | ||
| 56 | ns %= BILLION; | ||
| 57 | |||
| 58 | if (ns < 0) | ||
| 59 | { | ||
| 60 | s--; | ||
| 61 | ns += BILLION; | ||
| 62 | } | ||
| 63 | |||
| 64 | r.tv_sec = s; | ||
| 65 | r.tv_nsec = ns; | ||
| 66 | } | ||
| 67 | |||
| 68 | return r; | ||
| 69 | } | ||
diff --git a/lib/gettime.c b/lib/gettime.c new file mode 100644 index 00000000000..8075bfaf999 --- /dev/null +++ b/lib/gettime.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* gettime -- get the system clock | ||
| 2 | |||
| 3 | Copyright (C) 2002, 2004-2007, 2009-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | #include "timespec.h" | ||
| 23 | |||
| 24 | #include <sys/time.h> | ||
| 25 | |||
| 26 | /* Get the system time into *TS. */ | ||
| 27 | |||
| 28 | void | ||
| 29 | gettime (struct timespec *ts) | ||
| 30 | { | ||
| 31 | #if HAVE_NANOTIME | ||
| 32 | nanotime (ts); | ||
| 33 | #else | ||
| 34 | |||
| 35 | # if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME | ||
| 36 | if (clock_gettime (CLOCK_REALTIME, ts) == 0) | ||
| 37 | return; | ||
| 38 | # endif | ||
| 39 | |||
| 40 | { | ||
| 41 | struct timeval tv; | ||
| 42 | gettimeofday (&tv, NULL); | ||
| 43 | ts->tv_sec = tv.tv_sec; | ||
| 44 | ts->tv_nsec = tv.tv_usec * 1000; | ||
| 45 | } | ||
| 46 | |||
| 47 | #endif | ||
| 48 | } | ||
diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c new file mode 100644 index 00000000000..5d35060950a --- /dev/null +++ b/lib/gettimeofday.c | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | /* Provide gettimeofday for systems that don't have it or for which it's broken. | ||
| 2 | |||
| 3 | Copyright (C) 2001-2003, 2005-2007, 2009-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3, or (at your option) | ||
| 8 | any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* written by Jim Meyering */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | /* Specification. */ | ||
| 23 | #include <sys/time.h> | ||
| 24 | |||
| 25 | #include <time.h> | ||
| 26 | |||
| 27 | #if HAVE_SYS_TIMEB_H | ||
| 28 | # include <sys/timeb.h> | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME | ||
| 32 | |||
| 33 | /* Work around the bug in some systems whereby gettimeofday clobbers | ||
| 34 | the static buffer that localtime uses for its return value. The | ||
| 35 | gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has | ||
| 36 | this problem. The tzset replacement is necessary for at least | ||
| 37 | Solaris 2.5, 2.5.1, and 2.6. */ | ||
| 38 | |||
| 39 | static struct tm tm_zero_buffer; | ||
| 40 | static struct tm *localtime_buffer_addr = &tm_zero_buffer; | ||
| 41 | |||
| 42 | # undef localtime | ||
| 43 | extern struct tm *localtime (time_t const *); | ||
| 44 | |||
| 45 | # undef gmtime | ||
| 46 | extern struct tm *gmtime (time_t const *); | ||
| 47 | |||
| 48 | /* This is a wrapper for localtime. It is used only on systems for which | ||
| 49 | gettimeofday clobbers the static buffer used for localtime's result. | ||
| 50 | |||
| 51 | On the first call, record the address of the static buffer that | ||
| 52 | localtime uses for its result. */ | ||
| 53 | |||
| 54 | struct tm * | ||
| 55 | rpl_localtime (time_t const *timep) | ||
| 56 | { | ||
| 57 | struct tm *tm = localtime (timep); | ||
| 58 | |||
| 59 | if (localtime_buffer_addr == &tm_zero_buffer) | ||
| 60 | localtime_buffer_addr = tm; | ||
| 61 | |||
| 62 | return tm; | ||
| 63 | } | ||
| 64 | |||
| 65 | /* Same as above, since gmtime and localtime use the same buffer. */ | ||
| 66 | struct tm * | ||
| 67 | rpl_gmtime (time_t const *timep) | ||
| 68 | { | ||
| 69 | struct tm *tm = gmtime (timep); | ||
| 70 | |||
| 71 | if (localtime_buffer_addr == &tm_zero_buffer) | ||
| 72 | localtime_buffer_addr = tm; | ||
| 73 | |||
| 74 | return tm; | ||
| 75 | } | ||
| 76 | |||
| 77 | #endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */ | ||
| 78 | |||
| 79 | #if TZSET_CLOBBERS_LOCALTIME | ||
| 80 | |||
| 81 | # undef tzset | ||
| 82 | extern void tzset (void); | ||
| 83 | |||
| 84 | /* This is a wrapper for tzset, for systems on which tzset may clobber | ||
| 85 | the static buffer used for localtime's result. */ | ||
| 86 | void | ||
| 87 | rpl_tzset (void) | ||
| 88 | { | ||
| 89 | /* Save and restore the contents of the buffer used for localtime's | ||
| 90 | result around the call to tzset. */ | ||
| 91 | struct tm save = *localtime_buffer_addr; | ||
| 92 | tzset (); | ||
| 93 | *localtime_buffer_addr = save; | ||
| 94 | } | ||
| 95 | #endif | ||
| 96 | |||
| 97 | /* This is a wrapper for gettimeofday. It is used only on systems | ||
| 98 | that lack this function, or whose implementation of this function | ||
| 99 | causes problems. */ | ||
| 100 | |||
| 101 | int | ||
| 102 | gettimeofday (struct timeval *restrict tv, void *restrict tz) | ||
| 103 | { | ||
| 104 | #undef gettimeofday | ||
| 105 | #if HAVE_GETTIMEOFDAY | ||
| 106 | # if GETTIMEOFDAY_CLOBBERS_LOCALTIME | ||
| 107 | /* Save and restore the contents of the buffer used for localtime's | ||
| 108 | result around the call to gettimeofday. */ | ||
| 109 | struct tm save = *localtime_buffer_addr; | ||
| 110 | # endif | ||
| 111 | |||
| 112 | # if defined timeval /* 'struct timeval' overridden by gnulib? */ | ||
| 113 | # undef timeval | ||
| 114 | struct timeval otv; | ||
| 115 | int result = gettimeofday (&otv, (struct timezone *) tz); | ||
| 116 | if (result == 0) | ||
| 117 | { | ||
| 118 | tv->tv_sec = otv.tv_sec; | ||
| 119 | tv->tv_usec = otv.tv_usec; | ||
| 120 | } | ||
| 121 | # else | ||
| 122 | int result = gettimeofday (tv, (struct timezone *) tz); | ||
| 123 | # endif | ||
| 124 | |||
| 125 | # if GETTIMEOFDAY_CLOBBERS_LOCALTIME | ||
| 126 | *localtime_buffer_addr = save; | ||
| 127 | # endif | ||
| 128 | |||
| 129 | return result; | ||
| 130 | |||
| 131 | #else | ||
| 132 | |||
| 133 | # if HAVE__FTIME | ||
| 134 | |||
| 135 | struct _timeb timebuf; | ||
| 136 | _ftime (&timebuf); | ||
| 137 | tv->tv_sec = timebuf.time; | ||
| 138 | tv->tv_usec = timebuf.millitm * 1000; | ||
| 139 | |||
| 140 | # else | ||
| 141 | |||
| 142 | # if !defined OK_TO_USE_1S_CLOCK | ||
| 143 | # error "Only 1-second nominal clock resolution found. Is that intended?" \ | ||
| 144 | "If so, compile with the -DOK_TO_USE_1S_CLOCK option." | ||
| 145 | # endif | ||
| 146 | tv->tv_sec = time (NULL); | ||
| 147 | tv->tv_usec = 0; | ||
| 148 | |||
| 149 | # endif | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | |||
| 153 | #endif | ||
| 154 | } | ||
diff --git a/lib/pselect.c b/lib/pselect.c new file mode 100644 index 00000000000..d8ebc70f6c6 --- /dev/null +++ b/lib/pselect.c | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* pselect - synchronous I/O multiplexing | ||
| 2 | |||
| 3 | Copyright 2011-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of gnulib. | ||
| 6 | |||
| 7 | This program is free software; you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation; either version 3, or (at your option) | ||
| 10 | any later version. | ||
| 11 | |||
| 12 | This program is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License along | ||
| 18 | with this program; if not, see <http://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | /* written by Paul Eggert */ | ||
| 21 | |||
| 22 | #include <config.h> | ||
| 23 | |||
| 24 | #include <sys/select.h> | ||
| 25 | |||
| 26 | #include <errno.h> | ||
| 27 | #include <signal.h> | ||
| 28 | |||
| 29 | /* Examine the size-NFDS file descriptor sets in RFDS, WFDS, and XFDS | ||
| 30 | to see whether some of their descriptors are ready for reading, | ||
| 31 | ready for writing, or have exceptions pending. Wait for at most | ||
| 32 | TIMEOUT seconds, and use signal mask SIGMASK while waiting. A null | ||
| 33 | pointer parameter stands for no descriptors, an infinite timeout, | ||
| 34 | or an unaffected signal mask. */ | ||
| 35 | |||
| 36 | int | ||
| 37 | pselect (int nfds, fd_set *restrict rfds, | ||
| 38 | fd_set *restrict wfds, fd_set *restrict xfds, | ||
| 39 | struct timespec const *restrict timeout, | ||
| 40 | sigset_t const *restrict sigmask) | ||
| 41 | { | ||
| 42 | int select_result; | ||
| 43 | sigset_t origmask; | ||
| 44 | struct timeval tv, *tvp; | ||
| 45 | |||
| 46 | if (timeout) | ||
| 47 | { | ||
| 48 | if (! (0 <= timeout->tv_nsec && timeout->tv_nsec < 1000000000)) | ||
| 49 | { | ||
| 50 | errno = EINVAL; | ||
| 51 | return -1; | ||
| 52 | } | ||
| 53 | |||
| 54 | tv.tv_sec = timeout->tv_sec; | ||
| 55 | tv.tv_usec = (timeout->tv_nsec + 999) / 1000; | ||
| 56 | tvp = &tv; | ||
| 57 | } | ||
| 58 | else | ||
| 59 | tvp = NULL; | ||
| 60 | |||
| 61 | /* Signal mask munging should be atomic, but this is the best we can | ||
| 62 | do in this emulation. */ | ||
| 63 | if (sigmask) | ||
| 64 | pthread_sigmask (SIG_SETMASK, sigmask, &origmask); | ||
| 65 | |||
| 66 | select_result = select (nfds, rfds, wfds, xfds, tvp); | ||
| 67 | |||
| 68 | if (sigmask) | ||
| 69 | { | ||
| 70 | int select_errno = errno; | ||
| 71 | pthread_sigmask (SIG_SETMASK, &origmask, NULL); | ||
| 72 | errno = select_errno; | ||
| 73 | } | ||
| 74 | |||
| 75 | return select_result; | ||
| 76 | } | ||
diff --git a/lib/stat-time.h b/lib/stat-time.h new file mode 100644 index 00000000000..30c2acdab63 --- /dev/null +++ b/lib/stat-time.h | |||
| @@ -0,0 +1,189 @@ | |||
| 1 | /* stat-related time functions. | ||
| 2 | |||
| 3 | Copyright (C) 2005, 2007, 2009-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | #ifndef STAT_TIME_H | ||
| 21 | #define STAT_TIME_H 1 | ||
| 22 | |||
| 23 | #include <sys/stat.h> | ||
| 24 | #include <time.h> | ||
| 25 | |||
| 26 | /* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type | ||
| 27 | struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST, | ||
| 28 | ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST, | ||
| 29 | if available. ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim | ||
| 30 | for access, status change, data modification, or birth (creation) | ||
| 31 | time respectively. | ||
| 32 | |||
| 33 | These macros are private to stat-time.h. */ | ||
| 34 | #if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC | ||
| 35 | # ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC | ||
| 36 | # define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim) | ||
| 37 | # else | ||
| 38 | # define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec) | ||
| 39 | # endif | ||
| 40 | #elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC | ||
| 41 | # define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec) | ||
| 42 | #elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC | ||
| 43 | # define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec) | ||
| 44 | #elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC | ||
| 45 | # define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec) | ||
| 46 | #endif | ||
| 47 | |||
| 48 | /* Return the nanosecond component of *ST's access time. */ | ||
| 49 | static inline long int | ||
| 50 | get_stat_atime_ns (struct stat const *st) | ||
| 51 | { | ||
| 52 | # if defined STAT_TIMESPEC | ||
| 53 | return STAT_TIMESPEC (st, st_atim).tv_nsec; | ||
| 54 | # elif defined STAT_TIMESPEC_NS | ||
| 55 | return STAT_TIMESPEC_NS (st, st_atim); | ||
| 56 | # else | ||
| 57 | return 0; | ||
| 58 | # endif | ||
| 59 | } | ||
| 60 | |||
| 61 | /* Return the nanosecond component of *ST's status change time. */ | ||
| 62 | static inline long int | ||
| 63 | get_stat_ctime_ns (struct stat const *st) | ||
| 64 | { | ||
| 65 | # if defined STAT_TIMESPEC | ||
| 66 | return STAT_TIMESPEC (st, st_ctim).tv_nsec; | ||
| 67 | # elif defined STAT_TIMESPEC_NS | ||
| 68 | return STAT_TIMESPEC_NS (st, st_ctim); | ||
| 69 | # else | ||
| 70 | return 0; | ||
| 71 | # endif | ||
| 72 | } | ||
| 73 | |||
| 74 | /* Return the nanosecond component of *ST's data modification time. */ | ||
| 75 | static inline long int | ||
| 76 | get_stat_mtime_ns (struct stat const *st) | ||
| 77 | { | ||
| 78 | # if defined STAT_TIMESPEC | ||
| 79 | return STAT_TIMESPEC (st, st_mtim).tv_nsec; | ||
| 80 | # elif defined STAT_TIMESPEC_NS | ||
| 81 | return STAT_TIMESPEC_NS (st, st_mtim); | ||
| 82 | # else | ||
| 83 | return 0; | ||
| 84 | # endif | ||
| 85 | } | ||
| 86 | |||
| 87 | /* Return the nanosecond component of *ST's birth time. */ | ||
| 88 | static inline long int | ||
| 89 | get_stat_birthtime_ns (struct stat const *st) | ||
| 90 | { | ||
| 91 | # if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC | ||
| 92 | return STAT_TIMESPEC (st, st_birthtim).tv_nsec; | ||
| 93 | # elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC | ||
| 94 | return STAT_TIMESPEC_NS (st, st_birthtim); | ||
| 95 | # else | ||
| 96 | /* Avoid a "parameter unused" warning. */ | ||
| 97 | (void) st; | ||
| 98 | return 0; | ||
| 99 | # endif | ||
| 100 | } | ||
| 101 | |||
| 102 | /* Return *ST's access time. */ | ||
| 103 | static inline struct timespec | ||
| 104 | get_stat_atime (struct stat const *st) | ||
| 105 | { | ||
| 106 | #ifdef STAT_TIMESPEC | ||
| 107 | return STAT_TIMESPEC (st, st_atim); | ||
| 108 | #else | ||
| 109 | struct timespec t; | ||
| 110 | t.tv_sec = st->st_atime; | ||
| 111 | t.tv_nsec = get_stat_atime_ns (st); | ||
| 112 | return t; | ||
| 113 | #endif | ||
| 114 | } | ||
| 115 | |||
| 116 | /* Return *ST's status change time. */ | ||
| 117 | static inline struct timespec | ||
| 118 | get_stat_ctime (struct stat const *st) | ||
| 119 | { | ||
| 120 | #ifdef STAT_TIMESPEC | ||
| 121 | return STAT_TIMESPEC (st, st_ctim); | ||
| 122 | #else | ||
| 123 | struct timespec t; | ||
| 124 | t.tv_sec = st->st_ctime; | ||
| 125 | t.tv_nsec = get_stat_ctime_ns (st); | ||
| 126 | return t; | ||
| 127 | #endif | ||
| 128 | } | ||
| 129 | |||
| 130 | /* Return *ST's data modification time. */ | ||
| 131 | static inline struct timespec | ||
| 132 | get_stat_mtime (struct stat const *st) | ||
| 133 | { | ||
| 134 | #ifdef STAT_TIMESPEC | ||
| 135 | return STAT_TIMESPEC (st, st_mtim); | ||
| 136 | #else | ||
| 137 | struct timespec t; | ||
| 138 | t.tv_sec = st->st_mtime; | ||
| 139 | t.tv_nsec = get_stat_mtime_ns (st); | ||
| 140 | return t; | ||
| 141 | #endif | ||
| 142 | } | ||
| 143 | |||
| 144 | /* Return *ST's birth time, if available; otherwise return a value | ||
| 145 | with tv_sec and tv_nsec both equal to -1. */ | ||
| 146 | static inline struct timespec | ||
| 147 | get_stat_birthtime (struct stat const *st) | ||
| 148 | { | ||
| 149 | struct timespec t; | ||
| 150 | |||
| 151 | #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ | ||
| 152 | || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) | ||
| 153 | t = STAT_TIMESPEC (st, st_birthtim); | ||
| 154 | #elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC | ||
| 155 | t.tv_sec = st->st_birthtime; | ||
| 156 | t.tv_nsec = st->st_birthtimensec; | ||
| 157 | #elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 158 | /* Native Windows platforms (but not Cygwin) put the "file creation | ||
| 159 | time" in st_ctime (!). See | ||
| 160 | <http://msdn2.microsoft.com/de-de/library/14h5k7ff(VS.80).aspx>. */ | ||
| 161 | t.tv_sec = st->st_ctime; | ||
| 162 | t.tv_nsec = 0; | ||
| 163 | #else | ||
| 164 | /* Birth time is not supported. */ | ||
| 165 | t.tv_sec = -1; | ||
| 166 | t.tv_nsec = -1; | ||
| 167 | /* Avoid a "parameter unused" warning. */ | ||
| 168 | (void) st; | ||
| 169 | #endif | ||
| 170 | |||
| 171 | #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ | ||
| 172 | || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \ | ||
| 173 | || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) | ||
| 174 | /* FreeBSD and NetBSD sometimes signal the absence of knowledge by | ||
| 175 | using zero. Attempt to work around this problem. Alas, this can | ||
| 176 | report failure even for valid time stamps. Also, NetBSD | ||
| 177 | sometimes returns junk in the birth time fields; work around this | ||
| 178 | bug if it is detected. */ | ||
| 179 | if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) | ||
| 180 | { | ||
| 181 | t.tv_sec = -1; | ||
| 182 | t.tv_nsec = -1; | ||
| 183 | } | ||
| 184 | #endif | ||
| 185 | |||
| 186 | return t; | ||
| 187 | } | ||
| 188 | |||
| 189 | #endif | ||
diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h new file mode 100644 index 00000000000..0aee2a16cbf --- /dev/null +++ b/lib/sys_select.in.h | |||
| @@ -0,0 +1,298 @@ | |||
| 1 | /* Substitute for <sys/select.h>. | ||
| 2 | Copyright (C) 2007-2012 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 3, or (at your option) | ||
| 7 | any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, see <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | # if __GNUC__ >= 3 | ||
| 18 | @PRAGMA_SYSTEM_HEADER@ | ||
| 19 | # endif | ||
| 20 | @PRAGMA_COLUMNS@ | ||
| 21 | |||
| 22 | /* On OSF/1, <sys/types.h> and <sys/time.h> include <sys/select.h>. | ||
| 23 | Simply delegate to the system's header in this case. */ | ||
| 24 | #if @HAVE_SYS_SELECT_H@ && defined __osf__ && (defined _SYS_TYPES_H_ && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H) && defined _OSF_SOURCE | ||
| 25 | |||
| 26 | # define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H | ||
| 27 | # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ | ||
| 28 | |||
| 29 | #elif @HAVE_SYS_SELECT_H@ && defined __osf__ && (defined _SYS_TIME_H_ && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H) && defined _OSF_SOURCE | ||
| 30 | |||
| 31 | # define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H | ||
| 32 | # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ | ||
| 33 | |||
| 34 | /* On IRIX 6.5, <sys/timespec.h> includes <sys/types.h>, which includes | ||
| 35 | <sys/bsd_types.h>, which includes <sys/select.h>. At this point we cannot | ||
| 36 | include <signal.h>, because that includes <internal/signal_core.h>, which | ||
| 37 | gives a syntax error because <sys/timespec.h> has not been completely | ||
| 38 | processed. Simply delegate to the system's header in this case. */ | ||
| 39 | #elif @HAVE_SYS_SELECT_H@ && defined __sgi && (defined _SYS_BSD_TYPES_H && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H) | ||
| 40 | |||
| 41 | # define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H | ||
| 42 | # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ | ||
| 43 | |||
| 44 | /* On OpenBSD 5.0, <pthread.h> includes <sys/types.h>, which includes | ||
| 45 | <sys/select.h>. At this point we cannot include <signal.h>, because that | ||
| 46 | includes gnulib's pthread.h override, which gives a syntax error because | ||
| 47 | /usr/include/pthread.h has not been completely processed. Simply delegate | ||
| 48 | to the system's header in this case. */ | ||
| 49 | #elif @HAVE_SYS_SELECT_H@ && defined __OpenBSD__ && (defined _PTHREAD_H_ && !defined PTHREAD_MUTEX_INITIALIZER) | ||
| 50 | |||
| 51 | # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ | ||
| 52 | |||
| 53 | #else | ||
| 54 | |||
| 55 | #ifndef _@GUARD_PREFIX@_SYS_SELECT_H | ||
| 56 | |||
| 57 | /* On many platforms, <sys/select.h> assumes prior inclusion of | ||
| 58 | <sys/types.h>. Also, mingw defines sigset_t there, instead of | ||
| 59 | in <signal.h> where it belongs. */ | ||
| 60 | #include <sys/types.h> | ||
| 61 | |||
| 62 | #if @HAVE_SYS_SELECT_H@ | ||
| 63 | |||
| 64 | /* On OSF/1 4.0, <sys/select.h> provides only a forward declaration | ||
| 65 | of 'struct timeval', and no definition of this type. | ||
| 66 | Also, Mac OS X, AIX, HP-UX, IRIX, Solaris, Interix declare select() | ||
| 67 | in <sys/time.h>. | ||
| 68 | But avoid namespace pollution on glibc systems. */ | ||
| 69 | # ifndef __GLIBC__ | ||
| 70 | # include <sys/time.h> | ||
| 71 | # endif | ||
| 72 | |||
| 73 | /* On AIX 7 and Solaris 10, <sys/select.h> provides an FD_ZERO implementation | ||
| 74 | that relies on memset(), but without including <string.h>. | ||
| 75 | But in any case avoid namespace pollution on glibc systems. */ | ||
| 76 | # if (defined __OpenBSD__ || defined _AIX || defined __sun || defined __osf__ || defined __BEOS__) \ | ||
| 77 | && ! defined __GLIBC__ | ||
| 78 | # include <string.h> | ||
| 79 | # endif | ||
| 80 | |||
| 81 | /* The include_next requires a split double-inclusion guard. */ | ||
| 82 | # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ | ||
| 83 | |||
| 84 | #endif | ||
| 85 | |||
| 86 | /* Get definition of 'sigset_t'. | ||
| 87 | But avoid namespace pollution on glibc systems. | ||
| 88 | Do this after the include_next (for the sake of OpenBSD 5.0) but before | ||
| 89 | the split double-inclusion guard (for the sake of Solaris). */ | ||
| 90 | #if !(defined __GLIBC__ && !defined __UCLIBC__) | ||
| 91 | # include <signal.h> | ||
| 92 | #endif | ||
| 93 | |||
| 94 | #ifndef _@GUARD_PREFIX@_SYS_SELECT_H | ||
| 95 | #define _@GUARD_PREFIX@_SYS_SELECT_H | ||
| 96 | |||
| 97 | #if !@HAVE_SYS_SELECT_H@ | ||
| 98 | /* A platform that lacks <sys/select.h>. */ | ||
| 99 | /* Get the 'struct timeval' and 'fd_set' types and the FD_* macros | ||
| 100 | on most platforms. */ | ||
| 101 | # include <sys/time.h> | ||
| 102 | /* On HP-UX 11, <sys/time.h> provides an FD_ZERO implementation | ||
| 103 | that relies on memset(), but without including <string.h>. */ | ||
| 104 | # if defined __hpux | ||
| 105 | # include <string.h> | ||
| 106 | # endif | ||
| 107 | /* On native Windows platforms: | ||
| 108 | Get the 'fd_set' type. | ||
| 109 | Get the close() declaration before we override it. */ | ||
| 110 | # if @HAVE_WINSOCK2_H@ | ||
| 111 | # if !defined _GL_INCLUDING_WINSOCK2_H | ||
| 112 | # define _GL_INCLUDING_WINSOCK2_H | ||
| 113 | # include <winsock2.h> | ||
| 114 | # undef _GL_INCLUDING_WINSOCK2_H | ||
| 115 | # endif | ||
| 116 | # include <io.h> | ||
| 117 | # endif | ||
| 118 | #endif | ||
| 119 | |||
| 120 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 121 | |||
| 122 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 123 | |||
| 124 | |||
| 125 | /* Fix some definitions from <winsock2.h>. */ | ||
| 126 | |||
| 127 | #if @HAVE_WINSOCK2_H@ | ||
| 128 | |||
| 129 | # if !GNULIB_defined_rpl_fd_isset | ||
| 130 | |||
| 131 | /* Re-define FD_ISSET to avoid a WSA call while we are not using | ||
| 132 | network sockets. */ | ||
| 133 | static inline int | ||
| 134 | rpl_fd_isset (SOCKET fd, fd_set * set) | ||
| 135 | { | ||
| 136 | u_int i; | ||
| 137 | if (set == NULL) | ||
| 138 | return 0; | ||
| 139 | |||
| 140 | for (i = 0; i < set->fd_count; i++) | ||
| 141 | if (set->fd_array[i] == fd) | ||
| 142 | return 1; | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | # define GNULIB_defined_rpl_fd_isset 1 | ||
| 148 | # endif | ||
| 149 | |||
| 150 | # undef FD_ISSET | ||
| 151 | # define FD_ISSET(fd, set) rpl_fd_isset(fd, set) | ||
| 152 | |||
| 153 | #endif | ||
| 154 | |||
| 155 | /* Hide some function declarations from <winsock2.h>. */ | ||
| 156 | |||
| 157 | #if @HAVE_WINSOCK2_H@ | ||
| 158 | # if !defined _@GUARD_PREFIX@_UNISTD_H | ||
| 159 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 160 | # undef close | ||
| 161 | # define close close_used_without_including_unistd_h | ||
| 162 | # else | ||
| 163 | _GL_WARN_ON_USE (close, | ||
| 164 | "close() used without including <unistd.h>"); | ||
| 165 | # endif | ||
| 166 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 167 | # undef gethostname | ||
| 168 | # define gethostname gethostname_used_without_including_unistd_h | ||
| 169 | # else | ||
| 170 | _GL_WARN_ON_USE (gethostname, | ||
| 171 | "gethostname() used without including <unistd.h>"); | ||
| 172 | # endif | ||
| 173 | # endif | ||
| 174 | # if !defined _@GUARD_PREFIX@_SYS_SOCKET_H | ||
| 175 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 176 | # undef socket | ||
| 177 | # define socket socket_used_without_including_sys_socket_h | ||
| 178 | # undef connect | ||
| 179 | # define connect connect_used_without_including_sys_socket_h | ||
| 180 | # undef accept | ||
| 181 | # define accept accept_used_without_including_sys_socket_h | ||
| 182 | # undef bind | ||
| 183 | # define bind bind_used_without_including_sys_socket_h | ||
| 184 | # undef getpeername | ||
| 185 | # define getpeername getpeername_used_without_including_sys_socket_h | ||
| 186 | # undef getsockname | ||
| 187 | # define getsockname getsockname_used_without_including_sys_socket_h | ||
| 188 | # undef getsockopt | ||
| 189 | # define getsockopt getsockopt_used_without_including_sys_socket_h | ||
| 190 | # undef listen | ||
| 191 | # define listen listen_used_without_including_sys_socket_h | ||
| 192 | # undef recv | ||
| 193 | # define recv recv_used_without_including_sys_socket_h | ||
| 194 | # undef send | ||
| 195 | # define send send_used_without_including_sys_socket_h | ||
| 196 | # undef recvfrom | ||
| 197 | # define recvfrom recvfrom_used_without_including_sys_socket_h | ||
| 198 | # undef sendto | ||
| 199 | # define sendto sendto_used_without_including_sys_socket_h | ||
| 200 | # undef setsockopt | ||
| 201 | # define setsockopt setsockopt_used_without_including_sys_socket_h | ||
| 202 | # undef shutdown | ||
| 203 | # define shutdown shutdown_used_without_including_sys_socket_h | ||
| 204 | # else | ||
| 205 | _GL_WARN_ON_USE (socket, | ||
| 206 | "socket() used without including <sys/socket.h>"); | ||
| 207 | _GL_WARN_ON_USE (connect, | ||
| 208 | "connect() used without including <sys/socket.h>"); | ||
| 209 | _GL_WARN_ON_USE (accept, | ||
| 210 | "accept() used without including <sys/socket.h>"); | ||
| 211 | _GL_WARN_ON_USE (bind, | ||
| 212 | "bind() used without including <sys/socket.h>"); | ||
| 213 | _GL_WARN_ON_USE (getpeername, | ||
| 214 | "getpeername() used without including <sys/socket.h>"); | ||
| 215 | _GL_WARN_ON_USE (getsockname, | ||
| 216 | "getsockname() used without including <sys/socket.h>"); | ||
| 217 | _GL_WARN_ON_USE (getsockopt, | ||
| 218 | "getsockopt() used without including <sys/socket.h>"); | ||
| 219 | _GL_WARN_ON_USE (listen, | ||
| 220 | "listen() used without including <sys/socket.h>"); | ||
| 221 | _GL_WARN_ON_USE (recv, | ||
| 222 | "recv() used without including <sys/socket.h>"); | ||
| 223 | _GL_WARN_ON_USE (send, | ||
| 224 | "send() used without including <sys/socket.h>"); | ||
| 225 | _GL_WARN_ON_USE (recvfrom, | ||
| 226 | "recvfrom() used without including <sys/socket.h>"); | ||
| 227 | _GL_WARN_ON_USE (sendto, | ||
| 228 | "sendto() used without including <sys/socket.h>"); | ||
| 229 | _GL_WARN_ON_USE (setsockopt, | ||
| 230 | "setsockopt() used without including <sys/socket.h>"); | ||
| 231 | _GL_WARN_ON_USE (shutdown, | ||
| 232 | "shutdown() used without including <sys/socket.h>"); | ||
| 233 | # endif | ||
| 234 | # endif | ||
| 235 | #endif | ||
| 236 | |||
| 237 | |||
| 238 | #if @GNULIB_PSELECT@ | ||
| 239 | # if @REPLACE_PSELECT@ | ||
| 240 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 241 | # undef pselect | ||
| 242 | # define pselect rpl_pselect | ||
| 243 | # endif | ||
| 244 | _GL_FUNCDECL_RPL (pselect, int, | ||
| 245 | (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, | ||
| 246 | struct timespec const *restrict, const sigset_t *restrict)); | ||
| 247 | _GL_CXXALIAS_RPL (pselect, int, | ||
| 248 | (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, | ||
| 249 | struct timespec const *restrict, const sigset_t *restrict)); | ||
| 250 | # else | ||
| 251 | # if !@HAVE_PSELECT@ | ||
| 252 | _GL_FUNCDECL_SYS (pselect, int, | ||
| 253 | (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, | ||
| 254 | struct timespec const *restrict, const sigset_t *restrict)); | ||
| 255 | # endif | ||
| 256 | _GL_CXXALIAS_SYS (pselect, int, | ||
| 257 | (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, | ||
| 258 | struct timespec const *restrict, const sigset_t *restrict)); | ||
| 259 | # endif | ||
| 260 | _GL_CXXALIASWARN (pselect); | ||
| 261 | #elif defined GNULIB_POSIXCHECK | ||
| 262 | # undef pselect | ||
| 263 | # if HAVE_RAW_DECL_PSELECT | ||
| 264 | _GL_WARN_ON_USE (pselect, "pselect is not portable - " | ||
| 265 | "use gnulib module pselect for portability"); | ||
| 266 | # endif | ||
| 267 | #endif | ||
| 268 | |||
| 269 | #if @GNULIB_SELECT@ | ||
| 270 | # if @REPLACE_SELECT@ | ||
| 271 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 272 | # undef select | ||
| 273 | # define select rpl_select | ||
| 274 | # endif | ||
| 275 | _GL_FUNCDECL_RPL (select, int, | ||
| 276 | (int, fd_set *, fd_set *, fd_set *, struct timeval *)); | ||
| 277 | _GL_CXXALIAS_RPL (select, int, | ||
| 278 | (int, fd_set *, fd_set *, fd_set *, struct timeval *)); | ||
| 279 | # else | ||
| 280 | _GL_CXXALIAS_SYS (select, int, | ||
| 281 | (int, fd_set *, fd_set *, fd_set *, struct timeval *)); | ||
| 282 | # endif | ||
| 283 | _GL_CXXALIASWARN (select); | ||
| 284 | #elif @HAVE_WINSOCK2_H@ | ||
| 285 | # undef select | ||
| 286 | # define select select_used_without_requesting_gnulib_module_select | ||
| 287 | #elif defined GNULIB_POSIXCHECK | ||
| 288 | # undef select | ||
| 289 | # if HAVE_RAW_DECL_SELECT | ||
| 290 | _GL_WARN_ON_USE (select, "select is not always POSIX compliant - " | ||
| 291 | "use gnulib module select for portability"); | ||
| 292 | # endif | ||
| 293 | #endif | ||
| 294 | |||
| 295 | |||
| 296 | #endif /* _@GUARD_PREFIX@_SYS_SELECT_H */ | ||
| 297 | #endif /* _@GUARD_PREFIX@_SYS_SELECT_H */ | ||
| 298 | #endif /* OSF/1 */ | ||
diff --git a/lib/sys_time.in.h b/lib/sys_time.in.h new file mode 100644 index 00000000000..d915cee467a --- /dev/null +++ b/lib/sys_time.in.h | |||
| @@ -0,0 +1,205 @@ | |||
| 1 | /* Provide a more complete sys/time.h. | ||
| 2 | |||
| 3 | Copyright (C) 2007-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3, or (at your option) | ||
| 8 | any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | #if __GNUC__ >= 3 | ||
| 21 | @PRAGMA_SYSTEM_HEADER@ | ||
| 22 | #endif | ||
| 23 | @PRAGMA_COLUMNS@ | ||
| 24 | |||
| 25 | #if defined _@GUARD_PREFIX@_SYS_TIME_H | ||
| 26 | |||
| 27 | /* Simply delegate to the system's header, without adding anything. */ | ||
| 28 | # if @HAVE_SYS_TIME_H@ | ||
| 29 | # @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ | ||
| 30 | # endif | ||
| 31 | |||
| 32 | #else | ||
| 33 | |||
| 34 | # define _@GUARD_PREFIX@_SYS_TIME_H | ||
| 35 | |||
| 36 | # if @HAVE_SYS_TIME_H@ | ||
| 37 | # @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ | ||
| 38 | # else | ||
| 39 | # include <time.h> | ||
| 40 | # endif | ||
| 41 | |||
| 42 | /* On native Windows with MSVC, get the 'struct timeval' type. | ||
| 43 | Also, on native Windows with a 64-bit time_t, where we are overriding the | ||
| 44 | 'struct timeval' type, get all declarations of system functions whose | ||
| 45 | signature contains 'struct timeval'. */ | ||
| 46 | # if (defined _MSC_VER || @REPLACE_STRUCT_TIMEVAL@) && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H | ||
| 47 | # define _GL_INCLUDING_WINSOCK2_H | ||
| 48 | # include <winsock2.h> | ||
| 49 | # undef _GL_INCLUDING_WINSOCK2_H | ||
| 50 | # endif | ||
| 51 | |||
| 52 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 53 | |||
| 54 | /* The definition of _GL_ARG_NONNULL is copied here. */ | ||
| 55 | |||
| 56 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 57 | |||
| 58 | # ifdef __cplusplus | ||
| 59 | extern "C" { | ||
| 60 | # endif | ||
| 61 | |||
| 62 | # if !@HAVE_STRUCT_TIMEVAL@ || @REPLACE_STRUCT_TIMEVAL@ | ||
| 63 | |||
| 64 | # if @REPLACE_STRUCT_TIMEVAL@ | ||
| 65 | # define timeval rpl_timeval | ||
| 66 | # endif | ||
| 67 | |||
| 68 | # if !GNULIB_defined_struct_timeval | ||
| 69 | struct timeval | ||
| 70 | { | ||
| 71 | time_t tv_sec; | ||
| 72 | long int tv_usec; | ||
| 73 | }; | ||
| 74 | # define GNULIB_defined_struct_timeval 1 | ||
| 75 | # endif | ||
| 76 | |||
| 77 | # endif | ||
| 78 | |||
| 79 | # ifdef __cplusplus | ||
| 80 | } | ||
| 81 | # endif | ||
| 82 | |||
| 83 | # if @GNULIB_GETTIMEOFDAY@ | ||
| 84 | # if @REPLACE_GETTIMEOFDAY@ | ||
| 85 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 86 | # undef gettimeofday | ||
| 87 | # define gettimeofday rpl_gettimeofday | ||
| 88 | # endif | ||
| 89 | _GL_FUNCDECL_RPL (gettimeofday, int, | ||
| 90 | (struct timeval *restrict, void *restrict) | ||
| 91 | _GL_ARG_NONNULL ((1))); | ||
| 92 | _GL_CXXALIAS_RPL (gettimeofday, int, | ||
| 93 | (struct timeval *restrict, void *restrict)); | ||
| 94 | # else | ||
| 95 | # if !@HAVE_GETTIMEOFDAY@ | ||
| 96 | _GL_FUNCDECL_SYS (gettimeofday, int, | ||
| 97 | (struct timeval *restrict, void *restrict) | ||
| 98 | _GL_ARG_NONNULL ((1))); | ||
| 99 | # endif | ||
| 100 | /* Need to cast, because on glibc systems, by default, the second argument is | ||
| 101 | struct timezone *. */ | ||
| 102 | _GL_CXXALIAS_SYS_CAST (gettimeofday, int, | ||
| 103 | (struct timeval *restrict, void *restrict)); | ||
| 104 | # endif | ||
| 105 | _GL_CXXALIASWARN (gettimeofday); | ||
| 106 | # elif defined GNULIB_POSIXCHECK | ||
| 107 | # undef gettimeofday | ||
| 108 | # if HAVE_RAW_DECL_GETTIMEOFDAY | ||
| 109 | _GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - " | ||
| 110 | "use gnulib module gettimeofday for portability"); | ||
| 111 | # endif | ||
| 112 | # endif | ||
| 113 | |||
| 114 | /* Hide some function declarations from <winsock2.h>. */ | ||
| 115 | |||
| 116 | # if defined _MSC_VER && @HAVE_WINSOCK2_H@ | ||
| 117 | # if !defined _@GUARD_PREFIX@_UNISTD_H | ||
| 118 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 119 | # undef close | ||
| 120 | # define close close_used_without_including_unistd_h | ||
| 121 | # else | ||
| 122 | _GL_WARN_ON_USE (close, | ||
| 123 | "close() used without including <unistd.h>"); | ||
| 124 | # endif | ||
| 125 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 126 | # undef gethostname | ||
| 127 | # define gethostname gethostname_used_without_including_unistd_h | ||
| 128 | # else | ||
| 129 | _GL_WARN_ON_USE (gethostname, | ||
| 130 | "gethostname() used without including <unistd.h>"); | ||
| 131 | # endif | ||
| 132 | # endif | ||
| 133 | # if !defined _@GUARD_PREFIX@_SYS_SOCKET_H | ||
| 134 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 135 | # undef socket | ||
| 136 | # define socket socket_used_without_including_sys_socket_h | ||
| 137 | # undef connect | ||
| 138 | # define connect connect_used_without_including_sys_socket_h | ||
| 139 | # undef accept | ||
| 140 | # define accept accept_used_without_including_sys_socket_h | ||
| 141 | # undef bind | ||
| 142 | # define bind bind_used_without_including_sys_socket_h | ||
| 143 | # undef getpeername | ||
| 144 | # define getpeername getpeername_used_without_including_sys_socket_h | ||
| 145 | # undef getsockname | ||
| 146 | # define getsockname getsockname_used_without_including_sys_socket_h | ||
| 147 | # undef getsockopt | ||
| 148 | # define getsockopt getsockopt_used_without_including_sys_socket_h | ||
| 149 | # undef listen | ||
| 150 | # define listen listen_used_without_including_sys_socket_h | ||
| 151 | # undef recv | ||
| 152 | # define recv recv_used_without_including_sys_socket_h | ||
| 153 | # undef send | ||
| 154 | # define send send_used_without_including_sys_socket_h | ||
| 155 | # undef recvfrom | ||
| 156 | # define recvfrom recvfrom_used_without_including_sys_socket_h | ||
| 157 | # undef sendto | ||
| 158 | # define sendto sendto_used_without_including_sys_socket_h | ||
| 159 | # undef setsockopt | ||
| 160 | # define setsockopt setsockopt_used_without_including_sys_socket_h | ||
| 161 | # undef shutdown | ||
| 162 | # define shutdown shutdown_used_without_including_sys_socket_h | ||
| 163 | # else | ||
| 164 | _GL_WARN_ON_USE (socket, | ||
| 165 | "socket() used without including <sys/socket.h>"); | ||
| 166 | _GL_WARN_ON_USE (connect, | ||
| 167 | "connect() used without including <sys/socket.h>"); | ||
| 168 | _GL_WARN_ON_USE (accept, | ||
| 169 | "accept() used without including <sys/socket.h>"); | ||
| 170 | _GL_WARN_ON_USE (bind, | ||
| 171 | "bind() used without including <sys/socket.h>"); | ||
| 172 | _GL_WARN_ON_USE (getpeername, | ||
| 173 | "getpeername() used without including <sys/socket.h>"); | ||
| 174 | _GL_WARN_ON_USE (getsockname, | ||
| 175 | "getsockname() used without including <sys/socket.h>"); | ||
| 176 | _GL_WARN_ON_USE (getsockopt, | ||
| 177 | "getsockopt() used without including <sys/socket.h>"); | ||
| 178 | _GL_WARN_ON_USE (listen, | ||
| 179 | "listen() used without including <sys/socket.h>"); | ||
| 180 | _GL_WARN_ON_USE (recv, | ||
| 181 | "recv() used without including <sys/socket.h>"); | ||
| 182 | _GL_WARN_ON_USE (send, | ||
| 183 | "send() used without including <sys/socket.h>"); | ||
| 184 | _GL_WARN_ON_USE (recvfrom, | ||
| 185 | "recvfrom() used without including <sys/socket.h>"); | ||
| 186 | _GL_WARN_ON_USE (sendto, | ||
| 187 | "sendto() used without including <sys/socket.h>"); | ||
| 188 | _GL_WARN_ON_USE (setsockopt, | ||
| 189 | "setsockopt() used without including <sys/socket.h>"); | ||
| 190 | _GL_WARN_ON_USE (shutdown, | ||
| 191 | "shutdown() used without including <sys/socket.h>"); | ||
| 192 | # endif | ||
| 193 | # endif | ||
| 194 | # if !defined _@GUARD_PREFIX@_SYS_SELECT_H | ||
| 195 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 196 | # undef select | ||
| 197 | # define select select_used_without_including_sys_select_h | ||
| 198 | # else | ||
| 199 | _GL_WARN_ON_USE (select, | ||
| 200 | "select() used without including <sys/select.h>"); | ||
| 201 | # endif | ||
| 202 | # endif | ||
| 203 | # endif | ||
| 204 | |||
| 205 | #endif /* _@GUARD_PREFIX@_SYS_TIME_H */ | ||
diff --git a/lib/timespec-add.c b/lib/timespec-add.c new file mode 100644 index 00000000000..4e5c641ac12 --- /dev/null +++ b/lib/timespec-add.c | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* Add two struct timespec values. | ||
| 2 | |||
| 3 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | /* Return the sum of two timespec values A and B. On overflow, return | ||
| 21 | an extremal value. This assumes 0 <= tv_nsec <= 999999999. */ | ||
| 22 | |||
| 23 | #include <config.h> | ||
| 24 | #include "timespec.h" | ||
| 25 | |||
| 26 | #include "intprops.h" | ||
| 27 | |||
| 28 | struct timespec | ||
| 29 | timespec_add (struct timespec a, struct timespec b) | ||
| 30 | { | ||
| 31 | struct timespec r; | ||
| 32 | time_t rs = a.tv_sec; | ||
| 33 | time_t bs = b.tv_sec; | ||
| 34 | int ns = a.tv_nsec + b.tv_nsec; | ||
| 35 | int nsd = ns - 1000000000; | ||
| 36 | int rns = ns; | ||
| 37 | |||
| 38 | if (0 <= nsd) | ||
| 39 | { | ||
| 40 | rns = nsd; | ||
| 41 | if (rs == TYPE_MAXIMUM (time_t)) | ||
| 42 | { | ||
| 43 | if (0 <= bs) | ||
| 44 | goto high_overflow; | ||
| 45 | bs++; | ||
| 46 | } | ||
| 47 | else | ||
| 48 | rs++; | ||
| 49 | } | ||
| 50 | |||
| 51 | if (INT_ADD_OVERFLOW (rs, bs)) | ||
| 52 | { | ||
| 53 | if (rs < 0) | ||
| 54 | { | ||
| 55 | rs = TYPE_MINIMUM (time_t); | ||
| 56 | rns = 0; | ||
| 57 | } | ||
| 58 | else | ||
| 59 | { | ||
| 60 | high_overflow: | ||
| 61 | rs = TYPE_MAXIMUM (time_t); | ||
| 62 | rns = 999999999; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | else | ||
| 66 | rs += bs; | ||
| 67 | |||
| 68 | r.tv_sec = rs; | ||
| 69 | r.tv_nsec = rns; | ||
| 70 | return r; | ||
| 71 | } | ||
diff --git a/lib/timespec-sub.c b/lib/timespec-sub.c new file mode 100644 index 00000000000..0b3bb1b57e1 --- /dev/null +++ b/lib/timespec-sub.c | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* Subtract two struct timespec values. | ||
| 2 | |||
| 3 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | /* Return the difference between two timespec values A and B. On | ||
| 21 | overflow, return an extremal value. This assumes 0 <= tv_nsec <= | ||
| 22 | 999999999. */ | ||
| 23 | |||
| 24 | #include <config.h> | ||
| 25 | #include <config.h> | ||
| 26 | #include "timespec.h" | ||
| 27 | |||
| 28 | #include "intprops.h" | ||
| 29 | |||
| 30 | struct timespec | ||
| 31 | timespec_sub (struct timespec a, struct timespec b) | ||
| 32 | { | ||
| 33 | struct timespec r; | ||
| 34 | time_t rs = a.tv_sec; | ||
| 35 | time_t bs = b.tv_sec; | ||
| 36 | int ns = a.tv_nsec - b.tv_nsec; | ||
| 37 | int rns = ns; | ||
| 38 | |||
| 39 | if (ns < 0) | ||
| 40 | { | ||
| 41 | rns = ns + 1000000000; | ||
| 42 | if (rs == TYPE_MINIMUM (time_t)) | ||
| 43 | { | ||
| 44 | if (bs <= 0) | ||
| 45 | goto low_overflow; | ||
| 46 | bs--; | ||
| 47 | } | ||
| 48 | else | ||
| 49 | rs--; | ||
| 50 | } | ||
| 51 | |||
| 52 | if (INT_SUBTRACT_OVERFLOW (rs, bs)) | ||
| 53 | { | ||
| 54 | if (rs < 0) | ||
| 55 | { | ||
| 56 | low_overflow: | ||
| 57 | rs = TYPE_MINIMUM (time_t); | ||
| 58 | rns = 0; | ||
| 59 | } | ||
| 60 | else | ||
| 61 | { | ||
| 62 | rs = TYPE_MAXIMUM (time_t); | ||
| 63 | rns = 999999999; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | else | ||
| 67 | rs -= bs; | ||
| 68 | |||
| 69 | r.tv_sec = rs; | ||
| 70 | r.tv_nsec = rns; | ||
| 71 | return r; | ||
| 72 | } | ||
diff --git a/lib/timespec.h b/lib/timespec.h new file mode 100644 index 00000000000..388ddb83a76 --- /dev/null +++ b/lib/timespec.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* timespec -- System time interface | ||
| 2 | |||
| 3 | Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2012 Free Software | ||
| 4 | Foundation, Inc. | ||
| 5 | |||
| 6 | This program is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 3 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #if ! defined TIMESPEC_H | ||
| 20 | # define TIMESPEC_H | ||
| 21 | |||
| 22 | # include <time.h> | ||
| 23 | |||
| 24 | /* Return negative, zero, positive if A < B, A == B, A > B, respectively. | ||
| 25 | |||
| 26 | For each time stamp T, this code assumes that either: | ||
| 27 | |||
| 28 | * T.tv_nsec is in the range 0..999999999; or | ||
| 29 | * T.tv_sec corresponds to a valid leap second on a host that supports | ||
| 30 | leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or | ||
| 31 | * T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or | ||
| 32 | T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000. | ||
| 33 | This allows for special struct timespec values that are less or | ||
| 34 | greater than all possible valid time stamps. | ||
| 35 | |||
| 36 | In all these cases, it is safe to subtract two tv_nsec values and | ||
| 37 | convert the result to integer without worrying about overflow on | ||
| 38 | any platform of interest to the GNU project, since all such | ||
| 39 | platforms have 32-bit int or wider. | ||
| 40 | |||
| 41 | Replacing "(int) (a.tv_nsec - b.tv_nsec)" with something like | ||
| 42 | "a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause | ||
| 43 | this function to work in some cases where the above assumption is | ||
| 44 | violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2, | ||
| 45 | b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the | ||
| 46 | extra instructions. Using a subtraction has the advantage of | ||
| 47 | detecting some invalid cases on platforms that detect integer | ||
| 48 | overflow. | ||
| 49 | |||
| 50 | The (int) cast avoids a gcc -Wconversion warning. */ | ||
| 51 | |||
| 52 | static inline int | ||
| 53 | timespec_cmp (struct timespec a, struct timespec b) | ||
| 54 | { | ||
| 55 | return (a.tv_sec < b.tv_sec ? -1 | ||
| 56 | : a.tv_sec > b.tv_sec ? 1 | ||
| 57 | : (int) (a.tv_nsec - b.tv_nsec)); | ||
| 58 | } | ||
| 59 | |||
| 60 | /* Return -1, 0, 1, depending on the sign of A. A.tv_nsec must be | ||
| 61 | nonnegative. */ | ||
| 62 | static inline int | ||
| 63 | timespec_sign (struct timespec a) | ||
| 64 | { | ||
| 65 | return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec; | ||
| 66 | } | ||
| 67 | |||
| 68 | struct timespec timespec_add (struct timespec, struct timespec); | ||
| 69 | struct timespec timespec_sub (struct timespec, struct timespec); | ||
| 70 | struct timespec dtotimespec (double); | ||
| 71 | |||
| 72 | /* Return an approximation to A, of type 'double'. */ | ||
| 73 | static inline double | ||
| 74 | timespectod (struct timespec a) | ||
| 75 | { | ||
| 76 | return a.tv_sec + a.tv_nsec / 1e9; | ||
| 77 | } | ||
| 78 | |||
| 79 | void gettime (struct timespec *); | ||
| 80 | int settime (struct timespec const *); | ||
| 81 | |||
| 82 | #endif | ||
diff --git a/lib/utimens.c b/lib/utimens.c new file mode 100644 index 00000000000..c126b9551a6 --- /dev/null +++ b/lib/utimens.c | |||
| @@ -0,0 +1,533 @@ | |||
| 1 | /* Set file access and modification times. | ||
| 2 | |||
| 3 | Copyright (C) 2003-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify it | ||
| 6 | under the terms of the GNU General Public License as published by the | ||
| 7 | Free Software Foundation; either version 3 of the License, or any | ||
| 8 | later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | /* derived from a function in touch.c */ | ||
| 21 | |||
| 22 | #include <config.h> | ||
| 23 | |||
| 24 | #include "utimens.h" | ||
| 25 | |||
| 26 | #include <assert.h> | ||
| 27 | #include <errno.h> | ||
| 28 | #include <fcntl.h> | ||
| 29 | #include <stdbool.h> | ||
| 30 | #include <sys/stat.h> | ||
| 31 | #include <sys/time.h> | ||
| 32 | #include <unistd.h> | ||
| 33 | |||
| 34 | #include "stat-time.h" | ||
| 35 | #include "timespec.h" | ||
| 36 | |||
| 37 | #if HAVE_UTIME_H | ||
| 38 | # include <utime.h> | ||
| 39 | #endif | ||
| 40 | |||
| 41 | /* Some systems (even some that do have <utime.h>) don't declare this | ||
| 42 | structure anywhere. */ | ||
| 43 | #ifndef HAVE_STRUCT_UTIMBUF | ||
| 44 | struct utimbuf | ||
| 45 | { | ||
| 46 | long actime; | ||
| 47 | long modtime; | ||
| 48 | }; | ||
| 49 | #endif | ||
| 50 | |||
| 51 | /* Avoid recursion with rpl_futimens or rpl_utimensat. */ | ||
| 52 | #undef futimens | ||
| 53 | #undef utimensat | ||
| 54 | |||
| 55 | /* Solaris 9 mistakenly succeeds when given a non-directory with a | ||
| 56 | trailing slash. Force the use of rpl_stat for a fix. */ | ||
| 57 | #ifndef REPLACE_FUNC_STAT_FILE | ||
| 58 | # define REPLACE_FUNC_STAT_FILE 0 | ||
| 59 | #endif | ||
| 60 | |||
| 61 | #if HAVE_UTIMENSAT || HAVE_FUTIMENS | ||
| 62 | /* Cache variables for whether the utimensat syscall works; used to | ||
| 63 | avoid calling the syscall if we know it will just fail with ENOSYS, | ||
| 64 | and to avoid unnecessary work in massaging timestamps if the | ||
| 65 | syscall will work. Multiple variables are needed, to distinguish | ||
| 66 | between the following scenarios on Linux: | ||
| 67 | utimensat doesn't exist, or is in glibc but kernel 2.6.18 fails with ENOSYS | ||
| 68 | kernel 2.6.22 and earlier rejects AT_SYMLINK_NOFOLLOW | ||
| 69 | kernel 2.6.25 and earlier reject UTIME_NOW/UTIME_OMIT with non-zero tv_sec | ||
| 70 | kernel 2.6.32 used with xfs or ntfs-3g fail to honor UTIME_OMIT | ||
| 71 | utimensat completely works | ||
| 72 | For each cache variable: 0 = unknown, 1 = yes, -1 = no. */ | ||
| 73 | static int utimensat_works_really; | ||
| 74 | static int lutimensat_works_really; | ||
| 75 | #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ | ||
| 76 | |||
| 77 | /* Validate the requested timestamps. Return 0 if the resulting | ||
| 78 | timespec can be used for utimensat (after possibly modifying it to | ||
| 79 | work around bugs in utimensat). Return a positive value if the | ||
| 80 | timespec needs further adjustment based on stat results: 1 if any | ||
| 81 | adjustment is needed for utimes, and 2 if any adjustment is needed | ||
| 82 | for Linux utimensat. Return -1, with errno set to EINVAL, if | ||
| 83 | timespec is out of range. */ | ||
| 84 | static int | ||
| 85 | validate_timespec (struct timespec timespec[2]) | ||
| 86 | { | ||
| 87 | int result = 0; | ||
| 88 | int utime_omit_count = 0; | ||
| 89 | assert (timespec); | ||
| 90 | if ((timespec[0].tv_nsec != UTIME_NOW | ||
| 91 | && timespec[0].tv_nsec != UTIME_OMIT | ||
| 92 | && (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec)) | ||
| 93 | || (timespec[1].tv_nsec != UTIME_NOW | ||
| 94 | && timespec[1].tv_nsec != UTIME_OMIT | ||
| 95 | && (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec))) | ||
| 96 | { | ||
| 97 | errno = EINVAL; | ||
| 98 | return -1; | ||
| 99 | } | ||
| 100 | /* Work around Linux kernel 2.6.25 bug, where utimensat fails with | ||
| 101 | EINVAL if tv_sec is not 0 when using the flag values of tv_nsec. | ||
| 102 | Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT | ||
| 103 | fails to bump ctime. */ | ||
| 104 | if (timespec[0].tv_nsec == UTIME_NOW | ||
| 105 | || timespec[0].tv_nsec == UTIME_OMIT) | ||
| 106 | { | ||
| 107 | timespec[0].tv_sec = 0; | ||
| 108 | result = 1; | ||
| 109 | if (timespec[0].tv_nsec == UTIME_OMIT) | ||
| 110 | utime_omit_count++; | ||
| 111 | } | ||
| 112 | if (timespec[1].tv_nsec == UTIME_NOW | ||
| 113 | || timespec[1].tv_nsec == UTIME_OMIT) | ||
| 114 | { | ||
| 115 | timespec[1].tv_sec = 0; | ||
| 116 | result = 1; | ||
| 117 | if (timespec[1].tv_nsec == UTIME_OMIT) | ||
| 118 | utime_omit_count++; | ||
| 119 | } | ||
| 120 | return result + (utime_omit_count == 1); | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat | ||
| 124 | buffer STATBUF to obtain the current timestamps of the file. If | ||
| 125 | both times are UTIME_NOW, set *TS to NULL (as this can avoid some | ||
| 126 | permissions issues). If both times are UTIME_OMIT, return true | ||
| 127 | (nothing further beyond the prior collection of STATBUF is | ||
| 128 | necessary); otherwise return false. */ | ||
| 129 | static bool | ||
| 130 | update_timespec (struct stat const *statbuf, struct timespec *ts[2]) | ||
| 131 | { | ||
| 132 | struct timespec *timespec = *ts; | ||
| 133 | if (timespec[0].tv_nsec == UTIME_OMIT | ||
| 134 | && timespec[1].tv_nsec == UTIME_OMIT) | ||
| 135 | return true; | ||
| 136 | if (timespec[0].tv_nsec == UTIME_NOW | ||
| 137 | && timespec[1].tv_nsec == UTIME_NOW) | ||
| 138 | { | ||
| 139 | *ts = NULL; | ||
| 140 | return false; | ||
| 141 | } | ||
| 142 | |||
| 143 | if (timespec[0].tv_nsec == UTIME_OMIT) | ||
| 144 | timespec[0] = get_stat_atime (statbuf); | ||
| 145 | else if (timespec[0].tv_nsec == UTIME_NOW) | ||
| 146 | gettime (×pec[0]); | ||
| 147 | |||
| 148 | if (timespec[1].tv_nsec == UTIME_OMIT) | ||
| 149 | timespec[1] = get_stat_mtime (statbuf); | ||
| 150 | else if (timespec[1].tv_nsec == UTIME_NOW) | ||
| 151 | gettime (×pec[1]); | ||
| 152 | |||
| 153 | return false; | ||
| 154 | } | ||
| 155 | |||
| 156 | /* Set the access and modification time stamps of FD (a.k.a. FILE) to be | ||
| 157 | TIMESPEC[0] and TIMESPEC[1], respectively. | ||
| 158 | FD must be either negative -- in which case it is ignored -- | ||
| 159 | or a file descriptor that is open on FILE. | ||
| 160 | If FD is nonnegative, then FILE can be NULL, which means | ||
| 161 | use just futimes (or equivalent) instead of utimes (or equivalent), | ||
| 162 | and fail if on an old system without futimes (or equivalent). | ||
| 163 | If TIMESPEC is null, set the time stamps to the current time. | ||
| 164 | Return 0 on success, -1 (setting errno) on failure. */ | ||
| 165 | |||
| 166 | int | ||
| 167 | fdutimens (int fd, char const *file, struct timespec const timespec[2]) | ||
| 168 | { | ||
| 169 | struct timespec adjusted_timespec[2]; | ||
| 170 | struct timespec *ts = timespec ? adjusted_timespec : NULL; | ||
| 171 | int adjustment_needed = 0; | ||
| 172 | struct stat st; | ||
| 173 | |||
| 174 | if (ts) | ||
| 175 | { | ||
| 176 | adjusted_timespec[0] = timespec[0]; | ||
| 177 | adjusted_timespec[1] = timespec[1]; | ||
| 178 | adjustment_needed = validate_timespec (ts); | ||
| 179 | } | ||
| 180 | if (adjustment_needed < 0) | ||
| 181 | return -1; | ||
| 182 | |||
| 183 | /* Require that at least one of FD or FILE are potentially valid, to avoid | ||
| 184 | a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather | ||
| 185 | than failing. */ | ||
| 186 | if (fd < 0 && !file) | ||
| 187 | { | ||
| 188 | errno = EBADF; | ||
| 189 | return -1; | ||
| 190 | } | ||
| 191 | |||
| 192 | /* Some Linux-based NFS clients are buggy, and mishandle time stamps | ||
| 193 | of files in NFS file systems in some cases. We have no | ||
| 194 | configure-time test for this, but please see | ||
| 195 | <http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to | ||
| 196 | some of the problems with Linux 2.6.16. If this affects you, | ||
| 197 | compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to | ||
| 198 | help in some cases, albeit at a cost in performance. But you | ||
| 199 | really should upgrade your kernel to a fixed version, since the | ||
| 200 | problem affects many applications. */ | ||
| 201 | |||
| 202 | #if HAVE_BUGGY_NFS_TIME_STAMPS | ||
| 203 | if (fd < 0) | ||
| 204 | sync (); | ||
| 205 | else | ||
| 206 | fsync (fd); | ||
| 207 | #endif | ||
| 208 | |||
| 209 | /* POSIX 2008 added two interfaces to set file timestamps with | ||
| 210 | nanosecond resolution; newer Linux implements both functions via | ||
| 211 | a single syscall. We provide a fallback for ENOSYS (for example, | ||
| 212 | compiling against Linux 2.6.25 kernel headers and glibc 2.7, but | ||
| 213 | running on Linux 2.6.18 kernel). */ | ||
| 214 | #if HAVE_UTIMENSAT || HAVE_FUTIMENS | ||
| 215 | if (0 <= utimensat_works_really) | ||
| 216 | { | ||
| 217 | int result; | ||
| 218 | # if __linux__ | ||
| 219 | /* As recently as Linux kernel 2.6.32 (Dec 2009), several file | ||
| 220 | systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, | ||
| 221 | but work if both times are either explicitly specified or | ||
| 222 | UTIME_NOW. Work around it with a preparatory [f]stat prior | ||
| 223 | to calling futimens/utimensat; fortunately, there is not much | ||
| 224 | timing impact due to the extra syscall even on file systems | ||
| 225 | where UTIME_OMIT would have worked. FIXME: Simplify this in | ||
| 226 | 2012, when file system bugs are no longer common. */ | ||
| 227 | if (adjustment_needed == 2) | ||
| 228 | { | ||
| 229 | if (fd < 0 ? stat (file, &st) : fstat (fd, &st)) | ||
| 230 | return -1; | ||
| 231 | if (ts[0].tv_nsec == UTIME_OMIT) | ||
| 232 | ts[0] = get_stat_atime (&st); | ||
| 233 | else if (ts[1].tv_nsec == UTIME_OMIT) | ||
| 234 | ts[1] = get_stat_mtime (&st); | ||
| 235 | /* Note that st is good, in case utimensat gives ENOSYS. */ | ||
| 236 | adjustment_needed++; | ||
| 237 | } | ||
| 238 | # endif /* __linux__ */ | ||
| 239 | # if HAVE_UTIMENSAT | ||
| 240 | if (fd < 0) | ||
| 241 | { | ||
| 242 | result = utimensat (AT_FDCWD, file, ts, 0); | ||
| 243 | # ifdef __linux__ | ||
| 244 | /* Work around a kernel bug: | ||
| 245 | http://bugzilla.redhat.com/442352 | ||
| 246 | http://bugzilla.redhat.com/449910 | ||
| 247 | It appears that utimensat can mistakenly return 280 rather | ||
| 248 | than -1 upon ENOSYS failure. | ||
| 249 | FIXME: remove in 2010 or whenever the offending kernels | ||
| 250 | are no longer in common use. */ | ||
| 251 | if (0 < result) | ||
| 252 | errno = ENOSYS; | ||
| 253 | # endif /* __linux__ */ | ||
| 254 | if (result == 0 || errno != ENOSYS) | ||
| 255 | { | ||
| 256 | utimensat_works_really = 1; | ||
| 257 | return result; | ||
| 258 | } | ||
| 259 | } | ||
| 260 | # endif /* HAVE_UTIMENSAT */ | ||
| 261 | # if HAVE_FUTIMENS | ||
| 262 | if (0 <= fd) | ||
| 263 | { | ||
| 264 | result = futimens (fd, ts); | ||
| 265 | # ifdef __linux__ | ||
| 266 | /* Work around the same bug as above. */ | ||
| 267 | if (0 < result) | ||
| 268 | errno = ENOSYS; | ||
| 269 | # endif /* __linux__ */ | ||
| 270 | if (result == 0 || errno != ENOSYS) | ||
| 271 | { | ||
| 272 | utimensat_works_really = 1; | ||
| 273 | return result; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | # endif /* HAVE_FUTIMENS */ | ||
| 277 | } | ||
| 278 | utimensat_works_really = -1; | ||
| 279 | lutimensat_works_really = -1; | ||
| 280 | #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ | ||
| 281 | |||
| 282 | /* The platform lacks an interface to set file timestamps with | ||
| 283 | nanosecond resolution, so do the best we can, discarding any | ||
| 284 | fractional part of the timestamp. */ | ||
| 285 | |||
| 286 | if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0)) | ||
| 287 | { | ||
| 288 | if (adjustment_needed != 3 | ||
| 289 | && (fd < 0 ? stat (file, &st) : fstat (fd, &st))) | ||
| 290 | return -1; | ||
| 291 | if (ts && update_timespec (&st, &ts)) | ||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | { | ||
| 296 | #if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES | ||
| 297 | struct timeval timeval[2]; | ||
| 298 | struct timeval *t; | ||
| 299 | if (ts) | ||
| 300 | { | ||
| 301 | timeval[0].tv_sec = ts[0].tv_sec; | ||
| 302 | timeval[0].tv_usec = ts[0].tv_nsec / 1000; | ||
| 303 | timeval[1].tv_sec = ts[1].tv_sec; | ||
| 304 | timeval[1].tv_usec = ts[1].tv_nsec / 1000; | ||
| 305 | t = timeval; | ||
| 306 | } | ||
| 307 | else | ||
| 308 | t = NULL; | ||
| 309 | |||
| 310 | if (fd < 0) | ||
| 311 | { | ||
| 312 | # if HAVE_FUTIMESAT | ||
| 313 | return futimesat (AT_FDCWD, file, t); | ||
| 314 | # endif | ||
| 315 | } | ||
| 316 | else | ||
| 317 | { | ||
| 318 | /* If futimesat or futimes fails here, don't try to speed things | ||
| 319 | up by returning right away. glibc can incorrectly fail with | ||
| 320 | errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0 | ||
| 321 | in high security mode doesn't allow ordinary users to read | ||
| 322 | /proc/self, so glibc incorrectly fails with errno == EACCES. | ||
| 323 | If errno == EIO, EPERM, or EROFS, it's probably safe to fail | ||
| 324 | right away, but these cases are rare enough that they're not | ||
| 325 | worth optimizing, and who knows what other messed-up systems | ||
| 326 | are out there? So play it safe and fall back on the code | ||
| 327 | below. */ | ||
| 328 | |||
| 329 | # if (HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) || HAVE_FUTIMES | ||
| 330 | # if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG | ||
| 331 | # undef futimes | ||
| 332 | # define futimes(fd, t) futimesat (fd, NULL, t) | ||
| 333 | # endif | ||
| 334 | if (futimes (fd, t) == 0) | ||
| 335 | { | ||
| 336 | # if __linux__ && __GLIBC__ | ||
| 337 | /* Work around a longstanding glibc bug, still present as | ||
| 338 | of 2010-12-27. On older Linux kernels that lack both | ||
| 339 | utimensat and utimes, glibc's futimes rounds instead of | ||
| 340 | truncating when falling back on utime. The same bug | ||
| 341 | occurs in futimesat with a null 2nd arg. */ | ||
| 342 | if (t) | ||
| 343 | { | ||
| 344 | bool abig = 500000 <= t[0].tv_usec; | ||
| 345 | bool mbig = 500000 <= t[1].tv_usec; | ||
| 346 | if ((abig | mbig) && fstat (fd, &st) == 0) | ||
| 347 | { | ||
| 348 | /* If these two subtractions overflow, they'll | ||
| 349 | track the overflows inside the buggy glibc. */ | ||
| 350 | time_t adiff = st.st_atime - t[0].tv_sec; | ||
| 351 | time_t mdiff = st.st_mtime - t[1].tv_sec; | ||
| 352 | |||
| 353 | struct timeval *tt = NULL; | ||
| 354 | struct timeval truncated_timeval[2]; | ||
| 355 | truncated_timeval[0] = t[0]; | ||
| 356 | truncated_timeval[1] = t[1]; | ||
| 357 | if (abig && adiff == 1 && get_stat_atime_ns (&st) == 0) | ||
| 358 | { | ||
| 359 | tt = truncated_timeval; | ||
| 360 | tt[0].tv_usec = 0; | ||
| 361 | } | ||
| 362 | if (mbig && mdiff == 1 && get_stat_mtime_ns (&st) == 0) | ||
| 363 | { | ||
| 364 | tt = truncated_timeval; | ||
| 365 | tt[1].tv_usec = 0; | ||
| 366 | } | ||
| 367 | if (tt) | ||
| 368 | futimes (fd, tt); | ||
| 369 | } | ||
| 370 | } | ||
| 371 | # endif | ||
| 372 | |||
| 373 | return 0; | ||
| 374 | } | ||
| 375 | # endif | ||
| 376 | } | ||
| 377 | #endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ | ||
| 378 | |||
| 379 | if (!file) | ||
| 380 | { | ||
| 381 | #if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) \ | ||
| 382 | || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) | ||
| 383 | errno = ENOSYS; | ||
| 384 | #endif | ||
| 385 | return -1; | ||
| 386 | } | ||
| 387 | |||
| 388 | #if HAVE_WORKING_UTIMES | ||
| 389 | return utimes (file, t); | ||
| 390 | #else | ||
| 391 | { | ||
| 392 | struct utimbuf utimbuf; | ||
| 393 | struct utimbuf *ut; | ||
| 394 | if (ts) | ||
| 395 | { | ||
| 396 | utimbuf.actime = ts[0].tv_sec; | ||
| 397 | utimbuf.modtime = ts[1].tv_sec; | ||
| 398 | ut = &utimbuf; | ||
| 399 | } | ||
| 400 | else | ||
| 401 | ut = NULL; | ||
| 402 | |||
| 403 | return utime (file, ut); | ||
| 404 | } | ||
| 405 | #endif /* !HAVE_WORKING_UTIMES */ | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 409 | /* Set the access and modification time stamps of FILE to be | ||
| 410 | TIMESPEC[0] and TIMESPEC[1], respectively. */ | ||
| 411 | int | ||
| 412 | utimens (char const *file, struct timespec const timespec[2]) | ||
| 413 | { | ||
| 414 | return fdutimens (-1, file, timespec); | ||
| 415 | } | ||
| 416 | |||
| 417 | /* Set the access and modification time stamps of FILE to be | ||
| 418 | TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing | ||
| 419 | symlinks. Fail with ENOSYS if the platform does not support | ||
| 420 | changing symlink timestamps, but FILE was a symlink. */ | ||
| 421 | int | ||
| 422 | lutimens (char const *file, struct timespec const timespec[2]) | ||
| 423 | { | ||
| 424 | struct timespec adjusted_timespec[2]; | ||
| 425 | struct timespec *ts = timespec ? adjusted_timespec : NULL; | ||
| 426 | int adjustment_needed = 0; | ||
| 427 | struct stat st; | ||
| 428 | |||
| 429 | if (ts) | ||
| 430 | { | ||
| 431 | adjusted_timespec[0] = timespec[0]; | ||
| 432 | adjusted_timespec[1] = timespec[1]; | ||
| 433 | adjustment_needed = validate_timespec (ts); | ||
| 434 | } | ||
| 435 | if (adjustment_needed < 0) | ||
| 436 | return -1; | ||
| 437 | |||
| 438 | /* The Linux kernel did not support symlink timestamps until | ||
| 439 | utimensat, in version 2.6.22, so we don't need to mimic | ||
| 440 | fdutimens' worry about buggy NFS clients. But we do have to | ||
| 441 | worry about bogus return values. */ | ||
| 442 | |||
| 443 | #if HAVE_UTIMENSAT | ||
| 444 | if (0 <= lutimensat_works_really) | ||
| 445 | { | ||
| 446 | int result; | ||
| 447 | # if __linux__ | ||
| 448 | /* As recently as Linux kernel 2.6.32 (Dec 2009), several file | ||
| 449 | systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, | ||
| 450 | but work if both times are either explicitly specified or | ||
| 451 | UTIME_NOW. Work around it with a preparatory lstat prior to | ||
| 452 | calling utimensat; fortunately, there is not much timing | ||
| 453 | impact due to the extra syscall even on file systems where | ||
| 454 | UTIME_OMIT would have worked. FIXME: Simplify this in 2012, | ||
| 455 | when file system bugs are no longer common. */ | ||
| 456 | if (adjustment_needed == 2) | ||
| 457 | { | ||
| 458 | if (lstat (file, &st)) | ||
| 459 | return -1; | ||
| 460 | if (ts[0].tv_nsec == UTIME_OMIT) | ||
| 461 | ts[0] = get_stat_atime (&st); | ||
| 462 | else if (ts[1].tv_nsec == UTIME_OMIT) | ||
| 463 | ts[1] = get_stat_mtime (&st); | ||
| 464 | /* Note that st is good, in case utimensat gives ENOSYS. */ | ||
| 465 | adjustment_needed++; | ||
| 466 | } | ||
| 467 | # endif /* __linux__ */ | ||
| 468 | result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); | ||
| 469 | # ifdef __linux__ | ||
| 470 | /* Work around a kernel bug: | ||
| 471 | http://bugzilla.redhat.com/442352 | ||
| 472 | http://bugzilla.redhat.com/449910 | ||
| 473 | It appears that utimensat can mistakenly return 280 rather | ||
| 474 | than -1 upon ENOSYS failure. | ||
| 475 | FIXME: remove in 2010 or whenever the offending kernels | ||
| 476 | are no longer in common use. */ | ||
| 477 | if (0 < result) | ||
| 478 | errno = ENOSYS; | ||
| 479 | # endif | ||
| 480 | if (result == 0 || errno != ENOSYS) | ||
| 481 | { | ||
| 482 | utimensat_works_really = 1; | ||
| 483 | lutimensat_works_really = 1; | ||
| 484 | return result; | ||
| 485 | } | ||
| 486 | } | ||
| 487 | lutimensat_works_really = -1; | ||
| 488 | #endif /* HAVE_UTIMENSAT */ | ||
| 489 | |||
| 490 | /* The platform lacks an interface to set file timestamps with | ||
| 491 | nanosecond resolution, so do the best we can, discarding any | ||
| 492 | fractional part of the timestamp. */ | ||
| 493 | |||
| 494 | if (adjustment_needed || REPLACE_FUNC_STAT_FILE) | ||
| 495 | { | ||
| 496 | if (adjustment_needed != 3 && lstat (file, &st)) | ||
| 497 | return -1; | ||
| 498 | if (ts && update_timespec (&st, &ts)) | ||
| 499 | return 0; | ||
| 500 | } | ||
| 501 | |||
| 502 | /* On Linux, lutimes is a thin wrapper around utimensat, so there is | ||
| 503 | no point trying lutimes if utimensat failed with ENOSYS. */ | ||
| 504 | #if HAVE_LUTIMES && !HAVE_UTIMENSAT | ||
| 505 | { | ||
| 506 | struct timeval timeval[2]; | ||
| 507 | struct timeval *t; | ||
| 508 | int result; | ||
| 509 | if (ts) | ||
| 510 | { | ||
| 511 | timeval[0].tv_sec = ts[0].tv_sec; | ||
| 512 | timeval[0].tv_usec = ts[0].tv_nsec / 1000; | ||
| 513 | timeval[1].tv_sec = ts[1].tv_sec; | ||
| 514 | timeval[1].tv_usec = ts[1].tv_nsec / 1000; | ||
| 515 | t = timeval; | ||
| 516 | } | ||
| 517 | else | ||
| 518 | t = NULL; | ||
| 519 | |||
| 520 | result = lutimes (file, t); | ||
| 521 | if (result == 0 || errno != ENOSYS) | ||
| 522 | return result; | ||
| 523 | } | ||
| 524 | #endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */ | ||
| 525 | |||
| 526 | /* Out of luck for symlinks, but we still handle regular files. */ | ||
| 527 | if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st)) | ||
| 528 | return -1; | ||
| 529 | if (!S_ISLNK (st.st_mode)) | ||
| 530 | return fdutimens (-1, file, ts); | ||
| 531 | errno = ENOSYS; | ||
| 532 | return -1; | ||
| 533 | } | ||
diff --git a/lib/utimens.h b/lib/utimens.h new file mode 100644 index 00000000000..8c47cf93f88 --- /dev/null +++ b/lib/utimens.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | #include <time.h> | ||
| 2 | int fdutimens (int, char const *, struct timespec const [2]); | ||
| 3 | int utimens (char const *, struct timespec const [2]); | ||
| 4 | int lutimens (char const *, struct timespec const [2]); | ||
| 5 | |||
| 6 | #if GNULIB_FDUTIMENSAT | ||
| 7 | # include <fcntl.h> | ||
| 8 | # include <sys/stat.h> | ||
| 9 | |||
| 10 | int fdutimensat (int fd, int dir, char const *name, struct timespec const [2], | ||
| 11 | int atflag); | ||
| 12 | |||
| 13 | /* Using this function makes application code slightly more readable. */ | ||
| 14 | static inline int | ||
| 15 | lutimensat (int dir, char const *file, struct timespec const times[2]) | ||
| 16 | { | ||
| 17 | return utimensat (dir, file, times, AT_SYMLINK_NOFOLLOW); | ||
| 18 | } | ||
| 19 | #endif | ||
diff --git a/m4/clock_time.m4 b/m4/clock_time.m4 new file mode 100644 index 00000000000..0bec0ef860f --- /dev/null +++ b/m4/clock_time.m4 | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | # clock_time.m4 serial 10 | ||
| 2 | dnl Copyright (C) 2002-2006, 2009-2012 Free Software Foundation, Inc. | ||
| 3 | dnl This file is free software; the Free Software Foundation | ||
| 4 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 5 | dnl with or without modifications, as long as this notice is preserved. | ||
| 6 | |||
| 7 | # Check for clock_gettime and clock_settime, and set LIB_CLOCK_GETTIME. | ||
| 8 | # For a program named, say foo, you should add a line like the following | ||
| 9 | # in the corresponding Makefile.am file: | ||
| 10 | # foo_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) | ||
| 11 | |||
| 12 | AC_DEFUN([gl_CLOCK_TIME], | ||
| 13 | [ | ||
| 14 | dnl Persuade glibc and Solaris <time.h> to declare these functions. | ||
| 15 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
| 16 | |||
| 17 | # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function. | ||
| 18 | # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4. | ||
| 19 | |||
| 20 | # Save and restore LIBS so e.g., -lrt, isn't added to it. Otherwise, *all* | ||
| 21 | # programs in the package would end up linked with that potentially-shared | ||
| 22 | # library, inducing unnecessary run-time overhead. | ||
| 23 | LIB_CLOCK_GETTIME= | ||
| 24 | AC_SUBST([LIB_CLOCK_GETTIME]) | ||
| 25 | gl_saved_libs=$LIBS | ||
| 26 | AC_SEARCH_LIBS([clock_gettime], [rt posix4], | ||
| 27 | [test "$ac_cv_search_clock_gettime" = "none required" || | ||
| 28 | LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime]) | ||
| 29 | AC_CHECK_FUNCS([clock_gettime clock_settime]) | ||
| 30 | LIBS=$gl_saved_libs | ||
| 31 | ]) | ||
diff --git a/m4/gettime.m4 b/m4/gettime.m4 new file mode 100644 index 00000000000..7d03d1253bf --- /dev/null +++ b/m4/gettime.m4 | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # gettime.m4 serial 8 | ||
| 2 | dnl Copyright (C) 2002, 2004-2006, 2009-2012 Free Software Foundation, Inc. | ||
| 3 | dnl This file is free software; the Free Software Foundation | ||
| 4 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 5 | dnl with or without modifications, as long as this notice is preserved. | ||
| 6 | |||
| 7 | AC_DEFUN([gl_GETTIME], | ||
| 8 | [ | ||
| 9 | dnl Prerequisites of lib/gettime.c. | ||
| 10 | AC_REQUIRE([gl_CLOCK_TIME]) | ||
| 11 | AC_REQUIRE([gl_TIMESPEC]) | ||
| 12 | AC_CHECK_FUNCS_ONCE([gettimeofday nanotime]) | ||
| 13 | ]) | ||
diff --git a/m4/gettimeofday.m4 b/m4/gettimeofday.m4 new file mode 100644 index 00000000000..eda97027a92 --- /dev/null +++ b/m4/gettimeofday.m4 | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | # serial 20 | ||
| 2 | |||
| 3 | # Copyright (C) 2001-2003, 2005, 2007, 2009-2012 Free Software Foundation, Inc. | ||
| 4 | # This file is free software; the Free Software Foundation | ||
| 5 | # gives unlimited permission to copy and/or distribute it, | ||
| 6 | # with or without modifications, as long as this notice is preserved. | ||
| 7 | |||
| 8 | dnl From Jim Meyering. | ||
| 9 | |||
| 10 | AC_DEFUN([gl_FUNC_GETTIMEOFDAY], | ||
| 11 | [ | ||
| 12 | AC_REQUIRE([AC_C_RESTRICT]) | ||
| 13 | AC_REQUIRE([gl_HEADER_SYS_TIME_H]) | ||
| 14 | AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS]) | ||
| 15 | AC_CHECK_FUNCS_ONCE([gettimeofday]) | ||
| 16 | |||
| 17 | gl_gettimeofday_timezone=void | ||
| 18 | if test $ac_cv_func_gettimeofday != yes; then | ||
| 19 | HAVE_GETTIMEOFDAY=0 | ||
| 20 | else | ||
| 21 | gl_FUNC_GETTIMEOFDAY_CLOBBER | ||
| 22 | AC_CACHE_CHECK([for gettimeofday with POSIX signature], | ||
| 23 | [gl_cv_func_gettimeofday_posix_signature], | ||
| 24 | [AC_COMPILE_IFELSE( | ||
| 25 | [AC_LANG_PROGRAM( | ||
| 26 | [[#include <sys/time.h> | ||
| 27 | struct timeval c; | ||
| 28 | int gettimeofday (struct timeval *restrict, void *restrict); | ||
| 29 | ]], | ||
| 30 | [[/* glibc uses struct timezone * rather than the POSIX void * | ||
| 31 | if _GNU_SOURCE is defined. However, since the only portable | ||
| 32 | use of gettimeofday uses NULL as the second parameter, and | ||
| 33 | since the glibc definition is actually more typesafe, it is | ||
| 34 | not worth wrapping this to get a compliant signature. */ | ||
| 35 | int (*f) (struct timeval *restrict, void *restrict) | ||
| 36 | = gettimeofday; | ||
| 37 | int x = f (&c, 0); | ||
| 38 | return !(x | c.tv_sec | c.tv_usec); | ||
| 39 | ]])], | ||
| 40 | [gl_cv_func_gettimeofday_posix_signature=yes], | ||
| 41 | [AC_COMPILE_IFELSE( | ||
| 42 | [AC_LANG_PROGRAM( | ||
| 43 | [[#include <sys/time.h> | ||
| 44 | int gettimeofday (struct timeval *restrict, struct timezone *restrict); | ||
| 45 | ]])], | ||
| 46 | [gl_cv_func_gettimeofday_posix_signature=almost], | ||
| 47 | [gl_cv_func_gettimeofday_posix_signature=no])])]) | ||
| 48 | if test $gl_cv_func_gettimeofday_posix_signature = almost; then | ||
| 49 | gl_gettimeofday_timezone='struct timezone' | ||
| 50 | elif test $gl_cv_func_gettimeofday_posix_signature != yes; then | ||
| 51 | REPLACE_GETTIMEOFDAY=1 | ||
| 52 | fi | ||
| 53 | dnl If we override 'struct timeval', we also have to override gettimeofday. | ||
| 54 | if test $REPLACE_STRUCT_TIMEVAL = 1; then | ||
| 55 | REPLACE_GETTIMEOFDAY=1 | ||
| 56 | fi | ||
| 57 | m4_ifdef([gl_FUNC_TZSET_CLOBBER], [ | ||
| 58 | gl_FUNC_TZSET_CLOBBER | ||
| 59 | case "$gl_cv_func_tzset_clobber" in | ||
| 60 | *yes) | ||
| 61 | REPLACE_GETTIMEOFDAY=1 | ||
| 62 | gl_GETTIMEOFDAY_REPLACE_LOCALTIME | ||
| 63 | AC_DEFINE([tzset], [rpl_tzset], | ||
| 64 | [Define to rpl_tzset if the wrapper function should be used.]) | ||
| 65 | AC_DEFINE([TZSET_CLOBBERS_LOCALTIME], [1], | ||
| 66 | [Define if tzset clobbers localtime's static buffer.]) | ||
| 67 | ;; | ||
| 68 | esac | ||
| 69 | ]) | ||
| 70 | fi | ||
| 71 | AC_DEFINE_UNQUOTED([GETTIMEOFDAY_TIMEZONE], [$gl_gettimeofday_timezone], | ||
| 72 | [Define this to 'void' or 'struct timezone' to match the system's | ||
| 73 | declaration of the second argument to gettimeofday.]) | ||
| 74 | ]) | ||
| 75 | |||
| 76 | |||
| 77 | dnl See if gettimeofday clobbers the static buffer that localtime uses | ||
| 78 | dnl for its return value. The gettimeofday function from Mac OS X 10.0.4 | ||
| 79 | dnl (i.e., Darwin 1.3.7) has this problem. | ||
| 80 | dnl | ||
| 81 | dnl If it does, then arrange to use gettimeofday and localtime only via | ||
| 82 | dnl the wrapper functions that work around the problem. | ||
| 83 | |||
| 84 | AC_DEFUN([gl_FUNC_GETTIMEOFDAY_CLOBBER], | ||
| 85 | [ | ||
| 86 | AC_REQUIRE([gl_HEADER_SYS_TIME_H]) | ||
| 87 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 88 | |||
| 89 | AC_CACHE_CHECK([whether gettimeofday clobbers localtime buffer], | ||
| 90 | [gl_cv_func_gettimeofday_clobber], | ||
| 91 | [AC_RUN_IFELSE( | ||
| 92 | [AC_LANG_PROGRAM( | ||
| 93 | [[#include <string.h> | ||
| 94 | #include <sys/time.h> | ||
| 95 | #include <time.h> | ||
| 96 | #include <stdlib.h> | ||
| 97 | ]], | ||
| 98 | [[ | ||
| 99 | time_t t = 0; | ||
| 100 | struct tm *lt; | ||
| 101 | struct tm saved_lt; | ||
| 102 | struct timeval tv; | ||
| 103 | lt = localtime (&t); | ||
| 104 | saved_lt = *lt; | ||
| 105 | gettimeofday (&tv, NULL); | ||
| 106 | return memcmp (lt, &saved_lt, sizeof (struct tm)) != 0; | ||
| 107 | ]])], | ||
| 108 | [gl_cv_func_gettimeofday_clobber=no], | ||
| 109 | [gl_cv_func_gettimeofday_clobber=yes], | ||
| 110 | [# When cross-compiling: | ||
| 111 | case "$host_os" in | ||
| 112 | # Guess all is fine on glibc systems. | ||
| 113 | *-gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;; | ||
| 114 | # If we don't know, assume the worst. | ||
| 115 | *) gl_cv_func_gettimeofday_clobber="guessing yes" ;; | ||
| 116 | esac | ||
| 117 | ])]) | ||
| 118 | |||
| 119 | case "$gl_cv_func_gettimeofday_clobber" in | ||
| 120 | *yes) | ||
| 121 | REPLACE_GETTIMEOFDAY=1 | ||
| 122 | gl_GETTIMEOFDAY_REPLACE_LOCALTIME | ||
| 123 | AC_DEFINE([GETTIMEOFDAY_CLOBBERS_LOCALTIME], [1], | ||
| 124 | [Define if gettimeofday clobbers the localtime buffer.]) | ||
| 125 | ;; | ||
| 126 | esac | ||
| 127 | ]) | ||
| 128 | |||
| 129 | AC_DEFUN([gl_GETTIMEOFDAY_REPLACE_LOCALTIME], [ | ||
| 130 | AC_DEFINE([gmtime], [rpl_gmtime], | ||
| 131 | [Define to rpl_gmtime if the replacement function should be used.]) | ||
| 132 | AC_DEFINE([localtime], [rpl_localtime], | ||
| 133 | [Define to rpl_localtime if the replacement function should be used.]) | ||
| 134 | ]) | ||
| 135 | |||
| 136 | # Prerequisites of lib/gettimeofday.c. | ||
| 137 | AC_DEFUN([gl_PREREQ_GETTIMEOFDAY], [ | ||
| 138 | AC_CHECK_HEADERS([sys/timeb.h]) | ||
| 139 | AC_CHECK_FUNCS([_ftime]) | ||
| 140 | ]) | ||
diff --git a/m4/pselect.m4 b/m4/pselect.m4 new file mode 100644 index 00000000000..97bf12cd2d6 --- /dev/null +++ b/m4/pselect.m4 | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | # pselect.m4 | ||
| 2 | dnl Copyright (C) 2011-2012 Free Software Foundation, Inc. | ||
| 3 | dnl This file is free software; the Free Software Foundation | ||
| 4 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 5 | dnl with or without modifications, as long as this notice is preserved. | ||
| 6 | |||
| 7 | AC_DEFUN([gl_FUNC_PSELECT], | ||
| 8 | [ | ||
| 9 | AC_REQUIRE([gl_HEADER_SYS_SELECT]) | ||
| 10 | AC_REQUIRE([AC_C_RESTRICT]) | ||
| 11 | AC_CHECK_FUNCS_ONCE([pselect]) | ||
| 12 | |||
| 13 | if test $ac_cv_func_pselect = yes; then | ||
| 14 | AC_CACHE_CHECK([whether signature of pselect conforms to POSIX], | ||
| 15 | gl_cv_sig_pselect, | ||
| 16 | [AC_LINK_IFELSE( | ||
| 17 | [AC_LANG_PROGRAM( | ||
| 18 | [[#include <sys/select.h> | ||
| 19 | ]], | ||
| 20 | [[int (*p) (int, fd_set *, fd_set *, fd_set *restrict, | ||
| 21 | struct timespec const *restrict, | ||
| 22 | sigset_t const *restrict) = pselect; | ||
| 23 | return !p;]])], | ||
| 24 | [gl_cv_sig_pselect=yes], | ||
| 25 | [gl_cv_sig_pselect=no])]) | ||
| 26 | fi | ||
| 27 | |||
| 28 | if test $ac_cv_func_pselect = no || test $gl_cv_sig_pselect = no; then | ||
| 29 | REPLACE_PSELECT=1 | ||
| 30 | fi | ||
| 31 | ]) | ||
diff --git a/m4/stat-time.m4 b/m4/stat-time.m4 new file mode 100644 index 00000000000..2dbb1f3c752 --- /dev/null +++ b/m4/stat-time.m4 | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | # Checks for stat-related time functions. | ||
| 2 | |||
| 3 | # Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2012 Free Software | ||
| 4 | # Foundation, Inc. | ||
| 5 | |||
| 6 | # This file is free software; the Free Software Foundation | ||
| 7 | # gives unlimited permission to copy and/or distribute it, | ||
| 8 | # with or without modifications, as long as this notice is preserved. | ||
| 9 | |||
| 10 | dnl From Paul Eggert. | ||
| 11 | |||
| 12 | # st_atim.tv_nsec - Linux, Solaris, Cygwin | ||
| 13 | # st_atimespec.tv_nsec - FreeBSD, NetBSD, if ! defined _POSIX_SOURCE | ||
| 14 | # st_atimensec - FreeBSD, NetBSD, if defined _POSIX_SOURCE | ||
| 15 | # st_atim.st__tim.tv_nsec - UnixWare (at least 2.1.2 through 7.1) | ||
| 16 | |||
| 17 | # st_birthtimespec - FreeBSD, NetBSD (hidden on OpenBSD 3.9, anyway) | ||
| 18 | # st_birthtim - Cygwin 1.7.0+ | ||
| 19 | |||
| 20 | AC_DEFUN([gl_STAT_TIME], | ||
| 21 | [ | ||
| 22 | AC_REQUIRE([AC_C_INLINE]) | ||
| 23 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
| 24 | AC_CHECK_HEADERS_ONCE([sys/time.h]) | ||
| 25 | |||
| 26 | AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec], | ||
| 27 | [AC_CACHE_CHECK([whether struct stat.st_atim is of type struct timespec], | ||
| 28 | [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec], | ||
| 29 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM( | ||
| 30 | [[ | ||
| 31 | #include <sys/types.h> | ||
| 32 | #include <sys/stat.h> | ||
| 33 | #if HAVE_SYS_TIME_H | ||
| 34 | # include <sys/time.h> | ||
| 35 | #endif | ||
| 36 | #include <time.h> | ||
| 37 | struct timespec ts; | ||
| 38 | struct stat st; | ||
| 39 | ]], | ||
| 40 | [[ | ||
| 41 | st.st_atim = ts; | ||
| 42 | ]])], | ||
| 43 | [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=yes], | ||
| 44 | [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=no])]) | ||
| 45 | if test $ac_cv_typeof_struct_stat_st_atim_is_struct_timespec = yes; then | ||
| 46 | AC_DEFINE([TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC], [1], | ||
| 47 | [Define to 1 if the type of the st_atim member of a struct stat is | ||
| 48 | struct timespec.]) | ||
| 49 | fi], | ||
| 50 | [AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec], [], | ||
| 51 | [AC_CHECK_MEMBERS([struct stat.st_atimensec], [], | ||
| 52 | [AC_CHECK_MEMBERS([struct stat.st_atim.st__tim.tv_nsec], [], [], | ||
| 53 | [#include <sys/types.h> | ||
| 54 | #include <sys/stat.h>])], | ||
| 55 | [#include <sys/types.h> | ||
| 56 | #include <sys/stat.h>])], | ||
| 57 | [#include <sys/types.h> | ||
| 58 | #include <sys/stat.h>])], | ||
| 59 | [#include <sys/types.h> | ||
| 60 | #include <sys/stat.h>]) | ||
| 61 | ]) | ||
| 62 | |||
| 63 | # Check for st_birthtime, a feature from UFS2 (FreeBSD, NetBSD, OpenBSD, etc.) | ||
| 64 | # and NTFS (Cygwin). | ||
| 65 | # There was a time when this field was named st_createtime (21 June | ||
| 66 | # 2002 to 16 July 2002) But that window is very small and applied only | ||
| 67 | # to development code, so systems still using that configuration are | ||
| 68 | # not supported. See revisions 1.10 and 1.11 of FreeBSD's | ||
| 69 | # src/sys/ufs/ufs/dinode.h. | ||
| 70 | # | ||
| 71 | AC_DEFUN([gl_STAT_BIRTHTIME], | ||
| 72 | [ | ||
| 73 | AC_REQUIRE([AC_C_INLINE]) | ||
| 74 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
| 75 | AC_CHECK_HEADERS_ONCE([sys/time.h]) | ||
| 76 | AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec], [], | ||
| 77 | [AC_CHECK_MEMBERS([struct stat.st_birthtimensec], [], | ||
| 78 | [AC_CHECK_MEMBERS([struct stat.st_birthtim.tv_nsec], [], [], | ||
| 79 | [#include <sys/types.h> | ||
| 80 | #include <sys/stat.h>])], | ||
| 81 | [#include <sys/types.h> | ||
| 82 | #include <sys/stat.h>])], | ||
| 83 | [#include <sys/types.h> | ||
| 84 | #include <sys/stat.h>]) | ||
| 85 | ]) | ||
diff --git a/m4/sys_select_h.m4 b/m4/sys_select_h.m4 new file mode 100644 index 00000000000..eaf056a79a2 --- /dev/null +++ b/m4/sys_select_h.m4 | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | # sys_select_h.m4 serial 20 | ||
| 2 | dnl Copyright (C) 2006-2012 Free Software Foundation, Inc. | ||
| 3 | dnl This file is free software; the Free Software Foundation | ||
| 4 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 5 | dnl with or without modifications, as long as this notice is preserved. | ||
| 6 | |||
| 7 | AC_DEFUN([gl_HEADER_SYS_SELECT], | ||
| 8 | [ | ||
| 9 | AC_REQUIRE([AC_C_RESTRICT]) | ||
| 10 | AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS]) | ||
| 11 | AC_CACHE_CHECK([whether <sys/select.h> is self-contained], | ||
| 12 | [gl_cv_header_sys_select_h_selfcontained], | ||
| 13 | [ | ||
| 14 | dnl Test against two bugs: | ||
| 15 | dnl 1. On many platforms, <sys/select.h> assumes prior inclusion of | ||
| 16 | dnl <sys/types.h>. | ||
| 17 | dnl 2. On OSF/1 4.0, <sys/select.h> provides only a forward declaration | ||
| 18 | dnl of 'struct timeval', and no definition of this type. | ||
| 19 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/select.h>]], | ||
| 20 | [[struct timeval b;]])], | ||
| 21 | [gl_cv_header_sys_select_h_selfcontained=yes], | ||
| 22 | [gl_cv_header_sys_select_h_selfcontained=no]) | ||
| 23 | dnl Test against another bug: | ||
| 24 | dnl 3. On Solaris 10, <sys/select.h> provides an FD_ZERO implementation | ||
| 25 | dnl that relies on memset(), but without including <string.h>. | ||
| 26 | if test $gl_cv_header_sys_select_h_selfcontained = yes; then | ||
| 27 | AC_COMPILE_IFELSE( | ||
| 28 | [AC_LANG_PROGRAM([[#include <sys/select.h>]], | ||
| 29 | [[int memset; int bzero;]]) | ||
| 30 | ], | ||
| 31 | [AC_LINK_IFELSE( | ||
| 32 | [AC_LANG_PROGRAM([[#include <sys/select.h>]], [[ | ||
| 33 | #undef memset | ||
| 34 | #define memset nonexistent_memset | ||
| 35 | extern | ||
| 36 | #ifdef __cplusplus | ||
| 37 | "C" | ||
| 38 | #endif | ||
| 39 | void *memset (void *, int, unsigned long); | ||
| 40 | #undef bzero | ||
| 41 | #define bzero nonexistent_bzero | ||
| 42 | extern | ||
| 43 | #ifdef __cplusplus | ||
| 44 | "C" | ||
| 45 | #endif | ||
| 46 | void bzero (void *, unsigned long); | ||
| 47 | fd_set fds; | ||
| 48 | FD_ZERO (&fds); | ||
| 49 | ]]) | ||
| 50 | ], | ||
| 51 | [], | ||
| 52 | [gl_cv_header_sys_select_h_selfcontained=no]) | ||
| 53 | ]) | ||
| 54 | fi | ||
| 55 | ]) | ||
| 56 | dnl <sys/select.h> is always overridden, because of GNULIB_POSIXCHECK. | ||
| 57 | gl_CHECK_NEXT_HEADERS([sys/select.h]) | ||
| 58 | if test $ac_cv_header_sys_select_h = yes; then | ||
| 59 | HAVE_SYS_SELECT_H=1 | ||
| 60 | else | ||
| 61 | HAVE_SYS_SELECT_H=0 | ||
| 62 | fi | ||
| 63 | AC_SUBST([HAVE_SYS_SELECT_H]) | ||
| 64 | gl_PREREQ_SYS_H_WINSOCK2 | ||
| 65 | |||
| 66 | dnl Check for declarations of anything we want to poison if the | ||
| 67 | dnl corresponding gnulib module is not in use. | ||
| 68 | gl_WARN_ON_USE_PREPARE([[ | ||
| 69 | /* Some systems require prerequisite headers. */ | ||
| 70 | #include <sys/types.h> | ||
| 71 | #if !(defined __GLIBC__ && !defined __UCLIBC__) && HAVE_SYS_TIME_H | ||
| 72 | # include <sys/time.h> | ||
| 73 | #endif | ||
| 74 | #include <sys/select.h> | ||
| 75 | ]], [pselect select]) | ||
| 76 | ]) | ||
| 77 | |||
| 78 | AC_DEFUN([gl_SYS_SELECT_MODULE_INDICATOR], | ||
| 79 | [ | ||
| 80 | dnl Use AC_REQUIRE here, so that the default settings are expanded once only. | ||
| 81 | AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS]) | ||
| 82 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 83 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 84 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 85 | ]) | ||
| 86 | |||
| 87 | AC_DEFUN([gl_SYS_SELECT_H_DEFAULTS], | ||
| 88 | [ | ||
| 89 | GNULIB_PSELECT=0; AC_SUBST([GNULIB_PSELECT]) | ||
| 90 | GNULIB_SELECT=0; AC_SUBST([GNULIB_SELECT]) | ||
| 91 | dnl Assume proper GNU behavior unless another module says otherwise. | ||
| 92 | HAVE_PSELECT=1; AC_SUBST([HAVE_PSELECT]) | ||
| 93 | REPLACE_PSELECT=0; AC_SUBST([REPLACE_PSELECT]) | ||
| 94 | REPLACE_SELECT=0; AC_SUBST([REPLACE_SELECT]) | ||
| 95 | ]) | ||
diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4 new file mode 100644 index 00000000000..8d4e7e1ebb4 --- /dev/null +++ b/m4/sys_socket_h.m4 | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | # sys_socket_h.m4 serial 22 | ||
| 2 | dnl Copyright (C) 2005-2012 Free Software Foundation, Inc. | ||
| 3 | dnl This file is free software; the Free Software Foundation | ||
| 4 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 5 | dnl with or without modifications, as long as this notice is preserved. | ||
| 6 | |||
| 7 | dnl From Simon Josefsson. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_HEADER_SYS_SOCKET], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) | ||
| 12 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 13 | AC_REQUIRE([AC_C_INLINE]) | ||
| 14 | |||
| 15 | dnl On OSF/1, the functions recv(), send(), recvfrom(), sendto() have | ||
| 16 | dnl old-style declarations (with return type 'int' instead of 'ssize_t') | ||
| 17 | dnl unless _POSIX_PII_SOCKET is defined. | ||
| 18 | case "$host_os" in | ||
| 19 | osf*) | ||
| 20 | AC_DEFINE([_POSIX_PII_SOCKET], [1], | ||
| 21 | [Define to 1 in order to get the POSIX compatible declarations | ||
| 22 | of socket functions.]) | ||
| 23 | ;; | ||
| 24 | esac | ||
| 25 | |||
| 26 | AC_CACHE_CHECK([whether <sys/socket.h> is self-contained], | ||
| 27 | [gl_cv_header_sys_socket_h_selfcontained], | ||
| 28 | [ | ||
| 29 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]], [[]])], | ||
| 30 | [gl_cv_header_sys_socket_h_selfcontained=yes], | ||
| 31 | [gl_cv_header_sys_socket_h_selfcontained=no]) | ||
| 32 | ]) | ||
| 33 | if test $gl_cv_header_sys_socket_h_selfcontained = yes; then | ||
| 34 | dnl If the shutdown function exists, <sys/socket.h> should define | ||
| 35 | dnl SHUT_RD, SHUT_WR, SHUT_RDWR. | ||
| 36 | AC_CHECK_FUNCS([shutdown]) | ||
| 37 | if test $ac_cv_func_shutdown = yes; then | ||
| 38 | AC_CACHE_CHECK([whether <sys/socket.h> defines the SHUT_* macros], | ||
| 39 | [gl_cv_header_sys_socket_h_shut], | ||
| 40 | [ | ||
| 41 | AC_COMPILE_IFELSE( | ||
| 42 | [AC_LANG_PROGRAM([[#include <sys/socket.h>]], | ||
| 43 | [[int a[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };]])], | ||
| 44 | [gl_cv_header_sys_socket_h_shut=yes], | ||
| 45 | [gl_cv_header_sys_socket_h_shut=no]) | ||
| 46 | ]) | ||
| 47 | if test $gl_cv_header_sys_socket_h_shut = no; then | ||
| 48 | SYS_SOCKET_H='sys/socket.h' | ||
| 49 | fi | ||
| 50 | fi | ||
| 51 | fi | ||
| 52 | # We need to check for ws2tcpip.h now. | ||
| 53 | gl_PREREQ_SYS_H_SOCKET | ||
| 54 | AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ | ||
| 55 | /* sys/types.h is not needed according to POSIX, but the | ||
| 56 | sys/socket.h in i386-unknown-freebsd4.10 and | ||
| 57 | powerpc-apple-darwin5.5 required it. */ | ||
| 58 | #include <sys/types.h> | ||
| 59 | #ifdef HAVE_SYS_SOCKET_H | ||
| 60 | #include <sys/socket.h> | ||
| 61 | #endif | ||
| 62 | #ifdef HAVE_WS2TCPIP_H | ||
| 63 | #include <ws2tcpip.h> | ||
| 64 | #endif | ||
| 65 | ]) | ||
| 66 | if test $ac_cv_type_struct_sockaddr_storage = no; then | ||
| 67 | HAVE_STRUCT_SOCKADDR_STORAGE=0 | ||
| 68 | fi | ||
| 69 | if test $ac_cv_type_sa_family_t = no; then | ||
| 70 | HAVE_SA_FAMILY_T=0 | ||
| 71 | fi | ||
| 72 | if test $ac_cv_type_struct_sockaddr_storage != no; then | ||
| 73 | AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], | ||
| 74 | [], | ||
| 75 | [HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=0], | ||
| 76 | [#include <sys/types.h> | ||
| 77 | #ifdef HAVE_SYS_SOCKET_H | ||
| 78 | #include <sys/socket.h> | ||
| 79 | #endif | ||
| 80 | #ifdef HAVE_WS2TCPIP_H | ||
| 81 | #include <ws2tcpip.h> | ||
| 82 | #endif | ||
| 83 | ]) | ||
| 84 | fi | ||
| 85 | if test $HAVE_STRUCT_SOCKADDR_STORAGE = 0 || test $HAVE_SA_FAMILY_T = 0 \ | ||
| 86 | || test $HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = 0; then | ||
| 87 | SYS_SOCKET_H='sys/socket.h' | ||
| 88 | fi | ||
| 89 | gl_PREREQ_SYS_H_WINSOCK2 | ||
| 90 | |||
| 91 | dnl Check for declarations of anything we want to poison if the | ||
| 92 | dnl corresponding gnulib module is not in use. | ||
| 93 | gl_WARN_ON_USE_PREPARE([[ | ||
| 94 | /* Some systems require prerequisite headers. */ | ||
| 95 | #include <sys/types.h> | ||
| 96 | #include <sys/socket.h> | ||
| 97 | ]], [socket connect accept bind getpeername getsockname getsockopt | ||
| 98 | listen recv send recvfrom sendto setsockopt shutdown accept4]) | ||
| 99 | ]) | ||
| 100 | |||
| 101 | AC_DEFUN([gl_PREREQ_SYS_H_SOCKET], | ||
| 102 | [ | ||
| 103 | dnl Check prerequisites of the <sys/socket.h> replacement. | ||
| 104 | AC_REQUIRE([gl_CHECK_SOCKET_HEADERS]) | ||
| 105 | gl_CHECK_NEXT_HEADERS([sys/socket.h]) | ||
| 106 | if test $ac_cv_header_sys_socket_h = yes; then | ||
| 107 | HAVE_SYS_SOCKET_H=1 | ||
| 108 | HAVE_WS2TCPIP_H=0 | ||
| 109 | else | ||
| 110 | HAVE_SYS_SOCKET_H=0 | ||
| 111 | if test $ac_cv_header_ws2tcpip_h = yes; then | ||
| 112 | HAVE_WS2TCPIP_H=1 | ||
| 113 | else | ||
| 114 | HAVE_WS2TCPIP_H=0 | ||
| 115 | fi | ||
| 116 | fi | ||
| 117 | AC_SUBST([HAVE_SYS_SOCKET_H]) | ||
| 118 | AC_SUBST([HAVE_WS2TCPIP_H]) | ||
| 119 | ]) | ||
| 120 | |||
| 121 | # Common prerequisites of the <sys/socket.h> replacement and of the | ||
| 122 | # <sys/select.h> replacement. | ||
| 123 | # Sets and substitutes HAVE_WINSOCK2_H. | ||
| 124 | AC_DEFUN([gl_PREREQ_SYS_H_WINSOCK2], | ||
| 125 | [ | ||
| 126 | m4_ifdef([gl_UNISTD_H_DEFAULTS], [AC_REQUIRE([gl_UNISTD_H_DEFAULTS])]) | ||
| 127 | m4_ifdef([gl_SYS_IOCTL_H_DEFAULTS], [AC_REQUIRE([gl_SYS_IOCTL_H_DEFAULTS])]) | ||
| 128 | AC_CHECK_HEADERS_ONCE([sys/socket.h]) | ||
| 129 | if test $ac_cv_header_sys_socket_h != yes; then | ||
| 130 | dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make | ||
| 131 | dnl the check for those headers unconditional; yet cygwin reports | ||
| 132 | dnl that the headers are present but cannot be compiled (since on | ||
| 133 | dnl cygwin, all socket information should come from sys/socket.h). | ||
| 134 | AC_CHECK_HEADERS([winsock2.h]) | ||
| 135 | fi | ||
| 136 | if test "$ac_cv_header_winsock2_h" = yes; then | ||
| 137 | HAVE_WINSOCK2_H=1 | ||
| 138 | UNISTD_H_HAVE_WINSOCK2_H=1 | ||
| 139 | SYS_IOCTL_H_HAVE_WINSOCK2_H=1 | ||
| 140 | else | ||
| 141 | HAVE_WINSOCK2_H=0 | ||
| 142 | fi | ||
| 143 | AC_SUBST([HAVE_WINSOCK2_H]) | ||
| 144 | ]) | ||
| 145 | |||
| 146 | AC_DEFUN([gl_SYS_SOCKET_MODULE_INDICATOR], | ||
| 147 | [ | ||
| 148 | dnl Use AC_REQUIRE here, so that the default settings are expanded once only. | ||
| 149 | AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) | ||
| 150 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 151 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 152 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 153 | ]) | ||
| 154 | |||
| 155 | AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS], | ||
| 156 | [ | ||
| 157 | GNULIB_SOCKET=0; AC_SUBST([GNULIB_SOCKET]) | ||
| 158 | GNULIB_CONNECT=0; AC_SUBST([GNULIB_CONNECT]) | ||
| 159 | GNULIB_ACCEPT=0; AC_SUBST([GNULIB_ACCEPT]) | ||
| 160 | GNULIB_BIND=0; AC_SUBST([GNULIB_BIND]) | ||
| 161 | GNULIB_GETPEERNAME=0; AC_SUBST([GNULIB_GETPEERNAME]) | ||
| 162 | GNULIB_GETSOCKNAME=0; AC_SUBST([GNULIB_GETSOCKNAME]) | ||
| 163 | GNULIB_GETSOCKOPT=0; AC_SUBST([GNULIB_GETSOCKOPT]) | ||
| 164 | GNULIB_LISTEN=0; AC_SUBST([GNULIB_LISTEN]) | ||
| 165 | GNULIB_RECV=0; AC_SUBST([GNULIB_RECV]) | ||
| 166 | GNULIB_SEND=0; AC_SUBST([GNULIB_SEND]) | ||
| 167 | GNULIB_RECVFROM=0; AC_SUBST([GNULIB_RECVFROM]) | ||
| 168 | GNULIB_SENDTO=0; AC_SUBST([GNULIB_SENDTO]) | ||
| 169 | GNULIB_SETSOCKOPT=0; AC_SUBST([GNULIB_SETSOCKOPT]) | ||
| 170 | GNULIB_SHUTDOWN=0; AC_SUBST([GNULIB_SHUTDOWN]) | ||
| 171 | GNULIB_ACCEPT4=0; AC_SUBST([GNULIB_ACCEPT4]) | ||
| 172 | HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) | ||
| 173 | HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; | ||
| 174 | AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) | ||
| 175 | HAVE_SA_FAMILY_T=1; AC_SUBST([HAVE_SA_FAMILY_T]) | ||
| 176 | HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4]) | ||
| 177 | ]) | ||
diff --git a/m4/sys_time_h.m4 b/m4/sys_time_h.m4 new file mode 100644 index 00000000000..26eaf8ea7f3 --- /dev/null +++ b/m4/sys_time_h.m4 | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | # Configure a replacement for <sys/time.h>. | ||
| 2 | # serial 8 | ||
| 3 | |||
| 4 | # Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc. | ||
| 5 | # This file is free software; the Free Software Foundation | ||
| 6 | # gives unlimited permission to copy and/or distribute it, | ||
| 7 | # with or without modifications, as long as this notice is preserved. | ||
| 8 | |||
| 9 | # Written by Paul Eggert and Martin Lambers. | ||
| 10 | |||
| 11 | AC_DEFUN([gl_HEADER_SYS_TIME_H], | ||
| 12 | [ | ||
| 13 | dnl Use AC_REQUIRE here, so that the REPLACE_GETTIMEOFDAY=0 statement | ||
| 14 | dnl below is expanded once only, before all REPLACE_GETTIMEOFDAY=1 | ||
| 15 | dnl statements that occur in other macros. | ||
| 16 | AC_REQUIRE([gl_HEADER_SYS_TIME_H_BODY]) | ||
| 17 | ]) | ||
| 18 | |||
| 19 | AC_DEFUN([gl_HEADER_SYS_TIME_H_BODY], | ||
| 20 | [ | ||
| 21 | AC_REQUIRE([AC_C_RESTRICT]) | ||
| 22 | AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS]) | ||
| 23 | AC_CHECK_HEADERS_ONCE([sys/time.h]) | ||
| 24 | gl_CHECK_NEXT_HEADERS([sys/time.h]) | ||
| 25 | |||
| 26 | if test $ac_cv_header_sys_time_h != yes; then | ||
| 27 | HAVE_SYS_TIME_H=0 | ||
| 28 | fi | ||
| 29 | |||
| 30 | dnl On native Windows with MSVC, 'struct timeval' is defined in <winsock2.h> | ||
| 31 | dnl only. So include that header in the list. | ||
| 32 | gl_PREREQ_SYS_H_WINSOCK2 | ||
| 33 | AC_CACHE_CHECK([for struct timeval], [gl_cv_sys_struct_timeval], | ||
| 34 | [AC_COMPILE_IFELSE( | ||
| 35 | [AC_LANG_PROGRAM( | ||
| 36 | [[#if HAVE_SYS_TIME_H | ||
| 37 | #include <sys/time.h> | ||
| 38 | #endif | ||
| 39 | #include <time.h> | ||
| 40 | #if HAVE_WINSOCK2_H | ||
| 41 | # include <winsock2.h> | ||
| 42 | #endif | ||
| 43 | ]], | ||
| 44 | [[static struct timeval x; x.tv_sec = x.tv_usec;]])], | ||
| 45 | [gl_cv_sys_struct_timeval=yes], | ||
| 46 | [gl_cv_sys_struct_timeval=no]) | ||
| 47 | ]) | ||
| 48 | if test $gl_cv_sys_struct_timeval != yes; then | ||
| 49 | HAVE_STRUCT_TIMEVAL=0 | ||
| 50 | else | ||
| 51 | dnl On native Windows with a 64-bit 'time_t', 'struct timeval' is defined | ||
| 52 | dnl (in <sys/time.h> and <winsock2.h> for mingw64, in <winsock2.h> only | ||
| 53 | dnl for MSVC) with a tv_sec field of type 'long' (32-bit!), which is | ||
| 54 | dnl smaller than the 'time_t' type mandated by POSIX. | ||
| 55 | AC_CACHE_CHECK([for correct struct timeval.tv_sec member], | ||
| 56 | [gl_cv_sys_struct_timeval_tv_sec], | ||
| 57 | [AC_COMPILE_IFELSE( | ||
| 58 | [AC_LANG_PROGRAM( | ||
| 59 | [[#if HAVE_SYS_TIME_H | ||
| 60 | #include <sys/time.h> | ||
| 61 | #endif | ||
| 62 | #include <time.h> | ||
| 63 | #if HAVE_WINSOCK2_H | ||
| 64 | # include <winsock2.h> | ||
| 65 | #endif | ||
| 66 | ]], | ||
| 67 | [[static struct timeval x; | ||
| 68 | typedef int verify_tv_sec_type[sizeof (x.tv_sec) == sizeof (time_t) ? 1 : -1]; | ||
| 69 | ]])], | ||
| 70 | [gl_cv_sys_struct_timeval_tv_sec=yes], | ||
| 71 | [gl_cv_sys_struct_timeval_tv_sec=no]) | ||
| 72 | ]) | ||
| 73 | if test $gl_cv_sys_struct_timeval_tv_sec != yes; then | ||
| 74 | REPLACE_STRUCT_TIMEVAL=1 | ||
| 75 | fi | ||
| 76 | fi | ||
| 77 | |||
| 78 | dnl Check for declarations of anything we want to poison if the | ||
| 79 | dnl corresponding gnulib module is not in use. | ||
| 80 | gl_WARN_ON_USE_PREPARE([[ | ||
| 81 | #if HAVE_SYS_TIME_H | ||
| 82 | # include <sys/time.h> | ||
| 83 | #endif | ||
| 84 | #include <time.h> | ||
| 85 | ]], [gettimeofday]) | ||
| 86 | ]) | ||
| 87 | |||
| 88 | AC_DEFUN([gl_SYS_TIME_MODULE_INDICATOR], | ||
| 89 | [ | ||
| 90 | dnl Use AC_REQUIRE here, so that the default settings are expanded once only. | ||
| 91 | AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS]) | ||
| 92 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 93 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 94 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 95 | ]) | ||
| 96 | |||
| 97 | AC_DEFUN([gl_HEADER_SYS_TIME_H_DEFAULTS], | ||
| 98 | [ | ||
| 99 | GNULIB_GETTIMEOFDAY=0; AC_SUBST([GNULIB_GETTIMEOFDAY]) | ||
| 100 | dnl Assume POSIX behavior unless another module says otherwise. | ||
| 101 | HAVE_GETTIMEOFDAY=1; AC_SUBST([HAVE_GETTIMEOFDAY]) | ||
| 102 | HAVE_STRUCT_TIMEVAL=1; AC_SUBST([HAVE_STRUCT_TIMEVAL]) | ||
| 103 | HAVE_SYS_TIME_H=1; AC_SUBST([HAVE_SYS_TIME_H]) | ||
| 104 | REPLACE_GETTIMEOFDAY=0; AC_SUBST([REPLACE_GETTIMEOFDAY]) | ||
| 105 | REPLACE_STRUCT_TIMEVAL=0; AC_SUBST([REPLACE_STRUCT_TIMEVAL]) | ||
| 106 | ]) | ||
diff --git a/m4/timespec.m4 b/m4/timespec.m4 new file mode 100644 index 00000000000..597b9c2d1af --- /dev/null +++ b/m4/timespec.m4 | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | #serial 14 | ||
| 2 | |||
| 3 | # Copyright (C) 2000-2001, 2003-2007, 2009-2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | # This file is free software; the Free Software Foundation | ||
| 6 | # gives unlimited permission to copy and/or distribute it, | ||
| 7 | # with or without modifications, as long as this notice is preserved. | ||
| 8 | |||
| 9 | dnl From Jim Meyering | ||
| 10 | |||
| 11 | AC_DEFUN([gl_TIMESPEC], | ||
| 12 | [ | ||
| 13 | dnl Prerequisites of lib/timespec.h. | ||
| 14 | AC_REQUIRE([AC_C_INLINE]) | ||
| 15 | ]) | ||
diff --git a/m4/utimbuf.m4 b/m4/utimbuf.m4 new file mode 100644 index 00000000000..25eb85b326e --- /dev/null +++ b/m4/utimbuf.m4 | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | # serial 9 | ||
| 2 | |||
| 3 | # Copyright (C) 1998-2001, 2003-2004, 2007, 2009-2012 Free Software Foundation, | ||
| 4 | # Inc. | ||
| 5 | # | ||
| 6 | # This file is free software; the Free Software Foundation | ||
| 7 | # gives unlimited permission to copy and/or distribute it, | ||
| 8 | # with or without modifications, as long as this notice is preserved. | ||
| 9 | |||
| 10 | dnl From Jim Meyering | ||
| 11 | |||
| 12 | dnl Define HAVE_STRUCT_UTIMBUF if 'struct utimbuf' is declared -- | ||
| 13 | dnl usually in <utime.h>. | ||
| 14 | dnl Some systems have utime.h but don't declare the struct anywhere. | ||
| 15 | |||
| 16 | AC_DEFUN([gl_CHECK_TYPE_STRUCT_UTIMBUF], | ||
| 17 | [ | ||
| 18 | AC_CHECK_HEADERS_ONCE([sys/time.h utime.h]) | ||
| 19 | AC_CACHE_CHECK([for struct utimbuf], [gl_cv_sys_struct_utimbuf], | ||
| 20 | [AC_COMPILE_IFELSE( | ||
| 21 | [AC_LANG_PROGRAM( | ||
| 22 | [[#if HAVE_SYS_TIME_H | ||
| 23 | #include <sys/time.h> | ||
| 24 | #endif | ||
| 25 | #include <time.h> | ||
| 26 | #ifdef HAVE_UTIME_H | ||
| 27 | #include <utime.h> | ||
| 28 | #endif | ||
| 29 | ]], | ||
| 30 | [[static struct utimbuf x; x.actime = x.modtime;]])], | ||
| 31 | [gl_cv_sys_struct_utimbuf=yes], | ||
| 32 | [gl_cv_sys_struct_utimbuf=no])]) | ||
| 33 | |||
| 34 | if test $gl_cv_sys_struct_utimbuf = yes; then | ||
| 35 | AC_DEFINE([HAVE_STRUCT_UTIMBUF], [1], | ||
| 36 | [Define if struct utimbuf is declared -- usually in <utime.h>. | ||
| 37 | Some systems have utime.h but don't declare the struct anywhere. ]) | ||
| 38 | fi | ||
| 39 | ]) | ||
diff --git a/m4/utimens.m4 b/m4/utimens.m4 new file mode 100644 index 00000000000..6a8b6ab78c0 --- /dev/null +++ b/m4/utimens.m4 | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | dnl Copyright (C) 2003-2012 Free Software Foundation, Inc. | ||
| 2 | dnl This file is free software; the Free Software Foundation | ||
| 3 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 4 | dnl with or without modifications, as long as this notice is preserved. | ||
| 5 | |||
| 6 | dnl serial 7 | ||
| 7 | |||
| 8 | AC_DEFUN([gl_UTIMENS], | ||
| 9 | [ | ||
| 10 | dnl Prerequisites of lib/utimens.c. | ||
| 11 | AC_REQUIRE([gl_FUNC_UTIMES]) | ||
| 12 | AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC]) | ||
| 13 | AC_REQUIRE([gl_CHECK_TYPE_STRUCT_UTIMBUF]) | ||
| 14 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 15 | AC_CHECK_FUNCS_ONCE([futimes futimesat futimens utimensat lutimes]) | ||
| 16 | |||
| 17 | if test $ac_cv_func_futimens = no && test $ac_cv_func_futimesat = yes; then | ||
| 18 | dnl FreeBSD 8.0-rc2 mishandles futimesat(fd,NULL,time). It is not | ||
| 19 | dnl standardized, but Solaris implemented it first and uses it as | ||
| 20 | dnl its only means to set fd time. | ||
| 21 | AC_CACHE_CHECK([whether futimesat handles NULL file], | ||
| 22 | [gl_cv_func_futimesat_works], | ||
| 23 | [touch conftest.file | ||
| 24 | AC_RUN_IFELSE([AC_LANG_PROGRAM([[ | ||
| 25 | #include <stddef.h> | ||
| 26 | #include <sys/times.h> | ||
| 27 | #include <fcntl.h> | ||
| 28 | ]], [[ int fd = open ("conftest.file", O_RDWR); | ||
| 29 | if (fd < 0) return 1; | ||
| 30 | if (futimesat (fd, NULL, NULL)) return 2; | ||
| 31 | ]])], | ||
| 32 | [gl_cv_func_futimesat_works=yes], | ||
| 33 | [gl_cv_func_futimesat_works=no], | ||
| 34 | [case "$host_os" in | ||
| 35 | # Guess yes on glibc systems. | ||
| 36 | *-gnu*) gl_cv_func_futimesat_works="guessing yes" ;; | ||
| 37 | # If we don't know, assume the worst. | ||
| 38 | *) gl_cv_func_futimesat_works="guessing no" ;; | ||
| 39 | esac | ||
| 40 | ]) | ||
| 41 | rm -f conftest.file]) | ||
| 42 | case "$gl_cv_func_futimesat_works" in | ||
| 43 | *yes) ;; | ||
| 44 | *) | ||
| 45 | AC_DEFINE([FUTIMESAT_NULL_BUG], [1], | ||
| 46 | [Define to 1 if futimesat mishandles a NULL file name.]) | ||
| 47 | ;; | ||
| 48 | esac | ||
| 49 | fi | ||
| 50 | ]) | ||
diff --git a/m4/utimes.m4 b/m4/utimes.m4 new file mode 100644 index 00000000000..417103a7b72 --- /dev/null +++ b/m4/utimes.m4 | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | # Detect some bugs in glibc's implementation of utimes. | ||
| 2 | # serial 3 | ||
| 3 | |||
| 4 | dnl Copyright (C) 2003-2005, 2009-2012 Free Software Foundation, Inc. | ||
| 5 | dnl This file is free software; the Free Software Foundation | ||
| 6 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 7 | dnl with or without modifications, as long as this notice is preserved. | ||
| 8 | |||
| 9 | # See if we need to work around bugs in glibc's implementation of | ||
| 10 | # utimes from 2003-07-12 to 2003-09-17. | ||
| 11 | # First, there was a bug that would make utimes set mtime | ||
| 12 | # and atime to zero (1970-01-01) unconditionally. | ||
| 13 | # Then, there was code to round rather than truncate. | ||
| 14 | # Then, there was an implementation (sparc64, Linux-2.4.28, glibc-2.3.3) | ||
| 15 | # that didn't honor the NULL-means-set-to-current-time semantics. | ||
| 16 | # Finally, there was also a version of utimes that failed on read-only | ||
| 17 | # files, while utime worked fine (linux-2.2.20, glibc-2.2.5). | ||
| 18 | # | ||
| 19 | # From Jim Meyering, with suggestions from Paul Eggert. | ||
| 20 | |||
| 21 | AC_DEFUN([gl_FUNC_UTIMES], | ||
| 22 | [ | ||
| 23 | AC_CACHE_CHECK([whether the utimes function works], | ||
| 24 | [gl_cv_func_working_utimes], | ||
| 25 | [ | ||
| 26 | AC_RUN_IFELSE([AC_LANG_SOURCE([[ | ||
| 27 | #include <sys/types.h> | ||
| 28 | #include <sys/stat.h> | ||
| 29 | #include <fcntl.h> | ||
| 30 | #include <sys/time.h> | ||
| 31 | #include <time.h> | ||
| 32 | #include <unistd.h> | ||
| 33 | #include <stdlib.h> | ||
| 34 | #include <stdio.h> | ||
| 35 | #include <utime.h> | ||
| 36 | |||
| 37 | static int | ||
| 38 | inorder (time_t a, time_t b, time_t c) | ||
| 39 | { | ||
| 40 | return a <= b && b <= c; | ||
| 41 | } | ||
| 42 | |||
| 43 | int | ||
| 44 | main () | ||
| 45 | { | ||
| 46 | int result = 0; | ||
| 47 | char const *file = "conftest.utimes"; | ||
| 48 | static struct timeval timeval[2] = {{9, 10}, {999999, 999999}}; | ||
| 49 | |||
| 50 | /* Test whether utimes() essentially works. */ | ||
| 51 | { | ||
| 52 | struct stat sbuf; | ||
| 53 | FILE *f = fopen (file, "w"); | ||
| 54 | if (f == NULL) | ||
| 55 | result |= 1; | ||
| 56 | else if (fclose (f) != 0) | ||
| 57 | result |= 1; | ||
| 58 | else if (utimes (file, timeval) != 0) | ||
| 59 | result |= 2; | ||
| 60 | else if (lstat (file, &sbuf) != 0) | ||
| 61 | result |= 1; | ||
| 62 | else if (!(sbuf.st_atime == timeval[0].tv_sec | ||
| 63 | && sbuf.st_mtime == timeval[1].tv_sec)) | ||
| 64 | result |= 4; | ||
| 65 | if (unlink (file) != 0) | ||
| 66 | result |= 1; | ||
| 67 | } | ||
| 68 | |||
| 69 | /* Test whether utimes() with a NULL argument sets the file's timestamp | ||
| 70 | to the current time. Use 'fstat' as well as 'time' to | ||
| 71 | determine the "current" time, to accommodate NFS file systems | ||
| 72 | if there is a time skew between the host and the NFS server. */ | ||
| 73 | { | ||
| 74 | int fd = open (file, O_WRONLY|O_CREAT, 0644); | ||
| 75 | if (fd < 0) | ||
| 76 | result |= 1; | ||
| 77 | else | ||
| 78 | { | ||
| 79 | time_t t0, t2; | ||
| 80 | struct stat st0, st1, st2; | ||
| 81 | if (time (&t0) == (time_t) -1) | ||
| 82 | result |= 1; | ||
| 83 | else if (fstat (fd, &st0) != 0) | ||
| 84 | result |= 1; | ||
| 85 | else if (utimes (file, timeval) != 0) | ||
| 86 | result |= 2; | ||
| 87 | else if (utimes (file, NULL) != 0) | ||
| 88 | result |= 8; | ||
| 89 | else if (fstat (fd, &st1) != 0) | ||
| 90 | result |= 1; | ||
| 91 | else if (write (fd, "\n", 1) != 1) | ||
| 92 | result |= 1; | ||
| 93 | else if (fstat (fd, &st2) != 0) | ||
| 94 | result |= 1; | ||
| 95 | else if (time (&t2) == (time_t) -1) | ||
| 96 | result |= 1; | ||
| 97 | else | ||
| 98 | { | ||
| 99 | int m_ok_POSIX = inorder (t0, st1.st_mtime, t2); | ||
| 100 | int m_ok_NFS = inorder (st0.st_mtime, st1.st_mtime, st2.st_mtime); | ||
| 101 | if (! (st1.st_atime == st1.st_mtime)) | ||
| 102 | result |= 16; | ||
| 103 | if (! (m_ok_POSIX || m_ok_NFS)) | ||
| 104 | result |= 32; | ||
| 105 | } | ||
| 106 | if (close (fd) != 0) | ||
| 107 | result |= 1; | ||
| 108 | } | ||
| 109 | if (unlink (file) != 0) | ||
| 110 | result |= 1; | ||
| 111 | } | ||
| 112 | |||
| 113 | /* Test whether utimes() with a NULL argument works on read-only files. */ | ||
| 114 | { | ||
| 115 | int fd = open (file, O_WRONLY|O_CREAT, 0444); | ||
| 116 | if (fd < 0) | ||
| 117 | result |= 1; | ||
| 118 | else if (close (fd) != 0) | ||
| 119 | result |= 1; | ||
| 120 | else if (utimes (file, NULL) != 0) | ||
| 121 | result |= 64; | ||
| 122 | if (unlink (file) != 0) | ||
| 123 | result |= 1; | ||
| 124 | } | ||
| 125 | |||
| 126 | return result; | ||
| 127 | } | ||
| 128 | ]])], | ||
| 129 | [gl_cv_func_working_utimes=yes], | ||
| 130 | [gl_cv_func_working_utimes=no], | ||
| 131 | [gl_cv_func_working_utimes=no])]) | ||
| 132 | |||
| 133 | if test $gl_cv_func_working_utimes = yes; then | ||
| 134 | AC_DEFINE([HAVE_WORKING_UTIMES], [1], [Define if utimes works properly. ]) | ||
| 135 | fi | ||
| 136 | ]) | ||