1 /* Test of link() function.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
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.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* This file is designed to test both link(a,b) and
18 linkat(AT_FDCWD,a,AT_FDCWD,b,0). FUNC is the function to test.
19 Assumes that BASE and ASSERT are already defined, and that
20 appropriate headers are already included. If PRINT, warn before
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. */
25 test_link (int (*func) (char const *, char const *), bool print)
30 /* Create first file. */
31 fd = open (BASE "a", O_CREAT | O_EXCL | O_WRONLY, 0600);
33 ASSERT (write (fd, "hello", 5) == 5);
34 ASSERT (close (fd) == 0);
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");
45 ASSERT (stat (BASE "b", &st) == 0);
46 if (st.st_ino && st.st_nlink != 2)
48 ASSERT (unlink (BASE "b") == 0);
55 /* If the device does not support hard links, errno is
56 EPERM on Linux, EOPNOTSUPP on FreeBSD. */
62 fputs ("skipping test: "
63 "hard links not supported on this file system\n",
65 ASSERT (unlink (BASE "a") == 0);
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);
78 ASSERT (write (fd, "world", 5) == 5);
79 ASSERT (close (fd) == 0);
82 fd = open (BASE "a", O_RDONLY);
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);
90 ASSERT (read (fd, buf, 10) == 10);
91 ASSERT (strcmp (buf, "helloworld") == 0);
92 ASSERT (close (fd) == 0);
95 /* Test for various error conditions. */
96 ASSERT (mkdir (BASE "d", 0700) == 0);
98 ASSERT (func (BASE "a", ".") == -1);
99 ASSERT (errno == EEXIST || errno == EINVAL);
101 ASSERT (func (BASE "a", BASE "a") == -1);
102 ASSERT (errno == EEXIST);
103 ASSERT (func (BASE "a", BASE "b") == 0);
105 ASSERT (func (BASE "a", BASE "b") == -1);
106 ASSERT (errno == EEXIST);
108 ASSERT (func (BASE "a", BASE "d") == -1);
109 ASSERT (errno == EEXIST);
111 ASSERT (func (BASE "c", BASE "e") == -1);
112 ASSERT (errno == ENOENT);
114 ASSERT (func (BASE "a", BASE "c/.") == -1);
115 ASSERT (errno == ENOENT);
117 ASSERT (func (BASE "a/", BASE "c") == -1);
118 ASSERT (errno == ENOTDIR || errno == EINVAL);
120 ASSERT (func (BASE "a", BASE "c/") == -1);
121 ASSERT (errno == ENOTDIR || errno == ENOENT || errno == EINVAL);
123 /* Most platforms reject hard links to directories, and even on
124 those that do permit it, most users can't create them. We assume
125 that if this test is run as root and we managed to create a hard
126 link, then unlink better be able to clean it up. */
130 result = func (BASE "d", BASE "c");
133 /* Probably root on Solaris. */
134 ASSERT (unlink (BASE "c") == 0);
138 /* Most everyone else. */
139 ASSERT (errno == EPERM || errno == EACCES || errno == EISDIR);
141 ASSERT (func (BASE "d/.", BASE "c") == -1);
142 ASSERT (errno == EPERM || errno == EACCES || errno == EISDIR
145 ASSERT (func (BASE "d/.//", BASE "c") == -1);
146 ASSERT (errno == EPERM || errno == EACCES || errno == EISDIR
150 ASSERT (unlink (BASE "a") == 0);
152 ASSERT (unlink (BASE "c") == -1);
153 ASSERT (errno == ENOENT);
154 ASSERT (rmdir (BASE "d") == 0);
156 /* Test invalid use of symlink. */
157 if (symlink (BASE "a", BASE "link") != 0)
159 ASSERT (unlink (BASE "b") == 0);
161 fputs ("skipping test: symlinks not supported on this file system\n",
166 ASSERT (func (BASE "b", BASE "link/") == -1);
167 ASSERT (errno == ENOTDIR || errno == ENOENT || errno == EEXIST
170 ASSERT (func (BASE "b", BASE "link") == -1);
171 ASSERT (errno == EEXIST);
172 ASSERT (rename (BASE "b", BASE "a") == 0);
174 ASSERT (func (BASE "link/", BASE "b") == -1);
175 ASSERT (errno == ENOTDIR || errno == EEXIST || errno == EINVAL);
178 ASSERT (unlink (BASE "a") == 0);
179 ASSERT (unlink (BASE "link") == 0);