annotate lib/utimens.c @ 12173:efdb2ab5743f

utimens: let lutimens work on non-symlinks Coreutils new 'touch -h' is easier to write if we guarantee POSIX semantics of utimensat(fd,"file",NULL,AT_SYMLINK_NOFOLLOW), rather than blindly failing with ENOSYS even on non-symlinks. * lib/utimens.c (lutimens): Fall back to utimens rather than failing with ENOSYS, when file is not a symlink. (utimens): Reduce redirection. * tests/test-lutimens.h (test_lutimens): Update test to cover non-symlinks. * tests/test-utimens.h (test_utimens): Update test to cover symlinks. * tests/test-utimens.c (main): Update caller. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Thu, 15 Oct 2009 12:04:57 -0600
parents 52ebfd595434
children 73f2681e0524
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6734
3e5ad4566013 * utimens.c (futimens): glibc futimesat messes up if /proc
Paul Eggert <eggert@cs.ucla.edu>
parents: 6440
diff changeset
1 /* Set file access and modification times.
3e5ad4566013 * utimens.c (futimens): glibc futimesat messes up if /proc
Paul Eggert <eggert@cs.ucla.edu>
parents: 6440
diff changeset
2
11941
909daff94315 errno: use consistently
Eric Blake <ebb9@byu.net>
parents: 10186
diff changeset
3 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free
909daff94315 errno: use consistently
Eric Blake <ebb9@byu.net>
parents: 10186
diff changeset
4 Software Foundation, Inc.
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
5
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8842
diff changeset
6 This program is free software: you can redistribute it and/or modify it
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8842
diff changeset
8 Free Software Foundation; either version 3 of the License, or any
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
9 later version.
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
10
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
11 This program is distributed in the hope that it will be useful,
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
14 GNU General Public License for more details.
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
15
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8842
diff changeset
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
18
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
19 /* Written by Paul Eggert. */
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
20
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
21 /* derived from a function in touch.c */
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
22
7302
8a1a9361108c * _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents: 6819
diff changeset
23 #include <config.h>
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
24
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
25 #include "utimens.h"
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
26
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
27 #include <assert.h>
5589
6ddb405e16b6 (futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents: 5485
diff changeset
28 #include <errno.h>
6283
b377d8796118 * lib/utimens.c (futimens): Use futimesat if available.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
29 #include <fcntl.h>
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
30 #include <stdbool.h>
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
31 #include <sys/stat.h>
7897
b7a83a69ac23 * MODULES.html.sh (Support for systems lacking POSIX:2001): New
Paul Eggert <eggert@cs.ucla.edu>
parents: 7713
diff changeset
32 #include <sys/time.h>
6322
716071856296 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6297
diff changeset
33 #include <unistd.h>
5589
6ddb405e16b6 (futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents: 5485
diff changeset
34
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
35 #include "stat-time.h"
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
36 #include "timespec.h"
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
37
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
38 #if HAVE_UTIME_H
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
39 # include <utime.h>
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
40 #endif
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
41
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
42 /* Some systems (even some that do have <utime.h>) don't declare this
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
43 structure anywhere. */
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
44 #ifndef HAVE_STRUCT_UTIMBUF
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
45 struct utimbuf
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
46 {
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
47 long actime;
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
48 long modtime;
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
49 };
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
50 #endif
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
51
12162
fe82ecf4f214 futimens: new module
Eric Blake <ebb9@byu.net>
parents: 12161
diff changeset
52 /* Avoid recursion with rpl_futimens. */
fe82ecf4f214 futimens: new module
Eric Blake <ebb9@byu.net>
parents: 12161
diff changeset
53 #undef futimens
fe82ecf4f214 futimens: new module
Eric Blake <ebb9@byu.net>
parents: 12161
diff changeset
54
12172
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
55 #if HAVE_UTIMENSAT || HAVE_FUTIMENS
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
56 /* Cache variable for whether syscall works; used to avoid calling the
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
57 syscall if we know it will just fail with ENOSYS. 0 = unknown, 1 =
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
58 yes, -1 = no. */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
59 static int utimensat_works_really;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
60 #endif /* HAVE_UTIMENSAT || HAVE_UTIMENSAT */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
61
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
62 /* Validate the requested timestamps. Return 0 if the resulting
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
63 timespec can be used for utimensat (after possibly modifying it to
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
64 work around bugs in utimensat). Return 1 if the timespec needs
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
65 further adjustment based on stat results for utimes or other less
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
66 powerful interfaces. Return -1, with errno set to EINVAL, if
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
67 timespec is out of range. */
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
68 static int
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
69 validate_timespec (struct timespec timespec[2])
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
70 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
71 int result = 0;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
72 assert (timespec);
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
73 if ((timespec[0].tv_nsec != UTIME_NOW
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
74 && timespec[0].tv_nsec != UTIME_OMIT
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
75 && (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec))
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
76 || (timespec[1].tv_nsec != UTIME_NOW
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
77 && timespec[1].tv_nsec != UTIME_OMIT
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
78 && (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec)))
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
79 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
80 errno = EINVAL;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
81 return -1;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
82 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
83 /* Work around Linux kernel 2.6.25 bug, where utimensat fails with
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
84 EINVAL if tv_sec is not 0 when using the flag values of
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
85 tv_nsec. */
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
86 if (timespec[0].tv_nsec == UTIME_NOW
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
87 || timespec[0].tv_nsec == UTIME_OMIT)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
88 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
89 timespec[0].tv_sec = 0;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
90 result = 1;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
91 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
92 if (timespec[1].tv_nsec == UTIME_NOW
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
93 || timespec[1].tv_nsec == UTIME_OMIT)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
94 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
95 timespec[1].tv_sec = 0;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
96 result = 1;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
97 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
98 return result;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
99 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
100
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
101 /* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
102 buffer STATBUF to obtain the current timestamps of the file. If
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
103 both times are UTIME_NOW, set *TS to NULL (as this can avoid some
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
104 permissions issues). If both times are UTIME_OMIT, return true
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
105 (nothing further beyond the prior collection of STATBUF is
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
106 necessary); otherwise return false. */
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
107 static bool
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
108 update_timespec (struct stat const *statbuf, struct timespec *ts[2])
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
109 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
110 struct timespec *timespec = *ts;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
111 if (timespec[0].tv_nsec == UTIME_OMIT
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
112 && timespec[1].tv_nsec == UTIME_OMIT)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
113 return true;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
114 if (timespec[0].tv_nsec == UTIME_NOW
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
115 && timespec[1].tv_nsec == UTIME_NOW)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
116 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
117 *ts = NULL;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
118 return false;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
119 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
120
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
121 if (timespec[0].tv_nsec == UTIME_OMIT)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
122 timespec[0] = get_stat_atime (statbuf);
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
123 else if (timespec[0].tv_nsec == UTIME_NOW)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
124 gettime (&timespec[0]);
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
125
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
126 if (timespec[1].tv_nsec == UTIME_OMIT)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
127 timespec[1] = get_stat_mtime (statbuf);
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
128 else if (timespec[1].tv_nsec == UTIME_NOW)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
129 gettime (&timespec[1]);
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
130
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
131 return false;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
132 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
133
5485
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
134 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
135 TIMESPEC[0] and TIMESPEC[1], respectively.
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
136 FD must be either negative -- in which case it is ignored --
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
137 or a file descriptor that is open on FILE.
6297
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
138 If FD is nonnegative, then FILE can be NULL, which means
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
139 use just futimes (or equivalent) instead of utimes (or equivalent),
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
140 and fail if on an old system without futimes (or equivalent).
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
141 If TIMESPEC is null, set the time stamps to the current time.
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
142 Return 0 on success, -1 (setting errno) on failure. */
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
143
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
144 int
12161
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
145 fdutimens (char const *file, int fd, struct timespec const timespec[2])
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
146 {
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
147 struct timespec adjusted_timespec[2];
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
148 struct timespec *ts = timespec ? adjusted_timespec : NULL;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
149 int adjustment_needed = 0;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
150
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
151 if (ts)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
152 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
153 adjusted_timespec[0] = timespec[0];
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
154 adjusted_timespec[1] = timespec[1];
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
155 adjustment_needed = validate_timespec (ts);
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
156 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
157 if (adjustment_needed < 0)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
158 return -1;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
159
12157
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
160 /* Require that at least one of FD or FILE are valid. Works around
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
161 a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
162 than failing. */
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
163 if (!file)
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
164 {
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
165 if (fd < 0)
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
166 {
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
167 errno = EBADF;
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
168 return -1;
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
169 }
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
170 if (dup2 (fd, fd) != fd)
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
171 return -1;
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
172 }
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
173
7712
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
174 /* Some Linux-based NFS clients are buggy, and mishandle time stamps
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
175 of files in NFS file systems in some cases. We have no
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
176 configure-time test for this, but please see
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
177 <http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
178 some of the problems with Linux 2.6.16. If this affects you,
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
179 compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
180 help in some cases, albeit at a cost in performance. But you
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
181 really should upgrade your kernel to a fixed version, since the
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
182 problem affects many applications. */
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
183
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
184 #if HAVE_BUGGY_NFS_TIME_STAMPS
7713
064005e1c3c3 Prefer fd < 0 to ! (0 <= fd).
Paul Eggert <eggert@cs.ucla.edu>
parents: 7712
diff changeset
185 if (fd < 0)
064005e1c3c3 Prefer fd < 0 to ! (0 <= fd).
Paul Eggert <eggert@cs.ucla.edu>
parents: 7712
diff changeset
186 sync ();
064005e1c3c3 Prefer fd < 0 to ! (0 <= fd).
Paul Eggert <eggert@cs.ucla.edu>
parents: 7712
diff changeset
187 else
7712
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
188 fsync (fd);
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
189 #endif
aead3397193a * lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents: 7302
diff changeset
190
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
191 /* POSIX 2008 added two interfaces to set file timestamps with
12172
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
192 nanosecond resolution; newer Linux implements both functions via
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
193 a single syscall. We provide a fallback for ENOSYS (for example,
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
194 compiling against Linux 2.6.25 kernel headers and glibc 2.7, but
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
195 running on Linux 2.6.18 kernel). */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
196 #if HAVE_UTIMENSAT || HAVE_FUTIMENS
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
197 if (0 <= utimensat_works_really)
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
198 {
12172
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
199 # if HAVE_UTIMENSAT
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
200 if (fd < 0)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
201 {
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
202 int result = utimensat (AT_FDCWD, file, ts, 0);
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
203 # ifdef __linux__
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
204 /* Work around a kernel bug:
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
205 http://bugzilla.redhat.com/442352
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
206 http://bugzilla.redhat.com/449910
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
207 It appears that utimensat can mistakenly return 280 rather
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
208 than -1 upon ENOSYS failure.
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
209 FIXME: remove in 2010 or whenever the offending kernels
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
210 are no longer in common use. */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
211 if (0 < result)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
212 errno = ENOSYS;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
213 # endif /* __linux__ */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
214 if (result == 0 || errno != ENOSYS)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
215 {
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
216 utimensat_works_really = 1;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
217 return result;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
218 }
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
219 }
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
220 # endif /* HAVE_UTIMENSAT */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
221 # if HAVE_FUTIMENS
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
222 {
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
223 int result = futimens (fd, timespec);
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
224 # ifdef __linux__
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
225 /* Work around the same bug as above. */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
226 if (0 < result)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
227 errno = ENOSYS;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
228 # endif /* __linux__ */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
229 if (result == 0 || errno != ENOSYS)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
230 {
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
231 utimensat_works_really = 1;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
232 return result;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
233 }
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
234 }
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
235 # endif /* HAVE_FUTIMENS */
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
236 }
12172
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
237 utimensat_works_really = -1;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
238 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
239
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
240 /* The platform lacks an interface to set file timestamps with
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
241 nanosecond resolution, so do the best we can, discarding any
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
242 fractional part of the timestamp. */
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
243
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
244 if (adjustment_needed)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
245 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
246 struct stat st;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
247 if (fd < 0 ? stat (file, &st) : fstat (fd, &st))
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
248 return -1;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
249 if (update_timespec (&st, &ts))
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
250 return 0;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
251 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
252
6297
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
253 {
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
254 #if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
255 struct timeval timeval[2];
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
256 struct timeval const *t;
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
257 if (ts)
6297
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
258 {
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
259 timeval[0].tv_sec = ts[0].tv_sec;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
260 timeval[0].tv_usec = ts[0].tv_nsec / 1000;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
261 timeval[1].tv_sec = ts[1].tv_sec;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
262 timeval[1].tv_usec = ts[1].tv_nsec / 1000;
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
263 t = timeval;
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
264 }
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
265 else
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
266 t = NULL;
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
267
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
268 if (fd < 0)
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
269 {
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
270 # if HAVE_FUTIMESAT
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
271 return futimesat (AT_FDCWD, file, t);
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
272 # endif
6297
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
273 }
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
274 else
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
275 {
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
276 /* If futimesat or futimes fails here, don't try to speed things
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
277 up by returning right away. glibc can incorrectly fail with
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
278 errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
279 in high security mode doesn't allow ordinary users to read
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
280 /proc/self, so glibc incorrectly fails with errno == EACCES.
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
281 If errno == EIO, EPERM, or EROFS, it's probably safe to fail
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
282 right away, but these cases are rare enough that they're not
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
283 worth optimizing, and who knows what other messed-up systems
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
284 are out there? So play it safe and fall back on the code
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
285 below. */
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
286 # if HAVE_FUTIMESAT
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
287 if (futimesat (fd, NULL, t) == 0)
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
288 return 0;
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
289 # elif HAVE_FUTIMES
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
290 if (futimes (fd, t) == 0)
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
291 return 0;
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
292 # endif
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
293 }
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
294 #endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
295
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
296 if (!file)
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
297 {
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
298 #if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
299 errno = ENOSYS;
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
300 #endif
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
301 return -1;
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
302 }
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
303
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
304 #if HAVE_WORKING_UTIMES
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
305 return utimes (file, t);
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
306 #else
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
307 {
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
308 struct utimbuf utimbuf;
12157
7fb8a2ac5948 utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents: 12134
diff changeset
309 struct utimbuf *ut;
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
310 if (ts)
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
311 {
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
312 utimbuf.actime = ts[0].tv_sec;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
313 utimbuf.modtime = ts[1].tv_sec;
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
314 ut = &utimbuf;
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
315 }
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
316 else
12133
799664c0f270 openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents: 11941
diff changeset
317 ut = NULL;
10133
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
318
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
319 return utime (file, ut);
bbccff5988c3 Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents: 9613
diff changeset
320 }
10154
148190ed341d Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents: 10133
diff changeset
321 #endif /* !HAVE_WORKING_UTIMES */
6297
10379892281e * utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6283
diff changeset
322 }
5147
3249aec7f48c Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
323 }
5485
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
324
12161
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
325 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
326 TIMESPEC[0] and TIMESPEC[1], respectively.
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
327 FD must be either negative -- in which case it is ignored --
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
328 or a file descriptor that is open on FILE.
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
329 If FD is nonnegative, then FILE can be NULL, which means
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
330 use just futimes (or equivalent) instead of utimes (or equivalent),
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
331 and fail if on an old system without futimes (or equivalent).
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
332 If TIMESPEC is null, set the time stamps to the current time.
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
333 Return 0 on success, -1 (setting errno) on failure. */
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
334
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
335 int
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
336 gl_futimens (int fd, char const *file, struct timespec const timespec[2])
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
337 {
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
338 return fdutimens (file, fd, timespec);
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
339 }
c4a167621772 utimens: introduce fdutimens
Eric Blake <ebb9@byu.net>
parents: 12160
diff changeset
340
5485
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
341 /* Set the access and modification time stamps of FILE to be
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
342 TIMESPEC[0] and TIMESPEC[1], respectively. */
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
343 int
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
344 utimens (char const *file, struct timespec const timespec[2])
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
345 {
12173
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
346 return fdutimens (file, -1, timespec);
5485
863556283cee (__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5147
diff changeset
347 }
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
348
12173
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
349 /* Set the access and modification time stamps of FILE to be
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
350 TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
351 symlinks. Fail with ENOSYS if the platform does not support
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
352 changing symlink timestamps, but FILE was a symlink. */
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
353 int
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
354 lutimens (char const *file, struct timespec const timespec[2])
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
355 {
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
356 struct timespec adjusted_timespec[2];
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
357 struct timespec *ts = timespec ? adjusted_timespec : NULL;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
358 int adjustment_needed = 0;
12173
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
359 struct stat st;
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
360
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
361 if (ts)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
362 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
363 adjusted_timespec[0] = timespec[0];
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
364 adjusted_timespec[1] = timespec[1];
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
365 adjustment_needed = validate_timespec (ts);
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
366 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
367 if (adjustment_needed < 0)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
368 return -1;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
369
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
370 /* The Linux kernel did not support symlink timestamps until
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
371 utimensat, in version 2.6.22, so we don't need to mimic
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
372 gl_futimens' worry about buggy NFS clients. But we do have to
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
373 worry about bogus return values. */
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
374
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
375 #if HAVE_UTIMENSAT
12172
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
376 if (0 <= utimensat_works_really)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
377 {
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
378 int result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
379 # ifdef __linux__
12172
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
380 /* Work around a kernel bug:
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
381 http://bugzilla.redhat.com/442352
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
382 http://bugzilla.redhat.com/449910
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
383 It appears that utimensat can mistakenly return 280 rather
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
384 than -1 upon ENOSYS failure.
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
385 FIXME: remove in 2010 or whenever the offending kernels
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
386 are no longer in common use. */
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
387 if (0 < result)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
388 errno = ENOSYS;
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
389 # endif
12172
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
390 if (result == 0 || errno != ENOSYS)
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
391 {
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
392 utimensat_works_really = 1;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
393 return result;
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
394 }
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
395 }
52ebfd595434 utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents: 12162
diff changeset
396 utimensat_works_really = -1;
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
397 #endif /* HAVE_UTIMENSAT */
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
398
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
399 /* The platform lacks an interface to set file timestamps with
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
400 nanosecond resolution, so do the best we can, discarding any
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
401 fractional part of the timestamp. */
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
402
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
403 if (adjustment_needed)
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
404 {
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
405 if (lstat (file, &st))
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
406 return -1;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
407 if (update_timespec (&st, &ts))
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
408 return 0;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
409 }
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
410
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
411 #if HAVE_LUTIMES
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
412 {
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
413 struct timeval timeval[2];
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
414 struct timeval const *t;
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
415 if (ts)
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
416 {
12160
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
417 timeval[0].tv_sec = ts[0].tv_sec;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
418 timeval[0].tv_usec = ts[0].tv_nsec / 1000;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
419 timeval[1].tv_sec = ts[1].tv_sec;
d0732ed2dd55 utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents: 12158
diff changeset
420 timeval[1].tv_usec = ts[1].tv_nsec / 1000;
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
421 t = timeval;
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
422 }
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
423 else
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
424 t = NULL;
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
425
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
426 return lutimes (file, t);
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
427 }
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
428 #endif /* HAVE_LUTIMES */
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
429
12173
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
430 /* Out of luck for symlinks, but we still handle regular files. */
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
431 if (!adjustment_needed && lstat (file, &st))
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
432 return -1;
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
433 if (!S_ISLNK (st.st_mode))
efdb2ab5743f utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents: 12172
diff changeset
434 return fdutimens (file, -1, ts);
12158
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
435 errno = ENOSYS;
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
436 return -1;
899dd13e9f8b utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents: 12157
diff changeset
437 }