1 /* Set file access and modification times.
3 Copyright (C) 2003-2009 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3 of the License, or any
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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* Written by Paul Eggert. */
20 /* derived from a function in touch.c */
34 #include "stat-time.h"
41 /* Some systems (even some that do have <utime.h>) don't declare this
42 structure anywhere. */
43 #ifndef HAVE_STRUCT_UTIMBUF
51 /* Avoid recursion with rpl_futimens or rpl_utimensat. */
55 /* Solaris 9 mistakenly succeeds when given a non-directory with a
56 trailing slash. Force the use of rpl_stat for a fix. */
57 #ifndef REPLACE_FUNC_STAT_FILE
58 # define REPLACE_FUNC_STAT_FILE 0
61 #if HAVE_UTIMENSAT || HAVE_FUTIMENS
62 /* Cache variables for whether the utimensat syscall works; used to
63 avoid calling the syscall if we know it will just fail with ENOSYS,
64 and to avoid unnecessary work in massaging timestamps if the
65 syscall will work. Multiple variables are needed, to distinguish
66 between the following scenarios on Linux:
67 utimensat doesn't exist, or is in glibc but kernel 2.6.18 fails with ENOSYS
68 kernel 2.6.22 and earlier rejects AT_SYMLINK_NOFOLLOW
69 kernel 2.6.25 and earlier reject UTIME_NOW/UTIME_OMIT with non-zero tv_sec
70 kernel 2.6.32 and earlier fail to bump ctime if mtime is UTIME_OMIT
71 utimensat completely works
72 For each cache variable: 0 = unknown, 1 = yes, -1 = no. */
73 static int utimensat_works_really;
74 static int lutimensat_works_really;
75 static int utimensat_ctime_really;
77 /* Determine whether the kernel has a ctime bug. ST1 and ST2
78 correspond to stat data before and after a successful time change.
79 TIMES contains the timestamps that were used during the time change
80 (mtime will be UTIME_OMIT). Update the cache variable if there is
81 conclusive evidence of the kernel working or being buggy. Return
82 true if TIMES has been updated and another kernel call is needed,
83 whether or not the kernel is known to have the bug. */
85 detect_ctime_bug (struct stat *st1, struct stat *st2, struct timespec times[2])
88 if (st1->st_ctime != st2->st_ctime
89 || get_stat_ctime_ns (st1) != get_stat_ctime_ns (st2))
91 utimensat_ctime_really = 1;
94 /* The results are inconclusive if the ctime in st1 is within a file
95 system quantization window of now. For FAT, this is 2 seconds,
96 for systems with sub-second resolution, a typical resolution is
97 10 milliseconds; to be safe we declare an inconsistent result if
98 ctime is within a 20 millisecond window. Avoid an extra gettime
99 call if atime makes sense. It is unlikely that the original
100 ctime is later than now, but rather than deal with the overflow,
101 we treat that as consistent evidence of the bug. */
102 if (times[0].tv_nsec == UTIME_NOW)
103 now = get_stat_atime (st2);
106 if (now.tv_sec < st2->st_ctime
107 || 2 < now.tv_sec - st2->st_ctime
108 || (get_stat_ctime_ns (st2)
109 && now.tv_sec - st2->st_ctime < 2
110 && (20000000 < (1000000000 * (now.tv_sec - st2->st_ctime)
111 + now.tv_nsec - get_stat_ctime_ns (st2)))))
112 utimensat_ctime_really = -1;
113 times[1] = get_stat_mtime (st2);
116 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
118 /* Validate the requested timestamps. Return 0 if the resulting
119 timespec can be used for utimensat (after possibly modifying it to
120 work around bugs in utimensat). Return a positive value if the
121 timespec needs further adjustment based on stat results: 1 if any
122 adjustment is needed for utimes, and 2 if mtime was UTIME_OMIT and
123 an adjustment is needed for utimensat. Return -1, with errno set
124 to EINVAL, if timespec is out of range. */
126 validate_timespec (struct timespec timespec[2])
130 if ((timespec[0].tv_nsec != UTIME_NOW
131 && timespec[0].tv_nsec != UTIME_OMIT
132 && (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec))
133 || (timespec[1].tv_nsec != UTIME_NOW
134 && timespec[1].tv_nsec != UTIME_OMIT
135 && (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec)))
140 /* Work around Linux kernel 2.6.25 bug, where utimensat fails with
141 EINVAL if tv_sec is not 0 when using the flag values of tv_nsec.
142 Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT
143 fails to bump ctime. */
144 if (timespec[0].tv_nsec == UTIME_NOW
145 || timespec[0].tv_nsec == UTIME_OMIT)
147 timespec[0].tv_sec = 0;
150 if (timespec[1].tv_nsec == UTIME_NOW)
152 timespec[1].tv_sec = 0;
155 else if (timespec[1].tv_nsec == UTIME_OMIT)
157 timespec[1].tv_sec = 0;
163 /* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat
164 buffer STATBUF to obtain the current timestamps of the file. If
165 both times are UTIME_NOW, set *TS to NULL (as this can avoid some
166 permissions issues). If both times are UTIME_OMIT, return true
167 (nothing further beyond the prior collection of STATBUF is
168 necessary); otherwise return false. */
170 update_timespec (struct stat const *statbuf, struct timespec *ts[2])
172 struct timespec *timespec = *ts;
173 if (timespec[0].tv_nsec == UTIME_OMIT
174 && timespec[1].tv_nsec == UTIME_OMIT)
176 if (timespec[0].tv_nsec == UTIME_NOW
177 && timespec[1].tv_nsec == UTIME_NOW)
183 if (timespec[0].tv_nsec == UTIME_OMIT)
184 timespec[0] = get_stat_atime (statbuf);
185 else if (timespec[0].tv_nsec == UTIME_NOW)
186 gettime (×pec[0]);
188 if (timespec[1].tv_nsec == UTIME_OMIT)
189 timespec[1] = get_stat_mtime (statbuf);
190 else if (timespec[1].tv_nsec == UTIME_NOW)
191 gettime (×pec[1]);
196 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be
197 TIMESPEC[0] and TIMESPEC[1], respectively.
198 FD must be either negative -- in which case it is ignored --
199 or a file descriptor that is open on FILE.
200 If FD is nonnegative, then FILE can be NULL, which means
201 use just futimes (or equivalent) instead of utimes (or equivalent),
202 and fail if on an old system without futimes (or equivalent).
203 If TIMESPEC is null, set the time stamps to the current time.
204 Return 0 on success, -1 (setting errno) on failure. */
207 fdutimens (char const *file, int fd, struct timespec const timespec[2])
209 struct timespec adjusted_timespec[2];
210 struct timespec *ts = timespec ? adjusted_timespec : NULL;
211 int adjustment_needed = 0;
215 adjusted_timespec[0] = timespec[0];
216 adjusted_timespec[1] = timespec[1];
217 adjustment_needed = validate_timespec (ts);
219 if (adjustment_needed < 0)
222 /* Require that at least one of FD or FILE are valid. Works around
223 a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather
232 if (dup2 (fd, fd) != fd)
236 /* Some Linux-based NFS clients are buggy, and mishandle time stamps
237 of files in NFS file systems in some cases. We have no
238 configure-time test for this, but please see
239 <http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to
240 some of the problems with Linux 2.6.16. If this affects you,
241 compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to
242 help in some cases, albeit at a cost in performance. But you
243 really should upgrade your kernel to a fixed version, since the
244 problem affects many applications. */
246 #if HAVE_BUGGY_NFS_TIME_STAMPS
253 /* POSIX 2008 added two interfaces to set file timestamps with
254 nanosecond resolution; newer Linux implements both functions via
255 a single syscall. We provide a fallback for ENOSYS (for example,
256 compiling against Linux 2.6.25 kernel headers and glibc 2.7, but
257 running on Linux 2.6.18 kernel). */
258 #if HAVE_UTIMENSAT || HAVE_FUTIMENS
259 if (0 <= utimensat_works_really)
264 /* Linux kernel 2.6.32 has a bug where it fails to bump ctime if
265 UTIME_OMIT was used for mtime. It costs time to do an extra
266 [f]stat up front, so we cache whether the function works. */
267 if (utimensat_ctime_really <= 0 && adjustment_needed == 2)
269 if (fd < 0 ? stat (file, &st1) : fstat (fd, &st1))
271 if (ts[0].tv_nsec == UTIME_OMIT)
273 if (utimensat_ctime_really < 0)
274 ts[1] = get_stat_mtime (&st1);
279 result = utimensat (AT_FDCWD, file, ts, 0);
281 /* Work around a kernel bug:
282 http://bugzilla.redhat.com/442352
283 http://bugzilla.redhat.com/449910
284 It appears that utimensat can mistakenly return 280 rather
285 than -1 upon ENOSYS failure.
286 FIXME: remove in 2010 or whenever the offending kernels
287 are no longer in common use. */
290 # endif /* __linux__ */
291 if (result == 0 || errno != ENOSYS)
293 utimensat_works_really = 1;
294 if (result == 0 && utimensat_ctime_really == 0
295 && adjustment_needed == 2)
297 /* Perform a followup stat to see if the kernel has
299 if (stat (file, &st2))
301 if (detect_ctime_bug (&st1, &st2, ts))
302 result = utimensat (AT_FDCWD, file, ts, 0);
307 # endif /* HAVE_UTIMENSAT */
310 result = futimens (fd, ts);
312 /* Work around the same bug as above. */
315 # endif /* __linux__ */
316 if (result == 0 || errno != ENOSYS)
318 utimensat_works_really = 1;
319 /* Work around the same bug as above. */
320 if (result == 0 && utimensat_ctime_really == 0
321 && adjustment_needed == 2)
323 if (fstat (fd, &st2))
325 if (detect_ctime_bug (&st1, &st2, ts))
326 result = futimens (fd, ts);
331 # endif /* HAVE_FUTIMENS */
333 utimensat_works_really = -1;
334 lutimensat_works_really = -1;
335 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
337 /* The platform lacks an interface to set file timestamps with
338 nanosecond resolution, so do the best we can, discarding any
339 fractional part of the timestamp. */
341 if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0))
344 if (fd < 0 ? stat (file, &st) : fstat (fd, &st))
346 if (ts && update_timespec (&st, &ts))
351 #if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
352 struct timeval timeval[2];
353 struct timeval const *t;
356 timeval[0].tv_sec = ts[0].tv_sec;
357 timeval[0].tv_usec = ts[0].tv_nsec / 1000;
358 timeval[1].tv_sec = ts[1].tv_sec;
359 timeval[1].tv_usec = ts[1].tv_nsec / 1000;
368 return futimesat (AT_FDCWD, file, t);
373 /* If futimesat or futimes fails here, don't try to speed things
374 up by returning right away. glibc can incorrectly fail with
375 errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0
376 in high security mode doesn't allow ordinary users to read
377 /proc/self, so glibc incorrectly fails with errno == EACCES.
378 If errno == EIO, EPERM, or EROFS, it's probably safe to fail
379 right away, but these cases are rare enough that they're not
380 worth optimizing, and who knows what other messed-up systems
381 are out there? So play it safe and fall back on the code
383 # if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG
384 if (futimesat (fd, NULL, t) == 0)
387 if (futimes (fd, t) == 0)
391 #endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
395 #if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) \
396 || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
402 #if HAVE_WORKING_UTIMES
403 return utimes (file, t);
406 struct utimbuf utimbuf;
410 utimbuf.actime = ts[0].tv_sec;
411 utimbuf.modtime = ts[1].tv_sec;
417 return utime (file, ut);
419 #endif /* !HAVE_WORKING_UTIMES */
423 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be
424 TIMESPEC[0] and TIMESPEC[1], respectively.
425 FD must be either negative -- in which case it is ignored --
426 or a file descriptor that is open on FILE.
427 If FD is nonnegative, then FILE can be NULL, which means
428 use just futimes (or equivalent) instead of utimes (or equivalent),
429 and fail if on an old system without futimes (or equivalent).
430 If TIMESPEC is null, set the time stamps to the current time.
431 Return 0 on success, -1 (setting errno) on failure. */
434 gl_futimens (int fd, char const *file, struct timespec const timespec[2])
436 return fdutimens (file, fd, timespec);
439 /* Set the access and modification time stamps of FILE to be
440 TIMESPEC[0] and TIMESPEC[1], respectively. */
442 utimens (char const *file, struct timespec const timespec[2])
444 return fdutimens (file, -1, timespec);
447 /* Set the access and modification time stamps of FILE to be
448 TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
449 symlinks. Fail with ENOSYS if the platform does not support
450 changing symlink timestamps, but FILE was a symlink. */
452 lutimens (char const *file, struct timespec const timespec[2])
454 struct timespec adjusted_timespec[2];
455 struct timespec *ts = timespec ? adjusted_timespec : NULL;
456 int adjustment_needed = 0;
461 adjusted_timespec[0] = timespec[0];
462 adjusted_timespec[1] = timespec[1];
463 adjustment_needed = validate_timespec (ts);
465 if (adjustment_needed < 0)
468 /* The Linux kernel did not support symlink timestamps until
469 utimensat, in version 2.6.22, so we don't need to mimic
470 gl_futimens' worry about buggy NFS clients. But we do have to
471 worry about bogus return values. */
474 if (0 <= lutimensat_works_really)
479 /* Linux kernel 2.6.32 has a bug where it fails to bump ctime if
480 UTIME_OMIT was used for mtime. It costs time to do an extra
481 lstat up front, so we cache whether the function works. */
482 if (utimensat_ctime_really <= 0 && adjustment_needed == 2)
484 if (lstat (file, &st1))
486 if (ts[0].tv_nsec == UTIME_OMIT)
488 if (utimensat_ctime_really < 0)
489 ts[1] = get_stat_mtime (&st1);
491 result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
493 /* Work around a kernel bug:
494 http://bugzilla.redhat.com/442352
495 http://bugzilla.redhat.com/449910
496 It appears that utimensat can mistakenly return 280 rather
497 than -1 upon ENOSYS failure.
498 FIXME: remove in 2010 or whenever the offending kernels
499 are no longer in common use. */
503 if (result == 0 || errno != ENOSYS)
505 utimensat_works_really = 1;
506 lutimensat_works_really = 1;
507 if (result == 0 && utimensat_ctime_really == 0
508 && adjustment_needed == 2)
510 /* Perform a followup stat to see if the kernel has a
512 if (lstat (file, &st2))
514 if (detect_ctime_bug (&st1, &st2, ts))
515 result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
520 lutimensat_works_really = -1;
521 #endif /* HAVE_UTIMENSAT */
523 /* The platform lacks an interface to set file timestamps with
524 nanosecond resolution, so do the best we can, discarding any
525 fractional part of the timestamp. */
527 if (adjustment_needed || REPLACE_FUNC_STAT_FILE)
529 if (lstat (file, &st))
531 if (ts && update_timespec (&st, &ts))
535 /* On Linux, lutimes is a thin wrapper around utimensat, so there is
536 no point trying lutimes if utimensat failed with ENOSYS. */
537 #if HAVE_LUTIMES && !HAVE_UTIMENSAT
539 struct timeval timeval[2];
540 struct timeval const *t;
544 timeval[0].tv_sec = ts[0].tv_sec;
545 timeval[0].tv_usec = ts[0].tv_nsec / 1000;
546 timeval[1].tv_sec = ts[1].tv_sec;
547 timeval[1].tv_usec = ts[1].tv_nsec / 1000;
553 result = lutimes (file, t);
554 if (result == 0 || errno != ENOSYS)
557 #endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */
559 /* Out of luck for symlinks, but we still handle regular files. */
560 if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))
562 if (!S_ISLNK (st.st_mode))
563 return fdutimens (file, -1, ts);