1 /* Set file access and modification times.
3 Copyright (C) 2003-2010 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 used with xfs or ntfs-3g fail to honor 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 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
77 /* Validate the requested timestamps. Return 0 if the resulting
78 timespec can be used for utimensat (after possibly modifying it to
79 work around bugs in utimensat). Return a positive value if the
80 timespec needs further adjustment based on stat results: 1 if any
81 adjustment is needed for utimes, and 2 if any adjustment is needed
82 for Linux utimensat. Return -1, with errno set to EINVAL, if
83 timespec is out of range. */
85 validate_timespec (struct timespec timespec[2])
88 int utime_omit_count = 0;
90 if ((timespec[0].tv_nsec != UTIME_NOW
91 && timespec[0].tv_nsec != UTIME_OMIT
92 && (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec))
93 || (timespec[1].tv_nsec != UTIME_NOW
94 && timespec[1].tv_nsec != UTIME_OMIT
95 && (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec)))
100 /* Work around Linux kernel 2.6.25 bug, where utimensat fails with
101 EINVAL if tv_sec is not 0 when using the flag values of tv_nsec.
102 Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT
103 fails to bump ctime. */
104 if (timespec[0].tv_nsec == UTIME_NOW
105 || timespec[0].tv_nsec == UTIME_OMIT)
107 timespec[0].tv_sec = 0;
109 if (timespec[0].tv_nsec == UTIME_OMIT)
112 if (timespec[1].tv_nsec == UTIME_NOW
113 || timespec[1].tv_nsec == UTIME_OMIT)
115 timespec[1].tv_sec = 0;
117 if (timespec[1].tv_nsec == UTIME_OMIT)
120 return result + (utime_omit_count == 1);
123 /* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat
124 buffer STATBUF to obtain the current timestamps of the file. If
125 both times are UTIME_NOW, set *TS to NULL (as this can avoid some
126 permissions issues). If both times are UTIME_OMIT, return true
127 (nothing further beyond the prior collection of STATBUF is
128 necessary); otherwise return false. */
130 update_timespec (struct stat const *statbuf, struct timespec *ts[2])
132 struct timespec *timespec = *ts;
133 if (timespec[0].tv_nsec == UTIME_OMIT
134 && timespec[1].tv_nsec == UTIME_OMIT)
136 if (timespec[0].tv_nsec == UTIME_NOW
137 && timespec[1].tv_nsec == UTIME_NOW)
143 if (timespec[0].tv_nsec == UTIME_OMIT)
144 timespec[0] = get_stat_atime (statbuf);
145 else if (timespec[0].tv_nsec == UTIME_NOW)
146 gettime (×pec[0]);
148 if (timespec[1].tv_nsec == UTIME_OMIT)
149 timespec[1] = get_stat_mtime (statbuf);
150 else if (timespec[1].tv_nsec == UTIME_NOW)
151 gettime (×pec[1]);
156 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be
157 TIMESPEC[0] and TIMESPEC[1], respectively.
158 FD must be either negative -- in which case it is ignored --
159 or a file descriptor that is open on FILE.
160 If FD is nonnegative, then FILE can be NULL, which means
161 use just futimes (or equivalent) instead of utimes (or equivalent),
162 and fail if on an old system without futimes (or equivalent).
163 If TIMESPEC is null, set the time stamps to the current time.
164 Return 0 on success, -1 (setting errno) on failure. */
167 fdutimens (char const *file, int fd, struct timespec const timespec[2])
169 struct timespec adjusted_timespec[2];
170 struct timespec *ts = timespec ? adjusted_timespec : NULL;
171 int adjustment_needed = 0;
176 adjusted_timespec[0] = timespec[0];
177 adjusted_timespec[1] = timespec[1];
178 adjustment_needed = validate_timespec (ts);
180 if (adjustment_needed < 0)
183 /* Require that at least one of FD or FILE are valid. Works around
184 a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather
193 if (dup2 (fd, fd) != fd)
197 /* Some Linux-based NFS clients are buggy, and mishandle time stamps
198 of files in NFS file systems in some cases. We have no
199 configure-time test for this, but please see
200 <http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to
201 some of the problems with Linux 2.6.16. If this affects you,
202 compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to
203 help in some cases, albeit at a cost in performance. But you
204 really should upgrade your kernel to a fixed version, since the
205 problem affects many applications. */
207 #if HAVE_BUGGY_NFS_TIME_STAMPS
214 /* POSIX 2008 added two interfaces to set file timestamps with
215 nanosecond resolution; newer Linux implements both functions via
216 a single syscall. We provide a fallback for ENOSYS (for example,
217 compiling against Linux 2.6.25 kernel headers and glibc 2.7, but
218 running on Linux 2.6.18 kernel). */
219 #if HAVE_UTIMENSAT || HAVE_FUTIMENS
220 if (0 <= utimensat_works_really)
224 /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
225 systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
226 but work if both times are either explicitly specified or
227 UTIME_NOW. Work around it with a preparatory [f]stat prior
228 to calling futimens/utimensat; fortunately, there is not much
229 timing impact due to the extra syscall even on file systems
230 where UTIME_OMIT would have worked. FIXME: Simplify this in
231 2012, when file system bugs are no longer common. */
232 if (adjustment_needed == 2)
234 if (fd < 0 ? stat (file, &st) : fstat (fd, &st))
236 if (ts[0].tv_nsec == UTIME_OMIT)
237 ts[0] = get_stat_atime (&st);
238 else if (ts[1].tv_nsec == UTIME_OMIT)
239 ts[1] = get_stat_mtime (&st);
240 /* Note that st is good, in case utimensat gives ENOSYS. */
243 # endif /* __linux__ */
247 result = utimensat (AT_FDCWD, file, ts, 0);
249 /* Work around a kernel bug:
250 http://bugzilla.redhat.com/442352
251 http://bugzilla.redhat.com/449910
252 It appears that utimensat can mistakenly return 280 rather
253 than -1 upon ENOSYS failure.
254 FIXME: remove in 2010 or whenever the offending kernels
255 are no longer in common use. */
258 # endif /* __linux__ */
259 if (result == 0 || errno != ENOSYS)
261 utimensat_works_really = 1;
265 # endif /* HAVE_UTIMENSAT */
269 result = futimens (fd, ts);
271 /* Work around the same bug as above. */
274 # endif /* __linux__ */
275 if (result == 0 || errno != ENOSYS)
277 utimensat_works_really = 1;
281 # endif /* HAVE_FUTIMENS */
283 utimensat_works_really = -1;
284 lutimensat_works_really = -1;
285 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
287 /* The platform lacks an interface to set file timestamps with
288 nanosecond resolution, so do the best we can, discarding any
289 fractional part of the timestamp. */
291 if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0))
293 if (adjustment_needed != 3
294 && (fd < 0 ? stat (file, &st) : fstat (fd, &st)))
296 if (ts && update_timespec (&st, &ts))
301 #if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
302 struct timeval timeval[2];
306 timeval[0].tv_sec = ts[0].tv_sec;
307 timeval[0].tv_usec = ts[0].tv_nsec / 1000;
308 timeval[1].tv_sec = ts[1].tv_sec;
309 timeval[1].tv_usec = ts[1].tv_nsec / 1000;
318 return futimesat (AT_FDCWD, file, t);
323 /* If futimesat or futimes fails here, don't try to speed things
324 up by returning right away. glibc can incorrectly fail with
325 errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0
326 in high security mode doesn't allow ordinary users to read
327 /proc/self, so glibc incorrectly fails with errno == EACCES.
328 If errno == EIO, EPERM, or EROFS, it's probably safe to fail
329 right away, but these cases are rare enough that they're not
330 worth optimizing, and who knows what other messed-up systems
331 are out there? So play it safe and fall back on the code
333 # if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG
334 if (futimesat (fd, NULL, t) == 0)
337 if (futimes (fd, t) == 0)
341 #endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
345 #if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) \
346 || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
352 #if HAVE_WORKING_UTIMES
353 return utimes (file, t);
356 struct utimbuf utimbuf;
360 utimbuf.actime = ts[0].tv_sec;
361 utimbuf.modtime = ts[1].tv_sec;
367 return utime (file, ut);
369 #endif /* !HAVE_WORKING_UTIMES */
373 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be
374 TIMESPEC[0] and TIMESPEC[1], respectively.
375 FD must be either negative -- in which case it is ignored --
376 or a file descriptor that is open on FILE.
377 If FD is nonnegative, then FILE can be NULL, which means
378 use just futimes (or equivalent) instead of utimes (or equivalent),
379 and fail if on an old system without futimes (or equivalent).
380 If TIMESPEC is null, set the time stamps to the current time.
381 Return 0 on success, -1 (setting errno) on failure. */
384 gl_futimens (int fd, char const *file, struct timespec const timespec[2])
386 return fdutimens (file, fd, timespec);
389 /* Set the access and modification time stamps of FILE to be
390 TIMESPEC[0] and TIMESPEC[1], respectively. */
392 utimens (char const *file, struct timespec const timespec[2])
394 return fdutimens (file, -1, timespec);
397 /* Set the access and modification time stamps of FILE to be
398 TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
399 symlinks. Fail with ENOSYS if the platform does not support
400 changing symlink timestamps, but FILE was a symlink. */
402 lutimens (char const *file, struct timespec const timespec[2])
404 struct timespec adjusted_timespec[2];
405 struct timespec *ts = timespec ? adjusted_timespec : NULL;
406 int adjustment_needed = 0;
411 adjusted_timespec[0] = timespec[0];
412 adjusted_timespec[1] = timespec[1];
413 adjustment_needed = validate_timespec (ts);
415 if (adjustment_needed < 0)
418 /* The Linux kernel did not support symlink timestamps until
419 utimensat, in version 2.6.22, so we don't need to mimic
420 gl_futimens' worry about buggy NFS clients. But we do have to
421 worry about bogus return values. */
424 if (0 <= lutimensat_works_really)
428 /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
429 systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
430 but work if both times are either explicitly specified or
431 UTIME_NOW. Work around it with a preparatory lstat prior to
432 calling utimensat; fortunately, there is not much timing
433 impact due to the extra syscall even on file systems where
434 UTIME_OMIT would have worked. FIXME: Simplify this in 2012,
435 when file system bugs are no longer common. */
436 if (adjustment_needed == 2)
438 if (lstat (file, &st))
440 if (ts[0].tv_nsec == UTIME_OMIT)
441 ts[0] = get_stat_atime (&st);
442 else if (ts[1].tv_nsec == UTIME_OMIT)
443 ts[1] = get_stat_mtime (&st);
444 /* Note that st is good, in case utimensat gives ENOSYS. */
447 # endif /* __linux__ */
448 result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
450 /* Work around a kernel bug:
451 http://bugzilla.redhat.com/442352
452 http://bugzilla.redhat.com/449910
453 It appears that utimensat can mistakenly return 280 rather
454 than -1 upon ENOSYS failure.
455 FIXME: remove in 2010 or whenever the offending kernels
456 are no longer in common use. */
460 if (result == 0 || errno != ENOSYS)
462 utimensat_works_really = 1;
463 lutimensat_works_really = 1;
467 lutimensat_works_really = -1;
468 #endif /* HAVE_UTIMENSAT */
470 /* The platform lacks an interface to set file timestamps with
471 nanosecond resolution, so do the best we can, discarding any
472 fractional part of the timestamp. */
474 if (adjustment_needed || REPLACE_FUNC_STAT_FILE)
476 if (adjustment_needed != 3 && lstat (file, &st))
478 if (ts && update_timespec (&st, &ts))
482 /* On Linux, lutimes is a thin wrapper around utimensat, so there is
483 no point trying lutimes if utimensat failed with ENOSYS. */
484 #if HAVE_LUTIMES && !HAVE_UTIMENSAT
486 struct timeval timeval[2];
491 timeval[0].tv_sec = ts[0].tv_sec;
492 timeval[0].tv_usec = ts[0].tv_nsec / 1000;
493 timeval[1].tv_sec = ts[1].tv_sec;
494 timeval[1].tv_usec = ts[1].tv_nsec / 1000;
500 result = lutimes (file, t);
501 if (result == 0 || errno != ENOSYS)
504 #endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */
506 /* Out of luck for symlinks, but we still handle regular files. */
507 if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))
509 if (!S_ISLNK (st.st_mode))
510 return fdutimens (file, -1, ts);