Mercurial > hg > octave-shane > gnulib-hg
annotate lib/utimens.c @ 6297:10379892281e
* utimens.c (ENOSYS): Define if not already defined.
(futimens): Support having a null PATH if the file descriptor
is nonnegative.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Sun, 25 Sep 2005 06:22:34 +0000 |
parents | b377d8796118 |
children | 716071856296 |
rev | line source |
---|---|
5589
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
1 /* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. |
5147 | 2 |
3 This program is free software; you can redistribute it and/or modify it | |
4 under the terms of the GNU General Public License as published by the | |
5 Free Software Foundation; either version 2, or (at your option) any | |
6 later version. | |
7 | |
8 This program is distributed in the hope that it will be useful, | |
9 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 GNU General Public License for more details. | |
12 | |
13 You should have received a copy of the GNU General Public License | |
14 along with this program; if not, write to the Free Software Foundation, | |
5848
a48fb0e98c8c
*** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents:
5589
diff
changeset
|
15 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
5147 | 16 |
17 /* Written by Paul Eggert. */ | |
18 | |
19 /* derived from a function in touch.c */ | |
20 | |
21 #ifdef HAVE_CONFIG_H | |
22 # include <config.h> | |
23 #endif | |
24 | |
25 #include "utimens.h" | |
26 | |
5589
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
27 #include <errno.h> |
6283
b377d8796118
* lib/utimens.c (futimens): Use futimesat if available.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5848
diff
changeset
|
28 #include <fcntl.h> |
5589
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
29 |
5147 | 30 #if HAVE_UTIME_H |
31 # include <utime.h> | |
32 #endif | |
33 | |
34 /* Some systems (even some that do have <utime.h>) don't declare this | |
35 structure anywhere. */ | |
36 #ifndef HAVE_STRUCT_UTIMBUF | |
37 struct utimbuf | |
38 { | |
39 long actime; | |
40 long modtime; | |
41 }; | |
42 #endif | |
43 | |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
44 /* Some systems don't have ENOSYS. */ |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
45 #ifndef ENOSYS |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
46 # ifdef ENOTSUP |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
47 # define ENOSYS ENOTSUP |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
48 # else |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
49 /* Some systems don't have ENOTSUP either. */ |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
50 # define ENOSYS EINVAL |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
51 # endif |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
52 #endif |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
53 |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
54 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
55 # define __attribute__(x) |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
56 #endif |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
57 |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
58 #ifndef ATTRIBUTE_UNUSED |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
59 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
60 #endif |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
61 |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
62 /* 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
|
63 TIMESPEC[0] and TIMESPEC[1], respectively. |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
64 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
|
65 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
|
66 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
|
67 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
|
68 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
|
69 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
|
70 Return 0 on success, -1 (setting errno) on failure. */ |
5147 | 71 |
72 int | |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
73 futimens (int fd ATTRIBUTE_UNUSED, |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
74 char const *file, struct timespec const timespec[2]) |
5147 | 75 { |
76 /* There's currently no interface to set file timestamps with | |
77 nanosecond resolution, so do the best we can, discarding any | |
78 fractional part of the timestamp. */ | |
6283
b377d8796118
* lib/utimens.c (futimens): Use futimesat if available.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5848
diff
changeset
|
79 #if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES |
5147 | 80 struct timeval timeval[2]; |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
81 struct timeval const *t; |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
82 if (timespec) |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
83 { |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
84 timeval[0].tv_sec = timespec[0].tv_sec; |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
85 timeval[0].tv_usec = timespec[0].tv_nsec / 1000; |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
86 timeval[1].tv_sec = timespec[1].tv_sec; |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
87 timeval[1].tv_usec = timespec[1].tv_nsec / 1000; |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
88 t = timeval; |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
89 } |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
90 else |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
91 t = NULL; |
6283
b377d8796118
* lib/utimens.c (futimens): Use futimesat if available.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5848
diff
changeset
|
92 |
b377d8796118
* lib/utimens.c (futimens): Use futimesat if available.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5848
diff
changeset
|
93 # if HAVE_FUTIMESAT |
b377d8796118
* lib/utimens.c (futimens): Use futimesat if available.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5848
diff
changeset
|
94 return fd < 0 ? futimesat (AT_FDCWD, file, t) : futimesat (fd, NULL, t); |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
95 # elif HAVE_FUTIMES |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
96 if (0 <= fd) |
5589
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
97 { |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
98 if (futimes (fd, t) == 0) |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
99 return 0; |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
100 |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
101 /* On GNU/Linux without the futimes syscall and without /proc |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
102 mounted, glibc futimes fails with errno == ENOENT. Fall back |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
103 on utimes if we get a weird error number like that. */ |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
104 switch (errno) |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
105 { |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
106 case EACCES: |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
107 case EIO: |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
108 case EPERM: |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
109 case EROFS: |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
110 return -1; |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
111 } |
6ddb405e16b6
(futimens): Account for the fact that futimes
Paul Eggert <eggert@cs.ucla.edu>
parents:
5485
diff
changeset
|
112 } |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
113 # endif |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
114 #endif |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
115 |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
116 #if ! HAVE_FUTIMES_AT |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
117 |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
118 if (!file) |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
119 { |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
120 errno = ENOSYS; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
121 return -1; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
122 } |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
123 |
6297
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
124 # if HAVE_WORKING_UTIMES |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
125 return utimes (file, t); |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
126 # else |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
127 { |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
128 struct utimbuf utimbuf; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
129 struct utimbuf const *ut; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
130 if (timespec) |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
131 { |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
132 utimbuf.actime = timespec[0].tv_sec; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
133 utimbuf.modtime = timespec[1].tv_sec; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
134 ut = &utimbuf; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
135 } |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
136 else |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
137 ut = NULL; |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
138 |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
139 return utime (file, ut); |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
140 } |
10379892281e
* utimens.c (ENOSYS): Define if not already defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6283
diff
changeset
|
141 # endif |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
142 |
5147 | 143 #endif |
144 } | |
5485
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
145 |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
146 /* 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
|
147 TIMESPEC[0] and TIMESPEC[1], respectively. */ |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
148 int |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
149 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
|
150 { |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
151 return futimens (-1, file, timespec); |
863556283cee
(__attribute__, ATTRIBUTE_UNUSED): New macros.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5147
diff
changeset
|
152 } |