1 /*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * chdir04.c
23 *
24 * DESCRIPTION
25 * Testcase to test whether chdir(2) sets errno correctly.
26 *
27 * ALGORITHM
28 * 1. Test for ENAMETOOLONG:
29 * Create a bad directory name with length more than
30 *
31 * VFS_MAXNAMELEN (Linux kernel variable), and attempt to
32 * chdir(2) to it.
33 *
34 * 2. Test for ENOENT:
35 * Attempt to chdir(2) on a non-existent directory
36 *
37 * 3. Test for EFAULT:
38 * Pass an address which lies outside the address space of the
39 * process, and expect an EFAULT.
40 *
41 * USAGE: <for command-line>
42 * chdir04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
43 * where, -c n : Run n copies concurrently.
44 * -e : Turn on errno logging.
45 * -i n : Execute test n times.
46 * -I x : Execute test for x seconds.
47 * -P x : Pause for x seconds between iterations.
48 * -t : Turn on syscall timing.
49 *
50 * HISTORY
51 * 07/2001 Ported by Wayne Boyer
52 *
53 * RESTRICTIONS
54 * NONE
55 */
56
57 #include <stdio.h>
58 #include <errno.h>
59 #include <sys/stat.h>
60 #include <sys/mman.h>
61 #include "test.h"
62
63 char *TCID = "chdir04";
64
65 char bad_dir[] =
66 "abcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyz";
67
68 char noexist_dir[] = "/tmp/noexistdir";
69
70 struct test_case_t {
71 char *dname;
72 int error;
73 } TC[] = {
74 /*
75 * to test whether chdir() is setting ENAMETOOLONG if the
76 * directory is more than VFS_MAXNAMELEN
77 */
78 {
79 bad_dir, ENAMETOOLONG},
80 /*
81 * to test whether chdir() is setting ENOENT if the
82 * directory is not existing.
83 */
84 {
85 noexist_dir, ENOENT},
86 #ifndef UCLINUX
87 /*
88 * to test whether chdir() is setting EFAULT if the
89 * directory is an invalid address.
90 */
91 {
92 (void *)-1, EFAULT}
93 #endif
94 };
95
96 int TST_TOTAL = ARRAY_SIZE(TC);
97
98 int flag;
99 #define FAILED 1
100
101 void setup(void);
102 void cleanup(void);
103
104 char *bad_addr = 0;
105
main(int ac,char ** av)106 int main(int ac, char **av)
107 {
108 int lc;
109 int i;
110
111 tst_parse_opts(ac, av, NULL, NULL);
112
113 setup();
114
115 for (lc = 0; TEST_LOOPING(lc); lc++) {
116 tst_count = 0;
117
118 for (i = 0; i < TST_TOTAL; i++) {
119
120 TEST(chdir(TC[i].dname));
121
122 if (TEST_RETURN != -1) {
123 tst_resm(TFAIL, "call succeeded unexpectedly");
124 continue;
125 }
126
127 if (TEST_ERRNO == TC[i].error)
128 tst_resm(TPASS | TTERRNO, "failed as expected");
129 else {
130 tst_resm(TFAIL | TTERRNO,
131 "didn't fail as expected (expected %d)",
132 TC[i].error);
133 }
134 }
135 }
136 cleanup();
137
138 tst_exit();
139
140 }
141
setup(void)142 void setup(void)
143 {
144
145 tst_sig(NOFORK, DEF_HANDLER, cleanup);
146
147 TEST_PAUSE;
148
149 tst_tmpdir();
150
151 #ifdef UCLINUX
152 bad_addr = mmap(0, 1, PROT_NONE,
153 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
154 if (bad_addr == MAP_FAILED)
155 tst_brkm(TBROK | TERRNO, cleanup, "mmap() failed");
156 TC[2].dname = bad_addr;
157 #endif
158 }
159
cleanup(void)160 void cleanup(void)
161 {
162 tst_rmdir();
163
164 }
165