source: trunk/minix/test/test17.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 30.7 KB
Line 
1/* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
2
3/* "const.h", created by Rene Montsma and Menno Wilcke */
4
5#include <sys/types.h> /* type defs */
6#include <sys/stat.h> /* struct stat */
7#include <sys/wait.h>
8#include <errno.h> /* the error-numbers */
9#include <fcntl.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13#include <utime.h>
14#include <stdio.h>
15#include <limits.h>
16
17#define NOCRASH 1 /* test11(), 2nd pipe */
18#define PDPNOHANG 1 /* test03(), write_standards() */
19#define MAXERR 2
20
21#define USER_ID 12
22#define GROUP_ID 1
23#define FF 3 /* first free filedes. */
24#define USER 1 /* uid */
25#define GROUP 0 /* gid */
26
27#define ARSIZE 256 /* array size */
28#define PIPESIZE 3584 /* max number of bytes to be written on pipe */
29#define MAXOPEN (OPEN_MAX-3) /* maximum number of extra open files */
30#define MAXLINK 0177 /* maximum number of links per file */
31#define LINKCOUNT 5
32#define MASK 0777 /* selects lower nine bits */
33#define END_FILE 0 /* returned by read-call at eof */
34
35#define OK 0
36#define FAIL -1
37
38#define R 0 /* read (open-call) */
39#define W 1 /* write (open-call) */
40#define RW 2 /* read & write (open-call) */
41
42#define RWX 7 /* read & write & execute (mode) */
43
44#define NIL ""
45#define UMASK "umask"
46#define CREAT "creat"
47#define WRITE "write"
48#define READ "read"
49#define OPEN "open"
50#define CLOSE "close"
51#define LSEEK "lseek"
52#define ACCESS "access"
53#define CHDIR "chdir"
54#define CHMOD "chmod"
55#define LINK "link"
56#define UNLINK "unlink"
57#define PIPE "pipe"
58#define STAT "stat"
59#define FSTAT "fstat"
60#define DUP "dup"
61#define UTIME "utime"
62
63int errct;
64
65char *file[];
66char *fnames[];
67char *dir[];
68
69/* "decl.c", created by Rene Montsma and Menno Wilcke */
70
71/* Used in open_alot, close_alot */
72char *file[20] = {"f0", "f1", "f2", "f3", "f4", "f5", "f6",
73 "f7", "f8", "f9", "f10", "f11", "f12", "f13",
74 "f14", "f15", "f16", "f17", "f18", "f19"}, *fnames[8] = {"---", "--x", "-w-", "-wx", "r--",
75 "r-x", "rw-", "rwx"}, *dir[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",
76 "drw-", "drwx"};
77 /* Needed for easy creating and deleting of directories */
78
79/* "test.c", created by Rene Montsma and Menno Wilcke */
80
81_PROTOTYPE(int main, (int argc, char *argv []));
82_PROTOTYPE(void test, (int mask));
83_PROTOTYPE(void test01, (void));
84_PROTOTYPE(void test02, (void));
85_PROTOTYPE(void test08, (void));
86_PROTOTYPE(void test09, (void));
87_PROTOTYPE(void test10, (void));
88_PROTOTYPE(int link_alot, (char *bigboss));
89_PROTOTYPE(int unlink_alot, (int number));
90_PROTOTYPE(void get_new, (char name []));
91_PROTOTYPE(void test11, (void));
92_PROTOTYPE(void comp_stats, (struct stat *stbf1, struct stat *stbf2));
93_PROTOTYPE(void comp_inodes, (int m, int m1));
94_PROTOTYPE(void e, (char *string));
95_PROTOTYPE(void nlcr, (void));
96_PROTOTYPE(void str, (char *s));
97_PROTOTYPE(void err, (int number, char *scall, char *name));
98_PROTOTYPE(void make_and_fill_dirs, (void));
99_PROTOTYPE(void put_file_in_dir, (char *dirname, int mode));
100_PROTOTYPE(void init_array, (char *a));
101_PROTOTYPE(void clear_array, (char *b));
102_PROTOTYPE(int comp_array, (char *a, char *b, int range));
103_PROTOTYPE(void try_close, (int filedes, char *name));
104_PROTOTYPE(void try_unlink, (char *fname));
105_PROTOTYPE(void Remove, (int fdes, char *fname));
106_PROTOTYPE(int get_mode, (char *name));
107_PROTOTYPE(void check, (char *scall, int number));
108_PROTOTYPE(void put, (int nr));
109_PROTOTYPE(int open_alot, (void));
110_PROTOTYPE(int close_alot, (int number));
111_PROTOTYPE(void clean_up_the_mess, (void));
112_PROTOTYPE(void chmod_8_dirs, (int sw));
113_PROTOTYPE(void quit, (void));
114
115/*****************************************************************************
116 * TEST *
117 ****************************************************************************/
118int main(argc, argv)
119int argc;
120char *argv[];
121{
122 int n, mask;
123
124 sync();
125 if (geteuid() == 0 || getuid() == 0) {
126 printf("Test 17 cannot run as root; test aborted\n");
127 exit(1);
128 }
129
130 system("rm -rf DIR_18; mkdir DIR_18");
131 chdir("DIR_18");
132
133 mask = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
134
135 if (fork()) {
136 printf("Test 17 ");
137 fflush(stdout);
138
139 wait(&n);
140 clean_up_the_mess();
141 quit();
142 } else {
143 test(mask);
144 exit(0);
145 }
146 return(-1); /* impossible */
147}
148
149void test(mask)
150int mask;
151{
152 umask(0); /* not honest, but i always forget */
153
154 if (mask & 00001) test01();
155 if (mask & 00002) make_and_fill_dirs();
156 if (mask & 00004) test02();
157 if (mask & 00010) test08();
158 if (mask & 00020) test09();
159 if (mask & 00040) test10();
160 if (mask & 00100) test11();
161 umask(022);
162} /* test */
163
164/* "t1.c" created by Rene Montsma and Menno Wilcke */
165
166/*****************************************************************************
167 * test UMASK *
168 ****************************************************************************/
169void test01()
170{
171 int oldvalue, newvalue, tempvalue;
172 int nr;
173
174 if ((oldvalue = umask(0777)) != 0) err(0, UMASK, NIL);
175
176 /* Special test: only the lower 9 bits (protection bits) may part- *
177 * icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
178 * not change any value. */
179
180 if ((newvalue = umask(~0777)) != 0777) err(1, UMASK, "illegal");
181 if (oldvalue == newvalue) err(11, UMASK, "not change mask");
182
183 if ((tempvalue = umask(0)) != 0) err(2, UMASK, "values");
184
185 /* Now test all possible modes of umask on a file */
186 for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
187 tempvalue = umask(newvalue);
188 if (tempvalue != oldvalue) {
189 err(1, UMASK, "illegal");
190 break; /* no use trying more */
191 } else if ((nr = creat("file01", 0777)) < 0)
192 err(5, CREAT, "'file01'");
193 else {
194 try_close(nr, "'file01'");
195 if (get_mode("file01") != (MASK & ~newvalue))
196 err(7, UMASK, "mode computed");
197 try_unlink("file01");
198 }
199 oldvalue = newvalue;
200 }
201
202 /* The loop has terminated with umask(0) */
203 if ((tempvalue = umask(0)) != 0)
204 err(7, UMASK, "umask may influence rest of tests!");
205} /* test01 */
206
207/*****************************************************************************
208 * test CREAT *
209 ****************************************************************************/
210void test02()
211{
212 int n, n1, mode;
213 char a[ARSIZE], b[ARSIZE];
214 struct stat stbf1;
215
216 mode = 0;
217 /* Create twenty files, check filedes */
218 for (n = 0; n < MAXOPEN; n++) {
219 if (creat(file[n], mode) != FF + n)
220 err(13, CREAT, file[n]);
221 else {
222 if (get_mode(file[n]) != mode)
223 err(7, CREAT, "mode set while creating many files");
224
225 /* Change mode of file to standard mode, we want to *
226 * use a lot (20) of files to be opened later, see *
227 * open_alot(), close_alot(). */
228 if (chmod(file[n], 0700) != OK) err(5, CHMOD, file[n]);
229
230 }
231 mode = (mode + 0100) % 01000;
232 }
233
234 /* Already twenty files opened; opening another has to fail */
235 if (creat("file02", 0777) != FAIL)
236 err(9, CREAT, "created");
237 else
238 check(CREAT, EMFILE);
239
240 /* Close all files: seems blunt, but it isn't because we've *
241 * checked all fd's already */
242 if ((n = close_alot(MAXOPEN)) < MAXOPEN) err(5, CLOSE, "MAXOPEN files");
243
244 /* Creat 1 file twice; check */
245 if ((n = creat("file02", 0777)) < 0)
246 err(5, CREAT, "'file02'");
247 else {
248 init_array(a);
249 if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
250
251 if ((n1 = creat("file02", 0755)) < 0) /* receate 'file02' */
252 err(5, CREAT, "'file02' (2nd time)");
253 else {
254 /* Fd should be at the top after recreation */
255 if (lseek(n1, 0L, SEEK_END) != 0)
256 err(11, CREAT, "not truncate file by recreation");
257 else {
258 /* Try to write on recreated file */
259 clear_array(b);
260
261 if (lseek(n1, 0L, SEEK_SET) != 0)
262 err(5, LSEEK, "to top of 2nd fd 'file02'");
263 if (write(n1, a, ARSIZE) != ARSIZE)
264 err(1, WRITE, "(2) bad");
265
266 /* In order to read we've to close and open again */
267 try_close(n1, "'file02' (2nd creation)");
268 if ((n1 = open("file02", RW)) < 0)
269 err(5, OPEN, "'file02' (2nd recreation)");
270
271 /* Continue */
272 if (lseek(n1, 0L, SEEK_SET) != 0)
273 err(5, LSEEK, "to top 'file02'(2nd fd) (2)");
274 if (read(n1, b, ARSIZE) != ARSIZE)
275 err(1, READ, "wrong");
276
277 if (comp_array(a, b, ARSIZE) != OK) err(11, CREAT,
278 "not really truncate file by recreation");
279 }
280 if (get_mode("file02") != 0777)
281 err(11, CREAT, "not maintain mode by recreation");
282 try_close(n1, "recreated 'file02'");
283
284 }
285 Remove(n, "file02");
286 }
287
288 /* Give 'creat' wrong input: dir not searchable */
289 if (creat("drw-/file02", 0777) != FAIL)
290 err(4, CREAT, "'drw-'");
291 else
292 check(CREAT, EACCES);
293
294 /* Dir not writable */
295 if (creat("dr-x/file02", 0777) != FAIL)
296 err(12, CREAT, "'dr-x/file02'");
297 else
298 check(CREAT, EACCES);
299
300 /* File not writable */
301 if (creat("drwx/r-x", 0777) != FAIL)
302 err(11, CREAT, "recreate non-writable file");
303 else
304 check(CREAT, EACCES);
305
306 /* Try to creat a dir */
307 if ((n = creat("dir", 040777)) != FAIL) {
308 if (fstat(n, &stbf1) != OK)
309 err(5, FSTAT, "'dir'");
310 else if (stbf1.st_mode != (mode_t) 0100777)
311 /* cast because mode is negative :-( */
312 err(11, CREAT, "'creat' a new directory");
313 Remove(n, "dir");
314 }
315
316 /* We don't consider it to be a bug when creat * does not accept
317 * tricky modes */
318
319 /* File is an existing dir */
320 if (creat("drwx", 0777) != FAIL)
321 err(11, CREAT, "create an existing dir!");
322 else
323 check(CREAT, EISDIR);
324} /* test02 */
325
326void test08()
327{
328 /* Test chdir to searchable dir */
329 if (chdir("drwx") != OK)
330 err(5, CHDIR, "to accessible dir");
331 else if (chdir("..") != OK)
332 err(11, CHDIR, "not return to '..'");
333
334 /* Check the chdir(".") and chdir("..") mechanism */
335 if (chdir("drwx") != OK)
336 err(5, CHDIR, "to 'drwx'");
337 else {
338 if (chdir(".") != OK) err(5, CHDIR, "to working dir (.)");
339
340 /* If we still are in 'drwx' , we should be able to access *
341 * file 'rwx'. */
342 if (access("rwx", 0) != OK) err(5, CHDIR, "rightly to '.'");
343
344 /* Try to return to previous dir ('/' !!) */
345 if (chdir("././../././d--x/../d--x/././..") != OK)
346 err(5, CHDIR, "to motherdir (..)");
347
348 /* Check whether we are back in '/' */
349 if (chdir("d--x") != OK) err(5, CHDIR, "rightly to a '..'");
350 }
351
352 /* Return to '..' */
353 if (chdir("..") != OK) err(5, CHDIR, "to '..'");
354
355 if (chdir("././././drwx") != OK)
356 err(11, CHDIR, "not follow a path");
357 else if (chdir("././././..") != OK)
358 err(11, CHDIR, "not return to path");
359
360 /* Try giving chdir wrong parameters */
361 if (chdir("drwx/rwx") != FAIL)
362 err(11, CHDIR, "chdir to a file");
363 else
364 check(CHDIR, ENOTDIR);
365
366 if (chdir("drw-") != FAIL)
367 err(4, CHDIR, "'/drw-'");
368 else
369 check(CHDIR, EACCES);
370
371 /* To be sure: return to root */
372 /* If (chdir("/") != OK) err(5, CHDIR, "to '/' (2nd time)"); */
373} /* test08 */
374
375/* New page */
376
377/*****************************************************************************
378 * test CHMOD *
379 ****************************************************************************/
380void test09()
381{
382 int n;
383
384 /* Prepare file09 */
385 if ((n = creat("drwx/file09", 0644)) != FF) err(5, CREAT, "'drwx/file09'");
386
387 try_close(n, "'file09'");
388
389 /* Try to chmod a file, check and restore old values, check */
390 if (chmod("drwx/file09", 0700) != OK)
391 err(5, CHMOD, "'drwx/file09'"); /* set rwx */
392 else {
393 /* Check protection */
394 if (get_mode("drwx/file09") != 0700) err(7, CHMOD, "mode");
395
396 /* Test if chmod accepts just filenames too */
397 if (chdir("drwx") != OK)
398 err(5, CHDIR, "to '/drwx'");
399 else if (chmod("file09", 0177) != OK) /* restore oldies */
400 err(5, CHMOD, "'h1'");
401 else
402 /* Check if value has been restored */
403 if (get_mode("../drwx/file09") != 0177)
404 err(7, CHMOD, "restored mode");
405 }
406
407 /* Try setuid and setgid */
408 if ((chmod("file09", 04777) != OK) || (get_mode("file09") != 04777))
409 err(11, CHMOD, "not set uid-bit");
410 if ((chmod("file09", 02777) != OK) || (get_mode("file09") != 02777))
411 err(11, CHMOD, "not set gid-bit");
412
413 /* Remove testfile */
414 try_unlink("file09");
415
416 if (chdir("..") != OK) err(5, CHDIR, "to '..'");
417
418 /* Try to chmod directory */
419 if (chmod("d---", 0777) != OK)
420 err(5, CHMOD, "dir 'd---'");
421 else {
422 if (get_mode("d---") != 0777) err(7, CHMOD, "protection value");
423 if (chmod("d---", 0000) != OK) err(5, CHMOD, "dir 'a' 2nd time");
424
425 /* Check if old value has been restored */
426 if (get_mode("d---") != 0000)
427 err(7, CHMOD, "restored protection value");
428 }
429
430 /* Try to make chmod failures */
431
432 /* We still are in dir root */
433 /* Wrong filename */
434 if (chmod("non-file", 0777) != FAIL)
435 err(3, CHMOD, NIL);
436 else
437 check(CHMOD, ENOENT);
438
439} /* test 09 */
440
441/* New page */
442
443
444/* "t4.c", created by Rene Montsma and Menno Wilcke */
445
446/*****************************************************************************
447 * test LINK/UNLINK *
448 ****************************************************************************/
449void test10()
450{
451 int n, n1;
452 char a[ARSIZE], b[ARSIZE], *f, *lf;
453
454 f = "file10";
455 lf = "linkfile10";
456
457 if ((n = creat(f, 0702)) != FF) /* no other open files */
458 err(13, CREAT, f);
459 else {
460 /* Now link correctly */
461 if (link(f, lf) != OK)
462 err(5, LINK, lf);
463 else if ((n1 = open(lf, RW)) < 0)
464 err(5, OPEN, "'linkfile10'");
465 else {
466 init_array(a);
467 clear_array(b);
468
469 /* Write on 'file10' means being able to * read
470 * through linked filedescriptor */
471 if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
472 if (read(n1, b, ARSIZE) != ARSIZE) err(1, READ, "bad");
473 if (comp_array(a, b, ARSIZE) != OK) err(8, "r/w", NIL);
474
475 /* Clean up: unlink and close (twice): */
476 Remove(n, f);
477 try_close(n1, "'linkfile10'");
478
479 /* Check if "linkfile" exists and the info * on it
480 * is correct ('file' has been deleted) */
481 if ((n1 = open(lf, R)) < 0)
482 err(5, OPEN, "'linkfile10'");
483 else {
484 /* See if 'linkfile' still contains 0..511 ? */
485
486 clear_array(b);
487 if (read(n1, b, ARSIZE) != ARSIZE)
488 err(1, READ, "bad");
489 if (comp_array(a, b, ARSIZE) != OK)
490 err(8, "r/w", NIL);
491
492 try_close(n1, "'linkfile10' 2nd time");
493 try_unlink(lf);
494 }
495 }
496 }
497
498 /* Try if unlink fails with incorrect parameters */
499 /* File does not exist: */
500 if (unlink("non-file") != FAIL)
501 err(2, UNLINK, "name");
502 else
503 check(UNLINK, ENOENT);
504
505 /* Dir can't be written */
506 if (unlink("dr-x/rwx") != FAIL)
507 err(11, UNLINK, "could unlink in non-writable dir.");
508 else
509 check(UNLINK, EACCES);
510
511 /* Try to unlink a dir being user */
512 if (unlink("drwx") != FAIL)
513 err(11, UNLINK, "unlink dir's as user");
514 else
515 check(UNLINK, EPERM);
516
517 /* Try giving link wrong input */
518
519 /* First try if link fails with incorrect parameters * name1 does not
520 * exist. */
521 if (link("non-file", "linkfile") != FAIL)
522 err(2, LINK, "1st name");
523 else
524 check(LINK, ENOENT);
525
526 /* Name2 exists already */
527 if (link("drwx/rwx", "drwx/rw-") != FAIL)
528 err(2, LINK, "2nd name");
529 else
530 check(LINK, EEXIST);
531
532 /* Directory of name2 not writable: */
533 if (link("drwx/rwx", "dr-x/linkfile") != FAIL)
534 err(11, LINK, "link non-writable file");
535 else
536 check(LINK, EACCES);
537
538 /* Try to link a dir, being a user */
539 if (link("drwx", "linkfile") != FAIL)
540 err(11, LINK, "link a dir without superuser!");
541 else
542 check(LINK, EPERM);
543
544 /* File has too many links */
545 if ((n = link_alot("drwx/rwx")) != LINKCOUNT - 1) /* file already has one
546 * link */
547 err(5, LINK, "many files");
548 if (unlink_alot(n) != n) err(5, UNLINK, "all linked files");
549
550} /* test10 */
551
552int link_alot(bigboss)
553char *bigboss;
554{
555 int i;
556 static char employee[6] = "aaaaa";
557
558 /* Every file has already got 1 link, so link 0176 times */
559 for (i = 1; i < LINKCOUNT; i++) {
560 if (link(bigboss, employee) != OK)
561 break;
562 else
563 get_new(employee);
564 }
565
566 return(i - 1); /* number of linked files */
567} /* link_alot */
568
569int unlink_alot(number)
570int number; /* number of files to be unlinked */
571{
572 int j;
573 static char employee[6] = "aaaaa";
574
575 for (j = 0; j < number; j++) {
576 if (unlink(employee) != OK)
577 break;
578 else
579 get_new(employee);
580 }
581
582 return(j); /* return number of unlinked files */
583} /* unlink_alot */
584
585void get_new(name)
586char name[];
587 /* Every call changes string 'name' to a string alphabetically *
588 * higher. Start with "aaaaa", next value: "aaaab" . *
589 * N.B. after "aaaaz" comes "aaabz" and not "aaaba" (not needed). *
590 * The last possibility will be "zzzzz". *
591 * Total # possibilities: 26+25*4 = 126 = MAXLINK -1 (exactly needed) */
592{
593 int i;
594
595 for (i = 4; i >= 0; i--)
596 if (name[i] != 'z') {
597 name[i]++;
598 break;
599 }
600} /* get_new */
601
602/* New page */
603
604
605/*****************************************************************************
606 * test PIPE *
607 ****************************************************************************/
608void test11()
609{
610 int n, fd[2];
611 char a[ARSIZE], b[ARSIZE];
612
613 if (pipe(fd) != OK)
614 err(13, PIPE, NIL);
615 else {
616 /* Try reading and writing on a pipe */
617 init_array(a);
618 clear_array(b);
619
620 if (write(fd[1], a, ARSIZE) != ARSIZE)
621 err(5, WRITE, "on pipe");
622 else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
623 err(5, READ, "on pipe (2nd time)");
624 else if (comp_array(a, b, (ARSIZE / 2)) != OK)
625 err(7, PIPE, "values read/written");
626 else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
627 err(5, READ, "on pipe 2");
628 else if (comp_array(&a[ARSIZE / 2], b, (ARSIZE / 2)) != OK)
629 err(7, PIPE, "pipe created");
630
631 /* Try to let the pipe make a mistake */
632 if (write(fd[0], a, ARSIZE) != FAIL)
633 err(11, WRITE, "write on fd[0]");
634 if (read(fd[1], b, ARSIZE) != FAIL) err(11, READ, "read on fd[1]");
635
636 try_close(fd[1], "'fd[1]'");
637
638 /* Now we shouldn't be able to read, because fd[1] has been closed */
639 if (read(fd[0], b, ARSIZE) != END_FILE) err(2, PIPE, "'fd[1]'");
640
641 try_close(fd[0], "'fd[0]'");
642 }
643 if (pipe(fd) < 0)
644 err(5, PIPE, "2nd time");
645 else {
646 /* Test lseek on a pipe: should fail */
647 if (write(fd[1], a, ARSIZE) != ARSIZE)
648 err(5, WRITE, "on pipe (2nd time)");
649 if (lseek(fd[1], 10L, SEEK_SET) != FAIL)
650 err(11, LSEEK, "lseek on a pipe");
651 else
652 check(PIPE, ESPIPE);
653
654 /* Eat half of the pipe: no writing should be possible */
655 try_close(fd[0], "'fd[0]' (2nd time)");
656
657 /* This makes UNIX crash: omit it if pdp or VAX */
658#ifndef NOCRASH
659 if (write(fd[1], a, ARSIZE) != FAIL)
660 err(11, WRITE, "write on wrong pipe");
661 else
662 check(PIPE, EPIPE);
663#endif
664 try_close(fd[1], "'fd[1]' (2nd time)");
665 }
666
667 /* BUG : *
668 * Here we planned to test if we could write 4K bytes on a pipe. *
669 * However, this was not possible to implement, because the whole *
670 * Monix system crashed when we tried to write more then 3584 bytes *
671 * (3.5K) on a pipe. That's why we try to write only 3.5K in the *
672 * folowing test. */
673 if (pipe(fd) < 0)
674 err(5, PIPE, "3rd time");
675 else {
676 for (n = 0; n < (PIPESIZE / ARSIZE); n++)
677 if (write(fd[1], a, ARSIZE) != ARSIZE)
678 err(5, WRITE, "on pipe (3rd time) 4K");
679 try_close(fd[1], "'fd[1]' (3rd time)");
680
681 for (n = 0; n < (PIPESIZE / ARSIZE); n++)
682 if (read(fd[0], b, ARSIZE) != ARSIZE)
683 err(5, READ, "from pipe (3rd time) 4K");
684 try_close(fd[0], "'fd[0]' (3rd time)");
685 }
686
687 /* Test opening a lot of files */
688 if ((n = open_alot()) != MAXOPEN) err(5, OPEN, "MAXOPEN files");
689 if (pipe(fd) != FAIL)
690 err(9, PIPE, "open");
691 else
692 check(PIPE, EMFILE);
693 if (close_alot(n) != n) err(5, CLOSE, "all opened files");
694} /* test11 */
695
696/* New page */
697
698
699void comp_stats(stbf1, stbf2)
700struct stat *stbf1, *stbf2;
701{
702 if (stbf1->st_dev != stbf2->st_dev) err(7, "st/fst", "'dev'");
703 if (stbf1->st_ino != stbf2->st_ino) err(7, "st/fst", "'ino'");
704 if (stbf1->st_mode != stbf2->st_mode) err(7, "st/fst", "'mode'");
705 if (stbf1->st_nlink != stbf2->st_nlink) err(7, "st/fst", "'nlink'");
706 if (stbf1->st_uid != stbf2->st_uid) err(7, "st/fst", "'uid'");
707 if (stbf1->st_gid != stbf2->st_gid) err(7, "st/fst", "'gid'");
708 if (stbf1->st_rdev != stbf2->st_rdev) err(7, "st/fst", "'rdev'");
709 if (stbf1->st_size != stbf2->st_size) err(7, "st/fst", "'size'");
710 if (stbf1->st_atime != stbf2->st_atime) err(7, "st/fst", "'atime'");
711 if (stbf1->st_mtime != stbf2->st_mtime) err(7, "st/fst", "'mtime'");
712} /* comp_stats */
713
714/* New page */
715
716
717/* "t5.c", created by Rene Montsma and Menno Wilcke */
718
719void comp_inodes(m, m1)
720int m, m1; /* twee filedes's */
721{
722 struct stat stbf1, stbf2;
723
724 if (fstat(m, &stbf1) == OK)
725 if (fstat(m1, &stbf2) == OK) {
726 if (stbf1.st_ino != stbf2.st_ino)
727 err(7, DUP, "inode number");
728 } else
729 err(100, "comp_inodes", "cannot 'fstat' (m1)");
730 else
731 err(100, "comp_inodes", "cannot 'fstat' (m)");
732} /* comp_inodes */
733
734/* "support.c", created by Rene Montsma and Menno Wilcke */
735
736/* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
737 try_close, try_unlink, Remove, get_mode, check, open_alot,
738 close_alot, clean_up_the_mess.
739*/
740
741/***********************************************************************
742 * EXTENDED FIONS *
743 **********************************************************************/
744/* First extended functions (i.e. not oldfashioned monixcalls.
745 e(), nlcr(), octal.*/
746
747void e(string)
748char *string;
749{
750 printf("Error: %s ", string);
751}
752
753void nlcr()
754{
755 printf("\n");
756}
757
758void str(s)
759char *s;
760{
761 printf(s);
762}
763
764/*****************************************************************************
765* *
766* ERR(or) messages *
767* *
768*****************************************************************************/
769void err(number, scall, name)
770 /* Give nice error messages */
771
772char *scall, *name;
773int number;
774
775{
776 errct++;
777 if (errct > MAXERR) {
778 printf("Too many errors; test aborted\n");
779 quit();
780 }
781 e("");
782 str("\t");
783 switch (number) {
784 case 0:
785 str(scall);
786 str(": illegal initial value.");
787 break;
788 case 1:
789 str(scall);
790 str(": ");
791 str(name);
792 str(" value returned.");
793 break;
794 case 2:
795 str(scall);
796 str(": accepting illegal ");
797 str(name);
798 str(".");
799 break;
800 case 3:
801 str(scall);
802 str(": accepting non-existing file.");
803 break;
804 case 4:
805 str(scall);
806 str(": could search non-searchable dir (");
807 str(name);
808 str(").");
809 break;
810 case 5:
811 str(scall);
812 str(": cannot ");
813 str(scall);
814 str(" ");
815 str(name);
816 str(".");
817 break;
818 case 7:
819 str(scall);
820 str(": incorrect ");
821 str(name);
822 str(".");
823 break;
824 case 8:
825 str(scall);
826 str(": wrong values.");
827 break;
828 case 9:
829 str(scall);
830 str(": accepting too many ");
831 str(name);
832 str(" files.");
833 break;
834 case 10:
835 str(scall);
836 str(": even a superuser can't do anything!");
837 break;
838 case 11:
839 str(scall);
840 str(": could ");
841 str(name);
842 str(".");
843 break;
844 case 12:
845 str(scall);
846 str(": could write in non-writable dir (");
847 str(name);
848 str(").");
849 break;
850 case 13:
851 str(scall);
852 str(": wrong filedes returned (");
853 str(name);
854 str(").");
855 break;
856 case 100:
857 str(scall); /* very common */
858 str(": ");
859 str(name);
860 str(".");
861 break;
862 default: str("errornumber does not exist!\n");
863 }
864 nlcr();
865} /* err */
866
867/*****************************************************************************
868* *
869* MAKE_AND_FILL_DIRS *
870* *
871*****************************************************************************/
872
873void make_and_fill_dirs()
874 /* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", *
875 * "drw-", "drwx". * Then create 8 files
876 * in "drwx", and some needed files in other dirs. */
877{
878 int mode, i;
879
880 for (i = 0; i < 8; i++) {
881 mkdir(dir[i], 0700);
882 chown(dir[i], USER_ID, GROUP_ID);
883 }
884 setuid(USER_ID);
885 setgid(GROUP_ID);
886
887 for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
888
889 put_file_in_dir("d-wx", RWX);
890 put_file_in_dir("dr-x", RWX);
891 put_file_in_dir("drw-", RWX);
892
893 chmod_8_dirs(8); /* 8 means; 8 different modes */
894
895} /* make_and_fill_dirs */
896
897void put_file_in_dir(dirname, mode)
898char *dirname;
899int mode;
900 /* Fill directory 'dirname' with file with mode 'mode'. */
901{
902 int nr;
903
904 if (chdir(dirname) != OK)
905 err(5, CHDIR, "to dirname (put_f_in_dir)");
906 else {
907 /* Creat the file */
908 if ((nr = creat(fnames[mode], mode * 0100)) < 0)
909 err(13, CREAT, fnames[mode]);
910 else
911 try_close(nr, fnames[mode]);
912
913 if (chdir("..") != OK)
914 err(5, CHDIR, "to previous dir (put_f_in_dir)");
915 }
916} /* put_file_in_dir */
917
918/*****************************************************************************
919* *
920* MISCELLANEOUS *
921* *
922*(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode')*
923* *
924*****************************************************************************/
925
926void init_array(a)
927char *a;
928{
929 int i;
930
931 i = 0;
932 while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
933} /* init_array */
934
935void clear_array(b)
936char *b;
937{
938 int i;
939
940 i = 0;
941 while (i++ < ARSIZE) *b++ = '0';
942
943} /* clear_array */
944
945int comp_array(a, b, range)
946char *a, *b;
947int range;
948{
949 if ((range < 0) || (range > ARSIZE)) {
950 err(100, "comp_array", "illegal range");
951 return(FAIL);
952 } else {
953 while (range-- && (*a++ == *b++));
954 if (*--a == *--b)
955 return(OK);
956 else
957 return(FAIL);
958 }
959} /* comp_array */
960
961void try_close(filedes, name)
962int filedes;
963char *name;
964{
965 if (close(filedes) != OK) err(5, CLOSE, name);
966} /* try_close */
967
968void try_unlink(fname)
969char *fname;
970{
971 if (unlink(fname) != 0) err(5, UNLINK, fname);
972} /* try_unlink */
973
974void Remove(fdes, fname)
975int fdes;
976char *fname;
977{
978 try_close(fdes, fname);
979 try_unlink(fname);
980} /* Remove */
981
982int get_mode(name)
983char *name;
984{
985 struct stat stbf1;
986
987 if (stat(name, &stbf1) != OK) {
988 err(5, STAT, name);
989 return(stbf1.st_mode); /* return a mode which will cause *
990 * error in the calling function *
991 * (file/dir bit) */
992 } else
993 return(stbf1.st_mode & 07777); /* take last 4 bits */
994} /* get_mode */
995
996/*****************************************************************************
997* *
998* CHECK *
999* *
1000*****************************************************************************/
1001
1002void check(scall, number)
1003int number;
1004char *scall;
1005{
1006 if (errno != number) {
1007 e(NIL);
1008 str("\t");
1009 str(scall);
1010 str(": bad errno-value: ");
1011 put(errno);
1012 str(" should have been: ");
1013 put(number);
1014 nlcr();
1015 }
1016} /* check */
1017
1018void put(nr)
1019int nr;
1020{
1021 switch (nr) {
1022 case 0: str("unused"); break;
1023 case 1: str("EPERM"); break;
1024 case 2: str("ENOENT"); break;
1025 case 3: str("ESRCH"); break;
1026 case 4: str("EINTR"); break;
1027 case 5: str("EIO"); break;
1028 case 6: str("ENXIO"); break;
1029 case 7: str("E2BIG"); break;
1030 case 8: str("ENOEXEC"); break;
1031 case 9: str("EBADF"); break;
1032 case 10: str("ECHILD"); break;
1033 case 11: str("EAGAIN"); break;
1034 case 12: str("ENOMEM"); break;
1035 case 13: str("EACCES"); break;
1036 case 14: str("EFAULT"); break;
1037 case 15: str("ENOTBLK"); break;
1038 case 16: str("EBUSY"); break;
1039 case 17: str("EEXIST"); break;
1040 case 18: str("EXDEV"); break;
1041 case 19: str("ENODEV"); break;
1042 case 20: str("ENOTDIR"); break;
1043 case 21: str("EISDIR"); break;
1044 case 22: str("EINVAL"); break;
1045 case 23: str("ENFILE"); break;
1046 case 24: str("EMFILE"); break;
1047 case 25: str("ENOTTY"); break;
1048 case 26: str("ETXTBSY"); break;
1049 case 27: str("EFBIG"); break;
1050 case 28: str("ENOSPC"); break;
1051 case 29: str("ESPIPE"); break;
1052 case 30: str("EROFS"); break;
1053 case 31: str("EMLINK"); break;
1054 case 32: str("EPIPE"); break;
1055 case 33: str("EDOM"); break;
1056 case 34: str("ERANGE"); break;
1057 }
1058}
1059
1060/*****************************************************************************
1061* *
1062* ALOT-functions *
1063* *
1064*****************************************************************************/
1065
1066int open_alot()
1067{
1068 int i;
1069
1070 for (i = 0; i < MAXOPEN; i++)
1071 if (open(file[i], R) == FAIL) break;
1072 if (i == 0) err(5, "open_alot", "at all");
1073 return(i);
1074} /* open_alot */
1075
1076int close_alot(number)
1077int number;
1078{
1079 int i, count = 0;
1080
1081 if (number > MAXOPEN)
1082 err(5, "close_alot", "accept this argument");
1083 else
1084 for (i = FF; i < number + FF; i++)
1085 if (close(i) != OK) count++;
1086
1087 return(number - count); /* return number of closed files */
1088} /* close_alot */
1089
1090/*****************************************************************************
1091* *
1092* CLEAN UP THE MESS *
1093* *
1094*****************************************************************************/
1095
1096void clean_up_the_mess()
1097{
1098 int i;
1099 char dirname[6];
1100
1101 /* First remove 'a lot' files */
1102 for (i = 0; i < MAXOPEN; i++) try_unlink(file[i]);
1103
1104 /* Unlink the files in dir 'drwx' */
1105 if (chdir("drwx") != OK)
1106 err(5, CHDIR, "to 'drwx'");
1107 else {
1108 for (i = 0; i < 8; i++) try_unlink(fnames[i]);
1109 if (chdir("..") != OK) err(5, CHDIR, "to '..'");
1110 }
1111
1112 /* Before unlinking files in some dirs, make them writable */
1113 chmod_8_dirs(RWX);
1114
1115 /* Unlink files in other dirs */
1116 try_unlink("d-wx/rwx");
1117 try_unlink("dr-x/rwx");
1118 try_unlink("drw-/rwx");
1119
1120 /* Unlink dirs */
1121 for (i = 0; i < 8; i++) {
1122 strcpy(dirname, "d");
1123 strcat(dirname, fnames[i]);
1124
1125 /* 'dirname' contains the directoryname */
1126 rmdir(dirname);
1127 }
1128
1129 /* FINISH */
1130} /* clean_up_the_mess */
1131
1132void chmod_8_dirs(sw)
1133int sw; /* if switch == 8, give all different
1134 * mode,else the same mode */
1135{
1136 int mode;
1137 int i;
1138
1139 if (sw == 8)
1140 mode = 0;
1141 else
1142 mode = sw;
1143
1144 for (i = 0; i < 8; i++) {
1145 chmod(dir[i], 040000 + mode * 0100);
1146 if (sw == 8) mode++;
1147 }
1148}
1149
1150void quit()
1151{
1152
1153 chdir("..");
1154 system("rm -rf DIR*");
1155
1156 if (errct == 0) {
1157 printf("ok\n");
1158 exit(0);
1159 } else {
1160 printf("%d errors\n", errct);
1161 exit(1);
1162 }
1163}
Note: See TracBrowser for help on using the repository browser.