summaryrefslogtreecommitdiffstats
path: root/gl/stat-time.h
diff options
context:
space:
mode:
Diffstat (limited to 'gl/stat-time.h')
-rw-r--r--gl/stat-time.h45
1 files changed, 33 insertions, 12 deletions
diff --git a/gl/stat-time.h b/gl/stat-time.h
index 3cd8478f..38315b9f 100644
--- a/gl/stat-time.h
+++ b/gl/stat-time.h
@@ -1,6 +1,6 @@
1/* stat-related time functions. 1/* stat-related time functions.
2 2
3 Copyright (C) 2005, 2007, 2009-2024 Free Software Foundation, Inc. 3 Copyright (C) 2005, 2007, 2009-2025 Free Software Foundation, Inc.
4 4
5 This file is free software: you can redistribute it and/or modify 5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as 6 it under the terms of the GNU Lesser General Public License as
@@ -117,6 +117,31 @@ get_stat_birthtime_ns (_GL_UNUSED struct stat const *st)
117# endif 117# endif
118} 118}
119 119
120/* Constructs a 'struct timespec' with the given contents.
121 This macro / function is private to stat-time.h. */
122#if !defined __cplusplus
123/* Use a C99 compound literal.
124 This is guaranteed to initialize also the padding bits, for example on
125 platforms where tv_sec is 64 bits and tv_nsec is 32 bits, thus avoiding
126 gcc -Wuse-of-uninitialized-value warnings. */
127# define _gl_make_timespec(sec,nsec) \
128 (struct timespec) { .tv_sec = (sec), .tv_nsec = (nsec) }
129#else
130/* C++ does not have C99 compound literals.
131 A constructor invocation
132 timespec { (sec), (nsec) }
133 would make assumptions about the order of the fields of 'struct timespec',
134 which are not guaranteed by POSIX. So, use an inline function. */
135static inline struct timespec
136_gl_make_timespec (time_t sec, long nsec)
137{
138 struct timespec ts;
139 ts.tv_sec = sec;
140 ts.tv_nsec = nsec;
141 return ts;
142}
143#endif
144
120/* Return *ST's access time. */ 145/* Return *ST's access time. */
121_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE 146_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
122get_stat_atime (struct stat const *st) 147get_stat_atime (struct stat const *st)
@@ -124,8 +149,7 @@ get_stat_atime (struct stat const *st)
124#ifdef STAT_TIMESPEC 149#ifdef STAT_TIMESPEC
125 return STAT_TIMESPEC (st, st_atim); 150 return STAT_TIMESPEC (st, st_atim);
126#else 151#else
127 return (struct timespec) { .tv_sec = st->st_atime, 152 return _gl_make_timespec (st->st_atime, get_stat_atime_ns (st));
128 .tv_nsec = get_stat_atime_ns (st) };
129#endif 153#endif
130} 154}
131 155
@@ -136,8 +160,7 @@ get_stat_ctime (struct stat const *st)
136#ifdef STAT_TIMESPEC 160#ifdef STAT_TIMESPEC
137 return STAT_TIMESPEC (st, st_ctim); 161 return STAT_TIMESPEC (st, st_ctim);
138#else 162#else
139 return (struct timespec) { .tv_sec = st->st_ctime, 163 return _gl_make_timespec (st->st_ctime, get_stat_ctime_ns (st));
140 .tv_nsec = get_stat_ctime_ns (st) };
141#endif 164#endif
142} 165}
143 166
@@ -148,8 +171,7 @@ get_stat_mtime (struct stat const *st)
148#ifdef STAT_TIMESPEC 171#ifdef STAT_TIMESPEC
149 return STAT_TIMESPEC (st, st_mtim); 172 return STAT_TIMESPEC (st, st_mtim);
150#else 173#else
151 return (struct timespec) { .tv_sec = st->st_mtime, 174 return _gl_make_timespec (st->st_mtime, get_stat_mtime_ns (st));
152 .tv_nsec = get_stat_mtime_ns (st) };
153#endif 175#endif
154} 176}
155 177
@@ -164,8 +186,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
164 || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) 186 || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC)
165 t = STAT_TIMESPEC (st, st_birthtim); 187 t = STAT_TIMESPEC (st, st_birthtim);
166#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC 188#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
167 t = (struct timespec) { .tv_sec = st->st_birthtime, 189 t = _gl_make_timespec (st->st_birthtime, st->st_birthtimensec);
168 .tv_nsec = st->st_birthtimensec };
169#elif defined _WIN32 && ! defined __CYGWIN__ 190#elif defined _WIN32 && ! defined __CYGWIN__
170 /* Native Windows platforms (but not Cygwin) put the "file creation 191 /* Native Windows platforms (but not Cygwin) put the "file creation
171 time" in st_ctime (!). See 192 time" in st_ctime (!). See
@@ -173,11 +194,11 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
173# if _GL_WINDOWS_STAT_TIMESPEC 194# if _GL_WINDOWS_STAT_TIMESPEC
174 t = st->st_ctim; 195 t = st->st_ctim;
175# else 196# else
176 t = (struct timespec) { .tv_sec = st->st_ctime }; 197 t = _gl_make_timespec (st->st_ctime, 0);
177# endif 198# endif
178#else 199#else
179 /* Birth time is not supported. */ 200 /* Birth time is not supported. */
180 t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; 201 t = _gl_make_timespec (-1, -1);
181#endif 202#endif
182 203
183#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ 204#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
@@ -189,7 +210,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
189 sometimes returns junk in the birth time fields; work around this 210 sometimes returns junk in the birth time fields; work around this
190 bug if it is detected. */ 211 bug if it is detected. */
191 if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) 212 if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000))
192 t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; 213 t = _gl_make_timespec (-1, -1);
193#endif 214#endif
194 215
195 return t; 216 return t;