diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/allocator.h | 2 | ||||
| -rw-r--r-- | lib/fstatat.c | 12 | ||||
| -rw-r--r-- | lib/intprops.h | 6 | ||||
| -rw-r--r-- | lib/lstat.c | 39 | ||||
| -rw-r--r-- | lib/signal.in.h | 2 | ||||
| -rw-r--r-- | lib/stat-time.h | 45 | ||||
| -rw-r--r-- | lib/stdio-impl.h | 4 | ||||
| -rw-r--r-- | lib/stdio.in.h | 2 | ||||
| -rw-r--r-- | lib/timespec.h | 2 |
9 files changed, 85 insertions, 29 deletions
diff --git a/lib/allocator.h b/lib/allocator.h index 8f79d7435c3..fc3d646aa54 100644 --- a/lib/allocator.h +++ b/lib/allocator.h | |||
| @@ -29,7 +29,7 @@ struct allocator | |||
| 29 | /* Do not use GCC attributes such as __attribute__ ((malloc)) with | 29 | /* Do not use GCC attributes such as __attribute__ ((malloc)) with |
| 30 | the function types pointed at by these members, because these | 30 | the function types pointed at by these members, because these |
| 31 | attributes do not work with pointers to functions. See | 31 | attributes do not work with pointers to functions. See |
| 32 | <https://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00007.html>. */ | 32 | <https://lists.gnu.org/r/bug-gnulib/2011-04/msg00007.html>. */ |
| 33 | 33 | ||
| 34 | /* Call ALLOCATE to allocate memory, like 'malloc'. On failure ALLOCATE | 34 | /* Call ALLOCATE to allocate memory, like 'malloc'. On failure ALLOCATE |
| 35 | should return NULL, though not necessarily set errno. When given | 35 | should return NULL, though not necessarily set errno. When given |
diff --git a/lib/fstatat.c b/lib/fstatat.c index 294861f51b1..237e68c5da7 100644 --- a/lib/fstatat.c +++ b/lib/fstatat.c | |||
| @@ -41,6 +41,8 @@ orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) | |||
| 41 | above. */ | 41 | above. */ |
| 42 | #include "sys/stat.h" | 42 | #include "sys/stat.h" |
| 43 | 43 | ||
| 44 | #include "stat-time.h" | ||
| 45 | |||
| 44 | #include <errno.h> | 46 | #include <errno.h> |
| 45 | #include <fcntl.h> | 47 | #include <fcntl.h> |
| 46 | #include <string.h> | 48 | #include <string.h> |
| @@ -51,6 +53,12 @@ orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) | |||
| 51 | # define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 | 53 | # define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 |
| 52 | # endif | 54 | # endif |
| 53 | 55 | ||
| 56 | static int | ||
| 57 | normal_fstatat (int fd, char const *file, struct stat *st, int flag) | ||
| 58 | { | ||
| 59 | return stat_time_normalize (orig_fstatat (fd, file, st, flag), st); | ||
| 60 | } | ||
| 61 | |||
| 54 | /* fstatat should always follow symbolic links that end in /, but on | 62 | /* fstatat should always follow symbolic links that end in /, but on |
| 55 | Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified. | 63 | Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified. |
| 56 | Likewise, trailing slash on a non-directory should be an error. | 64 | Likewise, trailing slash on a non-directory should be an error. |
| @@ -63,7 +71,7 @@ orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) | |||
| 63 | int | 71 | int |
| 64 | rpl_fstatat (int fd, char const *file, struct stat *st, int flag) | 72 | rpl_fstatat (int fd, char const *file, struct stat *st, int flag) |
| 65 | { | 73 | { |
| 66 | int result = orig_fstatat (fd, file, st, flag); | 74 | int result = normal_fstatat (fd, file, st, flag); |
| 67 | size_t len; | 75 | size_t len; |
| 68 | 76 | ||
| 69 | if (LSTAT_FOLLOWS_SLASHED_SYMLINK || result != 0) | 77 | if (LSTAT_FOLLOWS_SLASHED_SYMLINK || result != 0) |
| @@ -79,7 +87,7 @@ rpl_fstatat (int fd, char const *file, struct stat *st, int flag) | |||
| 79 | errno = ENOTDIR; | 87 | errno = ENOTDIR; |
| 80 | return -1; | 88 | return -1; |
| 81 | } | 89 | } |
| 82 | result = orig_fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW); | 90 | result = normal_fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW); |
| 83 | } | 91 | } |
| 84 | /* Fix stat behavior. */ | 92 | /* Fix stat behavior. */ |
| 85 | if (result == 0 && !S_ISDIR (st->st_mode) && file[len - 1] == '/') | 93 | if (result == 0 && !S_ISDIR (st->st_mode) && file[len - 1] == '/') |
diff --git a/lib/intprops.h b/lib/intprops.h index a34e81c7b5e..2df7b1f9f69 100644 --- a/lib/intprops.h +++ b/lib/intprops.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) | 26 | #define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) |
| 27 | 27 | ||
| 28 | /* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see | 28 | /* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see |
| 29 | <https://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00406.html>. */ | 29 | <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00406.html>. */ |
| 30 | #define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) | 30 | #define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) |
| 31 | 31 | ||
| 32 | /* The extra casts in the following macros work around compiler bugs, | 32 | /* The extra casts in the following macros work around compiler bugs, |
| @@ -179,7 +179,7 @@ | |||
| 179 | /* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. | 179 | /* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. |
| 180 | See above for restrictions. Avoid && and || as they tickle | 180 | See above for restrictions. Avoid && and || as they tickle |
| 181 | bugs in Sun C 5.11 2010/08/13 and other compilers; see | 181 | bugs in Sun C 5.11 2010/08/13 and other compilers; see |
| 182 | <https://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>. */ | 182 | <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00401.html>. */ |
| 183 | #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ | 183 | #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ |
| 184 | ((b) < 0 \ | 184 | ((b) < 0 \ |
| 185 | ? ((a) < 0 \ | 185 | ? ((a) < 0 \ |
| @@ -443,7 +443,7 @@ | |||
| 443 | implementation-defined result or signal for values outside T's | 443 | implementation-defined result or signal for values outside T's |
| 444 | range. However, code that works around this theoretical problem | 444 | range. However, code that works around this theoretical problem |
| 445 | runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: | 445 | runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: |
| 446 | https://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html | 446 | https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html |
| 447 | As the compiler bug is real, don't try to work around the | 447 | As the compiler bug is real, don't try to work around the |
| 448 | theoretical problem. */ | 448 | theoretical problem. */ |
| 449 | 449 | ||
diff --git a/lib/lstat.c b/lib/lstat.c index c721a4e641c..f3c61779540 100644 --- a/lib/lstat.c +++ b/lib/lstat.c | |||
| @@ -47,6 +47,8 @@ orig_lstat (const char *filename, struct stat *buf) | |||
| 47 | above. */ | 47 | above. */ |
| 48 | # include "sys/stat.h" | 48 | # include "sys/stat.h" |
| 49 | 49 | ||
| 50 | # include "stat-time.h" | ||
| 51 | |||
| 50 | # include <string.h> | 52 | # include <string.h> |
| 51 | # include <errno.h> | 53 | # include <errno.h> |
| 52 | 54 | ||
| @@ -66,32 +68,33 @@ orig_lstat (const char *filename, struct stat *buf) | |||
| 66 | int | 68 | int |
| 67 | rpl_lstat (const char *file, struct stat *sbuf) | 69 | rpl_lstat (const char *file, struct stat *sbuf) |
| 68 | { | 70 | { |
| 69 | size_t len; | 71 | int result = orig_lstat (file, sbuf); |
| 70 | int lstat_result = orig_lstat (file, sbuf); | ||
| 71 | |||
| 72 | if (lstat_result != 0) | ||
| 73 | return lstat_result; | ||
| 74 | 72 | ||
| 75 | /* This replacement file can blindly check against '/' rather than | 73 | /* This replacement file can blindly check against '/' rather than |
| 76 | using the ISSLASH macro, because all platforms with '\\' either | 74 | using the ISSLASH macro, because all platforms with '\\' either |
| 77 | lack symlinks (mingw) or have working lstat (cygwin) and thus do | 75 | lack symlinks (mingw) or have working lstat (cygwin) and thus do |
| 78 | not compile this file. 0 len should have already been filtered | 76 | not compile this file. 0 len should have already been filtered |
| 79 | out above, with a failure return of ENOENT. */ | 77 | out above, with a failure return of ENOENT. */ |
| 80 | len = strlen (file); | 78 | if (result == 0) |
| 81 | if (file[len - 1] != '/' || S_ISDIR (sbuf->st_mode)) | ||
| 82 | return 0; | ||
| 83 | |||
| 84 | /* At this point, a trailing slash is only permitted on | ||
| 85 | symlink-to-dir; but it should have found information on the | ||
| 86 | directory, not the symlink. Call stat() to get info about the | ||
| 87 | link's referent. Our replacement stat guarantees valid results, | ||
| 88 | even if the symlink is not pointing to a directory. */ | ||
| 89 | if (!S_ISLNK (sbuf->st_mode)) | ||
| 90 | { | 79 | { |
| 91 | errno = ENOTDIR; | 80 | if (S_ISDIR (sbuf->st_mode) || file[strlen (file) - 1] != '/') |
| 92 | return -1; | 81 | result = stat_time_normalize (result, sbuf); |
| 82 | else | ||
| 83 | { | ||
| 84 | /* At this point, a trailing slash is permitted only on | ||
| 85 | symlink-to-dir; but it should have found information on the | ||
| 86 | directory, not the symlink. Call 'stat' to get info about the | ||
| 87 | link's referent. Our replacement stat guarantees valid results, | ||
| 88 | even if the symlink is not pointing to a directory. */ | ||
| 89 | if (!S_ISLNK (sbuf->st_mode)) | ||
| 90 | { | ||
| 91 | errno = ENOTDIR; | ||
| 92 | return -1; | ||
| 93 | } | ||
| 94 | result = stat (file, sbuf); | ||
| 95 | } | ||
| 93 | } | 96 | } |
| 94 | return stat (file, sbuf); | 97 | return result; |
| 95 | } | 98 | } |
| 96 | 99 | ||
| 97 | #endif /* HAVE_LSTAT */ | 100 | #endif /* HAVE_LSTAT */ |
diff --git a/lib/signal.in.h b/lib/signal.in.h index 9c32b14962f..e8107c37bf5 100644 --- a/lib/signal.in.h +++ b/lib/signal.in.h | |||
| @@ -200,7 +200,7 @@ typedef int verify_NSIG_constraint[NSIG <= 32 ? 1 : -1]; | |||
| 200 | /* When also using extern inline, suppress the use of static inline in | 200 | /* When also using extern inline, suppress the use of static inline in |
| 201 | standard headers of problematic Apple configurations, as Libc at | 201 | standard headers of problematic Apple configurations, as Libc at |
| 202 | least through Libc-825.26 (2013-04-09) mishandles it; see, e.g., | 202 | least through Libc-825.26 (2013-04-09) mishandles it; see, e.g., |
| 203 | <https://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html>. | 203 | <https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html>. |
| 204 | Perhaps Apple will fix this some day. */ | 204 | Perhaps Apple will fix this some day. */ |
| 205 | #if (defined _GL_EXTERN_INLINE_IN_USE && defined __APPLE__ \ | 205 | #if (defined _GL_EXTERN_INLINE_IN_USE && defined __APPLE__ \ |
| 206 | && (defined __i386__ || defined __x86_64__)) | 206 | && (defined __i386__ || defined __x86_64__)) |
diff --git a/lib/stat-time.h b/lib/stat-time.h index 47a3bf8f21e..1cf821992ed 100644 --- a/lib/stat-time.h +++ b/lib/stat-time.h | |||
| @@ -20,6 +20,10 @@ | |||
| 20 | #ifndef STAT_TIME_H | 20 | #ifndef STAT_TIME_H |
| 21 | #define STAT_TIME_H 1 | 21 | #define STAT_TIME_H 1 |
| 22 | 22 | ||
| 23 | #include "intprops.h" | ||
| 24 | |||
| 25 | #include <errno.h> | ||
| 26 | #include <stddef.h> | ||
| 23 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
| 24 | #include <time.h> | 28 | #include <time.h> |
| 25 | 29 | ||
| @@ -202,6 +206,47 @@ get_stat_birthtime (struct stat const *st) | |||
| 202 | return t; | 206 | return t; |
| 203 | } | 207 | } |
| 204 | 208 | ||
| 209 | /* If a stat-like function returned RESULT, normalize the timestamps | ||
| 210 | in *ST, in case this platform suffers from the Solaris 11 bug where | ||
| 211 | tv_nsec might be negative. Return the adjusted RESULT, setting | ||
| 212 | errno to EOVERFLOW if normalization overflowed. This function | ||
| 213 | is intended to be private to this .h file. */ | ||
| 214 | _GL_STAT_TIME_INLINE int | ||
| 215 | stat_time_normalize (int result, struct stat *st) | ||
| 216 | { | ||
| 217 | #if defined __sun && defined STAT_TIMESPEC | ||
| 218 | if (result == 0) | ||
| 219 | { | ||
| 220 | long int timespec_resolution = 1000000000; | ||
| 221 | short int const ts_off[] = { offsetof (struct stat, st_atim), | ||
| 222 | offsetof (struct stat, st_mtim), | ||
| 223 | offsetof (struct stat, st_ctim) }; | ||
| 224 | int i; | ||
| 225 | for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++) | ||
| 226 | { | ||
| 227 | struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]); | ||
| 228 | long int q = ts->tv_nsec / timespec_resolution; | ||
| 229 | long int r = ts->tv_nsec % timespec_resolution; | ||
| 230 | if (r < 0) | ||
| 231 | { | ||
| 232 | r += timespec_resolution; | ||
| 233 | q--; | ||
| 234 | } | ||
| 235 | ts->tv_nsec = r; | ||
| 236 | /* Overflow is possible, as Solaris 11 stat can yield | ||
| 237 | tv_sec == TYPE_MINIMUM (time_t) && tv_nsec == -1000000000. | ||
| 238 | INT_ADD_WRAPV is OK, since time_t is signed on Solaris. */ | ||
| 239 | if (INT_ADD_WRAPV (q, ts->tv_sec, &ts->tv_sec)) | ||
| 240 | { | ||
| 241 | errno = EOVERFLOW; | ||
| 242 | return -1; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | } | ||
| 246 | #endif | ||
| 247 | return result; | ||
| 248 | } | ||
| 249 | |||
| 205 | #ifdef __cplusplus | 250 | #ifdef __cplusplus |
| 206 | } | 251 | } |
| 207 | #endif | 252 | #endif |
diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h index 8960333687e..329801ad23b 100644 --- a/lib/stdio-impl.h +++ b/lib/stdio-impl.h | |||
| @@ -81,7 +81,7 @@ | |||
| 81 | #ifdef __TANDEM /* NonStop Kernel */ | 81 | #ifdef __TANDEM /* NonStop Kernel */ |
| 82 | # ifndef _IOERR | 82 | # ifndef _IOERR |
| 83 | /* These values were determined by the program 'stdioext-flags' at | 83 | /* These values were determined by the program 'stdioext-flags' at |
| 84 | <https://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00165.html>. */ | 84 | <https://lists.gnu.org/r/bug-gnulib/2010-12/msg00165.html>. */ |
| 85 | # define _IOERR 0x40 | 85 | # define _IOERR 0x40 |
| 86 | # define _IOREAD 0x80 | 86 | # define _IOREAD 0x80 |
| 87 | # define _IOWRT 0x4 | 87 | # define _IOWRT 0x4 |
| @@ -132,7 +132,7 @@ struct _gl_real_FILE | |||
| 132 | # define fp_ ((struct _gl_real_FILE *) fp) | 132 | # define fp_ ((struct _gl_real_FILE *) fp) |
| 133 | 133 | ||
| 134 | /* These values were determined by a program similar to the one at | 134 | /* These values were determined by a program similar to the one at |
| 135 | <https://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00165.html>. */ | 135 | <https://lists.gnu.org/r/bug-gnulib/2010-12/msg00165.html>. */ |
| 136 | # define _IOREAD 0x1 | 136 | # define _IOREAD 0x1 |
| 137 | # define _IOWRT 0x2 | 137 | # define _IOWRT 0x2 |
| 138 | # define _IORW 0x4 | 138 | # define _IORW 0x4 |
diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 066e08eba9a..505f3f49f4e 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h | |||
| @@ -152,7 +152,7 @@ | |||
| 152 | /* When also using extern inline, suppress the use of static inline in | 152 | /* When also using extern inline, suppress the use of static inline in |
| 153 | standard headers of problematic Apple configurations, as Libc at | 153 | standard headers of problematic Apple configurations, as Libc at |
| 154 | least through Libc-825.26 (2013-04-09) mishandles it; see, e.g., | 154 | least through Libc-825.26 (2013-04-09) mishandles it; see, e.g., |
| 155 | <https://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html>. | 155 | <https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html>. |
| 156 | Perhaps Apple will fix this some day. */ | 156 | Perhaps Apple will fix this some day. */ |
| 157 | #if (defined _GL_EXTERN_INLINE_IN_USE && defined __APPLE__ \ | 157 | #if (defined _GL_EXTERN_INLINE_IN_USE && defined __APPLE__ \ |
| 158 | && defined __GNUC__ && defined __STDC__) | 158 | && defined __GNUC__ && defined __STDC__) |
diff --git a/lib/timespec.h b/lib/timespec.h index cc34067374f..84c8146a3ea 100644 --- a/lib/timespec.h +++ b/lib/timespec.h | |||
| @@ -87,7 +87,7 @@ timespec_cmp (struct timespec a, struct timespec b) | |||
| 87 | return 1; | 87 | return 1; |
| 88 | 88 | ||
| 89 | /* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02). See: | 89 | /* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02). See: |
| 90 | http://lists.gnu.org/archive/html/bug-gnulib/2017-10/msg00006.html */ | 90 | http://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html */ |
| 91 | assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_RESOLUTION); | 91 | assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_RESOLUTION); |
| 92 | assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_RESOLUTION); | 92 | assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_RESOLUTION); |
| 93 | 93 | ||