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 "tst_test.h" 33 34 #define TST_EEXIST "tst_eexist" 35 #define TST_ENOENT "tst_enoent/tst" 36 #define TST_ENOTDIR_FILE "tst_enotdir" 37 #define TST_ENOTDIR_DIR "tst_enotdir/tst" 38 #define MODE 0777 39 40 #define MNT_POINT "mntpoint" 41 #define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \ 42 S_IXGRP|S_IROTH|S_IXOTH) 43 #define TST_EROFS "mntpoint/tst_erofs" 44 45 static char long_dir[PATH_MAX + 2] = {[0 ... PATH_MAX + 1] = 'a'}; 46 static char loop_dir[PATH_MAX] = "."; 47 48 struct tcase; 49 static void prot_none_pathname(struct tcase *tc); 50 51 static struct tcase { 52 char *pathname; 53 int exp_errno; 54 void (*setupfunc)(struct tcase *tc); 55 } TC[] = { 56 {NULL, EFAULT, prot_none_pathname}, 57 {long_dir, ENAMETOOLONG, NULL}, 58 {TST_EEXIST, EEXIST, NULL}, 59 {TST_ENOENT, ENOENT, NULL}, 60 {TST_ENOTDIR_DIR, ENOTDIR, NULL}, 61 {loop_dir, ELOOP, NULL}, 62 {TST_EROFS, EROFS, NULL}, 63 }; 64 65 static void verify_mkdir(unsigned int n) 66 { 67 struct tcase *tc = TC + n; 68 69 TEST(mkdir(tc->pathname, MODE)); 70 if (TEST_RETURN != -1) { 71 tst_res(TFAIL, "mkdir() returned %ld, expected -1, errno=%d", 72 TEST_RETURN, tc->exp_errno); 73 return; 74 } 75 76 if (TEST_ERRNO == tc->exp_errno) { 77 tst_res(TPASS | TTERRNO, "mkdir() failed as expected"); 78 } else { 79 tst_res(TFAIL | TTERRNO, 80 "mkdir() failed unexpectedly; expected: %d - %s", 81 tc->exp_errno, strerror(tc->exp_errno)); 82 } 83 } 84 85 static void prot_none_pathname(struct tcase *tc) 86 { 87 tc->pathname = SAFE_MMAP(0, 1, PROT_NONE, 88 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 89 } 90 91 static void setup(void) 92 { 93 unsigned int i; 94 95 SAFE_TOUCH(TST_EEXIST, MODE, NULL); 96 SAFE_TOUCH(TST_ENOTDIR_FILE, MODE, NULL); 97 98 SAFE_MKDIR("test_eloop", DIR_MODE); 99 SAFE_SYMLINK("../test_eloop", "test_eloop/test_eloop"); 100 for (i = 0; i < 43; i++) 101 strcat(loop_dir, "/test_eloop"); 102 103 for (i = 0; i < ARRAY_SIZE(TC); i++) { 104 if (TC[i].setupfunc) 105 TC[i].setupfunc(&TC[i]); 106 } 107 } 108 109 static struct tst_test test = { 110 .tcnt = ARRAY_SIZE(TC), 111 .needs_tmpdir = 1, 112 .needs_root = 1, 113 .needs_rofs = 1, 114 .mntpoint = MNT_POINT, 115 .setup = setup, 116 .test = verify_mkdir, 117 }; 118