Import upstream version 1.28
[debian/tar] / gnu / utimens.c
1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Set file access and modification times.
4
5    Copyright (C) 2003-2014 Free Software Foundation, Inc.
6
7    This program is free software: you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 3 of the License, or any
10    later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 /* Written by Paul Eggert.  */
21
22 /* derived from a function in touch.c */
23
24 #include <config.h>
25
26 #define _GL_UTIMENS_INLINE _GL_EXTERN_INLINE
27 #include "utimens.h"
28
29 #include <assert.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <stdbool.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35 #include <unistd.h>
36
37 #include "stat-time.h"
38 #include "timespec.h"
39
40 #if HAVE_UTIME_H
41 # include <utime.h>
42 #endif
43
44 /* Some systems (even some that do have <utime.h>) don't declare this
45    structure anywhere.  */
46 #ifndef HAVE_STRUCT_UTIMBUF
47 struct utimbuf
48 {
49   long actime;
50   long modtime;
51 };
52 #endif
53
54 /* Avoid recursion with rpl_futimens or rpl_utimensat.  */
55 #undef futimens
56 #undef utimensat
57
58 /* Solaris 9 mistakenly succeeds when given a non-directory with a
59    trailing slash.  Force the use of rpl_stat for a fix.  */
60 #ifndef REPLACE_FUNC_STAT_FILE
61 # define REPLACE_FUNC_STAT_FILE 0
62 #endif
63
64 #if HAVE_UTIMENSAT || HAVE_FUTIMENS
65 /* Cache variables for whether the utimensat syscall works; used to
66    avoid calling the syscall if we know it will just fail with ENOSYS,
67    and to avoid unnecessary work in massaging timestamps if the
68    syscall will work.  Multiple variables are needed, to distinguish
69    between the following scenarios on Linux:
70    utimensat doesn't exist, or is in glibc but kernel 2.6.18 fails with ENOSYS
71    kernel 2.6.22 and earlier rejects AT_SYMLINK_NOFOLLOW
72    kernel 2.6.25 and earlier reject UTIME_NOW/UTIME_OMIT with non-zero tv_sec
73    kernel 2.6.32 used with xfs or ntfs-3g fail to honor UTIME_OMIT
74    utimensat completely works
75    For each cache variable: 0 = unknown, 1 = yes, -1 = no.  */
76 static int utimensat_works_really;
77 static int lutimensat_works_really;
78 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
79
80 /* Validate the requested timestamps.  Return 0 if the resulting
81    timespec can be used for utimensat (after possibly modifying it to
82    work around bugs in utimensat).  Return a positive value if the
83    timespec needs further adjustment based on stat results: 1 if any
84    adjustment is needed for utimes, and 2 if any adjustment is needed
85    for Linux utimensat.  Return -1, with errno set to EINVAL, if
86    timespec is out of range.  */
87 static int
88 validate_timespec (struct timespec timespec[2])
89 {
90   int result = 0;
91   int utime_omit_count = 0;
92   assert (timespec);
93   if ((timespec[0].tv_nsec != UTIME_NOW
94        && timespec[0].tv_nsec != UTIME_OMIT
95        && ! (0 <= timespec[0].tv_nsec
96              && timespec[0].tv_nsec < TIMESPEC_RESOLUTION))
97       || (timespec[1].tv_nsec != UTIME_NOW
98           && timespec[1].tv_nsec != UTIME_OMIT
99           && ! (0 <= timespec[1].tv_nsec
100                 && timespec[1].tv_nsec < TIMESPEC_RESOLUTION)))
101     {
102       errno = EINVAL;
103       return -1;
104     }
105   /* Work around Linux kernel 2.6.25 bug, where utimensat fails with
106      EINVAL if tv_sec is not 0 when using the flag values of tv_nsec.
107      Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT
108      fails to bump ctime.  */
109   if (timespec[0].tv_nsec == UTIME_NOW
110       || timespec[0].tv_nsec == UTIME_OMIT)
111     {
112       timespec[0].tv_sec = 0;
113       result = 1;
114       if (timespec[0].tv_nsec == UTIME_OMIT)
115         utime_omit_count++;
116     }
117   if (timespec[1].tv_nsec == UTIME_NOW
118       || timespec[1].tv_nsec == UTIME_OMIT)
119     {
120       timespec[1].tv_sec = 0;
121       result = 1;
122       if (timespec[1].tv_nsec == UTIME_OMIT)
123         utime_omit_count++;
124     }
125   return result + (utime_omit_count == 1);
126 }
127
128 /* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat
129    buffer STATBUF to obtain the current timestamps of the file.  If
130    both times are UTIME_NOW, set *TS to NULL (as this can avoid some
131    permissions issues).  If both times are UTIME_OMIT, return true
132    (nothing further beyond the prior collection of STATBUF is
133    necessary); otherwise return false.  */
134 static bool
135 update_timespec (struct stat const *statbuf, struct timespec *ts[2])
136 {
137   struct timespec *timespec = *ts;
138   if (timespec[0].tv_nsec == UTIME_OMIT
139       && timespec[1].tv_nsec == UTIME_OMIT)
140     return true;
141   if (timespec[0].tv_nsec == UTIME_NOW
142       && timespec[1].tv_nsec == UTIME_NOW)
143     {
144       *ts = NULL;
145       return false;
146     }
147
148   if (timespec[0].tv_nsec == UTIME_OMIT)
149     timespec[0] = get_stat_atime (statbuf);
150   else if (timespec[0].tv_nsec == UTIME_NOW)
151     gettime (&timespec[0]);
152
153   if (timespec[1].tv_nsec == UTIME_OMIT)
154     timespec[1] = get_stat_mtime (statbuf);
155   else if (timespec[1].tv_nsec == UTIME_NOW)
156     gettime (&timespec[1]);
157
158   return false;
159 }
160
161 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be
162    TIMESPEC[0] and TIMESPEC[1], respectively.
163    FD must be either negative -- in which case it is ignored --
164    or a file descriptor that is open on FILE.
165    If FD is nonnegative, then FILE can be NULL, which means
166    use just futimes (or equivalent) instead of utimes (or equivalent),
167    and fail if on an old system without futimes (or equivalent).
168    If TIMESPEC is null, set the time stamps to the current time.
169    Return 0 on success, -1 (setting errno) on failure.  */
170
171 int
172 fdutimens (int fd, char const *file, struct timespec const timespec[2])
173 {
174   struct timespec adjusted_timespec[2];
175   struct timespec *ts = timespec ? adjusted_timespec : NULL;
176   int adjustment_needed = 0;
177   struct stat st;
178
179   if (ts)
180     {
181       adjusted_timespec[0] = timespec[0];
182       adjusted_timespec[1] = timespec[1];
183       adjustment_needed = validate_timespec (ts);
184     }
185   if (adjustment_needed < 0)
186     return -1;
187
188   /* Require that at least one of FD or FILE are potentially valid, to avoid
189      a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather
190      than failing.  */
191   if (fd < 0 && !file)
192     {
193       errno = EBADF;
194       return -1;
195     }
196
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.  */
206
207 #if HAVE_BUGGY_NFS_TIME_STAMPS
208   if (fd < 0)
209     sync ();
210   else
211     fsync (fd);
212 #endif
213
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)
221     {
222       int result;
223 # if __linux__ || __sun
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.
231
232          The same bug occurs in Solaris 11.1 (Apr 2013).
233
234          FIXME: Simplify this for Linux in 2016 and for Solaris in
235          2024, when file system bugs are no longer common.  */
236       if (adjustment_needed == 2)
237         {
238           if (fd < 0 ? stat (file, &st) : fstat (fd, &st))
239             return -1;
240           if (ts[0].tv_nsec == UTIME_OMIT)
241             ts[0] = get_stat_atime (&st);
242           else if (ts[1].tv_nsec == UTIME_OMIT)
243             ts[1] = get_stat_mtime (&st);
244           /* Note that st is good, in case utimensat gives ENOSYS.  */
245           adjustment_needed++;
246         }
247 # endif
248 # if HAVE_UTIMENSAT
249       if (fd < 0)
250         {
251           result = utimensat (AT_FDCWD, file, ts, 0);
252 #  ifdef __linux__
253           /* Work around a kernel bug:
254              http://bugzilla.redhat.com/442352
255              http://bugzilla.redhat.com/449910
256              It appears that utimensat can mistakenly return 280 rather
257              than -1 upon ENOSYS failure.
258              FIXME: remove in 2010 or whenever the offending kernels
259              are no longer in common use.  */
260           if (0 < result)
261             errno = ENOSYS;
262 #  endif /* __linux__ */
263           if (result == 0 || errno != ENOSYS)
264             {
265               utimensat_works_really = 1;
266               return result;
267             }
268         }
269 # endif /* HAVE_UTIMENSAT */
270 # if HAVE_FUTIMENS
271       if (0 <= fd)
272         {
273           result = futimens (fd, ts);
274 #  ifdef __linux__
275           /* Work around the same bug as above.  */
276           if (0 < result)
277             errno = ENOSYS;
278 #  endif /* __linux__ */
279           if (result == 0 || errno != ENOSYS)
280             {
281               utimensat_works_really = 1;
282               return result;
283             }
284         }
285 # endif /* HAVE_FUTIMENS */
286     }
287   utimensat_works_really = -1;
288   lutimensat_works_really = -1;
289 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
290
291   /* The platform lacks an interface to set file timestamps with
292      nanosecond resolution, so do the best we can, discarding any
293      fractional part of the timestamp.  */
294
295   if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0))
296     {
297       if (adjustment_needed != 3
298           && (fd < 0 ? stat (file, &st) : fstat (fd, &st)))
299         return -1;
300       if (ts && update_timespec (&st, &ts))
301         return 0;
302     }
303
304   {
305 #if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
306     struct timeval timeval[2];
307     struct timeval *t;
308     if (ts)
309       {
310         timeval[0].tv_sec = ts[0].tv_sec;
311         timeval[0].tv_usec = ts[0].tv_nsec / 1000;
312         timeval[1].tv_sec = ts[1].tv_sec;
313         timeval[1].tv_usec = ts[1].tv_nsec / 1000;
314         t = timeval;
315       }
316     else
317       t = NULL;
318
319     if (fd < 0)
320       {
321 # if HAVE_FUTIMESAT
322         return futimesat (AT_FDCWD, file, t);
323 # endif
324       }
325     else
326       {
327         /* If futimesat or futimes fails here, don't try to speed things
328            up by returning right away.  glibc can incorrectly fail with
329            errno == ENOENT if /proc isn't mounted.  Also, Mandrake 10.0
330            in high security mode doesn't allow ordinary users to read
331            /proc/self, so glibc incorrectly fails with errno == EACCES.
332            If errno == EIO, EPERM, or EROFS, it's probably safe to fail
333            right away, but these cases are rare enough that they're not
334            worth optimizing, and who knows what other messed-up systems
335            are out there?  So play it safe and fall back on the code
336            below.  */
337
338 # if (HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) || HAVE_FUTIMES
339 #  if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG
340 #   undef futimes
341 #   define futimes(fd, t) futimesat (fd, NULL, t)
342 #  endif
343         if (futimes (fd, t) == 0)
344           {
345 #  if __linux__ && __GLIBC__
346             /* Work around a longstanding glibc bug, still present as
347                of 2010-12-27.  On older Linux kernels that lack both
348                utimensat and utimes, glibc's futimes rounds instead of
349                truncating when falling back on utime.  The same bug
350                occurs in futimesat with a null 2nd arg.  */
351             if (t)
352               {
353                 bool abig = 500000 <= t[0].tv_usec;
354                 bool mbig = 500000 <= t[1].tv_usec;
355                 if ((abig | mbig) && fstat (fd, &st) == 0)
356                   {
357                     /* If these two subtractions overflow, they'll
358                        track the overflows inside the buggy glibc.  */
359                     time_t adiff = st.st_atime - t[0].tv_sec;
360                     time_t mdiff = st.st_mtime - t[1].tv_sec;
361
362                     struct timeval *tt = NULL;
363                     struct timeval truncated_timeval[2];
364                     truncated_timeval[0] = t[0];
365                     truncated_timeval[1] = t[1];
366                     if (abig && adiff == 1 && get_stat_atime_ns (&st) == 0)
367                       {
368                         tt = truncated_timeval;
369                         tt[0].tv_usec = 0;
370                       }
371                     if (mbig && mdiff == 1 && get_stat_mtime_ns (&st) == 0)
372                       {
373                         tt = truncated_timeval;
374                         tt[1].tv_usec = 0;
375                       }
376                     if (tt)
377                       futimes (fd, tt);
378                   }
379               }
380 #  endif
381
382             return 0;
383           }
384 # endif
385       }
386 #endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
387
388     if (!file)
389       {
390 #if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG)          \
391         || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
392         errno = ENOSYS;
393 #endif
394         return -1;
395       }
396
397 #if HAVE_WORKING_UTIMES
398     return utimes (file, t);
399 #else
400     {
401       struct utimbuf utimbuf;
402       struct utimbuf *ut;
403       if (ts)
404         {
405           utimbuf.actime = ts[0].tv_sec;
406           utimbuf.modtime = ts[1].tv_sec;
407           ut = &utimbuf;
408         }
409       else
410         ut = NULL;
411
412       return utime (file, ut);
413     }
414 #endif /* !HAVE_WORKING_UTIMES */
415   }
416 }
417
418 /* Set the access and modification time stamps of FILE to be
419    TIMESPEC[0] and TIMESPEC[1], respectively.  */
420 int
421 utimens (char const *file, struct timespec const timespec[2])
422 {
423   return fdutimens (-1, file, timespec);
424 }
425
426 /* Set the access and modification time stamps of FILE to be
427    TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
428    symlinks.  Fail with ENOSYS if the platform does not support
429    changing symlink timestamps, but FILE was a symlink.  */
430 int
431 lutimens (char const *file, struct timespec const timespec[2])
432 {
433   struct timespec adjusted_timespec[2];
434   struct timespec *ts = timespec ? adjusted_timespec : NULL;
435   int adjustment_needed = 0;
436   struct stat st;
437
438   if (ts)
439     {
440       adjusted_timespec[0] = timespec[0];
441       adjusted_timespec[1] = timespec[1];
442       adjustment_needed = validate_timespec (ts);
443     }
444   if (adjustment_needed < 0)
445     return -1;
446
447   /* The Linux kernel did not support symlink timestamps until
448      utimensat, in version 2.6.22, so we don't need to mimic
449      fdutimens' worry about buggy NFS clients.  But we do have to
450      worry about bogus return values.  */
451
452 #if HAVE_UTIMENSAT
453   if (0 <= lutimensat_works_really)
454     {
455       int result;
456 # if __linux__ || __sun
457       /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
458          systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
459          but work if both times are either explicitly specified or
460          UTIME_NOW.  Work around it with a preparatory lstat prior to
461          calling utimensat; fortunately, there is not much timing
462          impact due to the extra syscall even on file systems where
463          UTIME_OMIT would have worked.
464
465          The same bug occurs in Solaris 11.1 (Apr 2013).
466
467          FIXME: Simplify this for Linux in 2016 and for Solaris in
468          2024, when file system bugs are no longer common.  */
469       if (adjustment_needed == 2)
470         {
471           if (lstat (file, &st))
472             return -1;
473           if (ts[0].tv_nsec == UTIME_OMIT)
474             ts[0] = get_stat_atime (&st);
475           else if (ts[1].tv_nsec == UTIME_OMIT)
476             ts[1] = get_stat_mtime (&st);
477           /* Note that st is good, in case utimensat gives ENOSYS.  */
478           adjustment_needed++;
479         }
480 # endif
481       result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
482 # ifdef __linux__
483       /* Work around a kernel bug:
484          http://bugzilla.redhat.com/442352
485          http://bugzilla.redhat.com/449910
486          It appears that utimensat can mistakenly return 280 rather
487          than -1 upon ENOSYS failure.
488          FIXME: remove in 2010 or whenever the offending kernels
489          are no longer in common use.  */
490       if (0 < result)
491         errno = ENOSYS;
492 # endif
493       if (result == 0 || errno != ENOSYS)
494         {
495           utimensat_works_really = 1;
496           lutimensat_works_really = 1;
497           return result;
498         }
499     }
500   lutimensat_works_really = -1;
501 #endif /* HAVE_UTIMENSAT */
502
503   /* The platform lacks an interface to set file timestamps with
504      nanosecond resolution, so do the best we can, discarding any
505      fractional part of the timestamp.  */
506
507   if (adjustment_needed || REPLACE_FUNC_STAT_FILE)
508     {
509       if (adjustment_needed != 3 && lstat (file, &st))
510         return -1;
511       if (ts && update_timespec (&st, &ts))
512         return 0;
513     }
514
515   /* On Linux, lutimes is a thin wrapper around utimensat, so there is
516      no point trying lutimes if utimensat failed with ENOSYS.  */
517 #if HAVE_LUTIMES && !HAVE_UTIMENSAT
518   {
519     struct timeval timeval[2];
520     struct timeval *t;
521     int result;
522     if (ts)
523       {
524         timeval[0].tv_sec = ts[0].tv_sec;
525         timeval[0].tv_usec = ts[0].tv_nsec / 1000;
526         timeval[1].tv_sec = ts[1].tv_sec;
527         timeval[1].tv_usec = ts[1].tv_nsec / 1000;
528         t = timeval;
529       }
530     else
531       t = NULL;
532
533     result = lutimes (file, t);
534     if (result == 0 || errno != ENOSYS)
535       return result;
536   }
537 #endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */
538
539   /* Out of luck for symlinks, but we still handle regular files.  */
540   if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))
541     return -1;
542   if (!S_ISLNK (st.st_mode))
543     return fdutimens (-1, file, ts);
544   errno = ENOSYS;
545   return -1;
546 }