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