This source file includes following definitions.
- at_func2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #include "openat-priv.h"
22
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include "filename.h"
29 #include "filenamecat.h"
30 #include "openat.h"
31 #include "same-inode.h"
32 #include "save-cwd.h"
33
34
35
36
37
38
39 int
40 at_func2 (int fd1, char const *file1,
41 int fd2, char const *file2,
42 int (*func) (char const *file1, char const *file2))
43 {
44 struct saved_cwd saved_cwd;
45 int saved_errno;
46 int err;
47 char *file1_alt;
48 char *file2_alt;
49 struct stat st1;
50 struct stat st2;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 if ((fd1 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file1))
78 && (fd2 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file2)))
79 return func (file1, file2);
80
81
82 {
83 char proc_buf1[OPENAT_BUFFER_SIZE];
84 char *proc_file1 = ((fd1 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file1))
85 ? (char *) file1
86 : openat_proc_name (proc_buf1, fd1, file1));
87 if (proc_file1)
88 {
89 char proc_buf2[OPENAT_BUFFER_SIZE];
90 char *proc_file2 = ((fd2 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file2))
91 ? (char *) file2
92 : openat_proc_name (proc_buf2, fd2, file2));
93 if (proc_file2)
94 {
95 int proc_result = func (proc_file1, proc_file2);
96 int proc_errno = errno;
97 if (proc_file1 != proc_buf1 && proc_file1 != file1)
98 free (proc_file1);
99 if (proc_file2 != proc_buf2 && proc_file2 != file2)
100 free (proc_file2);
101
102
103
104 if (0 <= proc_result)
105 return proc_result;
106 if (! EXPECTED_ERRNO (proc_errno))
107 {
108 errno = proc_errno;
109 return proc_result;
110 }
111 }
112 else if (proc_file1 != proc_buf1 && proc_file1 != file1)
113 free (proc_file1);
114 }
115 }
116
117
118
119 if (IS_ABSOLUTE_FILE_NAME (file1))
120 fd1 = AT_FDCWD;
121 else if (IS_ABSOLUTE_FILE_NAME (file2))
122 fd2 = AT_FDCWD;
123
124
125
126 if (fd1 == AT_FDCWD)
127 {
128 if (stat (".", &st1) == -1 || fstat (fd2, &st2) == -1)
129 return -1;
130 if (!S_ISDIR (st2.st_mode))
131 {
132 errno = ENOTDIR;
133 return -1;
134 }
135 if (SAME_INODE (st1, st2))
136 return func (file1, file2);
137 }
138 else if (fd2 == AT_FDCWD)
139 {
140 if (stat (".", &st2) == -1 || fstat (fd1, &st1) == -1)
141 return -1;
142 if (!S_ISDIR (st1.st_mode))
143 {
144 errno = ENOTDIR;
145 return -1;
146 }
147 if (SAME_INODE (st1, st2))
148 return func (file1, file2);
149 }
150 else if (fd1 != fd2)
151 {
152 if (fstat (fd1, &st1) == -1 || fstat (fd2, &st2) == -1)
153 return -1;
154 if (!S_ISDIR (st1.st_mode) || !S_ISDIR (st2.st_mode))
155 {
156 errno = ENOTDIR;
157 return -1;
158 }
159 if (SAME_INODE (st1, st2))
160 {
161 fd2 = fd1;
162 if (stat (".", &st1) == 0 && SAME_INODE (st1, st2))
163 return func (file1, file2);
164 }
165 }
166 else
167 {
168 if (fstat (fd1, &st1) == -1)
169 return -1;
170 if (!S_ISDIR (st1.st_mode))
171 {
172 errno = ENOTDIR;
173 return -1;
174 }
175 if (stat (".", &st2) == 0 && SAME_INODE (st1, st2))
176 return func (file1, file2);
177 }
178
179
180 if (file1[0] == '\0' || file2[0] == '\0')
181 {
182 errno = ENOENT;
183 return -1;
184 }
185
186
187
188
189 if (save_cwd (&saved_cwd) != 0)
190 openat_save_fail (errno);
191
192 if (fd1 != AT_FDCWD && fd2 != AT_FDCWD && fd1 != fd2)
193 {
194 if (fchdir (fd1) != 0)
195 {
196 saved_errno = errno;
197 free_cwd (&saved_cwd);
198 errno = saved_errno;
199 return -1;
200 }
201 fd1 = AT_FDCWD;
202 }
203
204
205
206
207 file1_alt = (char *) file1;
208 file2_alt = (char *) file2;
209
210 if (fd1 == AT_FDCWD && !IS_ABSOLUTE_FILE_NAME (file1))
211 {
212
213
214
215 char *cwd = getcwd (NULL, 0);
216 if (!cwd)
217 {
218 saved_errno = errno;
219 free_cwd (&saved_cwd);
220 errno = saved_errno;
221 return -1;
222 }
223 file1_alt = mfile_name_concat (cwd, file1, NULL);
224 if (!file1_alt)
225 {
226 saved_errno = errno;
227 free (cwd);
228 free_cwd (&saved_cwd);
229 errno = saved_errno;
230 return -1;
231 }
232 free (cwd);
233 }
234 else if (fd2 == AT_FDCWD && !IS_ABSOLUTE_FILE_NAME (file2))
235 {
236 char *cwd = getcwd (NULL, 0);
237 if (!cwd)
238 {
239 saved_errno = errno;
240 free_cwd (&saved_cwd);
241 errno = saved_errno;
242 return -1;
243 }
244 file2_alt = mfile_name_concat (cwd, file2, NULL);
245 if (!file2_alt)
246 {
247 saved_errno = errno;
248 free (cwd);
249 free_cwd (&saved_cwd);
250 errno = saved_errno;
251 return -1;
252 }
253 free (cwd);
254 }
255
256
257 if (fchdir (fd1 == AT_FDCWD ? fd2 : fd1) != 0)
258 {
259 saved_errno = errno;
260 free_cwd (&saved_cwd);
261 if (file1 != file1_alt)
262 free (file1_alt);
263 else if (file2 != file2_alt)
264 free (file2_alt);
265 errno = saved_errno;
266 return -1;
267 }
268
269
270
271 err = func (file1_alt, file2_alt);
272 saved_errno = (err < 0 ? errno : 0);
273
274 if (file1 != file1_alt)
275 free (file1_alt);
276 else if (file2 != file2_alt)
277 free (file2_alt);
278
279 if (restore_cwd (&saved_cwd) != 0)
280 openat_restore_fail (errno);
281
282 free_cwd (&saved_cwd);
283
284 if (saved_errno)
285 errno = saved_errno;
286 return err;
287 }
288 #undef CALL_FUNC
289 #undef FUNC_RESULT