blob: 95827021c93dd0e339b9cec60a336e6fb0b08fb0 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +00002 * Copyright (c) International Business Machines Corp., 2001
3 * 07/2001 Ported by Wayne Boyer
plars865695b2001-08-27 22:15:12 +00004 *
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +00005 * 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.
plars865695b2001-08-27 22:15:12 +00009 *
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000010 * 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.
plars865695b2001-08-27 22:15:12 +000014 *
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000015 * 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:
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +000021 * 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.
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000026 * 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.
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +000038 * 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.
plars865695b2001-08-27 22:15:12 +000046 */
47
plars865695b2001-08-27 22:15:12 +000048#include <errno.h>
49#include <sys/stat.h>
50#include <sys/types.h>
plars1ad84512002-07-23 13:11:18 +000051#include <sys/mman.h>
plars865695b2001-08-27 22:15:12 +000052#include <fcntl.h>
53#include <unistd.h>
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +000054#include <pwd.h>
55#include <sys/mount.h>
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000056
subrata_modak4bb656a2009-02-26 12:02:09 +000057#include "test.h"
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000058#include "safe_macros.h"
plars865695b2001-08-27 22:15:12 +000059
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000060#define DIR_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
61#define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
plars865695b2001-08-27 22:15:12 +000062
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000063#define TESTDIR "testdir"
64#define TESTDIR2 "nosuchdir/testdir2"
65#define TESTDIR3 "testfile2/testdir3"
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +000066#define TESTDIR4 "/loopdir"
67#define MNTPOINT "mntpoint"
68#define TESTDIR5 "mntpoint/testdir5"
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000069#define TESTFILE "testdir/testfile"
70#define TESTFILE2 "testfile2"
plars865695b2001-08-27 22:15:12 +000071
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000072static char longpathname[PATH_MAX + 2];
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +000073static char looppathname[sizeof(TESTDIR4) * 43] = ".";
74
Cyril Hrubis76005632014-06-19 17:51:17 +020075static const char *device;
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +000076static int mount_flag;
77
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000078static struct test_case_t {
plars865695b2001-08-27 22:15:12 +000079 char *dir;
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000080 int exp_errno;
81} test_cases[] = {
82 {TESTDIR, ENOTEMPTY},
83 {longpathname, ENAMETOOLONG},
84 {TESTDIR2, ENOENT},
85 {TESTDIR3, ENOTDIR},
vapierb5ed1f62006-08-24 04:16:32 +000086#if !defined(UCLINUX)
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000087 {(char *)-1, EFAULT},
vapierb5ed1f62006-08-24 04:16:32 +000088#endif
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000089 {NULL, EFAULT},
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +000090 {looppathname, ELOOP},
91 {TESTDIR5, EROFS},
92 {MNTPOINT, EBUSY},
plars865695b2001-08-27 22:15:12 +000093};
Wanlong Gao354ebb42012-12-07 10:10:04 +080094
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +000095static void setup(void);
96static void rmdir_verify(struct test_case_t *tc);
97static void cleanup(void);
98
99char *TCID = "rmdir02";
100int TST_TOTAL = ARRAY_SIZE(test_cases);
plars865695b2001-08-27 22:15:12 +0000101
subrata_modak56207ce2009-03-23 13:35:39 +0000102int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000103{
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000104 int i, lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200105 const char *msg;
plars865695b2001-08-27 22:15:12 +0000106
Cyril Hrubis76005632014-06-19 17:51:17 +0200107 msg = parse_opts(ac, av, NULL, NULL);
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000108 if (msg != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800109 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000110
plars865695b2001-08-27 22:15:12 +0000111 setup();
subrata_modakbdbaec52009-02-26 12:14:51 +0000112
subrata_modak56207ce2009-03-23 13:35:39 +0000113 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800114 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000115
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000116 for (i = 0; i < TST_TOTAL; i++)
117 rmdir_verify(&test_cases[i]);
Garrett Cooper2c282152010-12-16 00:55:50 -0800118 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000119
plars865695b2001-08-27 22:15:12 +0000120 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800121 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800122}
plars865695b2001-08-27 22:15:12 +0000123
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000124static void setup(void)
plars865695b2001-08-27 22:15:12 +0000125{
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000126 int i;
Cyril Hrubis76005632014-06-19 17:51:17 +0200127 const char *fs_type;
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000128
129 tst_require_root(NULL);
130
plars865695b2001-08-27 22:15:12 +0000131 tst_sig(NOFORK, DEF_HANDLER, cleanup);
vapierb5ed1f62006-08-24 04:16:32 +0000132
plars865695b2001-08-27 22:15:12 +0000133 TEST_PAUSE;
134
plars865695b2001-08-27 22:15:12 +0000135 tst_tmpdir();
plars1ad84512002-07-23 13:11:18 +0000136
Cyril Hrubis76005632014-06-19 17:51:17 +0200137 fs_type = tst_dev_fs_type();
138 device = tst_acquire_device(cleanup);
139
140 if (!device)
141 tst_brkm(TCONF, cleanup, "Failed to acquire device");
142
143 tst_mkfs(cleanup, device, fs_type, NULL);
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000144 SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE);
Cyril Hrubis76005632014-06-19 17:51:17 +0200145 if (mount(device, MNTPOINT, fs_type, 0, NULL) == -1) {
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000146 tst_brkm(TBROK | TERRNO, cleanup,
147 "mount device:%s failed", device);
148 }
149 SAFE_MKDIR(cleanup, TESTDIR5, DIR_MODE);
Cyril Hrubis76005632014-06-19 17:51:17 +0200150 if (mount(device, MNTPOINT, fs_type, MS_REMOUNT | MS_RDONLY,
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000151 NULL) == -1) {
152 tst_brkm(TBROK | TERRNO, cleanup,
153 "mount device:%s failed", device);
154 }
155 mount_flag = 1;
156
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000157 SAFE_MKDIR(cleanup, TESTDIR, DIR_MODE);
158 SAFE_TOUCH(cleanup, TESTFILE, FILE_MODE, NULL);
159
160 memset(longpathname, 'a', PATH_MAX + 1);
161
162 SAFE_TOUCH(cleanup, TESTFILE2, FILE_MODE, NULL);
163
vapier62b16cf2007-02-09 20:48:23 +0000164#if !defined(UCLINUX)
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000165 test_cases[4].dir = SAFE_MMAP(cleanup, 0, 1, PROT_NONE,
166 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
vapierb5ed1f62006-08-24 04:16:32 +0000167#endif
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000168
169 /*
170 * NOTE: the ELOOP test is written based on that the
171 * consecutive symlinks limit in kernel is hardwired
172 * to 40.
173 */
174 SAFE_MKDIR(cleanup, "loopdir", DIR_MODE);
175 SAFE_SYMLINK(cleanup, "../loopdir", "loopdir/loopdir");
176 for (i = 0; i < 43; i++)
177 strcat(looppathname, TESTDIR4);
plars865695b2001-08-27 22:15:12 +0000178}
179
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000180static void rmdir_verify(struct test_case_t *tc)
plars865695b2001-08-27 22:15:12 +0000181{
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000182 TEST(rmdir(tc->dir));
183
184 if (TEST_RETURN != -1) {
185 tst_resm(TFAIL, "rmdir() returned %ld, "
186 "expected -1, errno:%d", TEST_RETURN,
187 tc->exp_errno);
188 return;
189 }
190
gux.fnst@cn.fujitsu.com19ec7752014-04-17 10:50:23 +0000191 if (TEST_ERRNO == tc->exp_errno) {
192 tst_resm(TPASS | TTERRNO, "rmdir() failed as expected");
193 } else {
194 tst_resm(TFAIL | TTERRNO,
195 "rmdir() failed unexpectedly; expected: %d - %s",
196 tc->exp_errno, strerror(tc->exp_errno));
197 }
198}
199
200static void cleanup(void)
201{
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100202 if (mount_flag && tst_umount(MNTPOINT) == -1)
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000203 tst_resm(TWARN | TERRNO, "umount %s failed", MNTPOINT);
204
Cyril Hrubis76005632014-06-19 17:51:17 +0200205 if (device)
206 tst_release_device(NULL, device);
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000207
Cyril Hrubis76005632014-06-19 17:51:17 +0200208 tst_rmdir();
gux.fnst@cn.fujitsu.comcce06402014-04-17 10:50:24 +0000209}