diff options
| author | Paul Eggert | 2017-11-25 22:28:31 -0800 |
|---|---|---|
| committer | Paul Eggert | 2017-11-25 22:48:09 -0800 |
| commit | 8be3aee2813f528b02bc913ca4d79e34e72b1754 (patch) | |
| tree | af1e8e35cedfe601076eade046a1a12303b93e84 /lib/stat-time.h | |
| parent | 265cee553f9d59a989d92e28865f6cc6fc02dcc9 (diff) | |
| download | emacs-8be3aee2813f528b02bc913ca4d79e34e72b1754.tar.gz emacs-8be3aee2813f528b02bc913ca4d79e34e72b1754.zip | |
Merge from Gnulib
This incorporates:
2017-11-23 stat: work around Solaris bug with tv_nsec < 0
2017-11-12 maint: shorten https://lists.gnu.org/archive/html/... links
* build-aux/config.sub, doc/misc/texinfo.tex, lib/allocator.h:
* lib/fstatat.c, lib/intprops.h, lib/lstat.c, lib/signal.in.h:
* lib/stat-time.h, lib/stdio-impl.h, lib/stdio.in.h:
* lib/timespec.h, m4/alloca.m4, m4/extern-inline.m4:
* m4/faccessat.m4, m4/fstatat.m4, m4/gnulib-common.m4:
* m4/lstat.m4, m4/std-gnu11.m4, m4/sys_types_h.m4:
* m4/vararrays.m4:
Copy from Gnulib.
Diffstat (limited to 'lib/stat-time.h')
| -rw-r--r-- | lib/stat-time.h | 45 |
1 files changed, 45 insertions, 0 deletions
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 |