blob: 0cec2c1b23ca1011ba65e572ddd162b9849744a4 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
plars865695b2001-08-27 22:15:12 +00002 * Copyright (c) International Business Machines Corp., 2001
zenglg.jyaa230562013-12-03 15:58:05 +08003 * Ported by Wayne Boyer
plars865695b2001-08-27 22:15:12 +00004 *
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
zenglg.jyaa230562013-12-03 15:58:05 +080016 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
plars865695b2001-08-27 22:15:12 +000021 * DESCRIPTION
22 * Testcase to check creat(2) sets the following errnos correctly:
23 * 1. EISDIR
24 * 2. ENAMETOOLONG
25 * 3. ENOENT
26 * 4. ENOTDIR
27 * 5. EFAULT
28 * 6. EACCES
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080029 * 7. ELOOP
30 * 8. EROFS
plars865695b2001-08-27 22:15:12 +000031 *
zenglg.jyaa230562013-12-03 15:58:05 +080032 *
plars865695b2001-08-27 22:15:12 +000033 * ALGORITHM
34 * 1. Attempt to creat(2) an existing directory, and test for
35 * EISDIR
36 * 2. Attempt to creat(2) a file whose name is more than
37 * VFS_MAXNAMLEN and test for ENAMETOOLONG.
38 * 3. Attempt to creat(2) a file inside a directory which doesn't
39 * exist, and test for ENOENT
40 * 4. Attempt to creat(2) a file, the pathname of which comprises
41 * a component which is a file, test for ENOTDIR.
42 * 5. Attempt to creat(2) a file with a bad address
43 * and test for EFAULT
44 * 6. Attempt to creat(2) a file in a directory with no
45 * execute permission and test for EACCES
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080046 * 7. Attempt to creat(2) a file which links the other file that
47 * links the former and test for ELOOP
48 * 8. Attempt to creat(2) a file in a Read-only file system
49 * and test for EROFS
plars865695b2001-08-27 22:15:12 +000050 */
51
52#include <stdio.h>
53#include <errno.h>
54#include <string.h>
robbiewe003b8c2001-08-31 15:41:20 +000055#include <pwd.h>
plars1ad84512002-07-23 13:11:18 +000056#include <sys/mman.h>
plars74948ad2002-11-14 16:16:14 +000057#include <sys/types.h>
robbiew2c945242002-11-11 19:01:25 +000058#include <sys/stat.h>
59#include <fcntl.h>
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080060#include <sys/mount.h>
plars865695b2001-08-27 22:15:12 +000061#include "test.h"
62#include "usctest.h"
zenglg.jyaa230562013-12-03 15:58:05 +080063#include "safe_macros.h"
plars865695b2001-08-27 22:15:12 +000064
zenglg.jyaa230562013-12-03 15:58:05 +080065#define TEST_FILE "test_dir"
66#define NO_DIR "testfile/testdir"
67#define NOT_DIR "file1/testdir"
68#define TEST6_FILE "dir6/file6"
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080069#define TEST7_FILE "file7"
70#define TEST8_FILE "mntpoint/tmp"
plars865695b2001-08-27 22:15:12 +000071
zenglg.jyaa230562013-12-03 15:58:05 +080072#define MODE1 0444
73#define MODE2 0666
plars865695b2001-08-27 22:15:12 +000074
zenglg.jyaa230562013-12-03 15:58:05 +080075static void setup(void);
76static void cleanup(void);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080077static void test6_setup(void);
78static void test6_cleanup(void);
zenglg.jyaa230562013-12-03 15:58:05 +080079#if !defined(UCLINUX)
80static void bad_addr_setup(int);
81#endif
plars865695b2001-08-27 22:15:12 +000082
zenglg.jyaa230562013-12-03 15:58:05 +080083static char long_name[PATH_MAX+2];
Cyril Hrubis4e74c992014-06-19 16:53:51 +020084static const char *device;
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080085static int mount_flag;
Cyril Hrubis4e74c992014-06-19 16:53:51 +020086
zenglg.jyaa230562013-12-03 15:58:05 +080087static struct test_case_t {
plars865695b2001-08-27 22:15:12 +000088 char *fname;
89 int mode;
90 int error;
zenglg.jyaa230562013-12-03 15:58:05 +080091 void (*setup)();
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080092 void (*cleanup)(void);
plars865695b2001-08-27 22:15:12 +000093} TC[] = {
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080094 {TEST_FILE, MODE1, EISDIR, NULL, NULL},
95 {long_name, MODE1, ENAMETOOLONG, NULL, NULL},
96 {NO_DIR, MODE1, ENOENT, NULL, NULL},
97 {NOT_DIR, MODE1, ENOTDIR, NULL, NULL},
vapierb5ed1f62006-08-24 04:16:32 +000098#if !defined(UCLINUX)
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080099 {NULL, MODE1, EFAULT, bad_addr_setup, NULL},
vapierb5ed1f62006-08-24 04:16:32 +0000100#endif
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800101 {TEST6_FILE, MODE1, EACCES, test6_setup, test6_cleanup},
102 {TEST7_FILE, MODE1, ELOOP, NULL, NULL},
103 {TEST8_FILE, MODE1, EROFS, NULL, NULL},
plars865695b2001-08-27 22:15:12 +0000104};
105
zenglg.jyaa230562013-12-03 15:58:05 +0800106char *TCID = "creat06";
107int TST_TOTAL = ARRAY_SIZE(TC);
108static int exp_enos[] = { EISDIR, ENAMETOOLONG, ENOENT, ENOTDIR,
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800109 EFAULT, EACCES, ELOOP, EROFS, 0 };
110static struct passwd *ltpuser;
plars1ad84512002-07-23 13:11:18 +0000111
subrata_modak56207ce2009-03-23 13:35:39 +0000112int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000113{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200114 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200115 const char *msg;
plars865695b2001-08-27 22:15:12 +0000116 int i;
117
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200118 msg = parse_opts(ac, av, NULL, NULL);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800119 if (msg != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800120 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000121
122 setup();
123
plars865695b2001-08-27 22:15:12 +0000124 TEST_EXP_ENOS(exp_enos);
125
plars865695b2001-08-27 22:15:12 +0000126 for (lc = 0; TEST_LOOPING(lc); lc++) {
127
Caspar Zhangd59a6592013-03-07 14:59:12 +0800128 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000129
plars865695b2001-08-27 22:15:12 +0000130 for (i = 0; i < TST_TOTAL; i++) {
131
zenglg.jyaa230562013-12-03 15:58:05 +0800132 if (TC[i].setup != NULL)
133 TC[i].setup(i);
134
plars865695b2001-08-27 22:15:12 +0000135 TEST(creat(TC[i].fname, TC[i].mode));
136
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800137 if (TC[i].cleanup != NULL)
138 TC[i].cleanup();
139
plars865695b2001-08-27 22:15:12 +0000140 if (TEST_RETURN != -1) {
141 tst_resm(TFAIL, "call succeeded unexpectedly");
142 continue;
143 }
144
plars865695b2001-08-27 22:15:12 +0000145 if (TEST_ERRNO == TC[i].error) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800146 tst_resm(TPASS | TTERRNO,
147 "got expected failure");
plars865695b2001-08-27 22:15:12 +0000148 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800149 tst_resm(TFAIL | TTERRNO, "wanted errno %d",
150 TC[i].error);
plars865695b2001-08-27 22:15:12 +0000151 }
152 }
153 }
zenglg.jyaa230562013-12-03 15:58:05 +0800154
plars865695b2001-08-27 22:15:12 +0000155 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800156 tst_exit();
Garrett Cooper87bc45c2010-12-17 01:56:08 -0800157}
plars865695b2001-08-27 22:15:12 +0000158
zenglg.jyaa230562013-12-03 15:58:05 +0800159static void setup(void)
plars865695b2001-08-27 22:15:12 +0000160{
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200161 const char *fs_type;
162
Garrett Cooper87bc45c2010-12-17 01:56:08 -0800163 tst_require_root(NULL);
164
zenglg.jyaa230562013-12-03 15:58:05 +0800165 ltpuser = SAFE_GETPWNAM(cleanup, "nobody");
166
plars865695b2001-08-27 22:15:12 +0000167 tst_sig(NOFORK, DEF_HANDLER, cleanup);
168
plars865695b2001-08-27 22:15:12 +0000169 TEST_PAUSE;
170
plars865695b2001-08-27 22:15:12 +0000171 tst_tmpdir();
172
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200173 fs_type = tst_dev_fs_type();
174 device = tst_acquire_device(cleanup);
175
176 if (!device)
177 tst_brkm(TCONF, cleanup, "Failed to acquire device");
178
zenglg.jyaa230562013-12-03 15:58:05 +0800179 SAFE_MKDIR(cleanup, TEST_FILE, MODE2);
plars865695b2001-08-27 22:15:12 +0000180
zenglg.jyaa230562013-12-03 15:58:05 +0800181 memset(long_name, 'a', PATH_MAX+1);
plars865695b2001-08-27 22:15:12 +0000182
zenglg.jyaa230562013-12-03 15:58:05 +0800183 SAFE_TOUCH(cleanup, "file1", MODE1, NULL);
plars1ad84512002-07-23 13:11:18 +0000184
zenglg.jyaa230562013-12-03 15:58:05 +0800185 SAFE_MKDIR(cleanup, "dir6", MODE2);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800186
187 SAFE_SYMLINK(cleanup, TEST7_FILE, "test_file_eloop2");
188 SAFE_SYMLINK(cleanup, "test_file_eloop2", TEST7_FILE);
189
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200190 tst_mkfs(cleanup, device, fs_type, NULL);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800191 SAFE_MKDIR(cleanup, "mntpoint", 0777);
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200192 if (mount(device, "mntpoint", fs_type, MS_RDONLY, NULL) < 0) {
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800193 tst_brkm(TBROK | TERRNO, cleanup,
194 "mount device:%s failed", device);
195 }
196 mount_flag = 1;
plars865695b2001-08-27 22:15:12 +0000197}
198
zenglg.jyaa230562013-12-03 15:58:05 +0800199#if !defined(UCLINUX)
200static void bad_addr_setup(int i)
plars865695b2001-08-27 22:15:12 +0000201{
zenglg.jyaa230562013-12-03 15:58:05 +0800202 TC[i].fname = SAFE_MMAP(cleanup, 0, 1, PROT_NONE,
203 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
204}
205#endif
mridge12952b02004-08-25 15:17:15 +0000206
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800207static void test6_setup(void)
208{
209 SAFE_SETEUID(cleanup, ltpuser->pw_uid);
210}
211
212static void test6_cleanup(void)
213{
214 SAFE_SETEUID(cleanup, 0);
215}
216
zenglg.jyaa230562013-12-03 15:58:05 +0800217static void cleanup(void)
218{
plars865695b2001-08-27 22:15:12 +0000219 TEST_CLEANUP;
220
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800221 if (mount_flag && umount("mntpoint") < 0) {
222 tst_brkm(TBROK | TERRNO, NULL,
223 "umount device:%s failed", device);
224 }
225
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200226 if (device)
227 tst_release_device(NULL, device);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800228
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200229 tst_rmdir();
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800230}