Mercurial > hg > octave-shane > gnulib-hg
annotate lib/utimens.c @ 12467:912bdb1c31fb
utimens: work around Linux ctime bug
Force a ctime update by using stat() before any utimensat call
with mtime of UTIME_OMIT. But avoid extra stat()s in later
calls, by doing extra work on the first instance in order to
cache whether the bug is actually present.
* lib/utimens.c (detect_ctime_bug): New helper function.
(update_timespec): Differentiate between workaround needed for
this bug vs. what is needed for systems that lack utimensat.
(fdutimens, lutimens): Work around bug.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Thu, 17 Dec 2009 16:57:37 -0700 |
parents | b79168ca6a08 |
children | b5e42ef33b49 |
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 | 3 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free |
4 Software Foundation, Inc. | |
5147 | 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 | 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 | 9 later version. |
10 | |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
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 | 18 |
19 /* Written by Paul Eggert. */ | |
20 | |
21 /* derived from a function in touch.c */ | |
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 | 24 |
25 #include "utimens.h" | |
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 | 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 | 38 #if HAVE_UTIME_H |
39 # include <utime.h> | |
40 #endif | |
41 | |
42 /* Some systems (even some that do have <utime.h>) don't declare this | |
43 structure anywhere. */ | |
44 #ifndef HAVE_STRUCT_UTIMBUF | |
45 struct utimbuf | |
46 { | |
47 long actime; | |
48 long modtime; | |
49 }; | |
50 #endif | |
51 | |
12174 | 52 /* Avoid recursion with rpl_futimens or rpl_utimensat. */ |
12162 | 53 #undef futimens |
12174 | 54 #undef utimensat |
12162 | 55 |
12194
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
56 /* Solaris 9 mistakenly succeeds when given a non-directory with a |
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
57 trailing slash. Force the use of rpl_stat for a fix. */ |
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
58 #ifndef REPLACE_FUNC_STAT_FILE |
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
59 # define REPLACE_FUNC_STAT_FILE 0 |
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
60 #endif |
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
61 |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
62 #if HAVE_UTIMENSAT || HAVE_FUTIMENS |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
63 /* Cache variables for whether the utimensat syscall works; used to |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
64 avoid calling the syscall if we know it will just fail with ENOSYS, |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
65 and to avoid unnecessary work in massaging timestamps if the |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
66 syscall will work. Multiple variables are needed, to distinguish |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
67 between the following scenarios on Linux: |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
68 utimensat doesn't exist, or is in glibc but kernel 2.6.18 fails with ENOSYS |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
69 kernel 2.6.22 and earlier rejects AT_SYMLINK_NOFOLLOW |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
70 kernel 2.6.25 and earlier reject UTIME_NOW/UTIME_OMIT with non-zero tv_sec |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
71 kernel 2.6.32 and earlier fail to bump ctime if mtime is UTIME_OMIT |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
72 utimensat completely works |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
73 For each cache variable: 0 = unknown, 1 = yes, -1 = no. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
74 static int utimensat_works_really; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
75 static int lutimensat_works_really; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
76 static int utimensat_ctime_really; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
77 |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
78 /* Determine whether the kernel has a ctime bug. ST1 and ST2 |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
79 correspond to stat data before and after a successful time change. |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
80 TIMES contains the timestamps that were used during the time change |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
81 (mtime will be UTIME_OMIT). Update the cache variable if there is |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
82 conclusive evidence of the kernel working or being buggy. Return |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
83 true if TIMES has been updated and another kernel call is needed, |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
84 whether or not the kernel is known to have the bug. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
85 static bool |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
86 detect_ctime_bug (struct stat *st1, struct stat *st2, struct timespec times[2]) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
87 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
88 struct timespec now; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
89 if (st1->st_ctime != st2->st_ctime |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
90 || get_stat_ctime_ns (st1) != get_stat_ctime_ns (st2)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
91 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
92 utimensat_ctime_really = 1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
93 return false; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
94 } |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
95 /* The results are inconclusive if the ctime in st1 is within a file |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
96 system quantization window of now. For FAT, this is 2 seconds, |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
97 for systems with sub-second resolution, a typical resolution is |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
98 10 milliseconds; to be safe we declare an inconsistent result if |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
99 ctime is within a 20 millisecond window. Avoid an extra gettime |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
100 call if atime makes sense. It is unlikely that the original |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
101 ctime is later than now, but rather than deal with the overflow, |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
102 we treat that as consistent evidence of the bug. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
103 if (times[0].tv_nsec == UTIME_NOW) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
104 now = get_stat_atime (st2); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
105 else |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
106 gettime (&now); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
107 if (now.tv_sec < st2->st_ctime |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
108 || 2 < now.tv_sec - st2->st_ctime |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
109 || (get_stat_ctime_ns (st2) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
110 && now.tv_sec - st2->st_ctime < 2 |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
111 && (20000000 < (1000000000 * (now.tv_sec - st2->st_ctime) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
112 + now.tv_nsec - get_stat_ctime_ns (st2))))) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
113 utimensat_ctime_really = -1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
114 times[1] = get_stat_mtime (st2); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
115 return true; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
116 } |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
117 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
118 |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
119 /* 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
|
120 timespec can be used for utimensat (after possibly modifying it to |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
121 work around bugs in utimensat). Return a positive value if the |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
122 timespec needs further adjustment based on stat results: 1 if any |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
123 adjustment is needed for utimes, and 2 if mtime was UTIME_OMIT and |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
124 an adjustment is needed for utimensat. Return -1, with errno set |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
125 to EINVAL, if timespec is out of range. */ |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
126 static int |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
127 validate_timespec (struct timespec timespec[2]) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
128 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
129 int result = 0; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
130 assert (timespec); |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
131 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
|
132 && timespec[0].tv_nsec != UTIME_OMIT |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
133 && (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
|
134 || (timespec[1].tv_nsec != UTIME_NOW |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
135 && timespec[1].tv_nsec != UTIME_OMIT |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
136 && (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
|
137 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
138 errno = EINVAL; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
139 return -1; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
140 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
141 /* Work around Linux kernel 2.6.25 bug, where utimensat fails with |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
142 EINVAL if tv_sec is not 0 when using the flag values of tv_nsec. |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
143 Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
144 fails to bump ctime. */ |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
145 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
|
146 || timespec[0].tv_nsec == UTIME_OMIT) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
147 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
148 timespec[0].tv_sec = 0; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
149 result = 1; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
150 } |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
151 if (timespec[1].tv_nsec == UTIME_NOW) |
12160
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 timespec[1].tv_sec = 0; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
154 result = 1; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
155 } |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
156 else if (timespec[1].tv_nsec == UTIME_OMIT) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
157 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
158 timespec[1].tv_sec = 0; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
159 result = 2; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
160 } |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
161 return result; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
162 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
163 |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
164 /* 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
|
165 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
|
166 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
|
167 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
|
168 (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
|
169 necessary); otherwise return false. */ |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
170 static bool |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
171 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
|
172 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
173 struct timespec *timespec = *ts; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
174 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
|
175 && timespec[1].tv_nsec == UTIME_OMIT) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
176 return true; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
177 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
|
178 && timespec[1].tv_nsec == UTIME_NOW) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
179 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
180 *ts = NULL; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
181 return false; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
182 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
183 |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
184 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
|
185 timespec[0] = get_stat_atime (statbuf); |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
186 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
|
187 gettime (×pec[0]); |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
188 |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
189 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
|
190 timespec[1] = get_stat_mtime (statbuf); |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
191 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
|
192 gettime (×pec[1]); |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
193 |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
194 return false; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
195 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
196 |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
197 /* 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
|
198 TIMESPEC[0] and TIMESPEC[1], respectively. |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
199 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
|
200 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
|
201 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
|
202 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
|
203 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
|
204 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
|
205 Return 0 on success, -1 (setting errno) on failure. */ |
5147 | 206 |
207 int | |
12161 | 208 fdutimens (char const *file, int fd, struct timespec const timespec[2]) |
5147 | 209 { |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
210 struct timespec adjusted_timespec[2]; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
211 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
|
212 int adjustment_needed = 0; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
213 |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
214 if (ts) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
215 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
216 adjusted_timespec[0] = timespec[0]; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
217 adjusted_timespec[1] = timespec[1]; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
218 adjustment_needed = validate_timespec (ts); |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
219 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
220 if (adjustment_needed < 0) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
221 return -1; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
222 |
12157
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
223 /* 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
|
224 a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
225 than failing. */ |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
226 if (!file) |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
227 { |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
228 if (fd < 0) |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
229 { |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
230 errno = EBADF; |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
231 return -1; |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
232 } |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
233 if (dup2 (fd, fd) != fd) |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
234 return -1; |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
235 } |
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
236 |
7712
aead3397193a
* lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
237 /* 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
|
238 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
|
239 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
|
240 <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
|
241 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
|
242 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
|
243 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
|
244 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
|
245 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
|
246 |
aead3397193a
* lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
247 #if HAVE_BUGGY_NFS_TIME_STAMPS |
7713
064005e1c3c3
Prefer fd < 0 to ! (0 <= fd).
Paul Eggert <eggert@cs.ucla.edu>
parents:
7712
diff
changeset
|
248 if (fd < 0) |
064005e1c3c3
Prefer fd < 0 to ! (0 <= fd).
Paul Eggert <eggert@cs.ucla.edu>
parents:
7712
diff
changeset
|
249 sync (); |
064005e1c3c3
Prefer fd < 0 to ! (0 <= fd).
Paul Eggert <eggert@cs.ucla.edu>
parents:
7712
diff
changeset
|
250 else |
7712
aead3397193a
* lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
251 fsync (fd); |
aead3397193a
* lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
252 #endif |
aead3397193a
* lib/utimens.c (futimens) [HAVE_BUGGY_NFS_TIME_STAMPS]: Add a
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
253 |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
254 /* 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
|
255 nanosecond resolution; newer Linux implements both functions via |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
256 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
|
257 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
|
258 running on Linux 2.6.18 kernel). */ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
259 #if HAVE_UTIMENSAT || HAVE_FUTIMENS |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
260 if (0 <= utimensat_works_really) |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
261 { |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
262 int result; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
263 struct stat st1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
264 struct stat st2; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
265 /* Linux kernel 2.6.32 has a bug where it fails to bump ctime if |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
266 UTIME_OMIT was used for mtime. It costs time to do an extra |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
267 [f]stat up front, so we cache whether the function works. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
268 if (utimensat_ctime_really <= 0 && adjustment_needed == 2) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
269 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
270 if (fd < 0 ? stat (file, &st1) : fstat (fd, &st1)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
271 return -1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
272 if (ts[0].tv_nsec == UTIME_OMIT) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
273 return 0; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
274 if (utimensat_ctime_really < 0) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
275 ts[1] = get_stat_mtime (&st1); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
276 } |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
277 # if HAVE_UTIMENSAT |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
278 if (fd < 0) |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
279 { |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
280 result = utimensat (AT_FDCWD, file, ts, 0); |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
281 # ifdef __linux__ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
282 /* Work around a kernel bug: |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
283 http://bugzilla.redhat.com/442352 |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
284 http://bugzilla.redhat.com/449910 |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
285 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
|
286 than -1 upon ENOSYS failure. |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
287 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
|
288 are no longer in common use. */ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
289 if (0 < result) |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
290 errno = ENOSYS; |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
291 # endif /* __linux__ */ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
292 if (result == 0 || errno != ENOSYS) |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
293 { |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
294 utimensat_works_really = 1; |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
295 if (result == 0 && utimensat_ctime_really == 0 |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
296 && adjustment_needed == 2) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
297 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
298 /* Perform a followup stat to see if the kernel has |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
299 a ctime bug. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
300 if (stat (file, &st2)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
301 return -1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
302 if (detect_ctime_bug (&st1, &st2, ts)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
303 result = utimensat (AT_FDCWD, file, ts, 0); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
304 } |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
305 return result; |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
306 } |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
307 } |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
308 # endif /* HAVE_UTIMENSAT */ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
309 # if HAVE_FUTIMENS |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
310 { |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
311 result = futimens (fd, ts); |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
312 # ifdef __linux__ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
313 /* Work around the same bug as above. */ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
314 if (0 < result) |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
315 errno = ENOSYS; |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
316 # endif /* __linux__ */ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
317 if (result == 0 || errno != ENOSYS) |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
318 { |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
319 utimensat_works_really = 1; |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
320 /* Work around the same bug as above. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
321 if (result == 0 && utimensat_ctime_really == 0 |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
322 && adjustment_needed == 2) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
323 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
324 if (fstat (fd, &st2)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
325 return -1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
326 if (detect_ctime_bug (&st1, &st2, ts)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
327 result = futimens (fd, ts); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
328 } |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
329 return result; |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
330 } |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
331 } |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
332 # endif /* HAVE_FUTIMENS */ |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
333 } |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
334 utimensat_works_really = -1; |
12353
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
335 lutimensat_works_really = -1; |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
336 #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
337 |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
338 /* The platform lacks an interface to set file timestamps with |
5147 | 339 nanosecond resolution, so do the best we can, discarding any |
340 fractional part of the timestamp. */ | |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
341 |
12194
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
342 if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0)) |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
343 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
344 struct stat st; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
345 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
|
346 return -1; |
12194
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
347 if (ts && update_timespec (&st, &ts)) |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
348 return 0; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
349 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
350 |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
351 { |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
352 #if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
353 struct timeval timeval[2]; |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
354 struct timeval const *t; |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
355 if (ts) |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
356 { |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
357 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
|
358 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
|
359 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
|
360 timeval[1].tv_usec = ts[1].tv_nsec / 1000; |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
361 t = timeval; |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
362 } |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
363 else |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
364 t = NULL; |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
365 |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
366 if (fd < 0) |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
367 { |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
368 # if HAVE_FUTIMESAT |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
369 return futimesat (AT_FDCWD, file, t); |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
370 # endif |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
371 } |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
372 else |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
373 { |
12317
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
374 /* If futimesat or futimes fails here, don't try to speed things |
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
375 up by returning right away. glibc can incorrectly fail with |
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
376 errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0 |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
377 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
|
378 /proc/self, so glibc incorrectly fails with errno == EACCES. |
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
379 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
|
380 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
|
381 worth optimizing, and who knows what other messed-up systems |
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
382 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
|
383 below. */ |
12317
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
384 # if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG |
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
385 if (futimesat (fd, NULL, t) == 0) |
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
386 return 0; |
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
387 # elif HAVE_FUTIMES |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
388 if (futimes (fd, t) == 0) |
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
389 return 0; |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
390 # endif |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
391 } |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
392 #endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
393 |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
394 if (!file) |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
395 { |
12317
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
396 #if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) \ |
407921985bc0
utimens: fix regression on Solaris
Eric Blake <ebb9@byu.net>
parents:
12256
diff
changeset
|
397 || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
398 errno = ENOSYS; |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
399 #endif |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
400 return -1; |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
401 } |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
402 |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
403 #if HAVE_WORKING_UTIMES |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
404 return utimes (file, t); |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
405 #else |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
406 { |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
407 struct utimbuf utimbuf; |
12157
7fb8a2ac5948
utimens: validate futimens usage
Eric Blake <ebb9@byu.net>
parents:
12134
diff
changeset
|
408 struct utimbuf *ut; |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
409 if (ts) |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
410 { |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
411 utimbuf.actime = ts[0].tv_sec; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
412 utimbuf.modtime = ts[1].tv_sec; |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
413 ut = &utimbuf; |
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
414 } |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
415 else |
12133
799664c0f270
openat, utimens: whitespace cleanup
Eric Blake <ebb9@byu.net>
parents:
11941
diff
changeset
|
416 ut = NULL; |
10133
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
417 |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
418 return utime (file, ut); |
bbccff5988c3
Prefer new POSIX 200x interfaces over futimesat.
Eric Blake <ebb9@byu.net>
parents:
9613
diff
changeset
|
419 } |
10154
148190ed341d
Provide futimens/utimensat fallbacks for older kernels.
Eric Blake <ebb9@byu.net>
parents:
10133
diff
changeset
|
420 #endif /* !HAVE_WORKING_UTIMES */ |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
421 } |
5147 | 422 } |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
423 |
12161 | 424 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be |
425 TIMESPEC[0] and TIMESPEC[1], respectively. | |
426 FD must be either negative -- in which case it is ignored -- | |
427 or a file descriptor that is open on FILE. | |
428 If FD is nonnegative, then FILE can be NULL, which means | |
429 use just futimes (or equivalent) instead of utimes (or equivalent), | |
430 and fail if on an old system without futimes (or equivalent). | |
431 If TIMESPEC is null, set the time stamps to the current time. | |
432 Return 0 on success, -1 (setting errno) on failure. */ | |
433 | |
434 int | |
435 gl_futimens (int fd, char const *file, struct timespec const timespec[2]) | |
436 { | |
437 return fdutimens (file, fd, timespec); | |
438 } | |
439 | |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
440 /* 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
|
441 TIMESPEC[0] and TIMESPEC[1], respectively. */ |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
442 int |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
443 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
|
444 { |
12173
efdb2ab5743f
utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents:
12172
diff
changeset
|
445 return fdutimens (file, -1, timespec); |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
446 } |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
447 |
12173
efdb2ab5743f
utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents:
12172
diff
changeset
|
448 /* 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
|
449 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
|
450 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
|
451 changing symlink timestamps, but FILE was a symlink. */ |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
452 int |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
453 lutimens (char const *file, struct timespec const timespec[2]) |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
454 { |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
455 struct timespec adjusted_timespec[2]; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
456 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
|
457 int adjustment_needed = 0; |
12173
efdb2ab5743f
utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents:
12172
diff
changeset
|
458 struct stat st; |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
459 |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
460 if (ts) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
461 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
462 adjusted_timespec[0] = timespec[0]; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
463 adjusted_timespec[1] = timespec[1]; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
464 adjustment_needed = validate_timespec (ts); |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
465 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
466 if (adjustment_needed < 0) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
467 return -1; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
468 |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
469 /* The Linux kernel did not support symlink timestamps until |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
470 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
|
471 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
|
472 worry about bogus return values. */ |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
473 |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
474 #if HAVE_UTIMENSAT |
12353
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
475 if (0 <= lutimensat_works_really) |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
476 { |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
477 int result; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
478 struct stat st1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
479 struct stat st2; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
480 /* Linux kernel 2.6.32 has a bug where it fails to bump ctime if |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
481 UTIME_OMIT was used for mtime. It costs time to do an extra |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
482 lstat up front, so we cache whether the function works. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
483 if (utimensat_ctime_really <= 0 && adjustment_needed == 2) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
484 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
485 if (lstat (file, &st1)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
486 return -1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
487 if (ts[0].tv_nsec == UTIME_OMIT) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
488 return 0; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
489 if (utimensat_ctime_really < 0) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
490 ts[1] = get_stat_mtime (&st1); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
491 } |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
492 result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
493 # ifdef __linux__ |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
494 /* Work around a kernel bug: |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
495 http://bugzilla.redhat.com/442352 |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
496 http://bugzilla.redhat.com/449910 |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
497 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
|
498 than -1 upon ENOSYS failure. |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
499 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
|
500 are no longer in common use. */ |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
501 if (0 < result) |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
502 errno = ENOSYS; |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
503 # endif |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
504 if (result == 0 || errno != ENOSYS) |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
505 { |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
506 utimensat_works_really = 1; |
12353
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
507 lutimensat_works_really = 1; |
12467
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
508 if (result == 0 && utimensat_ctime_really == 0 |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
509 && adjustment_needed == 2) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
510 { |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
511 /* Perform a followup stat to see if the kernel has a |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
512 ctime bug. */ |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
513 if (lstat (file, &st2)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
514 return -1; |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
515 if (detect_ctime_bug (&st1, &st2, ts)) |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
516 result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); |
912bdb1c31fb
utimens: work around Linux ctime bug
Eric Blake <ebb9@byu.net>
parents:
12447
diff
changeset
|
517 } |
12172
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
518 return result; |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
519 } |
52ebfd595434
utimens: cache whether utimensat syscall works
Eric Blake <ebb9@byu.net>
parents:
12162
diff
changeset
|
520 } |
12353
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
521 lutimensat_works_really = -1; |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
522 #endif /* HAVE_UTIMENSAT */ |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
523 |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
524 /* The platform lacks an interface to set file timestamps with |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
525 nanosecond resolution, so do the best we can, discarding any |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
526 fractional part of the timestamp. */ |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
527 |
12194
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
528 if (adjustment_needed || REPLACE_FUNC_STAT_FILE) |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
529 { |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
530 if (lstat (file, &st)) |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
531 return -1; |
12194
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
532 if (ts && update_timespec (&st, &ts)) |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
533 return 0; |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
534 } |
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
535 |
12353
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
536 /* On Linux, lutimes is a thin wrapper around utimensat, so there is |
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
537 no point trying lutimes if utimensat failed with ENOSYS. */ |
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
538 #if HAVE_LUTIMES && !HAVE_UTIMENSAT |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
539 { |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
540 struct timeval timeval[2]; |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
541 struct timeval const *t; |
12447
b79168ca6a08
utimens: one more try at avoiding compiler warning
Eric Blake <ebb9@byu.net>
parents:
12377
diff
changeset
|
542 int result; |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
543 if (ts) |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
544 { |
12160
d0732ed2dd55
utimens: add UTIME_NOW and UTIME_OMIT support
Eric Blake <ebb9@byu.net>
parents:
12158
diff
changeset
|
545 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
|
546 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
|
547 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
|
548 timeval[1].tv_usec = ts[1].tv_nsec / 1000; |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
549 t = timeval; |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
550 } |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
551 else |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
552 t = NULL; |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
553 |
12353
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
554 result = lutimes (file, t); |
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
555 if (result == 0 || errno != ENOSYS) |
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
556 return result; |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
557 } |
12353
fd066c132b7d
utimens: work around older Linux failure with symlinks
Eric Blake <ebb9@byu.net>
parents:
12317
diff
changeset
|
558 #endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */ |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
559 |
12173
efdb2ab5743f
utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents:
12172
diff
changeset
|
560 /* Out of luck for symlinks, but we still handle regular files. */ |
12194
16c7c4fa9754
utimensat: work around Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
12174
diff
changeset
|
561 if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st)) |
12173
efdb2ab5743f
utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents:
12172
diff
changeset
|
562 return -1; |
efdb2ab5743f
utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents:
12172
diff
changeset
|
563 if (!S_ISLNK (st.st_mode)) |
efdb2ab5743f
utimens: let lutimens work on non-symlinks
Eric Blake <ebb9@byu.net>
parents:
12172
diff
changeset
|
564 return fdutimens (file, -1, ts); |
12158
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
565 errno = ENOSYS; |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
566 return -1; |
899dd13e9f8b
utimens: add lutimens interface
Eric Blake <ebb9@byu.net>
parents:
12157
diff
changeset
|
567 } |