blob: 0989a99053eea22b68b93221a83c79c9c9007fb4 [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"
zenglg.jyaa230562013-12-03 15:58:05 +080062#include "safe_macros.h"
plars865695b2001-08-27 22:15:12 +000063
zenglg.jyaa230562013-12-03 15:58:05 +080064#define TEST_FILE "test_dir"
65#define NO_DIR "testfile/testdir"
66#define NOT_DIR "file1/testdir"
67#define TEST6_FILE "dir6/file6"
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080068#define TEST7_FILE "file7"
69#define TEST8_FILE "mntpoint/tmp"
plars865695b2001-08-27 22:15:12 +000070
zenglg.jyaa230562013-12-03 15:58:05 +080071#define MODE1 0444
72#define MODE2 0666
plars865695b2001-08-27 22:15:12 +000073
zenglg.jyaa230562013-12-03 15:58:05 +080074static void setup(void);
75static void cleanup(void);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080076static void test6_setup(void);
77static void test6_cleanup(void);
zenglg.jyaa230562013-12-03 15:58:05 +080078#if !defined(UCLINUX)
79static void bad_addr_setup(int);
80#endif
plars865695b2001-08-27 22:15:12 +000081
zenglg.jyaa230562013-12-03 15:58:05 +080082static char long_name[PATH_MAX+2];
Cyril Hrubis4e74c992014-06-19 16:53:51 +020083static const char *device;
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080084static int mount_flag;
Cyril Hrubis4e74c992014-06-19 16:53:51 +020085
zenglg.jyaa230562013-12-03 15:58:05 +080086static struct test_case_t {
plars865695b2001-08-27 22:15:12 +000087 char *fname;
88 int mode;
89 int error;
zenglg.jyaa230562013-12-03 15:58:05 +080090 void (*setup)();
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080091 void (*cleanup)(void);
plars865695b2001-08-27 22:15:12 +000092} TC[] = {
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080093 {TEST_FILE, MODE1, EISDIR, NULL, NULL},
94 {long_name, MODE1, ENAMETOOLONG, NULL, NULL},
95 {NO_DIR, MODE1, ENOENT, NULL, NULL},
96 {NOT_DIR, MODE1, ENOTDIR, NULL, NULL},
vapierb5ed1f62006-08-24 04:16:32 +000097#if !defined(UCLINUX)
Zeng Linggang6f0b85f2014-01-20 17:16:58 +080098 {NULL, MODE1, EFAULT, bad_addr_setup, NULL},
vapierb5ed1f62006-08-24 04:16:32 +000099#endif
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800100 {TEST6_FILE, MODE1, EACCES, test6_setup, test6_cleanup},
101 {TEST7_FILE, MODE1, ELOOP, NULL, NULL},
102 {TEST8_FILE, MODE1, EROFS, NULL, NULL},
plars865695b2001-08-27 22:15:12 +0000103};
104
zenglg.jyaa230562013-12-03 15:58:05 +0800105char *TCID = "creat06";
106int TST_TOTAL = ARRAY_SIZE(TC);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800107static struct passwd *ltpuser;
plars1ad84512002-07-23 13:11:18 +0000108
subrata_modak56207ce2009-03-23 13:35:39 +0000109int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000110{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200111 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200112 const char *msg;
plars865695b2001-08-27 22:15:12 +0000113 int i;
114
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200115 msg = parse_opts(ac, av, NULL, NULL);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800116 if (msg != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800117 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000118
119 setup();
120
plars865695b2001-08-27 22:15:12 +0000121 for (lc = 0; TEST_LOOPING(lc); lc++) {
122
Caspar Zhangd59a6592013-03-07 14:59:12 +0800123 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000124
plars865695b2001-08-27 22:15:12 +0000125 for (i = 0; i < TST_TOTAL; i++) {
126
zenglg.jyaa230562013-12-03 15:58:05 +0800127 if (TC[i].setup != NULL)
128 TC[i].setup(i);
129
plars865695b2001-08-27 22:15:12 +0000130 TEST(creat(TC[i].fname, TC[i].mode));
131
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800132 if (TC[i].cleanup != NULL)
133 TC[i].cleanup();
134
plars865695b2001-08-27 22:15:12 +0000135 if (TEST_RETURN != -1) {
136 tst_resm(TFAIL, "call succeeded unexpectedly");
137 continue;
138 }
139
plars865695b2001-08-27 22:15:12 +0000140 if (TEST_ERRNO == TC[i].error) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800141 tst_resm(TPASS | TTERRNO,
142 "got expected failure");
plars865695b2001-08-27 22:15:12 +0000143 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800144 tst_resm(TFAIL | TTERRNO, "wanted errno %d",
145 TC[i].error);
plars865695b2001-08-27 22:15:12 +0000146 }
147 }
148 }
zenglg.jyaa230562013-12-03 15:58:05 +0800149
plars865695b2001-08-27 22:15:12 +0000150 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800151 tst_exit();
Garrett Cooper87bc45c2010-12-17 01:56:08 -0800152}
plars865695b2001-08-27 22:15:12 +0000153
zenglg.jyaa230562013-12-03 15:58:05 +0800154static void setup(void)
plars865695b2001-08-27 22:15:12 +0000155{
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200156 const char *fs_type;
157
Garrett Cooper87bc45c2010-12-17 01:56:08 -0800158 tst_require_root(NULL);
159
zenglg.jyaa230562013-12-03 15:58:05 +0800160 ltpuser = SAFE_GETPWNAM(cleanup, "nobody");
161
plars865695b2001-08-27 22:15:12 +0000162 tst_sig(NOFORK, DEF_HANDLER, cleanup);
163
plars865695b2001-08-27 22:15:12 +0000164 TEST_PAUSE;
165
plars865695b2001-08-27 22:15:12 +0000166 tst_tmpdir();
167
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200168 fs_type = tst_dev_fs_type();
169 device = tst_acquire_device(cleanup);
170
171 if (!device)
172 tst_brkm(TCONF, cleanup, "Failed to acquire device");
173
zenglg.jyaa230562013-12-03 15:58:05 +0800174 SAFE_MKDIR(cleanup, TEST_FILE, MODE2);
plars865695b2001-08-27 22:15:12 +0000175
zenglg.jyaa230562013-12-03 15:58:05 +0800176 memset(long_name, 'a', PATH_MAX+1);
plars865695b2001-08-27 22:15:12 +0000177
zenglg.jyaa230562013-12-03 15:58:05 +0800178 SAFE_TOUCH(cleanup, "file1", MODE1, NULL);
plars1ad84512002-07-23 13:11:18 +0000179
zenglg.jyaa230562013-12-03 15:58:05 +0800180 SAFE_MKDIR(cleanup, "dir6", MODE2);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800181
182 SAFE_SYMLINK(cleanup, TEST7_FILE, "test_file_eloop2");
183 SAFE_SYMLINK(cleanup, "test_file_eloop2", TEST7_FILE);
184
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200185 tst_mkfs(cleanup, device, fs_type, NULL);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800186 SAFE_MKDIR(cleanup, "mntpoint", 0777);
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200187 if (mount(device, "mntpoint", fs_type, MS_RDONLY, NULL) < 0) {
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800188 tst_brkm(TBROK | TERRNO, cleanup,
189 "mount device:%s failed", device);
190 }
191 mount_flag = 1;
plars865695b2001-08-27 22:15:12 +0000192}
193
zenglg.jyaa230562013-12-03 15:58:05 +0800194#if !defined(UCLINUX)
195static void bad_addr_setup(int i)
plars865695b2001-08-27 22:15:12 +0000196{
zenglg.jyaa230562013-12-03 15:58:05 +0800197 TC[i].fname = SAFE_MMAP(cleanup, 0, 1, PROT_NONE,
198 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
199}
200#endif
mridge12952b02004-08-25 15:17:15 +0000201
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800202static void test6_setup(void)
203{
204 SAFE_SETEUID(cleanup, ltpuser->pw_uid);
205}
206
207static void test6_cleanup(void)
208{
209 SAFE_SETEUID(cleanup, 0);
210}
211
zenglg.jyaa230562013-12-03 15:58:05 +0800212static void cleanup(void)
213{
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100214 if (mount_flag && tst_umount("mntpoint") < 0) {
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800215 tst_brkm(TBROK | TERRNO, NULL,
216 "umount device:%s failed", device);
217 }
218
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200219 if (device)
220 tst_release_device(NULL, device);
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800221
Cyril Hrubis4e74c992014-06-19 16:53:51 +0200222 tst_rmdir();
Zeng Linggang6f0b85f2014-01-20 17:16:58 +0800223}