Annotation of embedaddon/libiconv/srclib/stat-time.h, revision 1.1.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>