3 /* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
5 /* "const.h", created by Rene Montsma and Menno Wilcke */
7 #include <sys/types.h> /* needed in struct stat */
8 #include <sys/stat.h> /* struct stat */
10 #include <errno.h> /* the error-numbers */
18 #define NOCRASH 1 /* test11(), 2nd pipe */
19 #define PDPNOHANG 1 /* test03(), write_standards() */
24 #define FF 3 /* first free filedes. */
25 #define USER 1 /* uid */
26 #define GROUP 0 /* gid */
28 #define ARSIZE 256 /* array size */
29 #define PIPESIZE 3584 /* maxnumber of bytes to be written on pipe */
30 #define MAXOPEN (OPEN_MAX-3) /* maximum number of extra open files */
31 #define MAXLINK 0177 /* maximum number of links per file */
32 #define MASK 0777 /* selects lower nine bits */
33 #define READ_EOF 0 /* returned by read-call at eof */
38 #define R 0 /* read (open-call) */
39 #define W 1 /* write (open-call) */
40 #define RW 2 /* read & write (open-call) */
42 #define RWX 7 /* read & write & execute (mode) */
52 #define ACCESS "access"
56 #define UNLINK "unlink"
69 /* "decl.c", created by Rene Montsma and Menno Wilcke */
71 /* Used in open_alot, close_alot */
72 char *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",
77 /* Needed for easy creating and deleting of directories */
79 /* "test.c", created by Rene Montsma and Menno Wilcke */
81 _PROTOTYPE(int main
, (void));
82 _PROTOTYPE(void test
, (void));
83 _PROTOTYPE(void test01
, (void));
84 _PROTOTYPE(void test02
, (void));
85 _PROTOTYPE(void test03
, (void));
86 _PROTOTYPE(void write_standards
, (int filedes
, char a
[]));
87 _PROTOTYPE(void test04
, (void));
88 _PROTOTYPE(void read_standards
, (int filedes
, char a
[]));
89 _PROTOTYPE(void read_more
, (int filedes
, char a
[]));
90 _PROTOTYPE(void test05
, (void));
91 _PROTOTYPE(void try_open
, (char *fname
, int mode
, int test
));
92 _PROTOTYPE(void test06
, (void));
93 _PROTOTYPE(void test07
, (void));
94 _PROTOTYPE(void access_standards
, (void));
95 _PROTOTYPE(void try_access
, (char *fname
, int mode
, int test
));
96 _PROTOTYPE(void e
, (char *string
));
97 _PROTOTYPE(void nlcr
, (void));
98 _PROTOTYPE(void str
, (char *s
));
99 _PROTOTYPE(void err
, (int number
, char *scall
, char *name
));
100 _PROTOTYPE(void make_and_fill_dirs
, (void));
101 _PROTOTYPE(void put_file_in_dir
, (char *dirname
, int mode
));
102 _PROTOTYPE(void init_array
, (char *a
));
103 _PROTOTYPE(void clear_array
, (char *b
));
104 _PROTOTYPE(int comp_array
, (char *a
, char *b
, int range
));
105 _PROTOTYPE(void try_close
, (int filedes
, char *name
));
106 _PROTOTYPE(void try_unlink
, (char *fname
));
107 _PROTOTYPE(void Remove
, (int fdes
, char *fname
));
108 _PROTOTYPE(int get_mode
, (char *name
));
109 _PROTOTYPE(void check
, (char *scall
, int number
));
110 _PROTOTYPE(void put
, (int nr
));
111 _PROTOTYPE(int open_alot
, (void));
112 _PROTOTYPE(int close_alot
, (int number
));
113 _PROTOTYPE(void clean_up_the_mess
, (void));
114 _PROTOTYPE(void chmod_8_dirs
, (int sw
));
115 _PROTOTYPE(void quit
, (void));
117 /*****************************************************************************
119 ****************************************************************************/
124 if (geteuid() == 0 || getuid() == 0) {
125 printf("Test 18 cannot run as root; test aborted\n");
129 system("rm -rf DIR_18; mkdir DIR_18");
134 fflush(stdout
); /* have to flush for child's benefit */
149 umask(0); /* not honest, but i always forget */
152 make_and_fill_dirs();
162 /* "t1.c" created by Rene Montsma and Menno Wilcke */
164 /*****************************************************************************
166 ****************************************************************************/
169 int oldvalue
, newvalue
, tempvalue
;
172 if ((oldvalue
= umask(0777)) != 0) err(0, UMASK
, NIL
);
174 /* Special test: only the lower 9 bits (protection bits) may part- *
175 * icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
176 * not change any value. */
178 if ((newvalue
= umask(~0777)) != 0777) err(1, UMASK
, "illegal");
179 if (oldvalue
== newvalue
) err(11, UMASK
, "not change mask");
181 if ((tempvalue
= umask(0)) != 0) err(2, UMASK
, "values");
183 /* Now test all possible modes of umask on a file */
184 for (newvalue
= MASK
; newvalue
>= 0; newvalue
-= 0111) {
185 tempvalue
= umask(newvalue
);
186 if (tempvalue
!= oldvalue
) {
187 err(1, UMASK
, "illegal");
188 break; /* no use trying more */
189 } else if ((nr
= creat("file01", 0777)) < 0)
190 err(5, CREAT
, "'file01'");
192 try_close(nr
, "'file01'");
193 if (get_mode("file01") != (MASK
& ~newvalue
))
194 err(7, UMASK
, "mode computed");
195 try_unlink("file01");
200 /* The loop has terminated with umask(0) */
201 if ((tempvalue
= umask(0)) != 0)
202 err(7, UMASK
, "umask may influence rest of tests!");
205 /*****************************************************************************
207 ****************************************************************************/
211 char a
[ARSIZE
], b
[ARSIZE
];
215 /* Create twenty files, check filedes */
216 for (n
= 0; n
< MAXOPEN
; n
++) {
217 if (creat(file
[n
], mode
) != FF
+ n
)
218 err(13, CREAT
, file
[n
]);
220 if (get_mode(file
[n
]) != mode
)
221 err(7, CREAT
, "mode set while creating many files");
223 /* Change mode of file to standard mode, we want to *
224 * use a lot (20) of files to be opened later, see *
225 * open_alot(), close_alot(). */
226 if (chmod(file
[n
], 0700) != OK
) err(5, CHMOD
, file
[n
]);
229 mode
= (mode
+ 0100) % 01000;
232 /* Already twenty files opened; opening another has to fail */
233 if (creat("file02", 0777) != FAIL
)
234 err(9, CREAT
, "created");
236 check(CREAT
, EMFILE
);
238 /* Close all files: seems blunt, but it isn't because we've *
239 * checked all fd's already */
240 if ((n
= close_alot(MAXOPEN
)) < MAXOPEN
) err(5, CLOSE
, "MAXOPEN files");
242 /* Creat 1 file twice; check */
243 if ((n
= creat("file02", 0777)) < 0)
244 err(5, CREAT
, "'file02'");
247 if (write(n
, a
, ARSIZE
) != ARSIZE
) err(1, WRITE
, "bad");
249 if ((n1
= creat("file02", 0755)) < 0) /* receate 'file02' */
250 err(5, CREAT
, "'file02' (2nd time)");
252 /* Fd should be at the top after recreation */
253 if (lseek(n1
, 0L, SEEK_END
) != 0)
254 err(11, CREAT
, "not truncate file by recreation");
256 /* Try to write on recreated file */
259 if (lseek(n1
, 0L, SEEK_SET
) != 0)
260 err(5, LSEEK
, "to top of 2nd fd 'file02'");
261 if (write(n1
, a
, ARSIZE
) != ARSIZE
)
262 err(1, WRITE
, "(2) bad");
264 /* In order to read we've to close and open again */
265 try_close(n1
, "'file02' (2nd creation)");
266 if ((n1
= open("file02", RW
)) < 0)
267 err(5, OPEN
, "'file02' (2nd recreation)");
270 if (lseek(n1
, 0L, SEEK_SET
) != 0)
271 err(5, LSEEK
, "to top 'file02'(2nd fd) (2)");
272 if (read(n1
, b
, ARSIZE
) != ARSIZE
)
273 err(1, READ
, "wrong");
275 if (comp_array(a
, b
, ARSIZE
) != OK
) err(11, CREAT
,
276 "not really truncate file by recreation");
278 if (get_mode("file02") != 0777)
279 err(11, CREAT
, "not maintain mode by recreation");
280 try_close(n1
, "recreated 'file02'");
286 /* Give 'creat' wrong input: dir not searchable */
287 if (creat("drw-/file02", 0777) != FAIL
)
288 err(4, CREAT
, "'drw-'");
290 check(CREAT
, EACCES
);
292 /* Dir not writable */
293 if (creat("dr-x/file02", 0777) != FAIL
)
294 err(12, CREAT
, "'dr-x/file02'");
296 check(CREAT
, EACCES
);
298 /* File not writable */
299 if (creat("drwx/r-x", 0777) != FAIL
)
300 err(11, CREAT
, "recreate non-writable file");
302 check(CREAT
, EACCES
);
304 /* Try to creat a dir */
305 if ((n
= creat("dir", 040777)) != FAIL
) {
306 if (fstat(n
, &stbf1
) != OK
)
307 err(5, FSTAT
, "'dir'");
308 else if (stbf1
.st_mode
!= (mode_t
) 0100777)
309 /* Cast because mode is negative :-(.
310 * HACK DEBUG FIXME: this appears to duplicate
313 err(11, CREAT
, "'creat' a new directory");
317 /* We don't consider it to be a bug when creat * does not accept
320 /* File is an existing dir */
321 if (creat("drwx", 0777) != FAIL
)
322 err(11, CREAT
, "create an existing dir!");
324 check(CREAT
, EISDIR
);
327 /*****************************************************************************
329 ****************************************************************************/
338 /* Test write after a CREAT */
339 if ((n
= creat("file03", 0700)) != FF
) /* 'file03' only open file */
340 err(13, CREAT
, "'file03'");
342 write_standards(n
, a
); /* test simple writes, wrong input too */
343 try_close(n
, "'file03'");
346 /* Test write after an OPEN */
347 if ((n
= open("file03", W
)) < 0)
348 err(5, OPEN
, "'file03'");
350 write_standards(n
, a
); /* test simple writes, wrong input too */
352 /* Test write after a DUP */
353 if ((n1
= dup(n
)) < 0)
354 err(5, DUP
, "'file03'");
356 write_standards(n1
, a
);
357 try_close(n1
, "duplicated fd 'file03'");
360 /* Remove testfile */
363 /* Test write after a PIPE */
367 write_standards(fd
[1], a
);
368 try_close(fd
[0], "'fd[0]'");
369 try_close(fd
[1], "'fd[1]'");
372 /* Last test: does write check protections ? */
373 if ((n
= open("drwx/r--", R
)) < 0)
374 err(5, OPEN
, "'drwx/r--'");
376 if (write(n
, a
, ARSIZE
) != FAIL
)
377 err(11, WRITE
, "write on non-writ. file");
380 try_close(n
, "'drwx/r--'");
384 void write_standards(filedes
, a
)
389 /* Write must return written account of numbers */
390 if (write(filedes
, a
, ARSIZE
) != ARSIZE
) err(1, WRITE
, "bad");
392 /* Try giving 'write' wrong input */
394 if (write(-1, a
, ARSIZE
) != FAIL
)
395 err(2, WRITE
, "filedes");
399 /* Wrong length (illegal) */
401 if (write(filedes
, a
, -ARSIZE
) != FAIL
)
402 err(2, WRITE
, "length");
404 check(WRITE
, EINVAL
); /* EFAULT on vu45 */
406 } /* write_standards */
408 /* "t2.c", created by Rene Montsma and Menno Wilcke */
410 /*****************************************************************************
412 ****************************************************************************/
418 /* Test read after creat */
419 if ((n
= creat("file04", 0700)) != FF
) /* no other open files may be
421 err(13, CREAT
, "'file04'");
423 /* Closing and opening needed before writing */
424 try_close(n
, "'file04'");
425 if ((n
= open("file04", RW
)) < 0) err(5, OPEN
, "'file04'");
429 if (write(n
, a
, ARSIZE
) != ARSIZE
)
430 err(1, WRITE
, "bad");
432 if (lseek(n
, 0L, SEEK_SET
) != 0) err(5, LSEEK
, "'file04'");
433 read_standards(n
, a
);
436 try_close(n
, "'file04'");
439 /* Test read after OPEN */
440 if ((n
= open("file04", R
)) < 0)
441 err(5, OPEN
, "'file04'");
443 read_standards(n
, a
);
445 try_close(n
, "'file04'");
448 /* Test read after DUP */
449 if ((n
= open("file04", R
)) < 0) err(5, OPEN
, "'file04'");
450 if ((n1
= dup(n
)) < 0)
451 err(5, DUP
, "'file04'");
453 read_standards(n1
, a
);
455 try_close(n1
, "duplicated fd 'file04'");
458 /* Remove testfile */
461 /* Test read after pipe */
465 if (write(fd
[1], a
, ARSIZE
) != ARSIZE
) {
466 err(5, WRITE
, "'fd[1]'");
467 try_close(fd
[1], "'fd[1]'");
469 try_close(fd
[1], "'fd[1]'");
470 read_standards(fd
[0], a
);
472 try_close(fd
[0], "'fd[0]'");
475 /* Last test: try to read a read-protected file */
476 if ((n
= open("drwx/-wx", W
)) < 0)
477 err(5, OPEN
, "'drwx/-wx'");
479 if (read(n
, a
, ARSIZE
) != FAIL
)
480 err(11, READ
, "read a non-read. file");
483 try_close(n
, "'/drwx/-wx'");
487 void read_standards(filedes
, a
)
494 if (read(filedes
, b
, ARSIZE
) != ARSIZE
)
496 else if (comp_array(a
, b
, ARSIZE
) != OK
)
497 err(7, "read/write", "values");
498 else if (read(filedes
, b
, ARSIZE
) != READ_EOF
)
499 err(11, READ
, "read beyond endoffile");
501 /* Try giving read wrong input: wrong filedes */
502 if (read(FAIL
, b
, ARSIZE
) != FAIL
)
503 err(2, READ
, "filedes");
508 if (read(filedes
, b
, -ARSIZE
) != FAIL
)
509 err(2, READ
, "length");
512 } /* read_standards */
514 void read_more(filedes
, a
)
517 /* Separated from read_standards() because the PIPE test * would fail. */
522 if (lseek(filedes
, (long) (ARSIZE
/ 2), SEEK_SET
) != ARSIZE
/ 2)
523 err(5, LSEEK
, "to location ARSIZE/2");
526 if (read(filedes
, b
, ARSIZE
) != ARSIZE
/ 2) err(1, READ
, "bad");
528 for (i
= 0; i
< ARSIZE
/ 2; i
++)
529 if (b
[i
] != a
[(ARSIZE
/ 2) + i
])
530 err(7, READ
, "from location ARSIZE/2");
533 /*****************************************************************************
535 ****************************************************************************/
538 int n
, n1
, mode
, fd
[2];
541 /* Test open after CREAT */
542 if ((n
= creat("file05", 0700)) != FF
) /* no other open files left */
543 err(13, CREAT
, "'file05'");
545 if ((n1
= open("file05", RW
)) != FF
+ 1)
546 err(13, OPEN
, "'file05' after creation");
547 try_close(n1
, "'file05' (open after creation)");
549 try_close(n
, "'file05'");
550 if ((n
= open("file05", R
)) != FF
)
551 err(13, OPEN
, "after closing");
553 try_close(n
, "'file05' (open after closing)");
555 /* Remove testfile */
556 try_unlink("file05");
559 /* Test all possible modes, try_open not only opens file (sometimes) *
560 * but closes files too (when opened) */
561 if ((n
= creat("file05", 0700)) < 0) /* no other files left */
562 err(5, CREAT
, "'file05' (2nd time)");
564 try_close(n
, "file05");
565 for (mode
= 0; mode
<= 0700; mode
+= 0100) {
566 if (chmod("file05", mode
) != OK
) err(5, CHMOD
, "'file05'");
569 try_open("file05", R
, FAIL
);
570 try_open("file05", W
, FAIL
);
571 try_open("file05", RW
, FAIL
);
572 } else if (mode
>= 0200 && mode
<= 0300) {
573 try_open("file05", R
, FAIL
);
574 try_open("file05", W
, FF
);
575 try_open("file05", RW
, FAIL
);
576 } else if (mode
>= 0400 && mode
<= 0500) {
577 try_open("file05", R
, FF
);
578 try_open("file05", W
, FAIL
);
579 try_open("file05", RW
, FAIL
);
581 try_open("file05", R
, FF
);
582 try_open("file05", W
, FF
);
583 try_open("file05", RW
, FF
);
588 /* Test opening existing file */
589 if ((n
= open("drwx/rwx", R
)) < 0)
590 err(13, OPEN
, "existing file");
591 else { /* test close after DUP */
592 if ((n1
= dup(n
)) < 0)
593 err(13, DUP
, "'drwx/rwx'");
595 try_close(n1
, "duplicated fd 'drwx/rwx'");
597 if (read(n1
, b
, ARSIZE
) != FAIL
)
598 err(11, READ
, "on closed dupped fd 'drwx/rwx'");
602 if (read(n
, b
, ARSIZE
) == FAIL
) /* should read an eof */
603 err(13, READ
, "on fd '/drwx/rwx'");
605 try_close(n
, "'drwx/rwx'");
608 /* Test close after PIPE */
612 try_close(fd
[1], "duplicated fd 'fd[1]'");
614 /* Fd[1] really should be closed now; check */
616 if (read(fd
[0], b
, ARSIZE
) != READ_EOF
)
617 err(11, READ
, "read on empty pipe (and fd[1] was closed)");
618 try_close(fd
[0], "duplicated fd 'fd[0]'");
621 /* Try to open a non-existing file */
622 if (open("non-file", R
) != FAIL
)
623 err(11, OPEN
, "open non-executable file");
627 /* Dir does not exist */
628 if (open("dzzz/file05", R
) != FAIL
)
629 err(11, OPEN
, "open in an non-searchable dir");
633 /* Dir is not searchable */
634 if (n
= open("drw-/rwx", R
) != FAIL
)
635 err(11, OPEN
, "open in an non-searchabledir");
639 /* Unlink testfile */
640 try_unlink("file05");
642 /* File is not readable */
643 if (open("drwx/-wx", R
) != FAIL
)
644 err(11, OPEN
, "open unreadable file for reading");
648 /* File is not writable */
649 if (open("drwx/r-x", W
) != FAIL
)
650 err(11, OPEN
, "open unwritable file for writing");
654 /* Try opening more than MAXOPEN ('extra' (19-8-85)) files */
655 if ((n
= open_alot()) != MAXOPEN
)
656 err(13, OPEN
, "MAXOPEN files");
658 /* Maximum # of files opened now, another open should fail
659 * because * all filedescriptors have already been used. */
660 if (open("drwx/rwx", RW
) != FAIL
)
661 err(9, OPEN
, "open");
664 if (close_alot(n
) != n
) err(5, CLOSE
, "all opened files");
666 /* Can close make mistakes ? */
667 if (close(-1) != FAIL
)
668 err(2, CLOSE
, "filedes");
673 void try_open(fname
, mode
, test
)
679 if ((n
= open(fname
, mode
)) != test
)
680 err(11, OPEN
, "break through filepermission with an incorrect mode");
681 if (n
!= FAIL
) try_close(n
, fname
); /* cleanup */
684 /*****************************************************************************
686 ****************************************************************************/
689 char a
[ARSIZE
], b
[ARSIZE
];
692 if ((fd
= open("drwx/rwx", RW
)) != FF
) /* there should be no */
693 err(13, OPEN
, "'drwx/rwx'"); /* other open files */
696 if (write(fd
, a
, 10) != 10)
697 err(1, WRITE
, "bad");
699 /* Lseek back to begin file */
700 if (lseek(fd
, 0L, SEEK_SET
) != 0)
701 err(5, LSEEK
, "to begin file");
702 else if (read(fd
, b
, 10) != 10)
704 else if (comp_array(a
, b
, 10) != OK
)
705 err(7, LSEEK
, "values r/w after lseek to begin");
706 /* Lseek to endoffile */
707 if (lseek(fd
, 0L, SEEK_END
) != 10)
708 err(5, LSEEK
, "to end of file");
709 else if (read(fd
, b
, 1) != READ_EOF
)
710 err(7, LSEEK
, "read at end of file");
711 /* Lseek beyond file */
712 if (lseek(fd
, 10L, SEEK_CUR
) != 20)
713 err(5, LSEEK
, "beyond end of file");
714 else if (write(fd
, a
, 10) != 10)
715 err(1, WRITE
, "bad");
717 /* Lseek to begin second write */
718 if (lseek(fd
, 20L, SEEK_SET
) != 20)
719 err(5, LSEEK
, "'/drwx/rwx'");
720 if (read(fd
, b
, 10) != 10)
722 else if (comp_array(a
, b
, 10) != OK
)
724 "values read after lseek MAXOPEN");
728 /* Lseek to position before begin of file */
729 if (lseek(fd
, -1L, 0) != FAIL
)
730 err(11, LSEEK
, "lseek before beginning of file");
732 try_close(fd
, "'drwx/rwx'");
735 /* Lseek on invalid filediscriptor */
736 if (lseek(-1, 0L, SEEK_SET
) != FAIL
)
737 err(2, LSEEK
, "filedes");
743 /* "t3.c", created by Rene Montsma and Menno Wilcke */
745 /*****************************************************************************
747 ****************************************************************************/
750 /* Check with proper parameters */
751 if (access("drwx/rwx", RWX
) != OK
) err(5, ACCESS
, "accessible file");
753 if (access("./././drwx/././rwx", 0) != OK
)
754 err(5, ACCESS
, "'/./.(etc)/drwx///rwx'");
756 /* Check 8 files with 8 different modes on 8 accesses */
757 if (chdir("drwx") != OK
) err(5, CHDIR
, "'drwx'");
761 if (chdir("..") != OK
) err(5, CHDIR
, "'..'");
763 /* Check several wrong combinations */
764 /* File does not exist */
765 if (access("non-file", 0) != FAIL
)
766 err(11, ACCESS
, "access non-existing file");
768 check(ACCESS
, ENOENT
);
770 /* Non-searchable dir */
771 if (access("drw-/rwx", 0) != FAIL
)
772 err(4, ACCESS
, "'drw-'");
774 check(ACCESS
, EACCES
);
776 /* Searchable dir, but wrong file-mode */
777 if (access("drwx/--x", RWX
) != FAIL
)
778 err(11, ACCESS
, "a non accessible file");
780 check(ACCESS
, EACCES
);
784 void access_standards()
788 for (i
= 0; i
< 8; i
++)
790 try_access(fnames
[mode
], i
, OK
);
792 try_access(fnames
[mode
], i
, FAIL
);
795 for (i
= 0; i
< 8; i
++)
797 try_access(fnames
[mode
], i
, OK
);
799 try_access(fnames
[mode
], i
, FAIL
);
802 for (i
= 0; i
< 8; i
++)
803 if (i
== 0 || i
== 2)
804 try_access(fnames
[mode
], i
, OK
);
806 try_access(fnames
[mode
], i
, FAIL
);
809 for (i
= 0; i
< 8; i
++)
811 try_access(fnames
[mode
], i
, OK
);
813 try_access(fnames
[mode
], i
, FAIL
);
816 for (i
= 0; i
< 8; i
++)
817 if (i
== 0 || i
== 4)
818 try_access(fnames
[mode
], i
, OK
);
820 try_access(fnames
[mode
], i
, FAIL
);
823 for (i
= 0; i
< 8; i
++)
824 if (i
== 0 || i
== 1 || i
== 4 || i
== 5)
825 try_access(fnames
[mode
], i
, OK
);
827 try_access(fnames
[mode
], i
, FAIL
);
830 for (i
= 0; i
< 8; i
++)
832 try_access(fnames
[mode
], i
, OK
);
834 try_access(fnames
[mode
], i
, FAIL
);
837 for (i
= 0; i
< 8; i
++) try_access(fnames
[mode
], i
, OK
);
838 } /* access_standards */
840 void try_access(fname
, mode
, test
)
844 if (access(fname
, mode
) != test
)
845 err(100, ACCESS
, "incorrect access on a file (try_access)");
848 /* "support.c", created by Rene Montsma and Menno Wilcke */
850 /* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
851 try_close, try_unlink, Remove, get_mode, check, open_alot,
852 close_alot, clean_up_the_mess.
855 /***********************************************************************
857 **********************************************************************/
858 /* First extended functions (i.e. not oldfashioned monixcalls.
859 e(), nlcr(), octal.*/
864 printf("Test program error: %s\n", string
);
879 /*****************************************************************************
883 *****************************************************************************/
884 void err(number
, scall
, name
)
885 /* Give nice error messages */
892 if (errct
> MAXERR
) {
893 printf("Too many errors; test aborted\n");
895 system("rm -rf DIR*");
903 str(": illegal initial value.");
909 str(" value returned.");
913 str(": accepting illegal ");
919 str(": accepting non-existing file.");
923 str(": could search non-searchable dir (");
943 str(": wrong values.");
947 str(": accepting too many ");
953 str(": even a superuser can't do anything!");
963 str(": could write in non-writable dir (");
969 str(": wrong filedes returned (");
974 str(scall
); /* very common */
979 default: str("errornumber does not exist!\n");
984 /*****************************************************************************
986 * MAKE_AND_FILL_DIRS *
988 *****************************************************************************/
990 void make_and_fill_dirs()
991 /* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", *
992 * "drw-", "drwx". * Then create 8 files
993 * in "drwx", and some needed files in other dirs. */
997 for (i
= 0; i
< 8; i
++) {
999 chown(dir
[i
], USER_ID
, GROUP_ID
);
1004 for (mode
= 0; mode
< 8; mode
++) put_file_in_dir("drwx", mode
);
1006 put_file_in_dir("d-wx", RWX
);
1007 put_file_in_dir("dr-x", RWX
);
1008 put_file_in_dir("drw-", RWX
);
1010 chmod_8_dirs(8); /* 8 means; 8 different modes */
1012 } /* make_and_fill_dirs */
1014 void put_file_in_dir(dirname
, mode
)
1017 /* Fill directory 'dirname' with file with mode 'mode'. */
1021 if (chdir(dirname
) != OK
)
1022 err(5, CHDIR
, "to dirname (put_f_in_dir)");
1024 /* Creat the file */
1025 if ((nr
= creat(fnames
[mode
], mode
* 0100)) < 0)
1026 err(13, CREAT
, fnames
[mode
]);
1028 try_close(nr
, fnames
[mode
]);
1030 if (chdir("..") != OK
)
1031 err(5, CHDIR
, "to previous dir (put_f_in_dir)");
1033 } /* put_file_in_dir */
1035 /*****************************************************************************
1039 *(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode') *
1041 *****************************************************************************/
1049 while (i
++ < ARSIZE
) *a
++ = 'a' + (i
% 26);
1058 while (i
++ < ARSIZE
) *b
++ = '0';
1062 int comp_array(a
, b
, range
)
1066 if ((range
< 0) || (range
> ARSIZE
)) {
1067 err(100, "comp_array", "illegal range");
1070 while (range
-- && (*a
++ == *b
++));
1078 void try_close(filedes
, name
)
1082 if (close(filedes
) != OK
) err(5, CLOSE
, name
);
1085 void try_unlink(fname
)
1088 if (unlink(fname
) != 0) err(5, UNLINK
, fname
);
1091 void Remove(fdes
, fname
)
1095 try_close(fdes
, fname
);
1104 if (stat(name
, &stbf1
) != OK
) {
1106 return(stbf1
.st_mode
); /* return a mode which will cause *
1107 * error in the calling function *
1110 return(stbf1
.st_mode
& 07777); /* take last 4 bits */
1113 /*****************************************************************************
1117 *****************************************************************************/
1119 void check(scall
, number
)
1123 if (errno
!= number
) {
1127 str(": bad errno-value: ");
1129 str(" should have been: ");
1139 case 0: str("unused"); break;
1140 case 1: str("EPERM"); break;
1141 case 2: str("ENOENT"); break;
1142 case 3: str("ESRCH"); break;
1143 case 4: str("EINTR"); break;
1144 case 5: str("EIO"); break;
1145 case 6: str("ENXIO"); break;
1146 case 7: str("E2BIG"); break;
1147 case 8: str("ENOEXEC"); break;
1148 case 9: str("EBADF"); break;
1149 case 10: str("ECHILD"); break;
1150 case 11: str("EAGAIN"); break;
1151 case 12: str("ENOMEM"); break;
1152 case 13: str("EACCES"); break;
1153 case 14: str("EFAULT"); break;
1154 case 15: str("ENOTBLK"); break;
1155 case 16: str("EBUSY"); break;
1156 case 17: str("EEXIST"); break;
1157 case 18: str("EXDEV"); break;
1158 case 19: str("ENODEV"); break;
1159 case 20: str("ENOTDIR"); break;
1160 case 21: str("EISDIR"); break;
1161 case 22: str("EINVAL"); break;
1162 case 23: str("ENFILE"); break;
1163 case 24: str("EMFILE"); break;
1164 case 25: str("ENOTTY"); break;
1165 case 26: str("ETXTBSY"); break;
1166 case 27: str("EFBIG"); break;
1167 case 28: str("ENOSPC"); break;
1168 case 29: str("ESPIPE"); break;
1169 case 30: str("EROFS"); break;
1170 case 31: str("EMLINK"); break;
1171 case 32: str("EPIPE"); break;
1172 case 33: str("EDOM"); break;
1173 case 34: str("ERANGE"); break;
1177 /*****************************************************************************
1181 *****************************************************************************/
1187 for (i
= 0; i
< MAXOPEN
; i
++)
1188 if (open(file
[i
], R
) == FAIL
) break;
1189 if (i
== 0) err(5, "open_alot", "at all");
1193 int close_alot(number
)
1198 if (number
> MAXOPEN
)
1199 err(5, "close_alot", "accept this argument");
1201 for (i
= FF
; i
< number
+ FF
; i
++)
1202 if (close(i
) != OK
) count
++;
1204 return(number
- count
); /* return number of closed files */
1207 /*****************************************************************************
1209 * CLEAN UP THE MESS *
1211 *****************************************************************************/
1213 void clean_up_the_mess()
1218 /* First remove 'alot' files */
1219 for (i
= 0; i
< MAXOPEN
; i
++) try_unlink(file
[i
]);
1221 /* Unlink the files in dir 'drwx' */
1222 if (chdir("drwx") != OK
)
1223 err(5, CHDIR
, "to 'drwx'");
1225 for (i
= 0; i
< 8; i
++) try_unlink(fnames
[i
]);
1226 if (chdir("..") != OK
) err(5, CHDIR
, "to '..'");
1229 /* Before unlinking files in some dirs, make them writable */
1232 /* Unlink files in other dirs */
1233 try_unlink("d-wx/rwx");
1234 try_unlink("dr-x/rwx");
1235 try_unlink("drw-/rwx");
1238 for (i
= 0; i
< 8; i
++) {
1239 strcpy(dirname
, "d");
1240 strcat(dirname
, fnames
[i
]);
1241 /* 'dirname' contains the directoryname */
1246 } /* clean_up_the_mess */
1248 void chmod_8_dirs(sw
)
1249 int sw
; /* if switch == 8, give all different
1250 * mode,else the same mode */
1260 for (i
= 0; i
< 8; i
++) {
1261 chmod(dir
[i
], 040000 + mode
* 0100);
1262 if (sw
== 8) mode
++;
1270 system("rm -rf DIR*");
1276 printf("%d errors\n", errct
);