This source file includes following definitions.
- do_link
- check_same_link
- main
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 <unistd.h>
22
23 #include "signature.h"
24 SIGNATURE_CHECK (linkat, int, (int, char const *, int, char const *, int));
25
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <stdbool.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/stat.h>
33
34 #include "areadlink.h"
35 #include "filenamecat.h"
36 #include "same-inode.h"
37 #include "ignore-value.h"
38 #include "macros.h"
39
40 #define BASE "test-linkat.t"
41
42 #include "test-link.h"
43
44 static int dfd1 = AT_FDCWD;
45 static int dfd2 = AT_FDCWD;
46 static int flag = AT_SYMLINK_FOLLOW;
47
48
49 static int
50 do_link (char const *name1, char const *name2)
51 {
52 return linkat (dfd1, name1, dfd2, name2, flag);
53 }
54
55
56
57 #if LINK_FOLLOWS_SYMLINKS == 0
58 # define EXPECT_LINK_HARDLINKS_SYMLINKS 1
59 #elif LINK_FOLLOWS_SYMLINKS == -1
60 extern int __xpg4;
61 # define EXPECT_LINK_HARDLINKS_SYMLINKS (__xpg4 == 0)
62 #else
63 # define EXPECT_LINK_HARDLINKS_SYMLINKS 0
64 #endif
65
66
67 static void
68 check_same_link (char const *name1, char const *name2)
69 {
70 struct stat st1;
71 struct stat st2;
72 char *contents1;
73 char *contents2;
74 ASSERT (lstat (name1, &st1) == 0);
75 ASSERT (lstat (name2, &st2) == 0);
76 contents1 = areadlink_with_size (name1, st1.st_size);
77 contents2 = areadlink_with_size (name2, st2.st_size);
78 ASSERT (contents1);
79 ASSERT (contents2);
80 ASSERT (strcmp (contents1, contents2) == 0);
81 if (EXPECT_LINK_HARDLINKS_SYMLINKS)
82 ASSERT (SAME_INODE (st1, st2));
83 free (contents1);
84 free (contents2);
85 }
86
87 int
88 main (void)
89 {
90 int i;
91 int dfd;
92 char *cwd;
93 int result;
94
95
96 ignore_value (system ("rm -rf " BASE "*"));
97
98
99 {
100 errno = 0;
101 ASSERT (linkat (-1, "foo", AT_FDCWD, "bar", 0) == -1);
102 ASSERT (errno == EBADF);
103 }
104 {
105 close (99);
106 errno = 0;
107 ASSERT (linkat (99, "foo", AT_FDCWD, "bar", 0) == -1);
108 ASSERT (errno == EBADF);
109 }
110 ASSERT (close (creat (BASE "oo", 0600)) == 0);
111 {
112 errno = 0;
113 ASSERT (linkat (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1);
114 ASSERT (errno == EBADF);
115 }
116 {
117 errno = 0;
118 ASSERT (linkat (AT_FDCWD, BASE "oo", 99, "bar", 0) == -1);
119 ASSERT (errno == EBADF);
120 }
121 ASSERT (unlink (BASE "oo") == 0);
122
123
124 result = test_link (do_link, true);
125 dfd1 = open (".", O_RDONLY);
126 ASSERT (0 <= dfd1);
127 ASSERT (test_link (do_link, false) == result);
128 dfd2 = dfd1;
129 ASSERT (test_link (do_link, false) == result);
130 dfd1 = AT_FDCWD;
131 ASSERT (test_link (do_link, false) == result);
132 flag = 0;
133 ASSERT (test_link (do_link, false) == result);
134 dfd1 = dfd2;
135 ASSERT (test_link (do_link, false) == result);
136 dfd2 = AT_FDCWD;
137 ASSERT (test_link (do_link, false) == result);
138 ASSERT (close (dfd1) == 0);
139 dfd1 = AT_FDCWD;
140 ASSERT (test_link (do_link, false) == result);
141
142
143 ASSERT (mkdir (BASE "sub1", 0700) == 0);
144 ASSERT (mkdir (BASE "sub2", 0700) == 0);
145 ASSERT (close (creat (BASE "00", 0600)) == 0);
146 cwd = getcwd (NULL, 0);
147 ASSERT (cwd);
148
149 dfd = open (BASE "sub1", O_RDONLY);
150 ASSERT (0 <= dfd);
151 ASSERT (chdir (BASE "sub2") == 0);
152
153
154
155
156
157
158
159
160
161
162
163
164
165 for (i = 0; i < 32; i++)
166 {
167 int fd1 = (i & 8) ? dfd : AT_FDCWD;
168 char *file1 = mfile_name_concat ((i & 4) ? ".." : cwd, BASE "xx", NULL);
169 int fd2 = (i & 2) ? dfd : AT_FDCWD;
170 char *file2 = mfile_name_concat ((i & 1) ? ".." : cwd, BASE "xx", NULL);
171 ASSERT (file1);
172 ASSERT (file2);
173 flag = (i & 0x10 ? AT_SYMLINK_FOLLOW : 0);
174
175 ASSERT (sprintf (strchr (file1, '\0') - 2, "%02d", i) == 2);
176 ASSERT (sprintf (strchr (file2, '\0') - 2, "%02d", i + 1) == 2);
177 ASSERT (linkat (fd1, file1, fd2, file2, flag) == 0);
178 ASSERT (unlinkat (fd1, file1, 0) == 0);
179 free (file1);
180 free (file2);
181 }
182 dfd2 = open ("..", O_RDONLY);
183 ASSERT (0 <= dfd2);
184 ASSERT (linkat (dfd, "../" BASE "32", dfd2, BASE "33", 0) == 0);
185 ASSERT (linkat (dfd, "../" BASE "33", dfd2, BASE "34",
186 AT_SYMLINK_FOLLOW) == 0);
187 ASSERT (close (dfd2) == 0);
188
189
190
191 ASSERT (chdir ("..") == 0);
192 ASSERT (close (dfd) == 0);
193 if (symlink (BASE "sub1", BASE "link1"))
194 {
195 ASSERT (unlink (BASE "32") == 0);
196 ASSERT (unlink (BASE "33") == 0);
197 ASSERT (unlink (BASE "34") == 0);
198 ASSERT (rmdir (BASE "sub1") == 0);
199 ASSERT (rmdir (BASE "sub2") == 0);
200 free (cwd);
201 if (!result)
202 fputs ("skipping test: symlinks not supported on this file system\n",
203 stderr);
204 return result;
205 }
206 dfd = open (".", O_RDONLY);
207 ASSERT (0 <= dfd);
208 ASSERT (symlink (BASE "34", BASE "link2") == 0);
209 ASSERT (symlink (BASE "link3", BASE "link3") == 0);
210 ASSERT (symlink (BASE "nowhere", BASE "link4") == 0);
211
212
213 errno = 0;
214 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "sub1", 0) == -1);
215 ASSERT (errno == EEXIST);
216 errno = 0;
217 ASSERT (linkat (dfd, BASE "link1/", dfd, BASE "sub1", 0) == -1);
218 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES);
219 errno = 0;
220 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "sub1/", 0) == -1);
221 ASSERT (errno == EEXIST || errno == ENOTDIR);
222 errno = 0;
223 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "sub1",
224 AT_SYMLINK_FOLLOW) == -1);
225 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES);
226 errno = 0;
227 ASSERT (linkat (dfd, BASE "link1/", dfd, BASE "sub1",
228 AT_SYMLINK_FOLLOW) == -1);
229 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES
230 || errno == EINVAL);
231 errno = 0;
232 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "sub1/",
233 AT_SYMLINK_FOLLOW) == -1);
234 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES
235 || errno == EINVAL);
236 errno = 0;
237 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link2", 0) == -1);
238 ASSERT (errno == EEXIST);
239 errno = 0;
240 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link2",
241 AT_SYMLINK_FOLLOW) == -1);
242 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES);
243 errno = 0;
244 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link3", 0) == -1);
245 ASSERT (errno == EEXIST || errno == ELOOP);
246 errno = 0;
247 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link3",
248 AT_SYMLINK_FOLLOW) == -1);
249 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES
250 || errno == ELOOP);
251 errno = 0;
252 ASSERT (linkat (dfd, BASE "link2", dfd, BASE "link3", 0) == -1);
253 ASSERT (errno == EEXIST || errno == ELOOP);
254 errno = 0;
255 ASSERT (linkat (dfd, BASE "link2", dfd, BASE "link3",
256 AT_SYMLINK_FOLLOW) == -1);
257 ASSERT (errno == EEXIST || errno == ELOOP);
258
259
260 errno = 0;
261 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link4", 0) == -1);
262 ASSERT (errno == EEXIST);
263 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link4",
264 AT_SYMLINK_FOLLOW) == -1);
265 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES);
266 errno = 0;
267 ASSERT (linkat (dfd, BASE "34", dfd, BASE "link4", 0) == -1);
268 ASSERT (errno == EEXIST);
269 errno = 0;
270 ASSERT (linkat (dfd, BASE "34", dfd, BASE "link4", AT_SYMLINK_FOLLOW) == -1);
271 ASSERT (errno == EEXIST);
272
273
274 errno = 0;
275 ASSERT (linkat (dfd, BASE "link2/", dfd, BASE "link5", 0) == -1);
276 ASSERT (errno == ENOTDIR);
277 errno = 0;
278 ASSERT (linkat (dfd, BASE "link2/", dfd, BASE "link5",
279 AT_SYMLINK_FOLLOW) == -1);
280 ASSERT (errno == ENOTDIR || errno == EINVAL);
281 errno = 0;
282 ASSERT (linkat (dfd, BASE "link3/", dfd, BASE "link5", 0) == -1);
283 ASSERT (errno == ELOOP);
284 errno = 0;
285 ASSERT (linkat (dfd, BASE "link3/", dfd, BASE "link5",
286 AT_SYMLINK_FOLLOW) == -1);
287 ASSERT (errno == ELOOP || errno == EINVAL);
288 errno = 0;
289 ASSERT (linkat (dfd, BASE "link4/", dfd, BASE "link5", 0) == -1);
290 ASSERT (errno == ENOENT);
291 errno = 0;
292 ASSERT (linkat (dfd, BASE "link4/", dfd, BASE "link5",
293 AT_SYMLINK_FOLLOW) == -1);
294 ASSERT (errno == ENOENT || errno == EINVAL);
295
296
297 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link5", 0) == 0);
298 check_same_link (BASE "link1", BASE "link5");
299 ASSERT (unlink (BASE "link5") == 0);
300 errno = 0;
301 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "link5",
302 AT_SYMLINK_FOLLOW) == -1);
303 ASSERT (errno == EPERM || errno == EACCES);
304 ASSERT (linkat (dfd, BASE "link2", dfd, BASE "link5", 0) == 0);
305 check_same_link (BASE "link2", BASE "link5");
306 ASSERT (unlink (BASE "link5") == 0);
307 ASSERT (linkat (dfd, BASE "link2", dfd, BASE "file", AT_SYMLINK_FOLLOW) == 0);
308 errno = 0;
309 ASSERT (areadlink (BASE "file") == NULL);
310 ASSERT (errno == EINVAL);
311 ASSERT (unlink (BASE "file") == 0);
312 ASSERT (linkat (dfd, BASE "link3", dfd, BASE "link5", 0) == 0);
313 check_same_link (BASE "link3", BASE "link5");
314 ASSERT (unlink (BASE "link5") == 0);
315 errno = 0;
316 ASSERT (linkat (dfd, BASE "link3", dfd, BASE "link5",
317 AT_SYMLINK_FOLLOW) == -1);
318 ASSERT (errno == ELOOP);
319 ASSERT (linkat (dfd, BASE "link4", dfd, BASE "link5", 0) == 0);
320 check_same_link (BASE "link4", BASE "link5");
321 ASSERT (unlink (BASE "link5") == 0);
322 errno = 0;
323 ASSERT (linkat (dfd, BASE "link4", dfd, BASE "link5",
324 AT_SYMLINK_FOLLOW) == -1);
325 ASSERT (errno == ENOENT);
326
327
328 ASSERT (symlink (BASE "link2", BASE "link5") == 0);
329 ASSERT (linkat (dfd, BASE "link5", dfd, BASE "link6", 0) == 0);
330 check_same_link (BASE "link5", BASE "link6");
331 ASSERT (unlink (BASE "link6") == 0);
332 ASSERT (linkat (dfd, BASE "link5", dfd, BASE "file", AT_SYMLINK_FOLLOW) == 0);
333 errno = 0;
334 ASSERT (areadlink (BASE "file") == NULL);
335 ASSERT (errno == EINVAL);
336 ASSERT (unlink (BASE "file") == 0);
337 ASSERT (unlink (BASE "link5") == 0);
338 ASSERT (symlink (BASE "link3", BASE "link5") == 0);
339 errno = 0;
340 ASSERT (linkat (dfd, BASE "link5", dfd, BASE "file",
341 AT_SYMLINK_FOLLOW) == -1);
342 ASSERT (errno == ELOOP);
343 ASSERT (unlink (BASE "link5") == 0);
344 ASSERT (symlink (BASE "link4", BASE "link5") == 0);
345 errno = 0;
346 ASSERT (linkat (dfd, BASE "link5", dfd, BASE "file",
347 AT_SYMLINK_FOLLOW) == -1);
348 ASSERT (errno == ENOENT);
349
350
351 ASSERT (symlink (cwd, BASE "sub1/link") == 0);
352 ASSERT (symlink (".././/" BASE "sub1/link/" BASE "link2",
353 BASE "sub2/link") == 0);
354 ASSERT (close (dfd) == 0);
355 dfd = open (BASE "sub1", O_RDONLY);
356 ASSERT (0 <= dfd);
357 dfd2 = open (BASE "sub2", O_RDONLY);
358 ASSERT (0 < dfd2);
359 ASSERT (linkat (dfd, "../" BASE "sub2/link", dfd2, "./..//" BASE "sub1/file",
360 AT_SYMLINK_FOLLOW) == 0);
361 errno = 0;
362 ASSERT (areadlink (BASE "sub1/file") == NULL);
363 ASSERT (errno == EINVAL);
364
365
366 ASSERT (close (dfd) == 0);
367 ASSERT (close (dfd2) == 0);
368 ASSERT (unlink (BASE "sub1/file") == 0);
369 ASSERT (unlink (BASE "sub1/link") == 0);
370 ASSERT (unlink (BASE "sub2/link") == 0);
371 ASSERT (unlink (BASE "32") == 0);
372 ASSERT (unlink (BASE "33") == 0);
373 ASSERT (unlink (BASE "34") == 0);
374 ASSERT (rmdir (BASE "sub1") == 0);
375 ASSERT (rmdir (BASE "sub2") == 0);
376 ASSERT (unlink (BASE "link1") == 0);
377 ASSERT (unlink (BASE "link2") == 0);
378 ASSERT (unlink (BASE "link3") == 0);
379 ASSERT (unlink (BASE "link4") == 0);
380 ASSERT (unlink (BASE "link5") == 0);
381 free (cwd);
382 return result;
383 }