1 /*
2 * Copyright (c) International Business Machines Corp., 2001
3 * 07/2001 Ported by Wayne Boyer
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * Description:
21 * 1) create a directory tstdir1, create a file under it.
22 * call rmdir(tstdir1), verify the return value is -1
23 * and the errno is ENOTEMPTY.
24 * 2) create a directory with long path, call rmdir(tstdir1),
25 * verify the return value is -1 and the errno is ENAMETOOLONG.
26 * 3) pass a pathname containing non-exist directory component
27 * to rmdir(), verify the return value is -1 and the errno
28 * is ENOENT.
29 * 4) pass a pathname containing a file component to rmdir(),
30 * verify the return value is -1 and the errno is ENOTDIR.
31 * 5) attempt to pass an invalid pathname with an address
32 * pointing outside the address space of the process, as the
33 * argument to rmdir(), verify the return value is -1 and
34 * the errno is EFAULT.
35 * 6) attempt to pass an invalid pathname with NULL, as the
36 * argument to rmdir(), verify the return value is -1 and
37 * the errno is EFAULT.
38 * 7) pass a pathname with too many symbolic links to rmdir(),
39 * verify the return value is -1 and the errno is ELOOP.
40 * 8) pass a pathname which refers to a directory on a read-only
41 * file system to rmdir(), verify the return value is -1 and
42 * the errno is EROFS.
43 * 9) pass a pathname which is currently used as a mount point
44 * to rmdir(), verify the return value is -1 and the errno is
45 * EBUSY.
46 */
47
48 #include <errno.h>
49 #include <sys/stat.h>
50 #include <sys/types.h>
51 #include <sys/mman.h>
52 #include <fcntl.h>
53 #include <unistd.h>
54 #include <pwd.h>
55 #include <sys/mount.h>
56
57 #include "test.h"
58 #include "safe_macros.h"
59
60 #define DIR_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
61 #define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
62
63 #define TESTDIR "testdir"
64 #define TESTDIR2 "nosuchdir/testdir2"
65 #define TESTDIR3 "testfile2/testdir3"
66 #define TESTDIR4 "/loopdir"
67 #define MNTPOINT "mntpoint"
68 #define TESTDIR5 "mntpoint/testdir5"
69 #define TESTFILE "testdir/testfile"
70 #define TESTFILE2 "testfile2"
71
72 static char longpathname[PATH_MAX + 2];
73 static char looppathname[sizeof(TESTDIR4) * 43] = ".";
74
75 static const char *device;
76 static int mount_flag;
77
78 static struct test_case_t {
79 char *dir;
80 int exp_errno;
81 } test_cases[] = {
82 {TESTDIR, ENOTEMPTY},
83 {longpathname, ENAMETOOLONG},
84 {TESTDIR2, ENOENT},
85 {TESTDIR3, ENOTDIR},
86 #if !defined(UCLINUX)
87 {(char *)-1, EFAULT},
88 #endif
89 {NULL, EFAULT},
90 {looppathname, ELOOP},
91 {TESTDIR5, EROFS},
92 {MNTPOINT, EBUSY},
93 };
94
95 static void setup(void);
96 static void rmdir_verify(struct test_case_t *tc);
97 static void cleanup(void);
98
99 char *TCID = "rmdir02";
100 int TST_TOTAL = ARRAY_SIZE(test_cases);
101
main(int ac,char ** av)102 int main(int ac, char **av)
103 {
104 int i, lc;
105
106 tst_parse_opts(ac, av, NULL, NULL);
107
108 setup();
109
110 for (lc = 0; TEST_LOOPING(lc); lc++) {
111 tst_count = 0;
112
113 for (i = 0; i < TST_TOTAL; i++)
114 rmdir_verify(&test_cases[i]);
115 }
116
117 cleanup();
118 tst_exit();
119 }
120
setup(void)121 static void setup(void)
122 {
123 int i;
124 const char *fs_type;
125
126 tst_require_root();
127
128 tst_sig(NOFORK, DEF_HANDLER, cleanup);
129
130 TEST_PAUSE;
131
132 tst_tmpdir();
133
134 fs_type = tst_dev_fs_type();
135 device = tst_acquire_device(cleanup);
136
137 if (!device)
138 tst_brkm(TCONF, cleanup, "Failed to acquire device");
139
140 tst_mkfs(cleanup, device, fs_type, NULL, NULL);
141 SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE);
142 if (mount(device, MNTPOINT, fs_type, 0, NULL) == -1) {
143 tst_brkm(TBROK | TERRNO, cleanup,
144 "mount device:%s failed", device);
145 }
146 SAFE_MKDIR(cleanup, TESTDIR5, DIR_MODE);
147 if (mount(device, MNTPOINT, fs_type, MS_REMOUNT | MS_RDONLY,
148 NULL) == -1) {
149 tst_brkm(TBROK | TERRNO, cleanup,
150 "mount device:%s failed", device);
151 }
152 mount_flag = 1;
153
154 SAFE_MKDIR(cleanup, TESTDIR, DIR_MODE);
155 SAFE_TOUCH(cleanup, TESTFILE, FILE_MODE, NULL);
156
157 memset(longpathname, 'a', PATH_MAX + 1);
158
159 SAFE_TOUCH(cleanup, TESTFILE2, FILE_MODE, NULL);
160
161 #if !defined(UCLINUX)
162 test_cases[4].dir = SAFE_MMAP(cleanup, 0, 1, PROT_NONE,
163 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
164 #endif
165
166 /*
167 * NOTE: the ELOOP test is written based on that the
168 * consecutive symlinks limit in kernel is hardwired
169 * to 40.
170 */
171 SAFE_MKDIR(cleanup, "loopdir", DIR_MODE);
172 SAFE_SYMLINK(cleanup, "../loopdir", "loopdir/loopdir");
173 for (i = 0; i < 43; i++)
174 strcat(looppathname, TESTDIR4);
175 }
176
rmdir_verify(struct test_case_t * tc)177 static void rmdir_verify(struct test_case_t *tc)
178 {
179 TEST(rmdir(tc->dir));
180
181 if (TEST_RETURN != -1) {
182 tst_resm(TFAIL, "rmdir() returned %ld, "
183 "expected -1, errno:%d", TEST_RETURN,
184 tc->exp_errno);
185 return;
186 }
187
188 if (TEST_ERRNO == tc->exp_errno) {
189 tst_resm(TPASS | TTERRNO, "rmdir() failed as expected");
190 } else {
191 tst_resm(TFAIL | TTERRNO,
192 "rmdir() failed unexpectedly; expected: %d - %s",
193 tc->exp_errno, strerror(tc->exp_errno));
194 }
195 }
196
cleanup(void)197 static void cleanup(void)
198 {
199 if (mount_flag && tst_umount(MNTPOINT) == -1)
200 tst_resm(TWARN | TERRNO, "umount %s failed", MNTPOINT);
201
202 if (device)
203 tst_release_device(device);
204
205 tst_rmdir();
206 }
207