Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/user/testbin/rmdirtest/rmdirtest.c
734 views
1
/*
2
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3
* The President and Fellows of Harvard College.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the University nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
/*
31
* rmdirtest.c
32
*
33
* Tests file system synchronization and directory implementation by
34
* removing the current directory under itself and then trying to do
35
* things. It's ok for most of those things to fail, but the system
36
* shouldn't crash.
37
*/
38
39
#include <sys/types.h>
40
#include <sys/stat.h>
41
#include <stdio.h>
42
#include <string.h>
43
#include <unistd.h>
44
#include <fcntl.h>
45
#include <errno.h>
46
#include <limits.h>
47
#include <err.h>
48
49
50
static const char testdir[] = "testdir";
51
static char startpoint[PATH_MAX - sizeof(testdir)];
52
53
/*
54
* Create the test directory, and change into it, remembering
55
* where we came from.
56
*/
57
58
static
59
void
60
startup(void)
61
{
62
if (getcwd(startpoint, sizeof(startpoint))==NULL) {
63
err(1, "getcwd (not in test dir)");
64
}
65
66
if (mkdir(testdir, 0775) < 0) {
67
err(1, "%s: mkdir", testdir);
68
}
69
70
if (chdir(testdir) < 0) {
71
err(1, "%s: chdir", testdir);
72
}
73
}
74
75
/*
76
* Remove the test directory.
77
*
78
* Note that even though it's the current directory, we can't do it
79
* with rmdir(".") - what that would try to do is remove the "." entry
80
* from the current directory, which is justifiably prohibited.
81
*/
82
83
static
84
void
85
killdir(void)
86
{
87
char tmp[PATH_MAX];
88
89
snprintf(tmp, sizeof(tmp), "%s/%s", startpoint, testdir);
90
if (rmdir(tmp)<0) {
91
err(1, "%s: rmdir", tmp);
92
}
93
}
94
95
/*
96
* Leave the test directory and go back to where we came from, so we
97
* can try again.
98
*/
99
100
static
101
void
102
finish(void)
103
{
104
if (chdir(startpoint)<0) {
105
err(1, "%s: chdir", startpoint);
106
}
107
}
108
109
/*************************************************************/
110
111
/*
112
* Basic test - just try removing the directory without doing anything
113
* evil.
114
*/
115
static
116
void
117
test1(void)
118
{
119
printf("Making %s\n", testdir);
120
startup();
121
122
printf("Removing %s while in it\n", testdir);
123
killdir();
124
125
printf("Leaving the test directory\n");
126
finish();
127
}
128
129
/*
130
* Now do it while we also have the directory open.
131
*/
132
133
static
134
void
135
test2(void)
136
{
137
int fd;
138
139
printf("Now trying with the directory open...\n");
140
startup();
141
fd = open(".", O_RDONLY);
142
if (fd<0) {
143
err(1, ".: open");
144
}
145
killdir();
146
finish();
147
148
/* close *after* leaving, just for excitement */
149
if (close(fd)<0) {
150
err(1, "removed %s: close", testdir);
151
}
152
}
153
154
/*
155
* Now see if . and .. work after rmdir.
156
*/
157
158
static
159
void
160
test3(void)
161
{
162
char buf[PATH_MAX];
163
int fd;
164
165
printf("Checking if . exists after rmdir\n");
166
startup();
167
killdir();
168
169
fd = open(".", O_RDONLY);
170
if (fd<0) {
171
switch (errno) {
172
case EINVAL:
173
case EIO:
174
case ENOENT:
175
break;
176
default:
177
err(1, ".");
178
break;
179
}
180
}
181
else {
182
close(fd);
183
}
184
185
fd = open("..", O_RDONLY);
186
if (fd<0) {
187
switch (errno) {
188
case EINVAL:
189
case EIO:
190
case ENOENT:
191
break;
192
default:
193
err(1, "..");
194
break;
195
}
196
}
197
else {
198
warnx("..: openable after rmdir - might be bad");
199
close(fd);
200
}
201
202
snprintf(buf, sizeof(buf), "../%s", testdir);
203
fd = open(buf, O_RDONLY);
204
if (fd<0) {
205
switch (errno) {
206
case EINVAL:
207
case EIO:
208
case ENOENT:
209
break;
210
default:
211
err(1, "%s", buf);
212
break;
213
}
214
}
215
else {
216
errx(1, "%s: works after rmdir", buf);
217
}
218
219
finish();
220
}
221
222
/*
223
* Now try to create files.
224
*/
225
226
static
227
void
228
test4(void)
229
{
230
char buf[4096];
231
int fd;
232
233
printf("Checking if creating files works after rmdir...\n");
234
startup();
235
killdir();
236
237
fd = open("newfile", O_WRONLY|O_CREAT|O_TRUNC, 0664);
238
if (fd<0) {
239
switch (errno) {
240
case EINVAL:
241
case EIO:
242
case ENOENT:
243
break;
244
default:
245
err(1, "%s", buf);
246
break;
247
}
248
}
249
else {
250
warnx("newfile: creating files after rmdir works");
251
warnx("(this is only ok if the space gets reclaimed)");
252
253
/*
254
* Waste a bunch of space so we'll be able to tell
255
*/
256
memset(buf, 'J', sizeof(buf));
257
write(fd, buf, sizeof(buf));
258
write(fd, buf, sizeof(buf));
259
write(fd, buf, sizeof(buf));
260
write(fd, buf, sizeof(buf));
261
close(fd);
262
}
263
264
finish();
265
}
266
267
/*
268
* Now try to create directories.
269
*/
270
271
static
272
void
273
test5(void)
274
{
275
printf("Checking if creating subdirs works after rmdir...\n");
276
startup();
277
killdir();
278
279
if (mkdir("newdir", 0775)<0) {
280
switch (errno) {
281
case EINVAL:
282
case EIO:
283
case ENOENT:
284
break;
285
default:
286
err(1, "mkdir in removed dir");
287
break;
288
}
289
}
290
else {
291
warnx("newfile: creating directories after rmdir works");
292
warnx("(this is only ok if the space gets reclaimed)");
293
294
/*
295
* Waste a bunch of space so we'll be able to tell
296
*/
297
mkdir("newdir/t0", 0775);
298
mkdir("newdir/t1", 0775);
299
mkdir("newdir/t2", 0775);
300
mkdir("newdir/t3", 0775);
301
mkdir("newdir/t4", 0775);
302
mkdir("newdir/t5", 0775);
303
}
304
305
finish();
306
}
307
308
/*
309
* Now try listing the directory.
310
*/
311
static
312
void
313
test6(void)
314
{
315
char buf[PATH_MAX];
316
int fd, len;
317
318
printf("Now trying to list the directory...\n");
319
startup();
320
fd = open(".", O_RDONLY);
321
if (fd<0) {
322
err(1, ".: open");
323
}
324
killdir();
325
326
while ((len = getdirentry(fd, buf, sizeof(buf)-1))>0) {
327
if ((unsigned)len >= sizeof(buf)-1) {
328
errx(1, ".: getdirentry: returned invalid length");
329
}
330
buf[len] = 0;
331
if (!strcmp(buf, ".") || !strcmp(buf, "..")) {
332
/* these are allowed to appear */
333
continue;
334
}
335
errx(1, ".: getdirentry: returned unexpected name %s", buf);
336
}
337
if (len==0) {
338
/* EOF - ok */
339
}
340
else { /* len < 0 */
341
switch (errno) {
342
case EINVAL:
343
case EIO:
344
break;
345
default:
346
err(1, ".: getdirentry");
347
break;
348
}
349
}
350
351
finish();
352
353
/* close *after* leaving, just for excitement */
354
if (close(fd)<0) {
355
err(1, "removed %s: close", testdir);
356
}
357
}
358
359
/*
360
* Try getcwd.
361
*/
362
static
363
void
364
test7(void)
365
{
366
char buf[PATH_MAX];
367
368
startup();
369
killdir();
370
if (getcwd(buf, sizeof(buf))==NULL) {
371
switch (errno) {
372
case EINVAL:
373
case EIO:
374
case ENOENT:
375
break;
376
default:
377
err(1, "getcwd after removing %s", testdir);
378
break;
379
}
380
}
381
else {
382
errx(1, "getcwd after removing %s: succeeded (got %s)",
383
testdir, buf);
384
}
385
386
finish();
387
}
388
389
/**************************************************************/
390
391
int
392
main(void)
393
{
394
test1();
395
test2();
396
test3();
397
test4();
398
test5();
399
test6();
400
test7();
401
402
printf("Whew... survived.\n");
403
return 0;
404
}
405
406