Annotation of embedaddon/libiconv/srclib/stat-time.h, revision 1.1

1.1     ! misho       1: /* stat-related time functions.
        !             2: 
        !             3:    Copyright (C) 2005, 2007, 2009-2019 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 <https://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 "intprops.h"
        !            24: 
        !            25: #include <errno.h>
        !            26: #include <stddef.h>
        !            27: #include <sys/stat.h>
        !            28: #include <time.h>
        !            29: 
        !            30: #ifndef _GL_INLINE_HEADER_BEGIN
        !            31:  #error "Please include config.h first."
        !            32: #endif
        !            33: _GL_INLINE_HEADER_BEGIN
        !            34: #ifndef _GL_STAT_TIME_INLINE
        !            35: # define _GL_STAT_TIME_INLINE _GL_INLINE
        !            36: #endif
        !            37: 
        !            38: #ifdef __cplusplus
        !            39: extern "C" {
        !            40: #endif
        !            41: 
        !            42: /* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type
        !            43:    struct timespec, if available.  If not, then STAT_TIMESPEC_NS (ST,
        !            44:    ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST,
        !            45:    if available.  ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim
        !            46:    for access, status change, data modification, or birth (creation)
        !            47:    time respectively.
        !            48: 
        !            49:    These macros are private to stat-time.h.  */
        !            50: #if _GL_WINDOWS_STAT_TIMESPEC || defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
        !            51: # if _GL_WINDOWS_STAT_TIMESPEC || defined TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC
        !            52: #  define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
        !            53: # else
        !            54: #  define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec)
        !            55: # endif
        !            56: #elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
        !            57: # define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec)
        !            58: #elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC
        !            59: # define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec)
        !            60: #elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC
        !            61: # define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec)
        !            62: #endif
        !            63: 
        !            64: /* Return the nanosecond component of *ST's access time.  */
        !            65: _GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE
        !            66: get_stat_atime_ns (struct stat const *st)
        !            67: {
        !            68: # if defined STAT_TIMESPEC
        !            69:   return STAT_TIMESPEC (st, st_atim).tv_nsec;
        !            70: # elif defined STAT_TIMESPEC_NS
        !            71:   return STAT_TIMESPEC_NS (st, st_atim);
        !            72: # else
        !            73:   return 0;
        !            74: # endif
        !            75: }
        !            76: 
        !            77: /* Return the nanosecond component of *ST's status change time.  */
        !            78: _GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE
        !            79: get_stat_ctime_ns (struct stat const *st)
        !            80: {
        !            81: # if defined STAT_TIMESPEC
        !            82:   return STAT_TIMESPEC (st, st_ctim).tv_nsec;
        !            83: # elif defined STAT_TIMESPEC_NS
        !            84:   return STAT_TIMESPEC_NS (st, st_ctim);
        !            85: # else
        !            86:   return 0;
        !            87: # endif
        !            88: }
        !            89: 
        !            90: /* Return the nanosecond component of *ST's data modification time.  */
        !            91: _GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE
        !            92: get_stat_mtime_ns (struct stat const *st)
        !            93: {
        !            94: # if defined STAT_TIMESPEC
        !            95:   return STAT_TIMESPEC (st, st_mtim).tv_nsec;
        !            96: # elif defined STAT_TIMESPEC_NS
        !            97:   return STAT_TIMESPEC_NS (st, st_mtim);
        !            98: # else
        !            99:   return 0;
        !           100: # endif
        !           101: }
        !           102: 
        !           103: /* Return the nanosecond component of *ST's birth time.  */
        !           104: _GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE
        !           105: get_stat_birthtime_ns (struct stat const *st _GL_UNUSED)
        !           106: {
        !           107: # if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
        !           108:   return STAT_TIMESPEC (st, st_birthtim).tv_nsec;
        !           109: # elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
        !           110:   return STAT_TIMESPEC_NS (st, st_birthtim);
        !           111: # else
        !           112:   return 0;
        !           113: # endif
        !           114: }
        !           115: 
        !           116: /* Return *ST's access time.  */
        !           117: _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
        !           118: get_stat_atime (struct stat const *st)
        !           119: {
        !           120: #ifdef STAT_TIMESPEC
        !           121:   return STAT_TIMESPEC (st, st_atim);
        !           122: #else
        !           123:   struct timespec t;
        !           124:   t.tv_sec = st->st_atime;
        !           125:   t.tv_nsec = get_stat_atime_ns (st);
        !           126:   return t;
        !           127: #endif
        !           128: }
        !           129: 
        !           130: /* Return *ST's status change time.  */
        !           131: _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
        !           132: get_stat_ctime (struct stat const *st)
        !           133: {
        !           134: #ifdef STAT_TIMESPEC
        !           135:   return STAT_TIMESPEC (st, st_ctim);
        !           136: #else
        !           137:   struct timespec t;
        !           138:   t.tv_sec = st->st_ctime;
        !           139:   t.tv_nsec = get_stat_ctime_ns (st);
        !           140:   return t;
        !           141: #endif
        !           142: }
        !           143: 
        !           144: /* Return *ST's data modification time.  */
        !           145: _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
        !           146: get_stat_mtime (struct stat const *st)
        !           147: {
        !           148: #ifdef STAT_TIMESPEC
        !           149:   return STAT_TIMESPEC (st, st_mtim);
        !           150: #else
        !           151:   struct timespec t;
        !           152:   t.tv_sec = st->st_mtime;
        !           153:   t.tv_nsec = get_stat_mtime_ns (st);
        !           154:   return t;
        !           155: #endif
        !           156: }
        !           157: 
        !           158: /* Return *ST's birth time, if available; otherwise return a value
        !           159:    with tv_sec and tv_nsec both equal to -1.  */
        !           160: _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
        !           161: get_stat_birthtime (struct stat const *st _GL_UNUSED)
        !           162: {
        !           163:   struct timespec t;
        !           164: 
        !           165: #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
        !           166:      || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC)
        !           167:   t = STAT_TIMESPEC (st, st_birthtim);
        !           168: #elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
        !           169:   t.tv_sec = st->st_birthtime;
        !           170:   t.tv_nsec = st->st_birthtimensec;
        !           171: #elif defined _WIN32 && ! defined __CYGWIN__
        !           172:   /* Native Windows platforms (but not Cygwin) put the "file creation
        !           173:      time" in st_ctime (!).  See
        !           174:      <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions>.  */
        !           175: # if _GL_WINDOWS_STAT_TIMESPEC
        !           176:   t = st->st_ctim;
        !           177: # else
        !           178:   t.tv_sec = st->st_ctime;
        !           179:   t.tv_nsec = 0;
        !           180: # endif
        !           181: #else
        !           182:   /* Birth time is not supported.  */
        !           183:   t.tv_sec = -1;
        !           184:   t.tv_nsec = -1;
        !           185: #endif
        !           186: 
        !           187: #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
        !           188:      || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \
        !           189:      || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
        !           190:   /* FreeBSD and NetBSD sometimes signal the absence of knowledge by
        !           191:      using zero.  Attempt to work around this problem.  Alas, this can
        !           192:      report failure even for valid timestamps.  Also, NetBSD
        !           193:      sometimes returns junk in the birth time fields; work around this
        !           194:      bug if it is detected.  */
        !           195:   if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000))
        !           196:     {
        !           197:       t.tv_sec = -1;
        !           198:       t.tv_nsec = -1;
        !           199:     }
        !           200: #endif
        !           201: 
        !           202:   return t;
        !           203: }
        !           204: 
        !           205: /* If a stat-like function returned RESULT, normalize the timestamps
        !           206:    in *ST, in case this platform suffers from the Solaris 11 bug where
        !           207:    tv_nsec might be negative.  Return the adjusted RESULT, setting
        !           208:    errno to EOVERFLOW if normalization overflowed.  This function
        !           209:    is intended to be private to this .h file.  */
        !           210: _GL_STAT_TIME_INLINE int
        !           211: stat_time_normalize (int result, struct stat *st _GL_UNUSED)
        !           212: {
        !           213: #if defined __sun && defined STAT_TIMESPEC
        !           214:   if (result == 0)
        !           215:     {
        !           216:       long int timespec_hz = 1000000000;
        !           217:       short int const ts_off[] = { offsetof (struct stat, st_atim),
        !           218:                                    offsetof (struct stat, st_mtim),
        !           219:                                    offsetof (struct stat, st_ctim) };
        !           220:       int i;
        !           221:       for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++)
        !           222:         {
        !           223:           struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]);
        !           224:           long int q = ts->tv_nsec / timespec_hz;
        !           225:           long int r = ts->tv_nsec % timespec_hz;
        !           226:           if (r < 0)
        !           227:             {
        !           228:               r += timespec_hz;
        !           229:               q--;
        !           230:             }
        !           231:           ts->tv_nsec = r;
        !           232:           /* Overflow is possible, as Solaris 11 stat can yield
        !           233:              tv_sec == TYPE_MINIMUM (time_t) && tv_nsec == -1000000000.
        !           234:              INT_ADD_WRAPV is OK, since time_t is signed on Solaris.  */
        !           235:           if (INT_ADD_WRAPV (q, ts->tv_sec, &ts->tv_sec))
        !           236:             {
        !           237:               errno = EOVERFLOW;
        !           238:               return -1;
        !           239:             }
        !           240:         }
        !           241:     }
        !           242: #endif
        !           243:   return result;
        !           244: }
        !           245: 
        !           246: #ifdef __cplusplus
        !           247: }
        !           248: #endif
        !           249: 
        !           250: _GL_INLINE_HEADER_END
        !           251: 
        !           252: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>