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 /*
87 * to test whether chdir() is setting EFAULT if the
88 * directory is an invalid address.
89 */
90 {
91 (void *)-1, EFAULT}
92 };
93
94 int TST_TOTAL = ARRAY_SIZE(TC);
95
96 int flag;
97 #define FAILED 1
98
99 void setup(void);
100 void cleanup(void);
101
102 char *bad_addr = 0;
103
main(int ac,char ** av)104 int main(int ac, char **av)
105 {
106 int lc;
107 int i;
108
109 tst_parse_opts(ac, av, NULL, NULL);
110
111 setup();
112
113 for (lc = 0; TEST_LOOPING(lc); lc++) {
114 tst_count = 0;
115
116 for (i = 0; i < TST_TOTAL; i++) {
117
118 TEST(chdir(TC[i].dname));
119
120 if (TEST_RETURN != -1) {
121 tst_resm(TFAIL, "call succeeded unexpectedly");
122 continue;
123 }
124
125 if (TEST_ERRNO == TC[i].error)
126 tst_resm(TPASS | TTERRNO, "failed as expected");
127 else {
128 tst_resm(TFAIL | TTERRNO,
129 "didn't fail as expected (expected %d)",
130 TC[i].error);
131 }
132 }
133 }
134 cleanup();
135
136 tst_exit();
137
138 }
139
setup(void)140 void setup(void)
141 {
142
143 tst_sig(NOFORK, DEF_HANDLER, cleanup);
144
145 TEST_PAUSE;
146
147 tst_tmpdir();
148
149 #ifdef UCLINUX
150 bad_addr = mmap(0, 1, PROT_NONE,
151 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
152 if (bad_addr == MAP_FAILED)
153 tst_brkm(TBROK | TERRNO, cleanup, "mmap() failed");
154 TC[2].dname = bad_addr;
155 #endif
156 }
157
cleanup(void)158 void cleanup(void)
159 {
160 tst_rmdir();
161
162 }
163