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 * check mkdir() with various error conditions that should produce 22 * EFAULT, ENAMETOOLONG, EEXIST, ENOENT, ENOTDIR, ELOOP and EROFS 23 */ 24 25 #include <errno.h> 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #include <sys/mman.h> 29 #include <fcntl.h> 30 #include <sys/mount.h> 31 32 #include "test.h" 33 #include "safe_macros.h" 34 35 static void setup(void); 36 struct test_case_t; 37 static void mkdir_verify(struct test_case_t *tc); 38 static void bad_addr_setup(struct test_case_t *tc); 39 static void cleanup(void); 40 static int mount_flag; 41 42 #define TST_EEXIST "tst_eexist" 43 #define TST_ENOENT "tst_enoent/tst" 44 #define TST_ENOTDIR "tst_enotdir/tst" 45 #define MODE 0777 46 47 #define MNT_POINT "mntpoint" 48 #define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \ 49 S_IXGRP|S_IROTH|S_IXOTH) 50 #define TST_EROFS "mntpoint/tst_erofs" 51 52 char *TCID = "mkdir03"; 53 54 static char long_dir[PATH_MAX+2]; 55 static char loop_dir[PATH_MAX] = "."; 56 static const char *device; 57 58 static struct test_case_t { 59 char *pathname; 60 int mode; 61 int exp_errno; 62 void (*setupfunc) (struct test_case_t *tc); 63 } TC[] = { 64 #if !defined(UCLINUX) 65 {NULL, MODE, EFAULT, bad_addr_setup}, 66 #endif 67 {long_dir, MODE, ENAMETOOLONG, NULL}, 68 {TST_EEXIST, MODE, EEXIST, NULL}, 69 {TST_ENOENT, MODE, ENOENT, NULL}, 70 {TST_ENOTDIR, MODE, ENOTDIR, NULL}, 71 {loop_dir, MODE, ELOOP, NULL}, 72 {TST_EROFS, MODE, EROFS, NULL}, 73 }; 74 75 int TST_TOTAL = ARRAY_SIZE(TC); 76 77 int main(int ac, char **av) 78 { 79 int i, lc; 80 81 tst_parse_opts(ac, av, NULL, NULL); 82 83 setup(); 84 85 for (lc = 0; TEST_LOOPING(lc); lc++) { 86 tst_count = 0; 87 for (i = 0; i < TST_TOTAL; i++) 88 mkdir_verify(&TC[i]); 89 } 90 91 cleanup(); 92 tst_exit(); 93 } 94 95 static void setup(void) 96 { 97 int i; 98 const char *fs_type; 99 100 tst_require_root(); 101 102 tst_sig(NOFORK, DEF_HANDLER, cleanup); 103 104 TEST_PAUSE; 105 106 tst_tmpdir(); 107 108 fs_type = tst_dev_fs_type(); 109 device = tst_acquire_device(cleanup); 110 111 if (!device) 112 tst_brkm(TCONF, cleanup, "Failed to acquire device"); 113 114 memset(long_dir, 'a', PATH_MAX+1); 115 116 SAFE_TOUCH(cleanup, TST_EEXIST, MODE, NULL); 117 118 SAFE_TOUCH(cleanup, "tst_enotdir", MODE, NULL); 119 120 SAFE_MKDIR(cleanup, "test_eloop", DIR_MODE); 121 SAFE_SYMLINK(cleanup, "../test_eloop", "test_eloop/test_eloop"); 122 for (i = 0; i < 43; i++) 123 strcat(loop_dir, "/test_eloop"); 124 125 tst_mkfs(cleanup, device, fs_type, NULL, NULL); 126 SAFE_MKDIR(cleanup, MNT_POINT, DIR_MODE); 127 if (mount(device, MNT_POINT, fs_type, MS_RDONLY, NULL) < 0) { 128 tst_brkm(TBROK | TERRNO, cleanup, 129 "mount device:%s failed", device); 130 } 131 mount_flag = 1; 132 } 133 134 #if !defined(UCLINUX) 135 static void bad_addr_setup(struct test_case_t *tc) 136 { 137 tc->pathname = SAFE_MMAP(cleanup, 0, 1, PROT_NONE, 138 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 139 } 140 #endif 141 142 static void mkdir_verify(struct test_case_t *tc) 143 { 144 if (tc->setupfunc != NULL) 145 tc->setupfunc(tc); 146 147 TEST(mkdir(tc->pathname, tc->mode)); 148 149 if (TEST_RETURN != -1) { 150 tst_resm(TFAIL, "mkdir() returned %ld, expected -1, errno=%d", 151 TEST_RETURN, tc->exp_errno); 152 return; 153 } 154 155 if (TEST_ERRNO == tc->exp_errno) { 156 tst_resm(TPASS | TTERRNO, "mkdir() failed as expected"); 157 } else { 158 tst_resm(TFAIL | TTERRNO, 159 "mkdir() failed unexpectedly; expected: %d - %s", 160 tc->exp_errno, strerror(tc->exp_errno)); 161 } 162 } 163 164 static void cleanup(void) 165 { 166 if (mount_flag && tst_umount(MNT_POINT) < 0) 167 tst_resm(TWARN | TERRNO, "umount device:%s failed", device); 168 169 if (device) 170 tst_release_device(device); 171 172 tst_rmdir(); 173 } 174