Mercurial > gnulib
annotate tests/test-linkat.c @ 40057:b06060465f09
maint: Run 'make update-copyright'
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Tue, 01 Jan 2019 00:25:11 +0100 |
parents | 10eb9086bea0 |
children |
rev | line source |
---|---|
12068 | 1 /* Tests of linkat. |
40057
b06060465f09
maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents:
19484
diff
changeset
|
2 Copyright (C) 2009-2019 Free Software Foundation, Inc. |
12068 | 3 |
4 This program is free software: you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 3 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
19190 | 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
12068 | 16 |
17 /* Written by Eric Blake <ebb9@byu.net>, 2009. */ | |
18 | |
19 #include <config.h> | |
20 | |
21 #include <unistd.h> | |
22 | |
12489 | 23 #include "signature.h" |
24 SIGNATURE_CHECK (linkat, int, (int, char const *, int, char const *, int)); | |
25 | |
12068 | 26 #include <fcntl.h> |
27 #include <errno.h> | |
28 #include <stdbool.h> | |
29 #include <stdio.h> | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
13405
e7645f87b96f
test-linkat: avoid failed assertion on "other" architectures
Jim Meyering <meyering@redhat.com>
parents:
12842
diff
changeset
|
32 #include <sys/stat.h> |
12068 | 33 |
34 #include "areadlink.h" | |
35 #include "filenamecat.h" | |
36 #include "same-inode.h" | |
12842
b2bf8684a2db
tests: silence warning about system return
Eric Blake <ebb9@byu.net>
parents:
12559
diff
changeset
|
37 #include "ignore-value.h" |
12496
a48d3d749ca5
Refactor common macros used in tests.
Bruno Haible <bruno@clisp.org>
parents:
12489
diff
changeset
|
38 #include "macros.h" |
12068 | 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 /* Wrapper to test linkat like link. */ | |
49 static int | |
50 do_link (char const *name1, char const *name2) | |
51 { | |
52 return linkat (dfd1, name1, dfd2, name2, flag); | |
53 } | |
54 | |
14050
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
55 /* Can we expect that link() and linkat(), when called on a symlink, |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
56 increment the link count of that symlink? */ |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
57 #if LINK_FOLLOWS_SYMLINKS == 0 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
58 # define EXPECT_LINK_HARDLINKS_SYMLINKS 1 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
59 #elif LINK_FOLLOWS_SYMLINKS == -1 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
60 extern int __xpg4; |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
61 # define EXPECT_LINK_HARDLINKS_SYMLINKS (__xpg4 == 0) |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
62 #else |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
63 # define EXPECT_LINK_HARDLINKS_SYMLINKS 0 |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
64 #endif |
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
65 |
12068 | 66 /* Wrapper to see if two symlinks act the same. */ |
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); | |
14050
6566818713fe
linkat: Make implementation robust against system behaviour variations.
Bruno Haible <bruno@clisp.org>
parents:
14048
diff
changeset
|
81 if (EXPECT_LINK_HARDLINKS_SYMLINKS) |
12068 | 82 ASSERT (SAME_INODE (st1, st2)); |
83 free (contents1); | |
84 free (contents2); | |
85 } | |
86 | |
87 int | |
12197
e45d9bb2233e
tests: avoid several compiler warnings
Eric Blake <ebb9@byu.net>
parents:
12146
diff
changeset
|
88 main (void) |
12068 | 89 { |
90 int i; | |
91 int dfd; | |
92 char *cwd; | |
93 int result; | |
94 | |
95 /* Clean up any trash from prior testsuite runs. */ | |
12842
b2bf8684a2db
tests: silence warning about system return
Eric Blake <ebb9@byu.net>
parents:
12559
diff
changeset
|
96 ignore_value (system ("rm -rf " BASE "*")); |
12068 | 97 |
15703
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
98 /* Test behaviour for invalid file descriptors. */ |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
99 { |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
100 errno = 0; |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
101 ASSERT (linkat (-1, "foo", AT_FDCWD, "bar", 0) == -1); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
102 ASSERT (errno == EBADF); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
103 } |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
104 { |
17292
3a09cc104f4c
tests: don't assume fd 99 is closed
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
105 close (99); |
15703
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
106 errno = 0; |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
107 ASSERT (linkat (99, "foo", AT_FDCWD, "bar", 0) == -1); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
108 ASSERT (errno == EBADF); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
109 } |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
110 ASSERT (close (creat (BASE "oo", 0600)) == 0); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
111 { |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
112 errno = 0; |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
113 ASSERT (linkat (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
114 ASSERT (errno == EBADF); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
115 } |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
116 { |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
117 errno = 0; |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
118 ASSERT (linkat (AT_FDCWD, BASE "oo", 99, "bar", 0) == -1); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
119 ASSERT (errno == EBADF); |
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
120 } |
15810
bf1b12f633c4
test-linkat: don't leave behind a temporary file
Jim Meyering <meyering@redhat.com>
parents:
15703
diff
changeset
|
121 ASSERT (unlink (BASE "oo") == 0); |
15703
97b70675b25e
linkat tests: EBADF tests.
Bruno Haible <bruno@clisp.org>
parents:
15298
diff
changeset
|
122 |
12068 | 123 /* Test basic link functionality, without mentioning symlinks. */ |
12263 | 124 result = test_link (do_link, true); |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
125 dfd1 = open (".", O_RDONLY); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
126 ASSERT (0 <= dfd1); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
127 ASSERT (test_link (do_link, false) == result); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
128 dfd2 = dfd1; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
129 ASSERT (test_link (do_link, false) == result); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
130 dfd1 = AT_FDCWD; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
131 ASSERT (test_link (do_link, false) == result); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
132 flag = 0; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
133 ASSERT (test_link (do_link, false) == result); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
134 dfd1 = dfd2; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
135 ASSERT (test_link (do_link, false) == result); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
136 dfd2 = AT_FDCWD; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
137 ASSERT (test_link (do_link, false) == result); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
138 ASSERT (close (dfd1) == 0); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
139 dfd1 = AT_FDCWD; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
140 ASSERT (test_link (do_link, false) == result); |
12068 | 141 |
142 /* Create locations to manipulate. */ | |
143 ASSERT (mkdir (BASE "sub1", 0700) == 0); | |
144 ASSERT (mkdir (BASE "sub2", 0700) == 0); | |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12071
diff
changeset
|
145 ASSERT (close (creat (BASE "00", 0600)) == 0); |
14632
4843b6870f07
tests: reduce dependencies
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
146 cwd = getcwd (NULL, 0); |
4843b6870f07
tests: reduce dependencies
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
147 ASSERT (cwd); |
12068 | 148 |
149 dfd = open (BASE "sub1", O_RDONLY); | |
150 ASSERT (0 <= dfd); | |
151 ASSERT (chdir (BASE "sub2") == 0); | |
152 | |
153 /* There are 16 possible scenarios, based on whether an fd is | |
154 AT_FDCWD or real, whether a file is absolute or relative, coupled | |
155 with whether flag is set for 32 iterations. | |
156 | |
157 To ensure that we test all of the code paths (rather than | |
158 triggering early normalization optimizations), we use a loop to | |
159 repeatedly rename a file in the parent directory, use an fd open | |
160 on subdirectory 1, all while executing in subdirectory 2; all | |
161 relative names are thus given with a leading "../". Finally, the | |
162 last scenario (two relative paths given, neither one AT_FDCWD) | |
163 has two paths, based on whether the two fds are equivalent, so we | |
164 do the other variant after the loop. */ | |
165 for (i = 0; i < 32; i++) | |
166 { | |
167 int fd1 = (i & 8) ? dfd : AT_FDCWD; | |
14645
5c448b1cba39
tests: drop unused link dependency
Eric Blake <eblake@redhat.com>
parents:
14632
diff
changeset
|
168 char *file1 = mfile_name_concat ((i & 4) ? ".." : cwd, BASE "xx", NULL); |
12068 | 169 int fd2 = (i & 2) ? dfd : AT_FDCWD; |
14645
5c448b1cba39
tests: drop unused link dependency
Eric Blake <eblake@redhat.com>
parents:
14632
diff
changeset
|
170 char *file2 = mfile_name_concat ((i & 1) ? ".." : cwd, BASE "xx", NULL); |
5c448b1cba39
tests: drop unused link dependency
Eric Blake <eblake@redhat.com>
parents:
14632
diff
changeset
|
171 ASSERT (file1); |
5c448b1cba39
tests: drop unused link dependency
Eric Blake <eblake@redhat.com>
parents:
14632
diff
changeset
|
172 ASSERT (file2); |
12197
e45d9bb2233e
tests: avoid several compiler warnings
Eric Blake <ebb9@byu.net>
parents:
12146
diff
changeset
|
173 flag = (i & 0x10 ? AT_SYMLINK_FOLLOW : 0); |
12068 | 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 /* Now we change back to the parent directory, and set dfd to ".", | |
190 in order to test behavior on symlinks. */ | |
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); | |
12263 | 201 if (!result) |
202 fputs ("skipping test: symlinks not supported on this file system\n", | |
203 stderr); | |
12068 | 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 /* Link cannot overwrite existing files. */ | |
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); | |
14048
2defc00f2b21
linkat test: Avoid failure on Solaris 11 2010-11.
Bruno Haible <bruno@clisp.org>
parents:
13405
diff
changeset
|
221 ASSERT (errno == EEXIST || errno == ENOTDIR); |
12068 | 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); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14645
diff
changeset
|
229 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES |
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14645
diff
changeset
|
230 || errno == EINVAL); |
12068 | 231 errno = 0; |
232 ASSERT (linkat (dfd, BASE "link1", dfd, BASE "sub1/", | |
233 AT_SYMLINK_FOLLOW) == -1); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14645
diff
changeset
|
234 ASSERT (errno == EEXIST || errno == EPERM || errno == EACCES |
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14645
diff
changeset
|
235 || errno == EINVAL); |
12068 | 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 /* AT_SYMLINK_FOLLOW only follows first argument, not second. */ | |
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 /* Trailing slash handling. */ | |
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); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14645
diff
changeset
|
280 ASSERT (errno == ENOTDIR || errno == EINVAL); |
12068 | 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); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14645
diff
changeset
|
287 ASSERT (errno == ELOOP || errno == EINVAL); |
12068 | 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); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14645
diff
changeset
|
294 ASSERT (errno == ENOENT || errno == EINVAL); |
12068 | 295 |
296 /* Check for hard links to symlinks. */ | |
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 /* Check that symlink to symlink to file is followed all the way. */ | |
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); | |
12071
8ae42b7a9fe9
test-linkat: make test more robust
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
336 ASSERT (unlink (BASE "file") == 0); |
12068 | 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 /* Now for some real fun with directory crossing. */ | |
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 /* Cleanup. */ | |
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 } |