source: trunk/minix/test/test18.c@ 15

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

Minix 3.1.2a

File size: 32.4 KB
Line 
1/* test 18 */
2
3/* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
4
5/* "const.h", created by Rene Montsma and Menno Wilcke */
6
7#include <sys/types.h> /* needed in struct stat */
8#include <sys/stat.h> /* struct stat */
9#include <sys/wait.h>
10#include <errno.h> /* the error-numbers */
11#include <fcntl.h>
12#include <stdlib.h>
13#include <unistd.h>
14#include <string.h>
15#include <stdio.h>
16#include <limits.h>
17
18#define NOCRASH 1 /* test11(), 2nd pipe */
19#define PDPNOHANG 1 /* test03(), write_standards() */
20#define MAXERR 5
21
22#define USER_ID 12
23#define GROUP_ID 1
24#define FF 3 /* first free filedes. */
25#define USER 1 /* uid */
26#define GROUP 0 /* gid */
27
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 */
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, (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));
116
117/*****************************************************************************
118 * TEST *
119 ****************************************************************************/
120int main()
121{
122 int n;
123
124 if (geteuid() == 0 || getuid() == 0) {
125 printf("Test 18 cannot run as root; test aborted\n");
126 exit(1);
127 }
128
129 system("rm -rf DIR_18; mkdir DIR_18");
130 chdir("DIR_18");
131
132 if (fork()) {
133 printf("Test 18 ");
134 fflush(stdout); /* have to flush for child's benefit */
135
136 wait(&n);
137 clean_up_the_mess();
138 quit();
139 } else {
140 test();
141 exit(0);
142 }
143
144 return(0);
145}
146
147void test()
148{
149 umask(0); /* not honest, but i always forget */
150
151 test01();
152 make_and_fill_dirs();
153 test02();
154 test03();
155 test04();
156 test05();
157 test06();
158 test07();
159 umask(022);
160} /* test */
161
162/* "t1.c" created by Rene Montsma and Menno Wilcke */
163
164/*****************************************************************************
165 * test UMASK *
166 ****************************************************************************/
167void test01()
168{
169 int oldvalue, newvalue, tempvalue;
170 int nr;
171
172 if ((oldvalue = umask(0777)) != 0) err(0, UMASK, NIL);
173
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. */
177
178 if ((newvalue = umask(~0777)) != 0777) err(1, UMASK, "illegal");
179 if (oldvalue == newvalue) err(11, UMASK, "not change mask");
180
181 if ((tempvalue = umask(0)) != 0) err(2, UMASK, "values");
182
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'");
191 else {
192 try_close(nr, "'file01'");
193 if (get_mode("file01") != (MASK & ~newvalue))
194 err(7, UMASK, "mode computed");
195 try_unlink("file01");
196 }
197 oldvalue = newvalue;
198 }
199
200 /* The loop has terminated with umask(0) */
201 if ((tempvalue = umask(0)) != 0)
202 err(7, UMASK, "umask may influence rest of tests!");
203} /* test01 */
204
205/*****************************************************************************
206 * test CREAT *
207 ****************************************************************************/
208void test02()
209{
210 int n, n1, mode;
211 char a[ARSIZE], b[ARSIZE];
212 struct stat stbf1;
213
214 mode = 0;
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]);
219 else {
220 if (get_mode(file[n]) != mode)
221 err(7, CREAT, "mode set while creating many files");
222
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]);
227
228 }
229 mode = (mode + 0100) % 01000;
230 }
231
232 /* Already twenty files opened; opening another has to fail */
233 if (creat("file02", 0777) != FAIL)
234 err(9, CREAT, "created");
235 else
236 check(CREAT, EMFILE);
237
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");
241
242 /* Creat 1 file twice; check */
243 if ((n = creat("file02", 0777)) < 0)
244 err(5, CREAT, "'file02'");
245 else {
246 init_array(a);
247 if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
248
249 if ((n1 = creat("file02", 0755)) < 0) /* receate 'file02' */
250 err(5, CREAT, "'file02' (2nd time)");
251 else {
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");
255 else {
256 /* Try to write on recreated file */
257 clear_array(b);
258
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");
263
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)");
268
269 /* Continue */
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");
274
275 if (comp_array(a, b, ARSIZE) != OK) err(11, CREAT,
276 "not really truncate file by recreation");
277 }
278 if (get_mode("file02") != 0777)
279 err(11, CREAT, "not maintain mode by recreation");
280 try_close(n1, "recreated 'file02'");
281
282 }
283 Remove(n, "file02");
284 }
285
286 /* Give 'creat' wrong input: dir not searchable */
287 if (creat("drw-/file02", 0777) != FAIL)
288 err(4, CREAT, "'drw-'");
289 else
290 check(CREAT, EACCES);
291
292 /* Dir not writable */
293 if (creat("dr-x/file02", 0777) != FAIL)
294 err(12, CREAT, "'dr-x/file02'");
295 else
296 check(CREAT, EACCES);
297
298 /* File not writable */
299 if (creat("drwx/r-x", 0777) != FAIL)
300 err(11, CREAT, "recreate non-writable file");
301 else
302 check(CREAT, EACCES);
303
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
311 * code in test17.c.
312 */
313 err(11, CREAT, "'creat' a new directory");
314 Remove(n, "dir");
315 }
316
317 /* We don't consider it to be a bug when creat * does not accept
318 * tricky modes */
319
320 /* File is an existing dir */
321 if (creat("drwx", 0777) != FAIL)
322 err(11, CREAT, "create an existing dir!");
323 else
324 check(CREAT, EISDIR);
325} /* test02 */
326
327/*****************************************************************************
328 * test WRITE *
329 ****************************************************************************/
330void test03()
331{
332 int n, n1;
333 int fd[2];
334 char a[ARSIZE];
335
336 init_array(a);
337
338 /* Test write after a CREAT */
339 if ((n = creat("file03", 0700)) != FF) /* 'file03' only open file */
340 err(13, CREAT, "'file03'");
341 else {
342 write_standards(n, a); /* test simple writes, wrong input too */
343 try_close(n, "'file03'");
344 }
345
346 /* Test write after an OPEN */
347 if ((n = open("file03", W)) < 0)
348 err(5, OPEN, "'file03'");
349 else
350 write_standards(n, a); /* test simple writes, wrong input too */
351
352 /* Test write after a DUP */
353 if ((n1 = dup(n)) < 0)
354 err(5, DUP, "'file03'");
355 else {
356 write_standards(n1, a);
357 try_close(n1, "duplicated fd 'file03'");
358 }
359
360 /* Remove testfile */
361 Remove(n, "file03");
362
363 /* Test write after a PIPE */
364 if (pipe(fd) < 0)
365 err(5, PIPE, NIL);
366 else {
367 write_standards(fd[1], a);
368 try_close(fd[0], "'fd[0]'");
369 try_close(fd[1], "'fd[1]'");
370 }
371
372 /* Last test: does write check protections ? */
373 if ((n = open("drwx/r--", R)) < 0)
374 err(5, OPEN, "'drwx/r--'");
375 else {
376 if (write(n, a, ARSIZE) != FAIL)
377 err(11, WRITE, "write on non-writ. file");
378 else
379 check(WRITE, EBADF);
380 try_close(n, "'drwx/r--'");
381 }
382} /* test03 */
383
384void write_standards(filedes, a)
385int filedes;
386char a[];
387{
388
389 /* Write must return written account of numbers */
390 if (write(filedes, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
391
392 /* Try giving 'write' wrong input */
393 /* Wrong filedes */
394 if (write(-1, a, ARSIZE) != FAIL)
395 err(2, WRITE, "filedes");
396 else
397 check(WRITE, EBADF);
398
399 /* Wrong length (illegal) */
400#ifndef PDPNOHANG
401 if (write(filedes, a, -ARSIZE) != FAIL)
402 err(2, WRITE, "length");
403 else
404 check(WRITE, EINVAL); /* EFAULT on vu45 */
405#endif
406} /* write_standards */
407
408/* "t2.c", created by Rene Montsma and Menno Wilcke */
409
410/*****************************************************************************
411 * test READ *
412 ****************************************************************************/
413void test04()
414{
415 int n, n1, fd[2];
416 char a[ARSIZE];
417
418 /* Test read after creat */
419 if ((n = creat("file04", 0700)) != FF) /* no other open files may be
420 * left */
421 err(13, CREAT, "'file04'");
422 else {
423 /* Closing and opening needed before writing */
424 try_close(n, "'file04'");
425 if ((n = open("file04", RW)) < 0) err(5, OPEN, "'file04'");
426
427 init_array(a);
428
429 if (write(n, a, ARSIZE) != ARSIZE)
430 err(1, WRITE, "bad");
431 else {
432 if (lseek(n, 0L, SEEK_SET) != 0) err(5, LSEEK, "'file04'");
433 read_standards(n, a);
434 read_more(n, a);
435 }
436 try_close(n, "'file04'");
437 }
438
439 /* Test read after OPEN */
440 if ((n = open("file04", R)) < 0)
441 err(5, OPEN, "'file04'");
442 else {
443 read_standards(n, a);
444 read_more(n, a);
445 try_close(n, "'file04'");
446 }
447
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'");
452 else {
453 read_standards(n1, a);
454 read_more(n1, a);
455 try_close(n1, "duplicated fd 'file04'");
456 }
457
458 /* Remove testfile */
459 Remove(n, "file04");
460
461 /* Test read after pipe */
462 if (pipe(fd) < 0)
463 err(5, PIPE, NIL);
464 else {
465 if (write(fd[1], a, ARSIZE) != ARSIZE) {
466 err(5, WRITE, "'fd[1]'");
467 try_close(fd[1], "'fd[1]'");
468 } else {
469 try_close(fd[1], "'fd[1]'");
470 read_standards(fd[0], a);
471 }
472 try_close(fd[0], "'fd[0]'");
473 }
474
475 /* Last test: try to read a read-protected file */
476 if ((n = open("drwx/-wx", W)) < 0)
477 err(5, OPEN, "'drwx/-wx'");
478 else {
479 if (read(n, a, ARSIZE) != FAIL)
480 err(11, READ, "read a non-read. file");
481 else
482 check(READ, EBADF);
483 try_close(n, "'/drwx/-wx'");
484 }
485} /* test04 */
486
487void read_standards(filedes, a)
488int filedes;
489char a[];
490{
491 char b[ARSIZE];
492
493 clear_array(b);
494 if (read(filedes, b, ARSIZE) != ARSIZE)
495 err(1, READ, "bad");
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");
500
501 /* Try giving read wrong input: wrong filedes */
502 if (read(FAIL, b, ARSIZE) != FAIL)
503 err(2, READ, "filedes");
504 else
505 check(READ, EBADF);
506
507 /* Wrong length */
508 if (read(filedes, b, -ARSIZE) != FAIL)
509 err(2, READ, "length");
510 else
511 check(READ, EINVAL);
512} /* read_standards */
513
514void read_more(filedes, a)
515int filedes;
516char a[];
517 /* Separated from read_standards() because the PIPE test * would fail. */
518{
519 int i;
520 char b[ARSIZE];
521
522 if (lseek(filedes, (long) (ARSIZE / 2), SEEK_SET) != ARSIZE / 2)
523 err(5, LSEEK, "to location ARSIZE/2");
524
525 clear_array(b);
526 if (read(filedes, b, ARSIZE) != ARSIZE / 2) err(1, READ, "bad");
527
528 for (i = 0; i < ARSIZE / 2; i++)
529 if (b[i] != a[(ARSIZE / 2) + i])
530 err(7, READ, "from location ARSIZE/2");
531}
532
533/*****************************************************************************
534 * test OPEN/CLOSE *
535 ****************************************************************************/
536void test05()
537{
538 int n, n1, mode, fd[2];
539 char b[ARSIZE];
540
541 /* Test open after CREAT */
542 if ((n = creat("file05", 0700)) != FF) /* no other open files left */
543 err(13, CREAT, "'file05'");
544 else {
545 if ((n1 = open("file05", RW)) != FF + 1)
546 err(13, OPEN, "'file05' after creation");
547 try_close(n1, "'file05' (open after creation)");
548
549 try_close(n, "'file05'");
550 if ((n = open("file05", R)) != FF)
551 err(13, OPEN, "after closing");
552 else
553 try_close(n, "'file05' (open after closing)");
554
555 /* Remove testfile */
556 try_unlink("file05");
557 }
558
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)");
563 else {
564 try_close(n, "file05");
565 for (mode = 0; mode <= 0700; mode += 0100) {
566 if (chmod("file05", mode) != OK) err(5, CHMOD, "'file05'");
567
568 if (mode <= 0100) {
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);
580 } else {
581 try_open("file05", R, FF);
582 try_open("file05", W, FF);
583 try_open("file05", RW, FF);
584 }
585 }
586 }
587
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'");
594 else {
595 try_close(n1, "duplicated fd 'drwx/rwx'");
596
597 if (read(n1, b, ARSIZE) != FAIL)
598 err(11, READ, "on closed dupped fd 'drwx/rwx'");
599 else
600 check(READ, EBADF);
601
602 if (read(n, b, ARSIZE) == FAIL) /* should read an eof */
603 err(13, READ, "on fd '/drwx/rwx'");
604 }
605 try_close(n, "'drwx/rwx'");
606 }
607
608 /* Test close after PIPE */
609 if (pipe(fd) < 0)
610 err(13, PIPE, NIL);
611 else {
612 try_close(fd[1], "duplicated fd 'fd[1]'");
613
614 /* Fd[1] really should be closed now; check */
615 clear_array(b);
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]'");
619 }
620
621 /* Try to open a non-existing file */
622 if (open("non-file", R) != FAIL)
623 err(11, OPEN, "open non-executable file");
624 else
625 check(OPEN, ENOENT);
626
627 /* Dir does not exist */
628 if (open("dzzz/file05", R) != FAIL)
629 err(11, OPEN, "open in an non-searchable dir");
630 else
631 check(OPEN, ENOENT);
632
633 /* Dir is not searchable */
634 if (n = open("drw-/rwx", R) != FAIL)
635 err(11, OPEN, "open in an non-searchabledir");
636 else
637 check(OPEN, EACCES);
638
639 /* Unlink testfile */
640 try_unlink("file05");
641
642 /* File is not readable */
643 if (open("drwx/-wx", R) != FAIL)
644 err(11, OPEN, "open unreadable file for reading");
645 else
646 check(OPEN, EACCES);
647
648 /* File is not writable */
649 if (open("drwx/r-x", W) != FAIL)
650 err(11, OPEN, "open unwritable file for writing");
651 else
652 check(OPEN, EACCES);
653
654 /* Try opening more than MAXOPEN ('extra' (19-8-85)) files */
655 if ((n = open_alot()) != MAXOPEN)
656 err(13, OPEN, "MAXOPEN files");
657 else
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");
662 else
663 check(OPEN, EMFILE);
664 if (close_alot(n) != n) err(5, CLOSE, "all opened files");
665
666 /* Can close make mistakes ? */
667 if (close(-1) != FAIL)
668 err(2, CLOSE, "filedes");
669 else
670 check(CLOSE, EBADF);
671} /* test05 */
672
673void try_open(fname, mode, test)
674int mode, test;
675char *fname;
676{
677 int n;
678
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 */
682} /* try_open */
683
684/*****************************************************************************
685 * test LSEEK *
686 ****************************************************************************/
687void test06()
688{
689 char a[ARSIZE], b[ARSIZE];
690 int fd;
691
692 if ((fd = open("drwx/rwx", RW)) != FF) /* there should be no */
693 err(13, OPEN, "'drwx/rwx'"); /* other open files */
694 else {
695 init_array(a);
696 if (write(fd, a, 10) != 10)
697 err(1, WRITE, "bad");
698 else {
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)
703 err(1, READ, "bad");
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");
716 else {
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)
721 err(1, READ, "bad");
722 else if (comp_array(a, b, 10) != OK)
723 err(7, LSEEK,
724 "values read after lseek MAXOPEN");
725 }
726 }
727
728 /* Lseek to position before begin of file */
729 if (lseek(fd, -1L, 0) != FAIL)
730 err(11, LSEEK, "lseek before beginning of file");
731
732 try_close(fd, "'drwx/rwx'");
733 }
734
735 /* Lseek on invalid filediscriptor */
736 if (lseek(-1, 0L, SEEK_SET) != FAIL)
737 err(2, LSEEK, "filedes");
738 else
739 check(LSEEK, EBADF);
740
741}
742
743/* "t3.c", created by Rene Montsma and Menno Wilcke */
744
745/*****************************************************************************
746 * test ACCESS *
747 ****************************************************************************/
748void test07()
749{
750 /* Check with proper parameters */
751 if (access("drwx/rwx", RWX) != OK) err(5, ACCESS, "accessible file");
752
753 if (access("./././drwx/././rwx", 0) != OK)
754 err(5, ACCESS, "'/./.(etc)/drwx///rwx'");
755
756 /* Check 8 files with 8 different modes on 8 accesses */
757 if (chdir("drwx") != OK) err(5, CHDIR, "'drwx'");
758
759 access_standards();
760
761 if (chdir("..") != OK) err(5, CHDIR, "'..'");
762
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");
767 else
768 check(ACCESS, ENOENT);
769
770 /* Non-searchable dir */
771 if (access("drw-/rwx", 0) != FAIL)
772 err(4, ACCESS, "'drw-'");
773 else
774 check(ACCESS, EACCES);
775
776 /* Searchable dir, but wrong file-mode */
777 if (access("drwx/--x", RWX) != FAIL)
778 err(11, ACCESS, "a non accessible file");
779 else
780 check(ACCESS, EACCES);
781
782} /* test07 */
783
784void access_standards()
785{
786 int i, mode = 0;
787
788 for (i = 0; i < 8; i++)
789 if (i == 0)
790 try_access(fnames[mode], i, OK);
791 else
792 try_access(fnames[mode], i, FAIL);
793 mode++;
794
795 for (i = 0; i < 8; i++)
796 if (i < 2)
797 try_access(fnames[mode], i, OK);
798 else
799 try_access(fnames[mode], i, FAIL);
800 mode++;
801
802 for (i = 0; i < 8; i++)
803 if (i == 0 || i == 2)
804 try_access(fnames[mode], i, OK);
805 else
806 try_access(fnames[mode], i, FAIL);
807 mode++;
808
809 for (i = 0; i < 8; i++)
810 if (i < 4)
811 try_access(fnames[mode], i, OK);
812 else
813 try_access(fnames[mode], i, FAIL);
814 mode++;
815
816 for (i = 0; i < 8; i++)
817 if (i == 0 || i == 4)
818 try_access(fnames[mode], i, OK);
819 else
820 try_access(fnames[mode], i, FAIL);
821 mode++;
822
823 for (i = 0; i < 8; i++)
824 if (i == 0 || i == 1 || i == 4 || i == 5)
825 try_access(fnames[mode], i, OK);
826 else
827 try_access(fnames[mode], i, FAIL);
828 mode++;
829
830 for (i = 0; i < 8; i++)
831 if (i % 2 == 0)
832 try_access(fnames[mode], i, OK);
833 else
834 try_access(fnames[mode], i, FAIL);
835 mode++;
836
837 for (i = 0; i < 8; i++) try_access(fnames[mode], i, OK);
838} /* access_standards */
839
840void try_access(fname, mode, test)
841int mode, test;
842char *fname;
843{
844 if (access(fname, mode) != test)
845 err(100, ACCESS, "incorrect access on a file (try_access)");
846} /* try_access */
847
848/* "support.c", created by Rene Montsma and Menno Wilcke */
849
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.
853*/
854
855/***********************************************************************
856 * EXTENDED FIONS *
857 **********************************************************************/
858/* First extended functions (i.e. not oldfashioned monixcalls.
859 e(), nlcr(), octal.*/
860
861void e(string)
862char *string;
863{
864 printf("Test program error: %s\n", string);
865 errct++;
866}
867
868void nlcr()
869{
870 printf("\n");
871}
872
873void str(s)
874char *s;
875{
876 printf(s);
877}
878
879/*****************************************************************************
880* *
881* ERR(or) messages *
882* *
883*****************************************************************************/
884void err(number, scall, name)
885 /* Give nice error messages */
886
887char *scall, *name;
888int number;
889
890{
891 errct++;
892 if (errct > MAXERR) {
893 printf("Too many errors; test aborted\n");
894 chdir("..");
895 system("rm -rf DIR*");
896 quit();
897 }
898 e("");
899 str("\t");
900 switch (number) {
901 case 0:
902 str(scall);
903 str(": illegal initial value.");
904 break;
905 case 1:
906 str(scall);
907 str(": ");
908 str(name);
909 str(" value returned.");
910 break;
911 case 2:
912 str(scall);
913 str(": accepting illegal ");
914 str(name);
915 str(".");
916 break;
917 case 3:
918 str(scall);
919 str(": accepting non-existing file.");
920 break;
921 case 4:
922 str(scall);
923 str(": could search non-searchable dir (");
924 str(name);
925 str(").");
926 break;
927 case 5:
928 str(scall);
929 str(": cannot ");
930 str(scall);
931 str(" ");
932 str(name);
933 str(".");
934 break;
935 case 7:
936 str(scall);
937 str(": incorrect ");
938 str(name);
939 str(".");
940 break;
941 case 8:
942 str(scall);
943 str(": wrong values.");
944 break;
945 case 9:
946 str(scall);
947 str(": accepting too many ");
948 str(name);
949 str(" files.");
950 break;
951 case 10:
952 str(scall);
953 str(": even a superuser can't do anything!");
954 break;
955 case 11:
956 str(scall);
957 str(": could ");
958 str(name);
959 str(".");
960 break;
961 case 12:
962 str(scall);
963 str(": could write in non-writable dir (");
964 str(name);
965 str(").");
966 break;
967 case 13:
968 str(scall);
969 str(": wrong filedes returned (");
970 str(name);
971 str(").");
972 break;
973 case 100:
974 str(scall); /* very common */
975 str(": ");
976 str(name);
977 str(".");
978 break;
979 default: str("errornumber does not exist!\n");
980 }
981 nlcr();
982} /* err */
983
984/*****************************************************************************
985* *
986* MAKE_AND_FILL_DIRS *
987* *
988*****************************************************************************/
989
990void 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. */
994{
995 int mode, i;
996
997 for (i = 0; i < 8; i++) {
998 mkdir(dir[i], 0700);
999 chown(dir[i], USER_ID, GROUP_ID);
1000 }
1001 setuid(USER_ID);
1002 setgid(GROUP_ID);
1003
1004 for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
1005
1006 put_file_in_dir("d-wx", RWX);
1007 put_file_in_dir("dr-x", RWX);
1008 put_file_in_dir("drw-", RWX);
1009
1010 chmod_8_dirs(8); /* 8 means; 8 different modes */
1011
1012} /* make_and_fill_dirs */
1013
1014void put_file_in_dir(dirname, mode)
1015char *dirname;
1016int mode;
1017 /* Fill directory 'dirname' with file with mode 'mode'. */
1018{
1019 int nr;
1020
1021 if (chdir(dirname) != OK)
1022 err(5, CHDIR, "to dirname (put_f_in_dir)");
1023 else {
1024 /* Creat the file */
1025 if ((nr = creat(fnames[mode], mode * 0100)) < 0)
1026 err(13, CREAT, fnames[mode]);
1027 else
1028 try_close(nr, fnames[mode]);
1029
1030 if (chdir("..") != OK)
1031 err(5, CHDIR, "to previous dir (put_f_in_dir)");
1032 }
1033} /* put_file_in_dir */
1034
1035/*****************************************************************************
1036* *
1037* MISCELLANEOUS *
1038* *
1039*(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode') *
1040* *
1041*****************************************************************************/
1042
1043void init_array(a)
1044char *a;
1045{
1046 int i;
1047
1048 i = 0;
1049 while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
1050} /* init_array */
1051
1052void clear_array(b)
1053char *b;
1054{
1055 int i;
1056
1057 i = 0;
1058 while (i++ < ARSIZE) *b++ = '0';
1059
1060} /* clear_array */
1061
1062int comp_array(a, b, range)
1063char *a, *b;
1064int range;
1065{
1066 if ((range < 0) || (range > ARSIZE)) {
1067 err(100, "comp_array", "illegal range");
1068 return(FAIL);
1069 } else {
1070 while (range-- && (*a++ == *b++));
1071 if (*--a == *--b)
1072 return(OK);
1073 else
1074 return(FAIL);
1075 }
1076} /* comp_array */
1077
1078void try_close(filedes, name)
1079int filedes;
1080char *name;
1081{
1082 if (close(filedes) != OK) err(5, CLOSE, name);
1083} /* try_close */
1084
1085void try_unlink(fname)
1086char *fname;
1087{
1088 if (unlink(fname) != 0) err(5, UNLINK, fname);
1089} /* try_unlink */
1090
1091void Remove(fdes, fname)
1092int fdes;
1093char *fname;
1094{
1095 try_close(fdes, fname);
1096 try_unlink(fname);
1097} /* Remove */
1098
1099int get_mode(name)
1100char *name;
1101{
1102 struct stat stbf1;
1103
1104 if (stat(name, &stbf1) != OK) {
1105 err(5, STAT, name);
1106 return(stbf1.st_mode); /* return a mode which will cause *
1107 * error in the calling function *
1108 * (file/dir bit) */
1109 } else
1110 return(stbf1.st_mode & 07777); /* take last 4 bits */
1111} /* get_mode */
1112
1113/*****************************************************************************
1114* *
1115* CHECK *
1116* *
1117*****************************************************************************/
1118
1119void check(scall, number)
1120int number;
1121char *scall;
1122{
1123 if (errno != number) {
1124 e(NIL);
1125 str("\t");
1126 str(scall);
1127 str(": bad errno-value: ");
1128 put(errno);
1129 str(" should have been: ");
1130 put(number);
1131 nlcr();
1132 }
1133} /* check */
1134
1135void put(nr)
1136int nr;
1137{
1138 switch (nr) {
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;
1174 }
1175}
1176
1177/*****************************************************************************
1178* *
1179* ALOT-functions *
1180* *
1181*****************************************************************************/
1182
1183int open_alot()
1184{
1185 int i;
1186
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");
1190 return(i);
1191} /* open_alot */
1192
1193int close_alot(number)
1194int number;
1195{
1196 int i, count = 0;
1197
1198 if (number > MAXOPEN)
1199 err(5, "close_alot", "accept this argument");
1200 else
1201 for (i = FF; i < number + FF; i++)
1202 if (close(i) != OK) count++;
1203
1204 return(number - count); /* return number of closed files */
1205} /* close_alot */
1206
1207/*****************************************************************************
1208* *
1209* CLEAN UP THE MESS *
1210* *
1211*****************************************************************************/
1212
1213void clean_up_the_mess()
1214{
1215 int i;
1216 char dirname[6];
1217
1218 /* First remove 'alot' files */
1219 for (i = 0; i < MAXOPEN; i++) try_unlink(file[i]);
1220
1221 /* Unlink the files in dir 'drwx' */
1222 if (chdir("drwx") != OK)
1223 err(5, CHDIR, "to 'drwx'");
1224 else {
1225 for (i = 0; i < 8; i++) try_unlink(fnames[i]);
1226 if (chdir("..") != OK) err(5, CHDIR, "to '..'");
1227 }
1228
1229 /* Before unlinking files in some dirs, make them writable */
1230 chmod_8_dirs(RWX);
1231
1232 /* Unlink files in other dirs */
1233 try_unlink("d-wx/rwx");
1234 try_unlink("dr-x/rwx");
1235 try_unlink("drw-/rwx");
1236
1237 /* Unlink dirs */
1238 for (i = 0; i < 8; i++) {
1239 strcpy(dirname, "d");
1240 strcat(dirname, fnames[i]);
1241 /* 'dirname' contains the directoryname */
1242 rmdir(dirname);
1243 }
1244
1245 /* FINISH */
1246} /* clean_up_the_mess */
1247
1248void chmod_8_dirs(sw)
1249int sw; /* if switch == 8, give all different
1250 * mode,else the same mode */
1251{
1252 int mode;
1253 int i;
1254
1255 if (sw == 8)
1256 mode = 0;
1257 else
1258 mode = sw;
1259
1260 for (i = 0; i < 8; i++) {
1261 chmod(dir[i], 040000 + mode * 0100);
1262 if (sw == 8) mode++;
1263 }
1264}
1265
1266void quit()
1267{
1268
1269 chdir("..");
1270 system("rm -rf DIR*");
1271
1272 if (errct == 0) {
1273 printf("ok\n");
1274 exit(0);
1275 } else {
1276 printf("%d errors\n", errct);
1277 exit(1);
1278 }
1279}
Note: See TracBrowser for help on using the repository browser.