test17.c

Go to the documentation of this file.
00001 /* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
00002 
00003 /* "const.h", created by Rene Montsma and Menno Wilcke */
00004 
00005 #include <sys/types.h>          /* type defs */
00006 #include <sys/stat.h>           /* struct stat */
00007 #include <sys/wait.h>
00008 #include <errno.h>              /* the error-numbers */
00009 #include <fcntl.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include <unistd.h>
00013 #include <utime.h>
00014 #include <stdio.h>
00015 #include <limits.h>
00016 
00017 #define NOCRASH 1               /* test11(), 2nd pipe */
00018 #define PDPNOHANG  1            /* test03(), write_standards() */
00019 #define MAXERR 2
00020 
00021 #define USER_ID   12
00022 #define GROUP_ID   1
00023 #define FF        3             /* first free filedes. */
00024 #define USER      1             /* uid */
00025 #define GROUP     0             /* gid */
00026 
00027 #define ARSIZE   256            /* array size */
00028 #define PIPESIZE 3584           /* max number of bytes to be written on pipe */
00029 #define MAXOPEN  (OPEN_MAX-3)           /* maximum number of extra open files */
00030 #define MAXLINK 0177            /* maximum number of links per file */
00031 #define LINKCOUNT 5
00032 #define MASK    0777            /* selects lower nine bits */
00033 #define END_FILE     0          /* returned by read-call at eof */
00034 
00035 #define OK      0
00036 #define FAIL   -1
00037 
00038 #define R       0               /* read (open-call) */
00039 #define W       1               /* write (open-call) */
00040 #define RW      2               /* read & write (open-call) */
00041 
00042 #define RWX     7               /* read & write & execute (mode) */
00043 
00044 #define NIL     ""
00045 #define UMASK   "umask"
00046 #define CREAT   "creat"
00047 #define WRITE   "write"
00048 #define READ    "read"
00049 #define OPEN    "open"
00050 #define CLOSE   "close"
00051 #define LSEEK   "lseek"
00052 #define ACCESS  "access"
00053 #define CHDIR   "chdir"
00054 #define CHMOD   "chmod"
00055 #define LINK    "link"
00056 #define UNLINK  "unlink"
00057 #define PIPE    "pipe"
00058 #define STAT    "stat"
00059 #define FSTAT   "fstat"
00060 #define DUP     "dup"
00061 #define UTIME   "utime"
00062 
00063 int errct;
00064 
00065 char *file[];
00066 char *fnames[];
00067 char *dir[];
00068 
00069 /* "decl.c", created by Rene Montsma and Menno Wilcke */
00070 
00071 /* Used in open_alot, close_alot */
00072 char *file[20] = {"f0", "f1", "f2", "f3", "f4", "f5", "f6",
00073           "f7", "f8", "f9", "f10", "f11", "f12", "f13",
00074           "f14", "f15", "f16", "f17", "f18", "f19"}, *fnames[8] = {"---", "--x", "-w-", "-wx", "r--",
00075                                                                    "r-x", "rw-", "rwx"}, *dir[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",
00076                                                     "drw-", "drwx"};
00077  /* Needed for easy creating and deleting of directories */
00078 
00079 /* "test.c", created by Rene Montsma and Menno Wilcke */
00080 
00081 _PROTOTYPE(int main, (int argc, char *argv []));
00082 _PROTOTYPE(void test, (int mask));
00083 _PROTOTYPE(void test01, (void));
00084 _PROTOTYPE(void test02, (void));
00085 _PROTOTYPE(void test08, (void));
00086 _PROTOTYPE(void test09, (void));
00087 _PROTOTYPE(void test10, (void));
00088 _PROTOTYPE(int link_alot, (char *bigboss));
00089 _PROTOTYPE(int unlink_alot, (int number));
00090 _PROTOTYPE(void get_new, (char name []));
00091 _PROTOTYPE(void test11, (void));
00092 _PROTOTYPE(void comp_stats, (struct stat *stbf1, struct stat *stbf2));
00093 _PROTOTYPE(void comp_inodes, (int m, int m1));
00094 _PROTOTYPE(void e, (char *string));
00095 _PROTOTYPE(void nlcr, (void));
00096 _PROTOTYPE(void str, (char *s));
00097 _PROTOTYPE(void err, (int number, char *scall, char *name));
00098 _PROTOTYPE(void make_and_fill_dirs, (void));
00099 _PROTOTYPE(void put_file_in_dir, (char *dirname, int mode));
00100 _PROTOTYPE(void init_array, (char *a));
00101 _PROTOTYPE(void clear_array, (char *b));
00102 _PROTOTYPE(int comp_array, (char *a, char *b, int range));
00103 _PROTOTYPE(void try_close, (int filedes, char *name));
00104 _PROTOTYPE(void try_unlink, (char *fname));
00105 _PROTOTYPE(void Remove, (int fdes, char *fname));
00106 _PROTOTYPE(int get_mode, (char *name));
00107 _PROTOTYPE(void check, (char *scall, int number));
00108 _PROTOTYPE(void put, (int nr));
00109 _PROTOTYPE(int open_alot, (void));
00110 _PROTOTYPE(int close_alot, (int number));
00111 _PROTOTYPE(void clean_up_the_mess, (void));
00112 _PROTOTYPE(void chmod_8_dirs, (int sw));
00113 _PROTOTYPE(void quit, (void));
00114 
00115 /*****************************************************************************
00116  *                              TEST                                         *
00117  ****************************************************************************/
00118 int main(argc, argv)
00119 int argc;
00120 char *argv[];
00121 {
00122   int n, mask;
00123 
00124   sync();
00125   if (geteuid() == 0 || getuid() == 0) {
00126         printf("Test 17 cannot run as root; test aborted\n");
00127         exit(1);
00128   }
00129 
00130   system("rm -rf DIR_18; mkdir DIR_18");
00131   chdir("DIR_18");
00132 
00133   mask = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
00134 
00135   if (fork()) {
00136         printf("Test 17 ");
00137         fflush(stdout);
00138 
00139         wait(&n);
00140         clean_up_the_mess();
00141         quit();
00142   } else {
00143         test(mask);
00144         exit(0);
00145   }
00146   return(-1);                   /* impossible */
00147 }
00148 
00149 void test(mask)
00150 int mask;
00151 {
00152   umask(0);                     /* not honest, but i always forget */
00153 
00154   if (mask & 00001) test01();
00155   if (mask & 00002) make_and_fill_dirs();
00156   if (mask & 00004) test02();
00157   if (mask & 00010) test08();
00158   if (mask & 00020) test09();
00159   if (mask & 00040) test10();
00160   if (mask & 00100) test11();
00161   umask(022);
00162 }                               /* test */
00163 
00164 /* "t1.c" created by Rene Montsma and Menno Wilcke */
00165 
00166 /*****************************************************************************
00167  *                              test UMASK                                   *
00168  ****************************************************************************/
00169 void test01()
00170 {
00171   int oldvalue, newvalue, tempvalue;
00172   int nr;
00173 
00174   if ((oldvalue = umask(0777)) != 0) err(0, UMASK, NIL);
00175 
00176   /* Special test: only the lower 9 bits (protection bits) may part- *
00177    * icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
00178    * not change any value.                                           */
00179 
00180   if ((newvalue = umask(~0777)) != 0777) err(1, UMASK, "illegal");
00181   if (oldvalue == newvalue) err(11, UMASK, "not change mask");
00182 
00183   if ((tempvalue = umask(0)) != 0) err(2, UMASK, "values");
00184 
00185   /* Now test all possible modes of umask on a file */
00186   for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
00187         tempvalue = umask(newvalue);
00188         if (tempvalue != oldvalue) {
00189                 err(1, UMASK, "illegal");
00190                 break;          /* no use trying more */
00191         } else if ((nr = creat("file01", 0777)) < 0)
00192                 err(5, CREAT, "'file01'");
00193         else {
00194                 try_close(nr, "'file01'");
00195                 if (get_mode("file01") != (MASK & ~newvalue))
00196                         err(7, UMASK, "mode computed");
00197                 try_unlink("file01");
00198         }
00199         oldvalue = newvalue;
00200   }
00201 
00202   /* The loop has terminated with umask(0) */
00203   if ((tempvalue = umask(0)) != 0)
00204         err(7, UMASK, "umask may influence rest of tests!");
00205 }                               /* test01 */
00206 
00207 /*****************************************************************************
00208  *                              test CREAT                                   *
00209  ****************************************************************************/
00210 void test02()
00211 {
00212   int n, n1, mode;
00213   char a[ARSIZE], b[ARSIZE];
00214   struct stat stbf1;
00215 
00216   mode = 0;
00217   /* Create twenty files, check filedes */
00218   for (n = 0; n < MAXOPEN; n++) {
00219         if (creat(file[n], mode) != FF + n)
00220                 err(13, CREAT, file[n]);
00221         else {
00222                 if (get_mode(file[n]) != mode)
00223                         err(7, CREAT, "mode set while creating many files");
00224 
00225                 /* Change  mode of file to standard mode, we want to *
00226                  * use a lot (20) of files to be opened later, see   *
00227                  * open_alot(), close_alot().                        */
00228                 if (chmod(file[n], 0700) != OK) err(5, CHMOD, file[n]);
00229 
00230         }
00231         mode = (mode + 0100) % 01000;
00232   }
00233 
00234   /* Already twenty files opened; opening another has to fail */
00235   if (creat("file02", 0777) != FAIL)
00236         err(9, CREAT, "created");
00237   else
00238         check(CREAT, EMFILE);
00239 
00240   /* Close all files: seems blunt, but it isn't because we've  *
00241    * checked all fd's already                                  */
00242   if ((n = close_alot(MAXOPEN)) < MAXOPEN) err(5, CLOSE, "MAXOPEN files");
00243 
00244   /* Creat 1 file twice; check */
00245   if ((n = creat("file02", 0777)) < 0)
00246         err(5, CREAT, "'file02'");
00247   else {
00248         init_array(a);
00249         if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
00250 
00251         if ((n1 = creat("file02", 0755)) < 0)   /* receate 'file02' */
00252                 err(5, CREAT, "'file02' (2nd time)");
00253         else {
00254                 /* Fd should be at the top after recreation */
00255                 if (lseek(n1, 0L, SEEK_END) != 0)
00256                         err(11, CREAT, "not truncate file by recreation");
00257                 else {
00258                         /* Try to write on recreated file */
00259                         clear_array(b);
00260 
00261                         if (lseek(n1, 0L, SEEK_SET) != 0)
00262                                 err(5, LSEEK, "to top of 2nd fd 'file02'");
00263                         if (write(n1, a, ARSIZE) != ARSIZE)
00264                                 err(1, WRITE, "(2) bad");
00265 
00266                         /* In order to read we've to close and open again */
00267                         try_close(n1, "'file02'  (2nd creation)");
00268                         if ((n1 = open("file02", RW)) < 0)
00269                                 err(5, OPEN, "'file02'  (2nd recreation)");
00270 
00271                         /* Continue */
00272                         if (lseek(n1, 0L, SEEK_SET) != 0)
00273                                 err(5, LSEEK, "to top 'file02'(2nd fd) (2)");
00274                         if (read(n1, b, ARSIZE) != ARSIZE)
00275                                 err(1, READ, "wrong");
00276 
00277                         if (comp_array(a, b, ARSIZE) != OK) err(11, CREAT,
00278                                     "not really truncate file by recreation");
00279                 }
00280                 if (get_mode("file02") != 0777)
00281                         err(11, CREAT, "not maintain mode by recreation");
00282                 try_close(n1, "recreated 'file02'");
00283 
00284         }
00285         Remove(n, "file02");
00286   }
00287 
00288   /* Give 'creat' wrong input: dir not searchable */
00289   if (creat("drw-/file02", 0777) != FAIL)
00290         err(4, CREAT, "'drw-'");
00291   else
00292         check(CREAT, EACCES);
00293 
00294   /* Dir not writable */
00295   if (creat("dr-x/file02", 0777) != FAIL)
00296         err(12, CREAT, "'dr-x/file02'");
00297   else
00298         check(CREAT, EACCES);
00299 
00300   /* File not writable */
00301   if (creat("drwx/r-x", 0777) != FAIL)
00302         err(11, CREAT, "recreate non-writable file");
00303   else
00304         check(CREAT, EACCES);
00305 
00306   /* Try to creat a dir */
00307   if ((n = creat("dir", 040777)) != FAIL) {
00308         if (fstat(n, &stbf1) != OK)
00309                 err(5, FSTAT, "'dir'");
00310         else if (stbf1.st_mode != (mode_t) 0100777)
00311                                 /* cast because mode is negative :-( */
00312                 err(11, CREAT, "'creat' a new directory");
00313         Remove(n, "dir");
00314   }
00315 
00316   /* We don't consider it to be a bug when creat * does not accept
00317    * tricky modes                */
00318 
00319   /* File is an existing dir */
00320   if (creat("drwx", 0777) != FAIL)
00321         err(11, CREAT, "create an existing dir!");
00322   else
00323         check(CREAT, EISDIR);
00324 }                               /* test02 */
00325 
00326 void test08()
00327 {
00328   /* Test chdir to searchable dir */
00329   if (chdir("drwx") != OK)
00330         err(5, CHDIR, "to accessible dir");
00331   else if (chdir("..") != OK)
00332         err(11, CHDIR, "not return to '..'");
00333 
00334   /* Check the chdir(".") and chdir("..") mechanism */
00335   if (chdir("drwx") != OK)
00336         err(5, CHDIR, "to 'drwx'");
00337   else {
00338         if (chdir(".") != OK) err(5, CHDIR, "to working dir (.)");
00339 
00340         /* If we still are in 'drwx' , we should be able to access *
00341          * file 'rwx'.                                              */
00342         if (access("rwx", 0) != OK) err(5, CHDIR, "rightly to '.'");
00343 
00344         /* Try to return to previous dir ('/' !!) */
00345         if (chdir("././../././d--x/../d--x/././..") != OK)
00346                 err(5, CHDIR, "to motherdir (..)");
00347 
00348         /* Check whether we are back in '/' */
00349         if (chdir("d--x") != OK) err(5, CHDIR, "rightly to  a '..'");
00350   }
00351 
00352   /* Return to '..' */
00353   if (chdir("..") != OK) err(5, CHDIR, "to '..'");
00354 
00355   if (chdir("././././drwx") != OK)
00356         err(11, CHDIR, "not follow a path");
00357   else if (chdir("././././..") != OK)
00358         err(11, CHDIR, "not return to path");
00359 
00360   /* Try giving chdir wrong parameters */
00361   if (chdir("drwx/rwx") != FAIL)
00362         err(11, CHDIR, "chdir to a file");
00363   else
00364         check(CHDIR, ENOTDIR);
00365 
00366   if (chdir("drw-") != FAIL)
00367         err(4, CHDIR, "'/drw-'");
00368   else
00369         check(CHDIR, EACCES);
00370 
00371   /* To be sure: return to root */
00372   /* If (chdir("/") != OK) err(5, CHDIR, "to '/' (2nd time)"); */
00373 }                               /* test08 */
00374 
00375 /* New page */
00376 /*****************************************************************************
00377  *                              test CHMOD                                   *
00378  ****************************************************************************/
00379 void test09()
00380 {
00381   int n;
00382 
00383   /* Prepare file09 */
00384   if ((n = creat("drwx/file09", 0644)) != FF) err(5, CREAT, "'drwx/file09'");
00385 
00386   try_close(n, "'file09'");
00387 
00388   /* Try to chmod a file, check and restore old values, check */
00389   if (chmod("drwx/file09", 0700) != OK)
00390         err(5, CHMOD, "'drwx/file09'"); /* set rwx */
00391   else {
00392         /* Check protection */
00393         if (get_mode("drwx/file09") != 0700) err(7, CHMOD, "mode");
00394 
00395         /* Test if chmod accepts just filenames too */
00396         if (chdir("drwx") != OK)
00397                 err(5, CHDIR, "to '/drwx'");
00398         else if (chmod("file09", 0177) != OK)   /* restore oldies */
00399                 err(5, CHMOD, "'h1'");
00400         else
00401                 /* Check if value has been restored */
00402         if (get_mode("../drwx/file09") != 0177)
00403                 err(7, CHMOD, "restored mode");
00404   }
00405 
00406   /* Try setuid and setgid */
00407   if ((chmod("file09", 04777) != OK) || (get_mode("file09") != 04777))
00408         err(11, CHMOD, "not set uid-bit");
00409   if ((chmod("file09", 02777) != OK) || (get_mode("file09") != 02777))
00410         err(11, CHMOD, "not set gid-bit");
00411 
00412   /* Remove testfile */
00413   try_unlink("file09");
00414 
00415   if (chdir("..") != OK) err(5, CHDIR, "to '..'");
00416 
00417   /* Try to chmod directory */
00418   if (chmod("d---", 0777) != OK)
00419         err(5, CHMOD, "dir 'd---'");
00420   else {
00421         if (get_mode("d---") != 0777) err(7, CHMOD, "protection value");
00422         if (chmod("d---", 0000) != OK) err(5, CHMOD, "dir 'a' 2nd time");
00423 
00424         /* Check if old value has been restored */
00425         if (get_mode("d---") != 0000)
00426                 err(7, CHMOD, "restored protection value");
00427   }
00428 
00429   /* Try to make chmod failures */
00430 
00431   /* We still are in dir root */
00432   /* Wrong filename */
00433   if (chmod("non-file", 0777) != FAIL)
00434         err(3, CHMOD, NIL);
00435   else
00436         check(CHMOD, ENOENT);
00437 
00438 }                               /* test 09 */
00439 
00440 /* New page */
00441 
00442 /* "t4.c", created by Rene Montsma and Menno Wilcke */
00443 
00444 /*****************************************************************************
00445  *                              test LINK/UNLINK                             *
00446  ****************************************************************************/
00447 void test10()
00448 {
00449   int n, n1;
00450   char a[ARSIZE], b[ARSIZE], *f, *lf;
00451 
00452   f = "file10";
00453   lf = "linkfile10";
00454 
00455   if ((n = creat(f, 0702)) != FF)       /* no other open files */
00456         err(13, CREAT, f);
00457   else {
00458         /* Now link correctly */
00459         if (link(f, lf) != OK)
00460                 err(5, LINK, lf);
00461         else if ((n1 = open(lf, RW)) < 0)
00462                 err(5, OPEN, "'linkfile10'");
00463         else {
00464                 init_array(a);
00465                 clear_array(b);
00466 
00467                 /* Write on 'file10' means being able to    * read
00468                  * through linked filedescriptor       */
00469                 if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
00470                 if (read(n1, b, ARSIZE) != ARSIZE) err(1, READ, "bad");
00471                 if (comp_array(a, b, ARSIZE) != OK) err(8, "r/w", NIL);
00472 
00473                 /* Clean up: unlink and close (twice): */
00474                 Remove(n, f);
00475                 try_close(n1, "'linkfile10'");
00476 
00477                 /* Check if "linkfile" exists and the info    * on it
00478                  * is correct ('file' has been deleted) */
00479                 if ((n1 = open(lf, R)) < 0)
00480                         err(5, OPEN, "'linkfile10'");
00481                 else {
00482                         /* See if 'linkfile' still contains 0..511 ? */
00483 
00484                         clear_array(b);
00485                         if (read(n1, b, ARSIZE) != ARSIZE)
00486                                 err(1, READ, "bad");
00487                         if (comp_array(a, b, ARSIZE) != OK)
00488                                 err(8, "r/w", NIL);
00489 
00490                         try_close(n1, "'linkfile10' 2nd time");
00491                         try_unlink(lf);
00492                 }
00493         }
00494   }
00495 
00496   /* Try if unlink fails with incorrect parameters */
00497   /* File does not exist: */
00498   if (unlink("non-file") != FAIL)
00499         err(2, UNLINK, "name");
00500   else
00501         check(UNLINK, ENOENT);
00502 
00503   /* Dir can't be written */
00504   if (unlink("dr-x/rwx") != FAIL)
00505         err(11, UNLINK, "could unlink in non-writable dir.");
00506   else
00507         check(UNLINK, EACCES);
00508 
00509   /* Try to unlink a dir being user */
00510   if (unlink("drwx") != FAIL)
00511         err(11, UNLINK, "unlink dir's as user");
00512   else
00513         check(UNLINK, EPERM);
00514 
00515   /* Try giving link wrong input */
00516 
00517   /* First try if link fails with incorrect parameters * name1 does not
00518    * exist.                             */
00519   if (link("non-file", "linkfile") != FAIL)
00520         err(2, LINK, "1st name");
00521   else
00522         check(LINK, ENOENT);
00523 
00524   /* Name2 exists already */
00525   if (link("drwx/rwx", "drwx/rw-") != FAIL)
00526         err(2, LINK, "2nd name");
00527   else
00528         check(LINK, EEXIST);
00529 
00530   /* Directory of name2 not writable:  */
00531   if (link("drwx/rwx", "dr-x/linkfile") != FAIL)
00532         err(11, LINK, "link non-writable  file");
00533   else
00534         check(LINK, EACCES);
00535 
00536   /* Try to link a dir, being a user */
00537   if (link("drwx", "linkfile") != FAIL)
00538         err(11, LINK, "link a dir without superuser!");
00539   else
00540         check(LINK, EPERM);
00541 
00542   /* File has too many links */
00543   if ((n = link_alot("drwx/rwx")) != LINKCOUNT - 1)     /* file already has one
00544                                                          * link */
00545         err(5, LINK, "many files");
00546   if (unlink_alot(n) != n) err(5, UNLINK, "all linked files");
00547 
00548 }                               /* test10 */
00549 
00550 int link_alot(bigboss)
00551 char *bigboss;
00552 {
00553   int i;
00554   static char employee[6] = "aaaaa";
00555 
00556   /* Every file has already got 1 link, so link 0176 times */
00557   for (i = 1; i < LINKCOUNT; i++) {
00558         if (link(bigboss, employee) != OK)
00559                 break;
00560         else
00561                 get_new(employee);
00562   }
00563 
00564   return(i - 1);                /* number of linked files */
00565 }                               /* link_alot */
00566 
00567 int unlink_alot(number)
00568 int number;                     /* number of files to be unlinked */
00569 {
00570   int j;
00571   static char employee[6] = "aaaaa";
00572 
00573   for (j = 0; j < number; j++) {
00574         if (unlink(employee) != OK)
00575                 break;
00576         else
00577                 get_new(employee);
00578   }
00579 
00580   return(j);                    /* return number of unlinked files */
00581 }                               /* unlink_alot */
00582 
00583 void get_new(name)
00584 char name[];
00585  /* Every call changes string 'name' to a string alphabetically          *
00586   * higher. Start with "aaaaa", next value: "aaaab" .                    *
00587   * N.B. after "aaaaz" comes "aaabz" and not "aaaba" (not needed).       *
00588   * The last possibility will be "zzzzz".                                *
00589   * Total # possibilities: 26+25*4 = 126 = MAXLINK -1 (exactly needed)   */
00590 {
00591   int i;
00592 
00593   for (i = 4; i >= 0; i--)
00594         if (name[i] != 'z') {
00595                 name[i]++;
00596                 break;
00597         }
00598 }                               /* get_new */
00599 
00600 /* New page */
00601 
00602 /*****************************************************************************
00603  *                              test PIPE                                    *
00604  ****************************************************************************/
00605 void test11()
00606 {
00607   int n, fd[2];
00608   char a[ARSIZE], b[ARSIZE];
00609 
00610   if (pipe(fd) != OK)
00611         err(13, PIPE, NIL);
00612   else {
00613         /* Try reading and writing on a pipe */
00614         init_array(a);
00615         clear_array(b);
00616 
00617         if (write(fd[1], a, ARSIZE) != ARSIZE)
00618                 err(5, WRITE, "on pipe");
00619         else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
00620                 err(5, READ, "on pipe (2nd time)");
00621         else if (comp_array(a, b, (ARSIZE / 2)) != OK)
00622                 err(7, PIPE, "values read/written");
00623         else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
00624                 err(5, READ, "on pipe 2");
00625         else if (comp_array(&a[ARSIZE / 2], b, (ARSIZE / 2)) != OK)
00626                 err(7, PIPE, "pipe created");
00627 
00628         /* Try to let the pipe make a mistake */
00629         if (write(fd[0], a, ARSIZE) != FAIL)
00630                 err(11, WRITE, "write on fd[0]");
00631         if (read(fd[1], b, ARSIZE) != FAIL) err(11, READ, "read on fd[1]");
00632 
00633         try_close(fd[1], "'fd[1]'");
00634 
00635         /* Now we shouldn't be able to read, because fd[1] has been closed */
00636         if (read(fd[0], b, ARSIZE) != END_FILE) err(2, PIPE, "'fd[1]'");
00637 
00638         try_close(fd[0], "'fd[0]'");
00639   }
00640   if (pipe(fd) < 0)
00641         err(5, PIPE, "2nd time");
00642   else {
00643         /* Test lseek on a pipe: should fail */
00644         if (write(fd[1], a, ARSIZE) != ARSIZE)
00645                 err(5, WRITE, "on pipe (2nd time)");
00646         if (lseek(fd[1], 10L, SEEK_SET) != FAIL)
00647                 err(11, LSEEK, "lseek on a pipe");
00648         else
00649                 check(PIPE, ESPIPE);
00650 
00651         /* Eat half of the pipe: no writing should be possible */
00652         try_close(fd[0], "'fd[0]'  (2nd time)");
00653 
00654         /* This makes UNIX crash: omit it if pdp or VAX */
00655 #ifndef NOCRASH
00656         if (write(fd[1], a, ARSIZE) != FAIL)
00657                 err(11, WRITE, "write on wrong pipe");
00658         else
00659                 check(PIPE, EPIPE);
00660 #endif
00661         try_close(fd[1], "'fd[1]'  (2nd time)");
00662   }
00663 
00664   /* BUG :                                                            *
00665    * Here we planned to test if we could write 4K bytes on a pipe.    *
00666    * However, this was not possible to implement, because the whole   *
00667    * Monix system crashed when we tried to write more then 3584 bytes *
00668    * (3.5K) on a pipe. That's why we try to write only 3.5K in the    *
00669    * folowing test.                                                   */
00670   if (pipe(fd) < 0)
00671         err(5, PIPE, "3rd time");
00672   else {
00673         for (n = 0; n < (PIPESIZE / ARSIZE); n++)
00674                 if (write(fd[1], a, ARSIZE) != ARSIZE)
00675                         err(5, WRITE, "on pipe (3rd time) 4K");
00676         try_close(fd[1], "'fd[1]' (3rd time)");
00677 
00678         for (n = 0; n < (PIPESIZE / ARSIZE); n++)
00679                 if (read(fd[0], b, ARSIZE) != ARSIZE)
00680                         err(5, READ, "from pipe (3rd time) 4K");
00681         try_close(fd[0], "'fd[0]' (3rd time)");
00682   }
00683 
00684   /* Test opening a lot of files */
00685   if ((n = open_alot()) != MAXOPEN) err(5, OPEN, "MAXOPEN files");
00686   if (pipe(fd) != FAIL)
00687         err(9, PIPE, "open");
00688   else
00689         check(PIPE, EMFILE);
00690   if (close_alot(n) != n) err(5, CLOSE, "all opened files");
00691 }                               /* test11 */
00692 
00693 /* New page */
00694 
00695 void comp_stats(stbf1, stbf2)
00696 struct stat *stbf1, *stbf2;
00697 {
00698   if (stbf1->st_dev != stbf2->st_dev) err(7, "st/fst", "'dev'");
00699   if (stbf1->st_ino != stbf2->st_ino) err(7, "st/fst", "'ino'");
00700   if (stbf1->st_mode != stbf2->st_mode) err(7, "st/fst", "'mode'");
00701   if (stbf1->st_nlink != stbf2->st_nlink) err(7, "st/fst", "'nlink'");
00702   if (stbf1->st_uid != stbf2->st_uid) err(7, "st/fst", "'uid'");
00703   if (stbf1->st_gid != stbf2->st_gid) err(7, "st/fst", "'gid'");
00704   if (stbf1->st_rdev != stbf2->st_rdev) err(7, "st/fst", "'rdev'");
00705   if (stbf1->st_size != stbf2->st_size) err(7, "st/fst", "'size'");
00706   if (stbf1->st_atime != stbf2->st_atime) err(7, "st/fst", "'atime'");
00707   if (stbf1->st_mtime != stbf2->st_mtime) err(7, "st/fst", "'mtime'");
00708 }                               /* comp_stats */
00709 
00710 /* New page */
00711 
00712 /* "t5.c", created by Rene Montsma and Menno Wilcke */
00713 
00714 void comp_inodes(m, m1)
00715 int m, m1;                      /* twee filedes's */
00716 {
00717   struct stat stbf1, stbf2;
00718 
00719   if (fstat(m, &stbf1) == OK)
00720         if (fstat(m1, &stbf2) == OK) {
00721                 if (stbf1.st_ino != stbf2.st_ino)
00722                         err(7, DUP, "inode number");
00723         } else
00724                 err(100, "comp_inodes", "cannot 'fstat' (m1)");
00725   else
00726         err(100, "comp_inodes", "cannot 'fstat' (m)");
00727 }                               /* comp_inodes */
00728 
00729 /* "support.c", created by Rene Montsma and Menno Wilcke */
00730 
00731 /* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
00732    try_close, try_unlink, Remove, get_mode, check, open_alot,
00733    close_alot, clean_up_the_mess.
00734 */
00735 
00736 /***********************************************************************
00737  *                              EXTENDED FIONS                         *
00738  **********************************************************************/
00739 /* First extended functions (i.e. not oldfashioned monixcalls.
00740    e(), nlcr(), octal.*/
00741 
00742 void e(string)
00743 char *string;
00744 {
00745   printf("Error: %s ", string);
00746 }
00747 
00748 void nlcr()
00749 {
00750   printf("\n");
00751 }
00752 
00753 void str(s)
00754 char *s;
00755 {
00756   printf(s);
00757 }
00758 
00759 /*****************************************************************************
00760 *                                                                            *
00761 *                               ERR(or) messages                             *
00762 *                                                                            *
00763 *****************************************************************************/
00764 void err(number, scall, name)
00765  /* Give nice error messages */
00766 
00767 char *scall, *name;
00768 int number;
00769 
00770 {
00771   errct++;
00772   if (errct > MAXERR) {
00773         printf("Too many errors;  test aborted\n");
00774         quit();
00775   }
00776   e("");
00777   str("\t");
00778   switch (number) {
00779       case 0:
00780         str(scall);
00781         str(": illegal initial value.");
00782         break;
00783       case 1:
00784         str(scall);
00785         str(": ");
00786         str(name);
00787         str(" value returned.");
00788         break;
00789       case 2:
00790         str(scall);
00791         str(": accepting illegal ");
00792         str(name);
00793         str(".");
00794         break;
00795       case 3:
00796         str(scall);
00797         str(": accepting non-existing file.");
00798         break;
00799       case 4:
00800         str(scall);
00801         str(": could search non-searchable dir (");
00802         str(name);
00803         str(").");
00804         break;
00805       case 5:
00806         str(scall);
00807         str(": cannot ");
00808         str(scall);
00809         str(" ");
00810         str(name);
00811         str(".");
00812         break;
00813       case 7:
00814         str(scall);
00815         str(": incorrect ");
00816         str(name);
00817         str(".");
00818         break;
00819       case 8:
00820         str(scall);
00821         str(": wrong values.");
00822         break;
00823       case 9:
00824         str(scall);
00825         str(": accepting too many ");
00826         str(name);
00827         str(" files.");
00828         break;
00829       case 10:
00830         str(scall);
00831         str(": even a superuser can't do anything!");
00832         break;
00833       case 11:
00834         str(scall);
00835         str(": could ");
00836         str(name);
00837         str(".");
00838         break;
00839       case 12:
00840         str(scall);
00841         str(": could write in non-writable dir (");
00842         str(name);
00843         str(").");
00844         break;
00845       case 13:
00846         str(scall);
00847         str(": wrong filedes returned (");
00848         str(name);
00849         str(").");
00850         break;
00851       case 100:
00852         str(scall);             /* very common */
00853         str(": ");
00854         str(name);
00855         str(".");
00856         break;
00857       default:  str("errornumber does not exist!\n");
00858   }
00859   nlcr();
00860 }                               /* err */
00861 
00862 /*****************************************************************************
00863 *                                                                            *
00864 *                          MAKE_AND_FILL_DIRS                                *
00865 *                                                                            *
00866 *****************************************************************************/
00867 
00868 void make_and_fill_dirs()
00869  /* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",     *
00870   * "drw-", "drwx".                                     * Then create 8 files
00871   * in "drwx", and some needed files in other dirs.  */
00872 {
00873   int mode, i;
00874 
00875   for (i = 0; i < 8; i++) {
00876         mkdir(dir[i], 0700);
00877         chown(dir[i], USER_ID, GROUP_ID);
00878   }
00879   setuid(USER_ID);
00880   setgid(GROUP_ID);
00881 
00882   for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
00883 
00884   put_file_in_dir("d-wx", RWX);
00885   put_file_in_dir("dr-x", RWX);
00886   put_file_in_dir("drw-", RWX);
00887 
00888   chmod_8_dirs(8);              /* 8 means; 8 different modes */
00889 
00890 }                               /* make_and_fill_dirs */
00891 
00892 void put_file_in_dir(dirname, mode)
00893 char *dirname;
00894 int mode;
00895  /* Fill directory 'dirname' with file with mode 'mode'.   */
00896 {
00897   int nr;
00898 
00899   if (chdir(dirname) != OK)
00900         err(5, CHDIR, "to dirname (put_f_in_dir)");
00901   else {
00902         /* Creat the file */
00903         if ((nr = creat(fnames[mode], mode * 0100)) < 0)
00904                 err(13, CREAT, fnames[mode]);
00905         else
00906                 try_close(nr, fnames[mode]);
00907 
00908         if (chdir("..") != OK)
00909                 err(5, CHDIR, "to previous dir (put_f_in_dir)");
00910   }
00911 }                               /* put_file_in_dir */
00912 
00913 /*****************************************************************************
00914 *                                                                            *
00915 *                               MISCELLANEOUS                                *
00916 *                                                                            *
00917 *(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode')*
00918 *                                                                            *
00919 *****************************************************************************/
00920 
00921 void init_array(a)
00922 char *a;
00923 {
00924   int i;
00925 
00926   i = 0;
00927   while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
00928 }                               /* init_array */
00929 
00930 void clear_array(b)
00931 char *b;
00932 {
00933   int i;
00934 
00935   i = 0;
00936   while (i++ < ARSIZE) *b++ = '0';
00937 
00938 }                               /* clear_array */
00939 
00940 int comp_array(a, b, range)
00941 char *a, *b;
00942 int range;
00943 {
00944   if ((range < 0) || (range > ARSIZE)) {
00945         err(100, "comp_array", "illegal range");
00946         return(FAIL);
00947   } else {
00948         while (range-- && (*a++ == *b++));
00949         if (*--a == *--b)
00950                 return(OK);
00951         else
00952                 return(FAIL);
00953   }
00954 }                               /* comp_array */
00955 
00956 void try_close(filedes, name)
00957 int filedes;
00958 char *name;
00959 {
00960   if (close(filedes) != OK) err(5, CLOSE, name);
00961 }                               /* try_close */
00962 
00963 void try_unlink(fname)
00964 char *fname;
00965 {
00966   if (unlink(fname) != 0) err(5, UNLINK, fname);
00967 }                               /* try_unlink */
00968 
00969 void Remove(fdes, fname)
00970 int fdes;
00971 char *fname;
00972 {
00973   try_close(fdes, fname);
00974   try_unlink(fname);
00975 }                               /* Remove */
00976 
00977 int get_mode(name)
00978 char *name;
00979 {
00980   struct stat stbf1;
00981 
00982   if (stat(name, &stbf1) != OK) {
00983         err(5, STAT, name);
00984         return(stbf1.st_mode);  /* return a mode which will cause *
00985                                  * error in the calling function  *
00986                                  * (file/dir bit)                 */
00987   } else
00988         return(stbf1.st_mode & 07777);  /* take last 4 bits */
00989 }                               /* get_mode */
00990 
00991 /*****************************************************************************
00992 *                                                                            *
00993 *                                  CHECK                                     *
00994 *                                                                            *
00995 *****************************************************************************/
00996 
00997 void check(scall, number)
00998 int number;
00999 char *scall;
01000 {
01001   if (errno != number) {
01002         e(NIL);
01003         str("\t");
01004         str(scall);
01005         str(": bad errno-value: ");
01006         put(errno);
01007         str(" should have been: ");
01008         put(number);
01009         nlcr();
01010   }
01011 }                               /* check */
01012 
01013 void put(nr)
01014 int nr;
01015 {
01016   switch (nr) {
01017       case 0:   str("unused");          break;
01018       case 1:   str("EPERM");           break;
01019       case 2:   str("ENOENT");          break;
01020       case 3:   str("ESRCH");           break;
01021       case 4:   str("EINTR");           break;
01022       case 5:   str("EIO");             break;
01023       case 6:   str("ENXIO");           break;
01024       case 7:   str("E2BIG");           break;
01025       case 8:   str("ENOEXEC");         break;
01026       case 9:   str("EBADF");           break;
01027       case 10:  str("ECHILD");          break;
01028       case 11:  str("EAGAIN");          break;
01029       case 12:  str("ENOMEM");          break;
01030       case 13:  str("EACCES");          break;
01031       case 14:  str("EFAULT");          break;
01032       case 15:  str("ENOTBLK");         break;
01033       case 16:  str("EBUSY");           break;
01034       case 17:  str("EEXIST");          break;
01035       case 18:  str("EXDEV");           break;
01036       case 19:  str("ENODEV");          break;
01037       case 20:  str("ENOTDIR");         break;
01038       case 21:  str("EISDIR");          break;
01039       case 22:  str("EINVAL");          break;
01040       case 23:  str("ENFILE");          break;
01041       case 24:  str("EMFILE");          break;
01042       case 25:  str("ENOTTY");          break;
01043       case 26:  str("ETXTBSY");         break;
01044       case 27:  str("EFBIG");           break;
01045       case 28:  str("ENOSPC");          break;
01046       case 29:  str("ESPIPE");          break;
01047       case 30:  str("EROFS");           break;
01048       case 31:  str("EMLINK");          break;
01049       case 32:  str("EPIPE");           break;
01050       case 33:  str("EDOM");            break;
01051       case 34:  str("ERANGE");          break;
01052   }
01053 }
01054 
01055 /*****************************************************************************
01056 *                                                                            *
01057 *                                ALOT-functions                              *
01058 *                                                                            *
01059 *****************************************************************************/
01060 
01061 int open_alot()
01062 {
01063   int i;
01064 
01065   for (i = 0; i < MAXOPEN; i++)
01066         if (open(file[i], R) == FAIL) break;
01067   if (i == 0) err(5, "open_alot", "at all");
01068   return(i);
01069 }                               /* open_alot */
01070 
01071 int close_alot(number)
01072 int number;
01073 {
01074   int i, count = 0;
01075 
01076   if (number > MAXOPEN)
01077         err(5, "close_alot", "accept this argument");
01078   else
01079         for (i = FF; i < number + FF; i++)
01080                 if (close(i) != OK) count++;
01081 
01082   return(number - count);       /* return number of closed files */
01083 }                               /* close_alot */
01084 
01085 /*****************************************************************************
01086 *                                                                            *
01087 *                         CLEAN UP THE MESS                                  *
01088 *                                                                            *
01089 *****************************************************************************/
01090 
01091 void clean_up_the_mess()
01092 {
01093   int i;
01094   char dirname[6];
01095 
01096   /* First remove 'a lot' files */
01097   for (i = 0; i < MAXOPEN; i++) try_unlink(file[i]);
01098 
01099   /* Unlink the files in dir 'drwx' */
01100   if (chdir("drwx") != OK)
01101         err(5, CHDIR, "to 'drwx'");
01102   else {
01103         for (i = 0; i < 8; i++) try_unlink(fnames[i]);
01104         if (chdir("..") != OK) err(5, CHDIR, "to '..'");
01105   }
01106 
01107   /* Before unlinking files in some dirs, make them writable */
01108   chmod_8_dirs(RWX);
01109 
01110   /* Unlink files in other dirs */
01111   try_unlink("d-wx/rwx");
01112   try_unlink("dr-x/rwx");
01113   try_unlink("drw-/rwx");
01114 
01115   /* Unlink dirs */
01116   for (i = 0; i < 8; i++) {
01117         strcpy(dirname, "d");
01118         strcat(dirname, fnames[i]);
01119 
01120         /* 'dirname' contains the directoryname */
01121         rmdir(dirname);
01122   }
01123 
01124   /* FINISH */
01125 }                               /* clean_up_the_mess */
01126 
01127 void chmod_8_dirs(sw)
01128 int sw;                         /* if switch == 8, give all different
01129                          * mode,else the same mode */
01130 {
01131   int mode;
01132   int i;
01133 
01134   if (sw == 8)
01135         mode = 0;
01136   else
01137         mode = sw;
01138 
01139   for (i = 0; i < 8; i++) {
01140         chmod(dir[i], 040000 + mode * 0100);
01141         if (sw == 8) mode++;
01142   }
01143 }
01144 
01145 void quit()
01146 {
01147 
01148   chdir("..");
01149   system("rm -rf DIR*");
01150 
01151   if (errct == 0) {
01152         printf("ok\n");
01153         exit(0);
01154   } else {
01155         printf("%d errors\n", errct);
01156         exit(1);
01157   }
01158 }

Generated on Fri Apr 14 22:57:33 2006 for minix by  doxygen 1.4.6