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 */
20 #define NOCRASH 1 /* test11(), 2nd pipe */
21 #define PDPNOHANG 1 /* test03(), write_standards() */
26 #define FF 3 /* first free filedes. */
27 #define USER 1 /* uid */
28 #define GROUP 0 /* gid */
30 #define ARSIZE 256 /* array size */
31 #define PIPESIZE 3584 /* maxnumber of bytes to be written on pipe */
32 #define MAXOPEN (OPEN_MAX-3) /* maximum number of extra open files */
33 #define MAXLINK 0177 /* maximum number of links per file */
34 #define MASK 0777 /* selects lower nine bits */
35 #define READ_EOF 0 /* returned by read-call at eof */
40 #define R 0 /* read (open-call) */
41 #define W 1 /* write (open-call) */
42 #define RW 2 /* read & write (open-call) */
44 #define RWX 7 /* read & write & execute (mode) */
50 #define WRITEV "writev"
56 #define ACCESS "access"
60 #define UNLINK "unlink"
73 /* "decl.c", created by Rene Montsma and Menno Wilcke */
75 /* Used in open_alot, close_alot */
76 char *file
[20] = {"f0", "f1", "f2", "f3", "f4", "f5", "f6",
77 "f7", "f8", "f9", "f10", "f11", "f12", "f13",
78 "f14", "f15", "f16", "f17", "f18", "f19"}, *fnames
[8] = {"---", "--x", "-w-", "-wx", "r--",
79 "r-x", "rw-", "rwx"}, *dir
[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",
81 /* Needed for easy creating and deleting of directories */
83 /* "test.c", created by Rene Montsma and Menno Wilcke */
85 _PROTOTYPE(int main
, (int argc
, char **argv
));
86 _PROTOTYPE(void test
, (void));
87 _PROTOTYPE(void test01
, (void));
88 _PROTOTYPE(void test02
, (void));
89 _PROTOTYPE(void test03
, (void));
90 _PROTOTYPE(void write_standards
, (int filedes
, char a
[]));
91 _PROTOTYPE(void test04
, (void));
92 _PROTOTYPE(void read_standards
, (int filedes
, char a
[]));
93 _PROTOTYPE(void read_more
, (int filedes
, char a
[]));
94 _PROTOTYPE(void test05
, (void));
95 _PROTOTYPE(void try_open
, (char *fname
, int mode
, int test
));
96 _PROTOTYPE(void test06
, (void));
97 _PROTOTYPE(void test07
, (void));
98 _PROTOTYPE(void access_standards
, (void));
99 _PROTOTYPE(void test08
, (void));
100 _PROTOTYPE(static int iovec_is_equal
,
101 (struct iovec
*x
, struct iovec
*y
, size_t size
));
102 _PROTOTYPE(static size_t iovec_setup
,
103 (int pattern
, struct iovec
*iovec
, char *buffer
, int count
));
104 _PROTOTYPE(static int power
, (int base
, int exponent
));
105 _PROTOTYPE(void try_access
, (char *fname
, int mode
, int test
));
106 _PROTOTYPE(void e
, (char *string
));
107 _PROTOTYPE(void nlcr
, (void));
108 _PROTOTYPE(void str
, (char *s
));
109 _PROTOTYPE(void err
, (int number
, char *scall
, char *name
));
110 _PROTOTYPE(void make_and_fill_dirs
, (void));
111 _PROTOTYPE(void put_file_in_dir
, (char *dirname
, int mode
));
112 _PROTOTYPE(void init_array
, (char *a
));
113 _PROTOTYPE(void clear_array
, (char *b
));
114 _PROTOTYPE(int comp_array
, (char *a
, char *b
, int range
));
115 _PROTOTYPE(void try_close
, (int filedes
, char *name
));
116 _PROTOTYPE(void try_unlink
, (char *fname
));
117 _PROTOTYPE(void Remove
, (int fdes
, char *fname
));
118 _PROTOTYPE(int get_mode
, (char *name
));
119 _PROTOTYPE(void check
, (char *scall
, int number
));
120 _PROTOTYPE(void put
, (int nr
));
121 _PROTOTYPE(int open_alot
, (void));
122 _PROTOTYPE(int close_alot
, (int number
));
123 _PROTOTYPE(void clean_up_the_mess
, (void));
124 _PROTOTYPE(void chmod_8_dirs
, (int sw
));
125 _PROTOTYPE(void quit
, (void));
127 /*****************************************************************************
129 ****************************************************************************/
130 int main(int argc
, char **argv
)
132 char buffer
[PATH_MAX
+ 1];
135 if (geteuid() == 0 || getuid() == 0) {
136 realpath(argv
[0], buffer
);
137 execl("/usr/bin/su", "/usr/bin/su", "-", "ast", "-c", buffer
, NULL
);
138 printf("Test 18 cannot run as root; test aborted\n");
142 system("rm -rf DIR_18; mkdir DIR_18");
147 fflush(stdout
); /* have to flush for child's benefit */
162 umask(0); /* not honest, but i always forget */
165 make_and_fill_dirs();
176 /* "t1.c" created by Rene Montsma and Menno Wilcke */
178 /*****************************************************************************
180 ****************************************************************************/
183 int oldvalue
, newvalue
, tempvalue
;
186 if ((oldvalue
= umask(0777)) != 0) err(0, UMASK
, NIL
);
188 /* Special test: only the lower 9 bits (protection bits) may part- *
189 * icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
190 * not change any value. */
192 if ((newvalue
= umask(~0777)) != 0777) err(1, UMASK
, "illegal");
193 if (oldvalue
== newvalue
) err(11, UMASK
, "not change mask");
195 if ((tempvalue
= umask(0)) != 0) err(2, UMASK
, "values");
197 /* Now test all possible modes of umask on a file */
198 for (newvalue
= MASK
; newvalue
>= 0; newvalue
-= 0111) {
199 tempvalue
= umask(newvalue
);
200 if (tempvalue
!= oldvalue
) {
201 err(1, UMASK
, "illegal");
202 break; /* no use trying more */
203 } else if ((nr
= creat("file01", 0777)) < 0)
204 err(5, CREAT
, "'file01'");
206 try_close(nr
, "'file01'");
207 if (get_mode("file01") != (MASK
& ~newvalue
))
208 err(7, UMASK
, "mode computed");
209 try_unlink("file01");
214 /* The loop has terminated with umask(0) */
215 if ((tempvalue
= umask(0)) != 0)
216 err(7, UMASK
, "umask may influence rest of tests!");
219 /*****************************************************************************
221 ****************************************************************************/
225 char a
[ARSIZE
], b
[ARSIZE
];
229 /* Create twenty files, check filedes */
230 for (n
= 0; n
< MAXOPEN
; n
++) {
231 if (creat(file
[n
], mode
) != FF
+ n
)
232 err(13, CREAT
, file
[n
]);
234 if (get_mode(file
[n
]) != mode
)
235 err(7, CREAT
, "mode set while creating many files");
237 /* Change mode of file to standard mode, we want to *
238 * use a lot (20) of files to be opened later, see *
239 * open_alot(), close_alot(). */
240 if (chmod(file
[n
], 0700) != OK
) err(5, CHMOD
, file
[n
]);
243 mode
= (mode
+ 0100) % 01000;
246 /* Already twenty files opened; opening another has to fail */
247 if (creat("file02", 0777) != FAIL
)
248 err(9, CREAT
, "created");
250 check(CREAT
, EMFILE
);
252 /* Close all files: seems blunt, but it isn't because we've *
253 * checked all fd's already */
254 if ((n
= close_alot(MAXOPEN
)) < MAXOPEN
) err(5, CLOSE
, "MAXOPEN files");
256 /* Creat 1 file twice; check */
257 if ((n
= creat("file02", 0777)) < 0)
258 err(5, CREAT
, "'file02'");
261 if (write(n
, a
, ARSIZE
) != ARSIZE
) err(1, WRITE
, "bad");
263 if ((n1
= creat("file02", 0755)) < 0) /* receate 'file02' */
264 err(5, CREAT
, "'file02' (2nd time)");
266 /* Fd should be at the top after recreation */
267 if (lseek(n1
, 0L, SEEK_END
) != 0)
268 err(11, CREAT
, "not truncate file by recreation");
270 /* Try to write on recreated file */
273 if (lseek(n1
, 0L, SEEK_SET
) != 0)
274 err(5, LSEEK
, "to top of 2nd fd 'file02'");
275 if (write(n1
, a
, ARSIZE
) != ARSIZE
)
276 err(1, WRITE
, "(2) bad");
278 /* In order to read we've to close and open again */
279 try_close(n1
, "'file02' (2nd creation)");
280 if ((n1
= open("file02", RW
)) < 0)
281 err(5, OPEN
, "'file02' (2nd recreation)");
284 if (lseek(n1
, 0L, SEEK_SET
) != 0)
285 err(5, LSEEK
, "to top 'file02'(2nd fd) (2)");
286 if (read(n1
, b
, ARSIZE
) != ARSIZE
)
287 err(1, READ
, "wrong");
289 if (comp_array(a
, b
, ARSIZE
) != OK
) err(11, CREAT
,
290 "not really truncate file by recreation");
292 if (get_mode("file02") != 0777)
293 err(11, CREAT
, "not maintain mode by recreation");
294 try_close(n1
, "recreated 'file02'");
300 /* Give 'creat' wrong input: dir not searchable */
301 if (creat("drw-/file02", 0777) != FAIL
)
302 err(4, CREAT
, "'drw-'");
304 check(CREAT
, EACCES
);
306 /* Dir not writable */
307 if (creat("dr-x/file02", 0777) != FAIL
)
308 err(12, CREAT
, "'dr-x/file02'");
310 check(CREAT
, EACCES
);
312 /* File not writable */
313 if (creat("drwx/r-x", 0777) != FAIL
)
314 err(11, CREAT
, "recreate non-writable file");
316 check(CREAT
, EACCES
);
318 /* Try to creat a dir */
319 if ((n
= creat("dir", 040777)) != FAIL
) {
320 if (fstat(n
, &stbf1
) != OK
)
321 err(5, FSTAT
, "'dir'");
322 else if (stbf1
.st_mode
!= (mode_t
) 0100777)
323 /* Cast because mode is negative :-(.
324 * HACK DEBUG FIXME: this appears to duplicate
327 err(11, CREAT
, "'creat' a new directory");
331 /* We don't consider it to be a bug when creat * does not accept
334 /* File is an existing dir */
335 if (creat("drwx", 0777) != FAIL
)
336 err(11, CREAT
, "create an existing dir!");
338 check(CREAT
, EISDIR
);
341 /*****************************************************************************
343 ****************************************************************************/
352 /* Test write after a CREAT */
353 if ((n
= creat("file03", 0700)) != FF
) /* 'file03' only open file */
354 err(13, CREAT
, "'file03'");
356 write_standards(n
, a
); /* test simple writes, wrong input too */
357 try_close(n
, "'file03'");
360 /* Test write after an OPEN */
361 if ((n
= open("file03", W
)) < 0)
362 err(5, OPEN
, "'file03'");
364 write_standards(n
, a
); /* test simple writes, wrong input too */
366 /* Test write after a DUP */
367 if ((n1
= dup(n
)) < 0)
368 err(5, DUP
, "'file03'");
370 write_standards(n1
, a
);
371 try_close(n1
, "duplicated fd 'file03'");
374 /* Remove testfile */
377 /* Test write after a PIPE */
381 write_standards(fd
[1], a
);
382 try_close(fd
[0], "'fd[0]'");
383 try_close(fd
[1], "'fd[1]'");
386 /* Last test: does write check protections ? */
387 if ((n
= open("drwx/r--", R
)) < 0)
388 err(5, OPEN
, "'drwx/r--'");
390 if (write(n
, a
, ARSIZE
) != FAIL
)
391 err(11, WRITE
, "write on non-writ. file");
394 try_close(n
, "'drwx/r--'");
398 void write_standards(filedes
, a
)
403 /* Write must return written account of numbers */
404 if (write(filedes
, a
, ARSIZE
) != ARSIZE
) err(1, WRITE
, "bad");
406 /* Try giving 'write' wrong input */
408 if (write(-1, a
, ARSIZE
) != FAIL
)
409 err(2, WRITE
, "filedes");
413 /* Wrong length (illegal) */
415 if (write(filedes
, a
, -ARSIZE
) != FAIL
)
416 err(2, WRITE
, "length");
418 check(WRITE
, EINVAL
); /* EFAULT on vu45 */
420 } /* write_standards */
422 /* "t2.c", created by Rene Montsma and Menno Wilcke */
424 /*****************************************************************************
426 ****************************************************************************/
432 /* Test read after creat */
433 if ((n
= creat("file04", 0700)) != FF
) /* no other open files may be
435 err(13, CREAT
, "'file04'");
437 /* Closing and opening needed before writing */
438 try_close(n
, "'file04'");
439 if ((n
= open("file04", RW
)) < 0) err(5, OPEN
, "'file04'");
443 if (write(n
, a
, ARSIZE
) != ARSIZE
)
444 err(1, WRITE
, "bad");
446 if (lseek(n
, 0L, SEEK_SET
) != 0) err(5, LSEEK
, "'file04'");
447 read_standards(n
, a
);
450 try_close(n
, "'file04'");
453 /* Test read after OPEN */
454 if ((n
= open("file04", R
)) < 0)
455 err(5, OPEN
, "'file04'");
457 read_standards(n
, a
);
459 try_close(n
, "'file04'");
462 /* Test read after DUP */
463 if ((n
= open("file04", R
)) < 0) err(5, OPEN
, "'file04'");
464 if ((n1
= dup(n
)) < 0)
465 err(5, DUP
, "'file04'");
467 read_standards(n1
, a
);
469 try_close(n1
, "duplicated fd 'file04'");
472 /* Remove testfile */
475 /* Test read after pipe */
479 if (write(fd
[1], a
, ARSIZE
) != ARSIZE
) {
480 err(5, WRITE
, "'fd[1]'");
481 try_close(fd
[1], "'fd[1]'");
483 try_close(fd
[1], "'fd[1]'");
484 read_standards(fd
[0], a
);
486 try_close(fd
[0], "'fd[0]'");
489 /* Last test: try to read a read-protected file */
490 if ((n
= open("drwx/-wx", W
)) < 0)
491 err(5, OPEN
, "'drwx/-wx'");
493 if (read(n
, a
, ARSIZE
) != FAIL
)
494 err(11, READ
, "read a non-read. file");
497 try_close(n
, "'/drwx/-wx'");
501 void read_standards(filedes
, a
)
508 if (read(filedes
, b
, ARSIZE
) != ARSIZE
)
510 else if (comp_array(a
, b
, ARSIZE
) != OK
)
511 err(7, "read/write", "values");
512 else if (read(filedes
, b
, ARSIZE
) != READ_EOF
)
513 err(11, READ
, "read beyond endoffile");
515 /* Try giving read wrong input: wrong filedes */
516 if (read(FAIL
, b
, ARSIZE
) != FAIL
)
517 err(2, READ
, "filedes");
522 if (read(filedes
, b
, -ARSIZE
) != FAIL
)
523 err(2, READ
, "length");
526 } /* read_standards */
528 void read_more(filedes
, a
)
531 /* Separated from read_standards() because the PIPE test * would fail. */
536 if (lseek(filedes
, (long) (ARSIZE
/ 2), SEEK_SET
) != ARSIZE
/ 2)
537 err(5, LSEEK
, "to location ARSIZE/2");
540 if (read(filedes
, b
, ARSIZE
) != ARSIZE
/ 2) err(1, READ
, "bad");
542 for (i
= 0; i
< ARSIZE
/ 2; i
++)
543 if (b
[i
] != a
[(ARSIZE
/ 2) + i
])
544 err(7, READ
, "from location ARSIZE/2");
547 /*****************************************************************************
549 ****************************************************************************/
552 int n
, n1
, mode
, fd
[2];
555 /* Test open after CREAT */
556 if ((n
= creat("file05", 0700)) != FF
) /* no other open files left */
557 err(13, CREAT
, "'file05'");
559 if ((n1
= open("file05", RW
)) != FF
+ 1)
560 err(13, OPEN
, "'file05' after creation");
561 try_close(n1
, "'file05' (open after creation)");
563 try_close(n
, "'file05'");
564 if ((n
= open("file05", R
)) != FF
)
565 err(13, OPEN
, "after closing");
567 try_close(n
, "'file05' (open after closing)");
569 /* Remove testfile */
570 try_unlink("file05");
573 /* Test all possible modes, try_open not only opens file (sometimes) *
574 * but closes files too (when opened) */
575 if ((n
= creat("file05", 0700)) < 0) /* no other files left */
576 err(5, CREAT
, "'file05' (2nd time)");
578 try_close(n
, "file05");
579 for (mode
= 0; mode
<= 0700; mode
+= 0100) {
580 if (chmod("file05", mode
) != OK
) err(5, CHMOD
, "'file05'");
583 try_open("file05", R
, FAIL
);
584 try_open("file05", W
, FAIL
);
585 try_open("file05", RW
, FAIL
);
586 } else if (mode
>= 0200 && mode
<= 0300) {
587 try_open("file05", R
, FAIL
);
588 try_open("file05", W
, FF
);
589 try_open("file05", RW
, FAIL
);
590 } else if (mode
>= 0400 && mode
<= 0500) {
591 try_open("file05", R
, FF
);
592 try_open("file05", W
, FAIL
);
593 try_open("file05", RW
, FAIL
);
595 try_open("file05", R
, FF
);
596 try_open("file05", W
, FF
);
597 try_open("file05", RW
, FF
);
602 /* Test opening existing file */
603 if ((n
= open("drwx/rwx", R
)) < 0)
604 err(13, OPEN
, "existing file");
605 else { /* test close after DUP */
606 if ((n1
= dup(n
)) < 0)
607 err(13, DUP
, "'drwx/rwx'");
609 try_close(n1
, "duplicated fd 'drwx/rwx'");
611 if (read(n1
, b
, ARSIZE
) != FAIL
)
612 err(11, READ
, "on closed dupped fd 'drwx/rwx'");
616 if (read(n
, b
, ARSIZE
) == FAIL
) /* should read an eof */
617 err(13, READ
, "on fd '/drwx/rwx'");
619 try_close(n
, "'drwx/rwx'");
622 /* Test close after PIPE */
626 try_close(fd
[1], "duplicated fd 'fd[1]'");
628 /* Fd[1] really should be closed now; check */
630 if (read(fd
[0], b
, ARSIZE
) != READ_EOF
)
631 err(11, READ
, "read on empty pipe (and fd[1] was closed)");
632 try_close(fd
[0], "duplicated fd 'fd[0]'");
635 /* Try to open a non-existing file */
636 if (open("non-file", R
) != FAIL
)
637 err(11, OPEN
, "open non-executable file");
641 /* Dir does not exist */
642 if (open("dzzz/file05", R
) != FAIL
)
643 err(11, OPEN
, "open in an non-searchable dir");
647 /* Dir is not searchable */
648 if (n
= open("drw-/rwx", R
) != FAIL
)
649 err(11, OPEN
, "open in an non-searchabledir");
653 /* Unlink testfile */
654 try_unlink("file05");
656 /* File is not readable */
657 if (open("drwx/-wx", R
) != FAIL
)
658 err(11, OPEN
, "open unreadable file for reading");
662 /* File is not writable */
663 if (open("drwx/r-x", W
) != FAIL
)
664 err(11, OPEN
, "open unwritable file for writing");
668 /* Try opening more than MAXOPEN ('extra' (19-8-85)) files */
669 if ((n
= open_alot()) != MAXOPEN
)
670 err(13, OPEN
, "MAXOPEN files");
672 /* Maximum # of files opened now, another open should fail
673 * because * all filedescriptors have already been used. */
674 if (open("drwx/rwx", RW
) != FAIL
)
675 err(9, OPEN
, "open");
678 if (close_alot(n
) != n
) err(5, CLOSE
, "all opened files");
680 /* Can close make mistakes ? */
681 if (close(-1) != FAIL
)
682 err(2, CLOSE
, "filedes");
687 void try_open(fname
, mode
, test
)
693 if ((n
= open(fname
, mode
)) != test
)
694 err(11, OPEN
, "break through filepermission with an incorrect mode");
695 if (n
!= FAIL
) try_close(n
, fname
); /* cleanup */
698 /*****************************************************************************
700 ****************************************************************************/
703 char a
[ARSIZE
], b
[ARSIZE
];
706 if ((fd
= open("drwx/rwx", RW
)) != FF
) /* there should be no */
707 err(13, OPEN
, "'drwx/rwx'"); /* other open files */
710 if (write(fd
, a
, 10) != 10)
711 err(1, WRITE
, "bad");
713 /* Lseek back to begin file */
714 if (lseek(fd
, 0L, SEEK_SET
) != 0)
715 err(5, LSEEK
, "to begin file");
716 else if (read(fd
, b
, 10) != 10)
718 else if (comp_array(a
, b
, 10) != OK
)
719 err(7, LSEEK
, "values r/w after lseek to begin");
720 /* Lseek to endoffile */
721 if (lseek(fd
, 0L, SEEK_END
) != 10)
722 err(5, LSEEK
, "to end of file");
723 else if (read(fd
, b
, 1) != READ_EOF
)
724 err(7, LSEEK
, "read at end of file");
725 /* Lseek beyond file */
726 if (lseek(fd
, 10L, SEEK_CUR
) != 20)
727 err(5, LSEEK
, "beyond end of file");
728 else if (write(fd
, a
, 10) != 10)
729 err(1, WRITE
, "bad");
731 /* Lseek to begin second write */
732 if (lseek(fd
, 20L, SEEK_SET
) != 20)
733 err(5, LSEEK
, "'/drwx/rwx'");
734 if (read(fd
, b
, 10) != 10)
736 else if (comp_array(a
, b
, 10) != OK
)
738 "values read after lseek MAXOPEN");
742 /* Lseek to position before begin of file */
743 if (lseek(fd
, -1L, 0) != FAIL
)
744 err(11, LSEEK
, "lseek before beginning of file");
746 try_close(fd
, "'drwx/rwx'");
749 /* Lseek on invalid filediscriptor */
750 if (lseek(-1, 0L, SEEK_SET
) != FAIL
)
751 err(2, LSEEK
, "filedes");
757 /* "t3.c", created by Rene Montsma and Menno Wilcke */
759 /*****************************************************************************
761 ****************************************************************************/
764 /* Check with proper parameters */
765 if (access("drwx/rwx", RWX
) != OK
) err(5, ACCESS
, "accessible file");
767 if (access("./././drwx/././rwx", 0) != OK
)
768 err(5, ACCESS
, "'/./.(etc)/drwx///rwx'");
770 /* Check 8 files with 8 different modes on 8 accesses */
771 if (chdir("drwx") != OK
) err(5, CHDIR
, "'drwx'");
775 if (chdir("..") != OK
) err(5, CHDIR
, "'..'");
777 /* Check several wrong combinations */
778 /* File does not exist */
779 if (access("non-file", 0) != FAIL
)
780 err(11, ACCESS
, "access non-existing file");
782 check(ACCESS
, ENOENT
);
784 /* Non-searchable dir */
785 if (access("drw-/rwx", 0) != FAIL
)
786 err(4, ACCESS
, "'drw-'");
788 check(ACCESS
, EACCES
);
790 /* Searchable dir, but wrong file-mode */
791 if (access("drwx/--x", RWX
) != FAIL
)
792 err(11, ACCESS
, "a non accessible file");
794 check(ACCESS
, EACCES
);
798 void access_standards()
802 for (i
= 0; i
< 8; i
++)
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
== 2)
818 try_access(fnames
[mode
], i
, OK
);
820 try_access(fnames
[mode
], i
, FAIL
);
823 for (i
= 0; i
< 8; i
++)
825 try_access(fnames
[mode
], i
, OK
);
827 try_access(fnames
[mode
], i
, FAIL
);
830 for (i
= 0; i
< 8; i
++)
831 if (i
== 0 || i
== 4)
832 try_access(fnames
[mode
], i
, OK
);
834 try_access(fnames
[mode
], i
, FAIL
);
837 for (i
= 0; i
< 8; i
++)
838 if (i
== 0 || i
== 1 || i
== 4 || i
== 5)
839 try_access(fnames
[mode
], i
, OK
);
841 try_access(fnames
[mode
], i
, FAIL
);
844 for (i
= 0; i
< 8; i
++)
846 try_access(fnames
[mode
], i
, OK
);
848 try_access(fnames
[mode
], i
, FAIL
);
851 for (i
= 0; i
< 8; i
++) try_access(fnames
[mode
], i
, OK
);
852 } /* access_standards */
854 void try_access(fname
, mode
, test
)
858 if (access(fname
, mode
) != test
)
859 err(100, ACCESS
, "incorrect access on a file (try_access)");
862 /* "support.c", created by Rene Montsma and Menno Wilcke */
864 /* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
865 try_close, try_unlink, Remove, get_mode, check, open_alot,
866 close_alot, clean_up_the_mess.
869 /*****************************************************************************
870 * test READV/WRITEV *
871 ****************************************************************************/
872 #define TEST8_BUFSZCOUNT 3
873 #define TEST8_BUFSZMAX 65536
874 #define TEST8_IOVCOUNT 4
878 char buffer_read
[TEST8_IOVCOUNT
* TEST8_BUFSZMAX
];
879 char buffer_write
[TEST8_IOVCOUNT
* TEST8_BUFSZMAX
];
880 struct iovec iovec_read
[TEST8_IOVCOUNT
];
881 struct iovec iovec_write
[TEST8_IOVCOUNT
];
882 int fd
, i
, j
, k
, l
, m
;
883 ssize_t sz_read
, sz_write
;
884 size_t sz_read_exp
, sz_read_sum
, sz_write_sum
;
886 /* try various combinations of buffer sizes */
887 for (i
= 0; i
<= TEST8_IOVCOUNT
; i
++)
888 for (j
= 0; j
< power(TEST8_BUFSZCOUNT
, i
); j
++)
889 for (k
= 0; k
<= TEST8_IOVCOUNT
; k
++)
890 for (l
= 0; l
< power(TEST8_BUFSZCOUNT
, k
); l
++)
892 /* put data in the buffers */
893 for (m
= 0; m
< sizeof(buffer_write
); m
++)
895 buffer_write
[m
] = m
^ (m
>> 8);
896 buffer_read
[m
] = ~buffer_write
[m
];
899 /* set up the vectors to point to the buffers */
900 sz_read_sum
= iovec_setup(j
, iovec_read
, buffer_read
, i
);
901 sz_write_sum
= iovec_setup(l
, iovec_write
, buffer_write
, k
);
902 sz_read_exp
= (sz_read_sum
< sz_write_sum
) ?
903 sz_read_sum
: sz_write_sum
;
905 /* test reading and writing */
906 if ((fd
= open("file08", O_RDWR
| O_CREAT
| O_TRUNC
, 0644)) < 0)
907 err(13, OPEN
, "'file08'");
909 sz_write
= writev(fd
, iovec_write
, k
);
910 if (sz_write
!= sz_write_sum
) err(5, WRITEV
, "'file08'");
911 if (lseek(fd
, 0, SEEK_SET
) != 0) err(5, LSEEK
, "'file08'");
912 sz_read
= readv(fd
, iovec_read
, i
);
913 if (sz_read
!= sz_read_exp
)
914 err(5, READV
, "'file08'");
917 if (!iovec_is_equal(iovec_read
, iovec_write
, sz_read
))
918 err(8, READV
, "'file08'");
921 /* Remove testfile */
922 Remove(fd
, "file08");
927 static int iovec_is_equal(struct iovec
*x
, struct iovec
*y
, size_t size
)
929 int xpos
= 0, xvec
= 0, ypos
= 0, yvec
= 0;
931 /* compare byte by byte */
934 /* skip over zero-byte buffers and those that have been completed */
935 while (xpos
>= x
[xvec
].iov_len
)
937 xpos
-= x
[xvec
++].iov_len
;
938 assert(xvec
< TEST8_IOVCOUNT
);
940 while (ypos
>= y
[yvec
].iov_len
)
942 ypos
-= y
[yvec
++].iov_len
;
943 assert(yvec
< TEST8_IOVCOUNT
);
947 if (((char *) x
[xvec
].iov_base
)[xpos
++] !=
948 ((char *) y
[yvec
].iov_base
)[ypos
++])
952 /* no difference found */
956 static size_t iovec_setup(int pattern
, struct iovec
*iovec
, char *buffer
, int count
)
958 static const size_t bufsizes
[TEST8_BUFSZCOUNT
] = { 0, 1, TEST8_BUFSZMAX
};
962 /* the pattern specifies each buffer */
963 for (i
= 0; i
< TEST8_IOVCOUNT
; i
++)
965 iovec
->iov_base
= buffer
;
966 sum
+= iovec
->iov_len
= bufsizes
[pattern
% TEST8_BUFSZCOUNT
];
969 buffer
+= TEST8_BUFSZMAX
;
970 pattern
/= TEST8_BUFSZCOUNT
;
976 static int power(int base
, int exponent
)
980 /* compute base^exponent */
981 while (exponent
-- > 0)
987 /***********************************************************************
989 **********************************************************************/
990 /* First extended functions (i.e. not oldfashioned monixcalls.
991 e(), nlcr(), octal.*/
996 printf("Test program error: %s\n", string
);
1011 /*****************************************************************************
1013 * ERR(or) messages *
1015 *****************************************************************************/
1016 void err(number
, scall
, name
)
1017 /* Give nice error messages */
1024 if (errct
> MAXERR
) {
1025 printf("Too many errors; test aborted\n");
1027 system("rm -rf DIR*");
1035 str(": illegal initial value.");
1041 str(" value returned.");
1045 str(": accepting illegal ");
1051 str(": accepting non-existing file.");
1055 str(": could search non-searchable dir (");
1069 str(": incorrect ");
1075 str(": wrong values.");
1079 str(": accepting too many ");
1085 str(": even a superuser can't do anything!");
1095 str(": could write in non-writable dir (");
1101 str(": wrong filedes returned (");
1106 str(scall
); /* very common */
1111 default: str("errornumber does not exist!\n");
1116 /*****************************************************************************
1118 * MAKE_AND_FILL_DIRS *
1120 *****************************************************************************/
1122 void make_and_fill_dirs()
1123 /* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", *
1124 * "drw-", "drwx". * Then create 8 files
1125 * in "drwx", and some needed files in other dirs. */
1129 for (i
= 0; i
< 8; i
++) {
1130 mkdir(dir
[i
], 0700);
1131 chown(dir
[i
], USER_ID
, GROUP_ID
);
1136 for (mode
= 0; mode
< 8; mode
++) put_file_in_dir("drwx", mode
);
1138 put_file_in_dir("d-wx", RWX
);
1139 put_file_in_dir("dr-x", RWX
);
1140 put_file_in_dir("drw-", RWX
);
1142 chmod_8_dirs(8); /* 8 means; 8 different modes */
1144 } /* make_and_fill_dirs */
1146 void put_file_in_dir(dirname
, mode
)
1149 /* Fill directory 'dirname' with file with mode 'mode'. */
1153 if (chdir(dirname
) != OK
)
1154 err(5, CHDIR
, "to dirname (put_f_in_dir)");
1156 /* Creat the file */
1157 if ((nr
= creat(fnames
[mode
], mode
* 0100)) < 0)
1158 err(13, CREAT
, fnames
[mode
]);
1160 try_close(nr
, fnames
[mode
]);
1162 if (chdir("..") != OK
)
1163 err(5, CHDIR
, "to previous dir (put_f_in_dir)");
1165 } /* put_file_in_dir */
1167 /*****************************************************************************
1171 *(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode') *
1173 *****************************************************************************/
1181 while (i
++ < ARSIZE
) *a
++ = 'a' + (i
% 26);
1190 while (i
++ < ARSIZE
) *b
++ = '0';
1194 int comp_array(a
, b
, range
)
1198 if ((range
< 0) || (range
> ARSIZE
)) {
1199 err(100, "comp_array", "illegal range");
1202 while (range
-- && (*a
++ == *b
++));
1210 void try_close(filedes
, name
)
1214 if (close(filedes
) != OK
) err(5, CLOSE
, name
);
1217 void try_unlink(fname
)
1220 if (unlink(fname
) != 0) err(5, UNLINK
, fname
);
1223 void Remove(fdes
, fname
)
1227 try_close(fdes
, fname
);
1236 if (stat(name
, &stbf1
) != OK
) {
1238 return(stbf1
.st_mode
); /* return a mode which will cause *
1239 * error in the calling function *
1242 return(stbf1
.st_mode
& 07777); /* take last 4 bits */
1245 /*****************************************************************************
1249 *****************************************************************************/
1251 void check(scall
, number
)
1255 if (errno
!= number
) {
1259 str(": bad errno-value: ");
1261 str(" should have been: ");
1271 case 0: str("unused"); break;
1272 case 1: str("EPERM"); break;
1273 case 2: str("ENOENT"); break;
1274 case 3: str("ESRCH"); break;
1275 case 4: str("EINTR"); break;
1276 case 5: str("EIO"); break;
1277 case 6: str("ENXIO"); break;
1278 case 7: str("E2BIG"); break;
1279 case 8: str("ENOEXEC"); break;
1280 case 9: str("EBADF"); break;
1281 case 10: str("ECHILD"); break;
1282 case 11: str("EAGAIN"); break;
1283 case 12: str("ENOMEM"); break;
1284 case 13: str("EACCES"); break;
1285 case 14: str("EFAULT"); break;
1286 case 15: str("ENOTBLK"); break;
1287 case 16: str("EBUSY"); break;
1288 case 17: str("EEXIST"); break;
1289 case 18: str("EXDEV"); break;
1290 case 19: str("ENODEV"); break;
1291 case 20: str("ENOTDIR"); break;
1292 case 21: str("EISDIR"); break;
1293 case 22: str("EINVAL"); break;
1294 case 23: str("ENFILE"); break;
1295 case 24: str("EMFILE"); break;
1296 case 25: str("ENOTTY"); break;
1297 case 26: str("ETXTBSY"); break;
1298 case 27: str("EFBIG"); break;
1299 case 28: str("ENOSPC"); break;
1300 case 29: str("ESPIPE"); break;
1301 case 30: str("EROFS"); break;
1302 case 31: str("EMLINK"); break;
1303 case 32: str("EPIPE"); break;
1304 case 33: str("EDOM"); break;
1305 case 34: str("ERANGE"); break;
1309 /*****************************************************************************
1313 *****************************************************************************/
1319 for (i
= 0; i
< MAXOPEN
; i
++)
1320 if (open(file
[i
], R
) == FAIL
) break;
1321 if (i
== 0) err(5, "open_alot", "at all");
1325 int close_alot(number
)
1330 if (number
> MAXOPEN
)
1331 err(5, "close_alot", "accept this argument");
1333 for (i
= FF
; i
< number
+ FF
; i
++)
1334 if (close(i
) != OK
) count
++;
1336 return(number
- count
); /* return number of closed files */
1339 /*****************************************************************************
1341 * CLEAN UP THE MESS *
1343 *****************************************************************************/
1345 void clean_up_the_mess()
1350 /* First remove 'alot' files */
1351 for (i
= 0; i
< MAXOPEN
; i
++) try_unlink(file
[i
]);
1353 /* Unlink the files in dir 'drwx' */
1354 if (chdir("drwx") != OK
)
1355 err(5, CHDIR
, "to 'drwx'");
1357 for (i
= 0; i
< 8; i
++) try_unlink(fnames
[i
]);
1358 if (chdir("..") != OK
) err(5, CHDIR
, "to '..'");
1361 /* Before unlinking files in some dirs, make them writable */
1364 /* Unlink files in other dirs */
1365 try_unlink("d-wx/rwx");
1366 try_unlink("dr-x/rwx");
1367 try_unlink("drw-/rwx");
1370 for (i
= 0; i
< 8; i
++) {
1371 strcpy(dirname
, "d");
1372 strcat(dirname
, fnames
[i
]);
1373 /* 'dirname' contains the directoryname */
1378 } /* clean_up_the_mess */
1380 void chmod_8_dirs(sw
)
1381 int sw
; /* if switch == 8, give all different
1382 * mode,else the same mode */
1392 for (i
= 0; i
< 8; i
++) {
1393 chmod(dir
[i
], 040000 + mode
* 0100);
1394 if (sw
== 8) mode
++;
1402 system("rm -rf DIR*");
1408 printf("%d errors\n", errct
);