blob: c80757e40028963a769791c4f47dc3700a06b687 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * NAME
22 * creat06.c
23 *
24 * DESCRIPTION
25 * Testcase to check creat(2) sets the following errnos correctly:
26 * 1. EISDIR
27 * 2. ENAMETOOLONG
28 * 3. ENOENT
29 * 4. ENOTDIR
30 * 5. EFAULT
31 * 6. EACCES
32 *
33 * 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
46 *
47 * USAGE: <for command-line>
48 * creat06 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
49 * where, -c n : Run n copies concurrently.
50 * -e : Turn on errno logging.
51 * -i n : Execute test n times.
52 * -I x : Execute test for x seconds.
53 * -P x : Pause for x seconds between iterations.
54 * -t : Turn on syscall timing.
55 *
56 * HISTORY
57 * 07/2001 Ported by Wayne Boyer
58 *
59 * RESTRICTIONS
60 * None
61 */
62
63#include <stdio.h>
64#include <errno.h>
65#include <string.h>
robbiewe003b8c2001-08-31 15:41:20 +000066#include <pwd.h>
plars1ad84512002-07-23 13:11:18 +000067#include <sys/mman.h>
plars74948ad2002-11-14 16:16:14 +000068#include <sys/types.h>
robbiew2c945242002-11-11 19:01:25 +000069#include <sys/stat.h>
70#include <fcntl.h>
plars865695b2001-08-27 22:15:12 +000071#include "test.h"
72#include "usctest.h"
73
74void setup(void);
75void cleanup(void);
76
77char user1name[] = "nobody";
78
79char *TCID = "creat06";
mridge12952b02004-08-25 15:17:15 +000080int fileHandle = 0;
plars865695b2001-08-27 22:15:12 +000081extern int Tst_count;
82
subrata_modak56207ce2009-03-23 13:35:39 +000083int exp_enos[] = { EISDIR, ENAMETOOLONG, ENOENT, ENOTDIR, EFAULT, EACCES, 0 };
plars865695b2001-08-27 22:15:12 +000084
85#define MODE1 0444
86#define MODE2 0666
robbiew066dbd42004-10-28 18:53:39 +000087#define NSIZE 1000
plars865695b2001-08-27 22:15:12 +000088
subrata_modak56207ce2009-03-23 13:35:39 +000089char long_name[] =
90 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyz";
plars865695b2001-08-27 22:15:12 +000091
92char good_dir[NSIZE];
93char no_dir[] = "testfile/testdir";
94char not_dir[] = "file1/testdir";
95char test6_file[] = "dir6/file6";
robbiewe003b8c2001-08-31 15:41:20 +000096char nobody_uid[] = "nobody";
plars865695b2001-08-27 22:15:12 +000097
robbiewe003b8c2001-08-31 15:41:20 +000098struct passwd *ltpuser;
plars865695b2001-08-27 22:15:12 +000099struct test_case_t {
100 char *fname;
101 int mode;
102 int error;
103} TC[] = {
104 /* The file name is an existing directory */
subrata_modak56207ce2009-03-23 13:35:39 +0000105 {
106 good_dir, MODE1, EISDIR},
107 /* The file name is too long - ENAMETOOLONG */
108 {
109 long_name, MODE1, ENAMETOOLONG},
110 /* Attept to create a file in a directory that doesn't exist - ENOENT */
111 {
112 no_dir, MODE1, ENOENT},
113 /* a compent of the file's path is not a directory - ENOTDIR */
114 {
115 not_dir, MODE1, ENOTDIR},
vapierb5ed1f62006-08-24 04:16:32 +0000116#if !defined(UCLINUX)
subrata_modak56207ce2009-03-23 13:35:39 +0000117 /* The file address is bad - EFAULT */
118 {
119 (char *)-1, MODE1, EFAULT},
vapierb5ed1f62006-08-24 04:16:32 +0000120#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000121 /* The directory lacks execute permission - EACCES */
122 {
123 test6_file, MODE1, EACCES}
plars865695b2001-08-27 22:15:12 +0000124};
125
vapierb5ed1f62006-08-24 04:16:32 +0000126int TST_TOTAL = (sizeof(TC) / sizeof(*TC));
127
subrata_modak56207ce2009-03-23 13:35:39 +0000128char *bad_addr = 0;
plars1ad84512002-07-23 13:11:18 +0000129
subrata_modak56207ce2009-03-23 13:35:39 +0000130int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000131{
subrata_modak56207ce2009-03-23 13:35:39 +0000132 int lc; /* loop counter */
133 char *msg; /* message returned from parse_opts */
plars865695b2001-08-27 22:15:12 +0000134 int i;
135
136 /* parse standard options */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800137 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
plars865695b2001-08-27 22:15:12 +0000138 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
139 }
140
141 setup();
142
143 /* set up the expected errnos */
144 TEST_EXP_ENOS(exp_enos);
145
146 /* check looping state if -i option given */
147 for (lc = 0; TEST_LOOPING(lc); lc++) {
148
149 /* reset Tst_count in case we are looping */
150 Tst_count = 0;
151
152 /* loop through the test cases */
153 for (i = 0; i < TST_TOTAL; i++) {
154
155 TEST(creat(TC[i].fname, TC[i].mode));
156
157 if (TEST_RETURN != -1) {
158 tst_resm(TFAIL, "call succeeded unexpectedly");
159 continue;
160 }
161
162 TEST_ERROR_LOG(TEST_ERRNO);
163
164 if (TEST_ERRNO == TC[i].error) {
vapierdac68732009-08-28 12:15:15 +0000165 tst_resm(TPASS|TTERRNO, "expected failure");
plars865695b2001-08-27 22:15:12 +0000166 } else {
vapierdac68732009-08-28 12:15:15 +0000167 tst_resm(TFAIL|TTERRNO, "wanted errno %d", TC[i].error);
plars865695b2001-08-27 22:15:12 +0000168 }
169 }
170 }
171 cleanup();
172
robbiew2c945242002-11-11 19:01:25 +0000173 return 0;
174 return 0;
subrata_modak56207ce2009-03-23 13:35:39 +0000175 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000176
177/*
178 * setup() - performs all ONE TIME setup for this test.
179 */
subrata_modak56207ce2009-03-23 13:35:39 +0000180void setup()
plars865695b2001-08-27 22:15:12 +0000181{
182 char *cur_dir = NULL;
183
robbiewe003b8c2001-08-31 15:41:20 +0000184 /* Switch to nobody user for correct error code collection */
subrata_modak56207ce2009-03-23 13:35:39 +0000185 if (geteuid() != 0) {
186 tst_brkm(TBROK, tst_exit, "Test must be run as root");
187 }
188 ltpuser = getpwnam(nobody_uid);
vapierdac68732009-08-28 12:15:15 +0000189 if (seteuid(ltpuser->pw_uid) == -1)
190 tst_resm(TINFO|TERRNO, "seteuid(%d) failed", ltpuser->pw_uid);
robbiewe003b8c2001-08-31 15:41:20 +0000191
plars865695b2001-08-27 22:15:12 +0000192 /* capture signals */
193 tst_sig(NOFORK, DEF_HANDLER, cleanup);
194
195 /* Pause if that option was specified */
196 TEST_PAUSE;
197
198 /* make a temporary directory and cd to it */
199 tst_tmpdir();
200
201 /* get the current directory for the first test */
202 if ((cur_dir = getcwd(cur_dir, 0)) == NULL) {
203 tst_brkm(TBROK, cleanup, "getcwd failed");
204 }
205
206 if (strncpy(good_dir, cur_dir, NSIZE) == NULL) {
207 tst_brkm(TBROK, cleanup, "couldn't copy currect directory");
208 }
209
210 /* create a file that will be used in test #3 */
mridge12952b02004-08-25 15:17:15 +0000211 if ((fileHandle = creat("file1", MODE1)) == -1) {
plars865695b2001-08-27 22:15:12 +0000212 tst_brkm(TBROK, cleanup, "couldn't create a test file");
213 }
vapier62b16cf2007-02-09 20:48:23 +0000214#if !defined(UCLINUX)
robbiewd34d5812005-07-11 22:28:09 +0000215 bad_addr = mmap(0, 1, PROT_NONE,
subrata_modak56207ce2009-03-23 13:35:39 +0000216 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
vapier0722a2b2006-05-12 15:44:11 +0000217 if (bad_addr == MAP_FAILED) {
plars1ad84512002-07-23 13:11:18 +0000218 tst_brkm(TBROK, cleanup, "mmap failed");
219 }
220 TC[4].fname = bad_addr;
vapierb5ed1f62006-08-24 04:16:32 +0000221#endif
plars1ad84512002-07-23 13:11:18 +0000222
plars865695b2001-08-27 22:15:12 +0000223 /* create a directory that will be used in test #6 */
224 if (mkdir("dir6", MODE2) == -1) {
225 tst_brkm(TBROK, cleanup, "couldn't creat a test directory");
226 }
227}
228
plars865695b2001-08-27 22:15:12 +0000229/*
230 * cleanup() - performs all ONE TIME cleanup for this test at
231 * completion or premature exit.
232 */
subrata_modak56207ce2009-03-23 13:35:39 +0000233void cleanup()
plars865695b2001-08-27 22:15:12 +0000234{
235 /*
236 * print timing stats if that option was specified.
237 * print errno log if that option was specified.
238 */
subrata_modak56207ce2009-03-23 13:35:39 +0000239 close(fileHandle);
mridge12952b02004-08-25 15:17:15 +0000240
plars865695b2001-08-27 22:15:12 +0000241 TEST_CLEANUP;
242
243 /* delete the test directory created in setup() */
244 tst_rmdir();
245
246 /* exit with return code appropriate for results */
247 tst_exit();
248}