aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stat-time.h
diff options
context:
space:
mode:
authorPaul Eggert2017-11-25 22:28:31 -0800
committerPaul Eggert2017-11-25 22:48:09 -0800
commit8be3aee2813f528b02bc913ca4d79e34e72b1754 (patch)
treeaf1e8e35cedfe601076eade046a1a12303b93e84 /lib/stat-time.h
parent265cee553f9d59a989d92e28865f6cc6fc02dcc9 (diff)
downloademacs-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.h45
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
215stat_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