Mercurial > gnulib
annotate tests/test-link.h @ 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 /* Test of link() function. |
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 | |
12520
e84eea643139
tests: fix license on several tests
Eric Blake <ebb9@byu.net>
parents:
12263
diff
changeset
|
6 the Free Software Foundation; either version 3 of the License, or |
12068 | 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 /* This file is designed to test both link(a,b) and | |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
18 linkat(AT_FDCWD,a,AT_FDCWD,b,0). FUNC is the function to test. |
12068 | 19 Assumes that BASE and ASSERT are already defined, and that |
20 appropriate headers are already included. If PRINT, warn before | |
12263 | 21 skipping tests with status 77. This test does not try to create |
22 hard links to symlinks, but does test other aspects of symlink. */ | |
12068 | 23 |
24 static int | |
25 test_link (int (*func) (char const *, char const *), bool print) | |
26 { | |
27 int fd; | |
28 int ret; | |
29 | |
30 /* Create first file. */ | |
31 fd = open (BASE "a", O_CREAT | O_EXCL | O_WRONLY, 0600); | |
32 ASSERT (0 <= fd); | |
33 ASSERT (write (fd, "hello", 5) == 5); | |
34 ASSERT (close (fd) == 0); | |
35 | |
36 /* Not all file systems support link. Mingw doesn't have reliable | |
37 st_nlink on hard links, but our implementation does fail with | |
38 EPERM on poor file systems, and we can detect the inferior stat() | |
39 via st_ino. Cygwin 1.5.x copies rather than links files on those | |
40 file systems, but there, st_nlink and st_ino are reliable. */ | |
41 ret = func (BASE "a", BASE "b"); | |
42 if (!ret) | |
43 { | |
44 struct stat st; | |
45 ASSERT (stat (BASE "b", &st) == 0); | |
46 if (st.st_ino && st.st_nlink != 2) | |
47 { | |
48 ASSERT (unlink (BASE "b") == 0); | |
49 errno = EPERM; | |
50 ret = -1; | |
51 } | |
52 } | |
53 if (ret == -1) | |
54 { | |
55 /* If the device does not support hard links, errno is | |
12102
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
56 EPERM on Linux, EOPNOTSUPP on FreeBSD. */ |
12068 | 57 switch (errno) |
12102
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
58 { |
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
59 case EPERM: |
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
60 case EOPNOTSUPP: |
12068 | 61 if (print) |
62 fputs ("skipping test: " | |
63 "hard links not supported on this file system\n", | |
64 stderr); | |
65 ASSERT (unlink (BASE "a") == 0); | |
12102
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
66 return 77; |
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
67 default: |
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
68 perror ("link"); |
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
69 return 1; |
3ba227551e1d
maint: cleanup whitespace in recent commits
Eric Blake <ebb9@byu.net>
parents:
12084
diff
changeset
|
70 } |
12068 | 71 } |
72 ASSERT (ret == 0); | |
73 | |
74 /* Now, for some behavior tests. Modify the contents of 'b', and | |
75 ensure that 'a' can see it, both while 'b' exists and after. */ | |
76 fd = open (BASE "b", O_APPEND | O_WRONLY); | |
77 ASSERT (0 <= fd); | |
78 ASSERT (write (fd, "world", 5) == 5); | |
79 ASSERT (close (fd) == 0); | |
80 { | |
81 char buf[11] = { 0 }; | |
82 fd = open (BASE "a", O_RDONLY); | |
83 ASSERT (0 <= fd); | |
84 ASSERT (read (fd, buf, 10) == 10); | |
85 ASSERT (strcmp (buf, "helloworld") == 0); | |
86 ASSERT (close (fd) == 0); | |
87 ASSERT (unlink (BASE "b") == 0); | |
88 fd = open (BASE "a", O_RDONLY); | |
89 ASSERT (0 <= fd); | |
90 ASSERT (read (fd, buf, 10) == 10); | |
91 ASSERT (strcmp (buf, "helloworld") == 0); | |
92 ASSERT (close (fd) == 0); | |
93 } | |
94 | |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
95 /* Test for various error conditions. */ |
12068 | 96 ASSERT (mkdir (BASE "d", 0700) == 0); |
97 errno = 0; | |
98 ASSERT (func (BASE "a", ".") == -1); | |
99 ASSERT (errno == EEXIST || errno == EINVAL); | |
100 errno = 0; | |
101 ASSERT (func (BASE "a", BASE "a") == -1); | |
102 ASSERT (errno == EEXIST); | |
103 ASSERT (func (BASE "a", BASE "b") == 0); | |
104 errno = 0; | |
105 ASSERT (func (BASE "a", BASE "b") == -1); | |
106 ASSERT (errno == EEXIST); | |
107 errno = 0; | |
108 ASSERT (func (BASE "a", BASE "d") == -1); | |
109 ASSERT (errno == EEXIST); | |
110 errno = 0; | |
111 ASSERT (func (BASE "c", BASE "e") == -1); | |
112 ASSERT (errno == ENOENT); | |
113 errno = 0; | |
114 ASSERT (func (BASE "a", BASE "c/.") == -1); | |
115 ASSERT (errno == ENOENT); | |
116 errno = 0; | |
117 ASSERT (func (BASE "a/", BASE "c") == -1); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14403
diff
changeset
|
118 ASSERT (errno == ENOTDIR || errno == EINVAL); |
12068 | 119 errno = 0; |
120 ASSERT (func (BASE "a", BASE "c/") == -1); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14403
diff
changeset
|
121 ASSERT (errno == ENOTDIR || errno == ENOENT || errno == EINVAL); |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
122 |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
123 /* Most platforms reject hard links to directories, and even on |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
124 those that do permit it, most users can't create them. We assume |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
125 that if this test is run as root and we managed to create a hard |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
126 link, then unlink better be able to clean it up. */ |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
127 { |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
128 int result; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
129 errno = 0; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
130 result = func (BASE "d", BASE "c"); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
131 if (result == 0) |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
132 { |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
133 /* Probably root on Solaris. */ |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
134 ASSERT (unlink (BASE "c") == 0); |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
135 } |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
136 else |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
137 { |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
138 /* Most everyone else. */ |
14403 | 139 ASSERT (errno == EPERM || errno == EACCES || errno == EISDIR); |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
140 errno = 0; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
141 ASSERT (func (BASE "d/.", BASE "c") == -1); |
14403 | 142 ASSERT (errno == EPERM || errno == EACCES || errno == EISDIR |
143 || errno == EINVAL); | |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
144 errno = 0; |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
145 ASSERT (func (BASE "d/.//", BASE "c") == -1); |
14403 | 146 ASSERT (errno == EPERM || errno == EACCES || errno == EISDIR |
147 || errno == EINVAL); | |
12084
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
148 } |
34277de50e87
tests: tighten link, rmdir, and remove tests
Eric Blake <ebb9@byu.net>
parents:
12068
diff
changeset
|
149 } |
12068 | 150 ASSERT (unlink (BASE "a") == 0); |
151 errno = 0; | |
152 ASSERT (unlink (BASE "c") == -1); | |
153 ASSERT (errno == ENOENT); | |
154 ASSERT (rmdir (BASE "d") == 0); | |
155 | |
12263 | 156 /* Test invalid use of symlink. */ |
157 if (symlink (BASE "a", BASE "link") != 0) | |
158 { | |
159 ASSERT (unlink (BASE "b") == 0); | |
160 if (print) | |
161 fputs ("skipping test: symlinks not supported on this file system\n", | |
162 stderr); | |
163 return 77; | |
164 } | |
165 errno = 0; | |
166 ASSERT (func (BASE "b", BASE "link/") == -1); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14403
diff
changeset
|
167 ASSERT (errno == ENOTDIR || errno == ENOENT || errno == EEXIST |
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14403
diff
changeset
|
168 || errno == EINVAL); |
15313
8dfa469e2ba8
link: work around IRIX bug
Eric Blake <eblake@redhat.com>
parents:
15298
diff
changeset
|
169 errno = 0; |
8dfa469e2ba8
link: work around IRIX bug
Eric Blake <eblake@redhat.com>
parents:
15298
diff
changeset
|
170 ASSERT (func (BASE "b", BASE "link") == -1); |
8dfa469e2ba8
link: work around IRIX bug
Eric Blake <eblake@redhat.com>
parents:
15298
diff
changeset
|
171 ASSERT (errno == EEXIST); |
12263 | 172 ASSERT (rename (BASE "b", BASE "a") == 0); |
173 errno = 0; | |
174 ASSERT (func (BASE "link/", BASE "b") == -1); | |
15298
9f6aa6c9dd0e
linkat test: Avoid test failure on AIX 7.1.
Bruno Haible <bruno@clisp.org>
parents:
14403
diff
changeset
|
175 ASSERT (errno == ENOTDIR || errno == EEXIST || errno == EINVAL); |
12263 | 176 |
177 /* Clean up. */ | |
178 ASSERT (unlink (BASE "a") == 0); | |
179 ASSERT (unlink (BASE "link") == 0); | |
180 | |
12068 | 181 return 0; |
182 } |