diff options
author | Andy Wingo <wingo@pobox.com> | 2021-01-20 21:52:54 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2021-01-20 23:03:56 +0100 |
commit | a91b95cca2d397c84f8b9bbd602d40209a7092ce (patch) | |
tree | 2c286a291f5a2b812d6e216be10936f2709d59cf /lib/stat-time.h | |
parent | 758b31994cff582c7e8785b4cc2240dbf3573837 (diff) | |
download | guile-a91b95cca2d397c84f8b9bbd602d40209a7092ce.tar.gz |
Update Gnulib to v0.1-4379-g2ef5a9b4b
Also bump required autoconf version to 2.64, as required by Gnulib.
Diffstat (limited to 'lib/stat-time.h')
-rw-r--r-- | lib/stat-time.h | 77 |
1 files changed, 65 insertions, 12 deletions
diff --git a/lib/stat-time.h b/lib/stat-time.h index f761d27bc..00c93296b 100644 --- a/lib/stat-time.h +++ b/lib/stat-time.h @@ -1,6 +1,6 @@ /* stat-related time functions. - Copyright (C) 2005, 2007, 2009-2017 Free Software Foundation, Inc. + Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -13,13 +13,17 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ + along with this program. If not, see <https://www.gnu.org/licenses/>. */ /* Written by Paul Eggert. */ #ifndef STAT_TIME_H #define STAT_TIME_H 1 +#include "intprops.h" + +#include <errno.h> +#include <stddef.h> #include <sys/stat.h> #include <time.h> @@ -31,6 +35,10 @@ _GL_INLINE_HEADER_BEGIN # define _GL_STAT_TIME_INLINE _GL_INLINE #endif +#ifdef __cplusplus +extern "C" { +#endif + /* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST, ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST, @@ -39,8 +47,8 @@ _GL_INLINE_HEADER_BEGIN time respectively. These macros are private to stat-time.h. */ -#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC -# ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC +#if _GL_WINDOWS_STAT_TIMESPEC || defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC +# if _GL_WINDOWS_STAT_TIMESPEC || defined TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC # define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim) # else # define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec) @@ -94,15 +102,13 @@ get_stat_mtime_ns (struct stat const *st) /* Return the nanosecond component of *ST's birth time. */ _GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE -get_stat_birthtime_ns (struct stat const *st) +get_stat_birthtime_ns (struct stat const *st _GL_UNUSED) { # if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC return STAT_TIMESPEC (st, st_birthtim).tv_nsec; # elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC return STAT_TIMESPEC_NS (st, st_birthtim); # else - /* Avoid a "parameter unused" warning. */ - (void) st; return 0; # endif } @@ -152,7 +158,7 @@ get_stat_mtime (struct stat const *st) /* Return *ST's birth time, if available; otherwise return a value with tv_sec and tv_nsec both equal to -1. */ _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE -get_stat_birthtime (struct stat const *st) +get_stat_birthtime (struct stat const *st _GL_UNUSED) { struct timespec t; @@ -162,18 +168,20 @@ get_stat_birthtime (struct stat const *st) #elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC t.tv_sec = st->st_birthtime; t.tv_nsec = st->st_birthtimensec; -#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +#elif defined _WIN32 && ! defined __CYGWIN__ /* Native Windows platforms (but not Cygwin) put the "file creation time" in st_ctime (!). See - <http://msdn2.microsoft.com/de-de/library/14h5k7ff(VS.80).aspx>. */ + <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions>. */ +# if _GL_WINDOWS_STAT_TIMESPEC + t = st->st_ctim; +# else t.tv_sec = st->st_ctime; t.tv_nsec = 0; +# endif #else /* Birth time is not supported. */ t.tv_sec = -1; t.tv_nsec = -1; - /* Avoid a "parameter unused" warning. */ - (void) st; #endif #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ @@ -194,6 +202,51 @@ get_stat_birthtime (struct stat const *st) return t; } +/* If a stat-like function returned RESULT, normalize the timestamps + in *ST, in case this platform suffers from the Solaris 11 bug where + tv_nsec might be negative. Return the adjusted RESULT, setting + errno to EOVERFLOW if normalization overflowed. This function + is intended to be private to this .h file. */ +_GL_STAT_TIME_INLINE int +stat_time_normalize (int result, struct stat *st _GL_UNUSED) +{ +#if defined __sun && defined STAT_TIMESPEC + if (result == 0) + { + long int timespec_hz = 1000000000; + short int const ts_off[] = { offsetof (struct stat, st_atim), + offsetof (struct stat, st_mtim), + offsetof (struct stat, st_ctim) }; + int i; + for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++) + { + struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]); + long int q = ts->tv_nsec / timespec_hz; + long int r = ts->tv_nsec % timespec_hz; + if (r < 0) + { + r += timespec_hz; + q--; + } + ts->tv_nsec = r; + /* Overflow is possible, as Solaris 11 stat can yield + tv_sec == TYPE_MINIMUM (time_t) && tv_nsec == -1000000000. + INT_ADD_WRAPV is OK, since time_t is signed on Solaris. */ + if (INT_ADD_WRAPV (q, ts->tv_sec, &ts->tv_sec)) + { + errno = EOVERFLOW; + return -1; + } + } + } +#endif + return result; +} + +#ifdef __cplusplus +} +#endif + _GL_INLINE_HEADER_END #endif |