1 /*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 * AUTHOR : Bill Branum
4 * CO-PILOT : Steve Shaw
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * Further, this software is distributed without any warranty that it is
15 * free of the rightful claim of any third person regarding infringement
16 * or the like. Any license provided herein, whether implied or
17 * otherwise, applies only to this software file. Patent licenses, if
18 * any, provided herein do not apply to combinations of this program with
19 * other software, or any other product whatsoever.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 *
25 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26 * Mountain View, CA 94043, or:
27 *
28 * http://www.sgi.com
29 *
30 * For further information regarding this notice, see:
31 *
32 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
33 *
34 */
35 /*
36 * TEST CASES
37 * rmdir(2) test for errno(s) EINVAL, EMLINK, EFAULT
38 */
39
40 #include <errno.h>
41 #include <signal.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <sys/mman.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include "test.h"
48 #include "safe_macros.h"
49
50 static void setup(void);
51 static void cleanup(void);
52
53 #if !defined(UCLINUX)
54 extern char *get_high_address();
55 int TST_TOTAL = 6;
56 #else
57 int TST_TOTAL = 4;
58 #endif
59
60 char *TCID = "rmdir05";
61
62 static struct stat stat_buf;
63 static char dir_name[256];
64
65 static char *bad_addr = NULL;
66
main(int argc,char ** argv)67 int main(int argc, char **argv)
68 {
69 int lc;
70
71 tst_parse_opts(argc, argv, NULL, NULL);
72
73 setup();
74
75 for (lc = 0; TEST_LOOPING(lc); lc++) {
76 tst_count = 0;
77
78 /*
79 * TEST CASE: 1
80 * path points to the current directory
81 */
82 TEST(rmdir("."));
83
84 if (TEST_RETURN == -1) {
85 if (TEST_ERRNO & (EBUSY | ENOTEMPTY)) {
86 /* For functionality tests, verify that the
87 * directory wasn't removed.
88 */
89 if (stat(".", &stat_buf) == -1) {
90 tst_resm(TFAIL,
91 "rmdir(\".\") removed the current working directory when it should have failed.");
92 } else {
93 tst_resm(TPASS,
94 "rmdir(\".\") failed to remove the current working directory. Returned %d : %s",
95 TEST_ERRNO,
96 strerror(TEST_ERRNO));
97 }
98 } else {
99 tst_resm(TFAIL,
100 "rmdir(\".\") failed with errno %d : %s but expected %d (EBUSY)",
101 TEST_ERRNO,
102 strerror(TEST_ERRNO), EBUSY);
103 }
104 } else {
105 tst_resm(TFAIL,
106 "rmdir(\".\") succeeded unexpectedly.");
107 }
108
109 /*
110 * TEST CASE: 2
111 * path points to the "." (dot) entry of a directory
112 */
113 tst_resm(TCONF, "rmdir on \"dir/.\" supported on Linux");
114
115 tst_resm(TCONF,
116 "linked directories test not implemented on Linux");
117
118 /*
119 * TEST CASE: 4
120 * path argument points below the minimum allocated address space
121 */
122 #if !defined(UCLINUX)
123 TEST(rmdir(bad_addr));
124
125 if (TEST_RETURN == -1) {
126 }
127
128 if (TEST_RETURN == -1) {
129 if (TEST_ERRNO == EFAULT) {
130 tst_resm(TPASS,
131 "rmdir() - path argument points below the minimum allocated address space failed as expected with errno %d : %s",
132 TEST_ERRNO,
133 strerror(TEST_ERRNO));
134 } else {
135 tst_resm(TFAIL,
136 "rmdir() - path argument points below the minimum allocated address space failed with errno %d : %s but expected %d (EFAULT)",
137 TEST_ERRNO,
138 strerror(TEST_ERRNO), EFAULT);
139 }
140 } else {
141 tst_resm(TFAIL,
142 "rmdir() - path argument points below the minimum allocated address space succeeded unexpectedly.");
143 }
144
145 /*
146 * TEST CASE: 5
147 * path argument points above the maximum allocated address space
148 */
149
150 TEST(rmdir(get_high_address()));
151
152 if (TEST_RETURN == -1) {
153 }
154
155 if (TEST_RETURN == -1) {
156 if (TEST_ERRNO == EFAULT) {
157 tst_resm(TPASS,
158 "rmdir() - path argument points above the maximum allocated address space failed as expected with errno %d : %s",
159 TEST_ERRNO,
160 strerror(TEST_ERRNO));
161 } else {
162 tst_resm(TFAIL,
163 "rmdir() - path argument points above the maximum allocated address space failed with errno %d : %s but expected %d (EFAULT)",
164 TEST_ERRNO,
165 strerror(TEST_ERRNO), EFAULT);
166 }
167 } else {
168 tst_resm(TFAIL,
169 "rmdir() - path argument points above the maximum allocated address space succeeded unexpectedly.");
170 }
171 #endif
172
173 /*
174 * TEST CASE: 6
175 * able to remove a directory
176 */
177
178 if (mkdir(dir_name, 0777) != 0) {
179 tst_brkm(TBROK, cleanup,
180 "mkdir(\"%s\") failed with errno %d : %s",
181 dir_name, errno, strerror(errno));
182 }
183
184 TEST(rmdir(dir_name));
185
186 if (TEST_RETURN == -1) {
187 tst_resm(TFAIL,
188 "rmdir(\"%s\") failed when it should have passed. Returned %d : %s",
189 dir_name, TEST_ERRNO, strerror(TEST_ERRNO));
190 } else {
191 /* Verify the directory was removed. */
192 if (stat(dir_name, &stat_buf) != 0) {
193 tst_resm(TPASS,
194 "rmdir(\"%s\") removed the directory as expected.",
195 dir_name);
196 } else {
197 tst_resm(TFAIL,
198 "rmdir(\"%s\") returned a zero exit status but failed to remove the directory.",
199 dir_name);
200 }
201 }
202
203 }
204
205 cleanup();
206 tst_exit();
207 }
208
setup(void)209 void setup(void)
210 {
211 tst_sig(FORK, DEF_HANDLER, cleanup);
212
213 TEST_PAUSE;
214
215 tst_tmpdir();
216
217 /* Create a directory. */
218 SAFE_MKDIR(cleanup, "dir1", 0777);
219
220 /* Create a unique directory name. */
221 sprintf(dir_name, "./dir_%d", getpid());
222
223 #if !defined(UCLINUX)
224 bad_addr = mmap(0, 1, PROT_NONE,
225 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
226 if (bad_addr == MAP_FAILED) {
227 tst_brkm(TBROK, cleanup, "mmap failed");
228 }
229 #endif
230 }
231
cleanup(void)232 void cleanup(void)
233 {
234 tst_rmdir();
235 }
236