This source file includes following definitions.
- rpl_utimensat
- rpl_utimensat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21
22 #include <sys/stat.h>
23
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/stat.h>
29
30 #include "stat-time.h"
31 #include "timespec.h"
32 #include "utimens.h"
33
34 #if HAVE_NEARLY_WORKING_UTIMENSAT
35
36
37 int
38 rpl_utimensat (int fd, char const *file, struct timespec const times[2],
39 int flag)
40 # undef utimensat
41 {
42 size_t len = strlen (file);
43 if (len && file[len - 1] == '/')
44 {
45 struct stat st;
46 if (fstatat (fd, file, &st, flag & AT_SYMLINK_NOFOLLOW) < 0)
47 return -1;
48 if (!S_ISDIR (st.st_mode))
49 {
50 errno = ENOTDIR;
51 return -1;
52 }
53 }
54
55 return utimensat (fd, file, times, flag);
56 }
57
58 #else
59
60 # if HAVE_UTIMENSAT
61
62
63
64
65
66
67
68
69
70 static int local_utimensat (int, char const *, struct timespec const[2], int);
71 # define AT_FUNC_NAME local_utimensat
72
73
74
75 int
76 rpl_utimensat (int fd, char const *file, struct timespec const times[2],
77 int flag)
78 # undef utimensat
79 {
80 # if defined __linux__ || defined __sun
81 struct timespec ts[2];
82 # endif
83
84
85 static int utimensat_works_really;
86 if (0 <= utimensat_works_really)
87 {
88 int result;
89 # if defined __linux__ || defined __sun
90 struct stat st;
91
92
93
94
95
96
97
98
99
100
101
102
103 if (times && (times[0].tv_nsec == UTIME_OMIT
104 || times[1].tv_nsec == UTIME_OMIT))
105 {
106 if (fstatat (fd, file, &st, flag))
107 return -1;
108 if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT)
109 return 0;
110 if (times[0].tv_nsec == UTIME_OMIT)
111 ts[0] = get_stat_atime (&st);
112 else
113 ts[0] = times[0];
114 if (times[1].tv_nsec == UTIME_OMIT)
115 ts[1] = get_stat_mtime (&st);
116 else
117 ts[1] = times[1];
118 times = ts;
119 }
120 # ifdef __hppa__
121
122
123 else if (times
124 && ((times[0].tv_nsec != UTIME_NOW
125 && ! (0 <= times[0].tv_nsec
126 && times[0].tv_nsec < TIMESPEC_HZ))
127 || (times[1].tv_nsec != UTIME_NOW
128 && ! (0 <= times[1].tv_nsec
129 && times[1].tv_nsec < TIMESPEC_HZ))))
130 {
131 errno = EINVAL;
132 return -1;
133 }
134 # endif
135 # endif
136 # if defined __APPLE__ && defined __MACH__
137
138 if (times
139 && ((times[0].tv_nsec != UTIME_OMIT
140 && times[0].tv_nsec != UTIME_NOW
141 && ! (0 <= times[0].tv_nsec
142 && times[0].tv_nsec < TIMESPEC_HZ))
143 || (times[1].tv_nsec != UTIME_OMIT
144 && times[1].tv_nsec != UTIME_NOW
145 && ! (0 <= times[1].tv_nsec
146 && times[1].tv_nsec < TIMESPEC_HZ))))
147 {
148 errno = EINVAL;
149 return -1;
150 }
151 size_t len = strlen (file);
152 if (len > 0 && file[len - 1] == '/')
153 {
154 struct stat statbuf;
155 if (fstatat (fd, file, &statbuf, 0) < 0)
156 return -1;
157 if (!S_ISDIR (statbuf.st_mode))
158 {
159 errno = ENOTDIR;
160 return -1;
161 }
162 }
163 # endif
164 result = utimensat (fd, file, times, flag);
165
166
167
168
169
170 if (result == -1 && errno == EINVAL && (flag & ~AT_SYMLINK_NOFOLLOW))
171 return result;
172 if (result == 0 || (errno != ENOSYS && errno != EINVAL))
173 {
174 utimensat_works_really = 1;
175 return result;
176 }
177 }
178
179
180
181
182 if (0 <= utimensat_works_really && errno == ENOSYS)
183 utimensat_works_really = -1;
184 return local_utimensat (fd, file, times, flag);
185 }
186
187 # else
188
189 # define AT_FUNC_NAME utimensat
190
191 # endif
192
193
194
195
196
197
198
199
200
201
202
203
204 # define AT_FUNC_F1 lutimens
205 # define AT_FUNC_F2 utimens
206 # define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
207 # define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag
208 # define AT_FUNC_POST_FILE_ARGS , ts
209 # include "at-func.c"
210 # undef AT_FUNC_NAME
211 # undef AT_FUNC_F1
212 # undef AT_FUNC_F2
213 # undef AT_FUNC_USE_F1_COND
214 # undef AT_FUNC_POST_FILE_PARAM_DECLS
215 # undef AT_FUNC_POST_FILE_ARGS
216
217 #endif