Mercurial > hg > octave-shane > gnulib-hg
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 |
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 | |
12162 | 52 /* Avoid recursion with rpl_futimens. */ |
53 #undef futimens | |
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 (×pec[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 (×pec[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 | 143 |
144 int | |
12161 | 145 fdutimens (char const *file, int fd, struct timespec const timespec[2]) |
5147 | 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 | 241 nanosecond resolution, so do the best we can, discarding any |
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 | 323 } |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
324 |
12161 | 325 /* Set the access and modification time stamps of FD (a.k.a. FILE) to be |
326 TIMESPEC[0] and TIMESPEC[1], respectively. | |
327 FD must be either negative -- in which case it is ignored -- | |
328 or a file descriptor that is open on FILE. | |
329 If FD is nonnegative, then FILE can be NULL, which means | |
330 use just futimes (or equivalent) instead of utimes (or equivalent), | |
331 and fail if on an old system without futimes (or equivalent). | |
332 If TIMESPEC is null, set the time stamps to the current time. | |
333 Return 0 on success, -1 (setting errno) on failure. */ | |
334 | |
335 int | |
336 gl_futimens (int fd, char const *file, struct timespec const timespec[2]) | |
337 { | |
338 return fdutimens (file, fd, timespec); | |
339 } | |
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 } |