1// SPDX-License-Identifier: GPL-2.0-or-later 2/* Copyright (c) International Business Machines Corp., 2001 3 * Ported to LTP: Wayne Boyer 4 */ 5/* 6 * Description: 7 * 1) attempt to rmdir() non-empty directory -> ENOTEMPTY 8 * 2) attempt to rmdir() directory with long path name -> ENAMETOOLONG 9 * 3) attempt to rmdir() non-existing directory -> ENOENT 10 * 4) attempt to rmdir() a file -> ENOTDIR 11 * 5) attempt to rmdir() invalid pointer -> EFAULT 12 * 6) attempt to rmdir() symlink loop -> ELOOP 13 * 7) attempt to rmdir() dir on RO mounted FS -> EROFS 14 * 8) attempt to rmdir() mount point -> EBUSY 15 * 9) attempt to rmdir() current directory "." -> EINVAL 16 */ 17 18#include <errno.h> 19 20#include "tst_test.h" 21 22#define DIR_MODE (S_IRWXU | S_IRWXG | S_IRWXO) 23#define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO) 24 25#define TESTDIR "testdir" 26#define TESTDIR2 "nosuchdir/testdir2" 27#define TESTDIR3 "testfile2/testdir3" 28#define TESTDIR4 "/loopdir" 29#define MNT_POINT "mntpoint" 30#define TESTDIR5 "mntpoint/dir" 31#define TESTFILE "testdir/testfile" 32#define TESTFILE2 "testfile2" 33 34static char longpathname[PATH_MAX + 2]; 35static char looppathname[sizeof(TESTDIR4) * 43] = "."; 36 37static struct testcase { 38 char *dir; 39 int exp_errno; 40} tcases[] = { 41 {TESTDIR, ENOTEMPTY}, 42 {longpathname, ENAMETOOLONG}, 43 {TESTDIR2, ENOENT}, 44 {TESTDIR3, ENOTDIR}, 45 {NULL, EFAULT}, 46 {looppathname, ELOOP}, 47 {TESTDIR5, EROFS}, 48 {MNT_POINT, EBUSY}, 49 {".", EINVAL} 50}; 51 52static void setup(void) 53{ 54 unsigned int i; 55 56 SAFE_MKDIR(TESTDIR, DIR_MODE); 57 SAFE_TOUCH(TESTFILE, FILE_MODE, NULL); 58 59 memset(longpathname, 'a', PATH_MAX + 1); 60 61 SAFE_TOUCH(TESTFILE2, FILE_MODE, NULL); 62 63 for (i = 0; i < ARRAY_SIZE(tcases); i++) { 64 if (!tcases[i].dir) 65 tcases[i].dir = tst_get_bad_addr(NULL); 66 } 67 68 /* 69 * NOTE: the ELOOP test is written based on that the 70 * consecutive symlinks limit in kernel is hardwired 71 * to 40. 72 */ 73 SAFE_MKDIR("loopdir", DIR_MODE); 74 SAFE_SYMLINK("../loopdir", "loopdir/loopdir"); 75 for (i = 0; i < 43; i++) 76 strcat(looppathname, TESTDIR4); 77} 78 79static void verify_rmdir(unsigned int n) 80{ 81 struct testcase *tc = &tcases[n]; 82 83 TEST(rmdir(tc->dir)); 84 85 if (TST_RET != -1) { 86 tst_res(TFAIL, "rmdir() succeeded unexpectedly (%li)", 87 TST_RET); 88 return; 89 } 90 91 if (TST_ERR == tc->exp_errno) { 92 tst_res(TPASS | TTERRNO, "rmdir() failed as expected"); 93 return; 94 } 95 96 tst_res(TFAIL | TTERRNO, 97 "rmdir() failed unexpectedly; expected: %d - %s", 98 tc->exp_errno, tst_strerrno(tc->exp_errno)); 99} 100 101static struct tst_test test = { 102 .setup = setup, 103 .tcnt = ARRAY_SIZE(tcases), 104 .test = verify_rmdir, 105 .needs_root = 1, 106 .needs_rofs = 1, 107 .mntpoint = MNT_POINT, 108}; 109