test25.c

Go to the documentation of this file.
00001 /* test25: open (), close ()    (p) Jan-Mark Wams. email: jms@cs.vu.nl */
00002 
00003 /* Not tested: O_NONBLOCK on special files, supporting it.
00004 ** On a read-only file system, some error reports are to be expected.
00005 */
00006 
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <sys/wait.h>
00010 #include <stdlib.h>
00011 #include <unistd.h>
00012 #include <string.h>
00013 #include <fcntl.h>
00014 #include <limits.h>
00015 #include <errno.h>
00016 #include <time.h>
00017 #include <stdio.h>
00018 
00019 #define MAX_ERROR       4
00020 #define ITERATIONS      2
00021 
00022 #define System(cmd)     if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
00023 #define Chdir(dir)      if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
00024 #define Stat(a,b)       if (stat(a,b) != 0) printf("Can't stat %s\n", a)
00025 #define Creat(f)        if (close(creat(f,0777))!=0) printf("Can't creat %s\n",f)
00026 #define Report(s,n)     printf("Subtest %d" s,subtest,(n))
00027 
00028 int errct = 0;
00029 int subtest = 1;
00030 int superuser;
00031 char MaxName[NAME_MAX + 1];     /* Name of maximum length */
00032 char MaxPath[PATH_MAX];         /* Same for path */
00033 char ToLongName[NAME_MAX + 2];  /* Name of maximum +1 length */
00034 char ToLongPath[PATH_MAX + 1];  /* Same for path, both too long */
00035 
00036 _PROTOTYPE(void main, (int argc, char *argv[]));
00037 _PROTOTYPE(void test25a, (void));
00038 _PROTOTYPE(void test25b, (void));
00039 _PROTOTYPE(void test25c, (void));
00040 _PROTOTYPE(void test25d, (void));
00041 _PROTOTYPE(void test25e, (void));
00042 _PROTOTYPE(void makelongnames, (void));
00043 _PROTOTYPE(void e, (int number));
00044 _PROTOTYPE(void quit, (void));
00045 
00046 void main(argc, argv)
00047 int argc;
00048 char *argv[];
00049 {
00050   int i, m = 0xFFFF;
00051 
00052   sync();
00053   if (geteuid() == 0 || getuid() == 0) {
00054         printf("Test 25 cannot run as root; test aborted\n");
00055         exit(1);
00056   }
00057 
00058   if (argc == 2) m = atoi(argv[1]);
00059   printf("Test 25 ");
00060   fflush(stdout);
00061   System("rm -rf DIR_25; mkdir DIR_25");
00062   Chdir("DIR_25");
00063   makelongnames();
00064   superuser = (geteuid() == 0);
00065 
00066   /* Close all files, the parent might have opened. */
00067   for (i = 3; i < 100; i++) close(i);
00068 
00069   for (i = 0; i < ITERATIONS; i++) {
00070         if (m & 001) test25a();
00071         if (m & 002) test25b();
00072         if (m & 004) test25c();
00073         if (m & 010) test25d();
00074         if (m & 020) test25e();
00075   }
00076   quit();
00077 }
00078 
00079 void test25a()
00080 {                               /* Test fcntl flags. */
00081   subtest = 1;
00082 
00083 #define EXCLUDE(a,b)    (((a)^(b)) == ((a)|(b)))
00084 #define ADDIT           (O_APPEND | O_CREAT | O_EXCL | O_NONBLOCK | O_TRUNC)
00085 
00086   /* If this compiles all flags are defined but they have to be or-able. */
00087   if (!(EXCLUDE(O_NONBLOCK, O_TRUNC))) e(1);
00088   if (!(EXCLUDE(O_EXCL, O_NONBLOCK | O_TRUNC))) e(2);
00089   if (!(EXCLUDE(O_CREAT, O_EXCL | O_NONBLOCK | O_TRUNC))) e(3);
00090   if (!(EXCLUDE(O_APPEND, O_CREAT | O_EXCL | O_NONBLOCK | O_TRUNC))) e(4);
00091   if (!(EXCLUDE(O_RDONLY, ADDIT))) e(5);
00092   if (!(EXCLUDE(O_WRONLY, ADDIT))) e(6);
00093   if (!(EXCLUDE(O_RDWR, ADDIT))) e(7);
00094 }
00095 
00096 void test25b()
00097 {                               /* Test normal operation. */
00098 
00099 #define BUF_SIZE 1024
00100 
00101   int fd1, fd2, fd3, fd4, fd5;
00102   char buf[BUF_SIZE];
00103   struct stat st1, st2, st3;
00104   time_t time1, time2;
00105   int stat_loc;
00106 
00107   subtest = 2;
00108 
00109   System("rm -rf ../DIR_25/*");
00110 
00111   System("echo Hello > he");    /* make test files */
00112   System("echo Hello > ha");    /* size 6 bytes */
00113   System("echo Hello > hi");
00114   System("echo Hello > ho");
00115 
00116   /* Check path resolution. Check if lowest fds are returned */
00117   if ((fd1 = open("he", O_RDONLY)) != 3) e(1);
00118   if (read(fd1, buf, BUF_SIZE) != 6) e(2);
00119   if ((fd2 = open("./ha", O_RDONLY)) != 4) e(3);
00120   if ((fd3 = open("../DIR_25/he", O_RDWR)) != 5) e(4);
00121   if ((fd4 = open("ho", O_WRONLY)) != 6) e(5);
00122   if (close(fd4) != 0) e(6);
00123   if (close(fd1) != 0) e(7);
00124   if ((fd1 = open("./././ho", O_RDWR)) != 3) e(8);
00125   if ((fd4 = open("../DIR_25/he", O_RDONLY)) != 6) e(9);
00126   if (close(fd2) != 0) e(10);
00127   if (close(fd3) != 0) e(11);
00128   if ((fd2 = open("ha", O_RDONLY)) != 4) e(12);
00129   if ((fd3 = open("/etc/passwd", O_RDONLY)) != 5) e(13);
00130   if (close(fd4) != 0) e(14);   /* close all */
00131   if (close(fd1) != 0) e(15);
00132   if (close(fd3) != 0) e(16);
00133 
00134   /* Check if processes share fd2, and if they have independent new fds */
00135   System("rm -rf /tmp/sema.25");
00136   switch (fork()) {
00137       case -1:  printf("Can't fork\n"); break;
00138 
00139       case 0:
00140         if ((fd1 = open("he", O_WRONLY)) != 3) e(17);
00141         if ((fd3 = open("../././DIR_25/ha", O_WRONLY)) != 5) e(18);
00142         if ((fd4 = open("../DIR_25/hi", O_WRONLY)) != 6) e(19);
00143         if ((fd5 = open("ho", O_WRONLY)) != 7) e(20);
00144         system("while test ! -f /tmp/sema.25; do sleep 1; done");  /* parent */
00145         if (read(fd2, buf, BUF_SIZE) != 3) e(21);       /* gets Hel */
00146         if (strncmp(buf, "lo\n", 3) != 0) e(22);        /* we get lo */
00147         if (close(fd1) != 0) e(23);
00148         if (close(fd2) != 0) e(24);
00149         if (close(fd3) != 0) e(25);
00150         if (close(fd4) != 0) e(26);
00151         if (close(fd5) != 0) e(27);
00152         exit(0);
00153 
00154       default:
00155         if ((fd1 = open("ha", O_RDONLY)) != 3) e(28);
00156         if ((fd3 = open("./he", O_RDONLY)) != 5) e(29);
00157         if ((fd4 = open("../DIR_25/hi", O_RDWR)) != 6) e(30);
00158         if ((fd5 = open("ho", O_WRONLY)) != 7) e(31);
00159         if (close(fd1) != 0) e(32);
00160         if (read(fd2, buf, 3) != 3) e(33);      /* get Hel */
00161         Creat("/tmp/sema.25");
00162         if (strncmp(buf, "Hel", 3) != 0) e(34);
00163         if (close(fd2) != 0) e(35);
00164         if (close(fd3) != 0) e(36);
00165         if (close(fd4) != 0) e(37);
00166         if (close(fd5) != 0) e(38);
00167         if (wait(&stat_loc) == -1) e(39);
00168         if (stat_loc != 0) e(40);
00169   }
00170   System("rm -f /tmp/sema.25");
00171 
00172   /* Check if the file status information is updated correctly */
00173   Stat("hi", &st1);             /* get info */
00174   Stat("ha", &st2);             /* of files */
00175   time(&time1);
00176   while (time1 >= time((time_t *)0))
00177         ;                       /* wait a sec */
00178   if ((fd1 = open("hi", O_RDONLY)) != 3) e(41); /* open files */
00179   if ((fd2 = open("ha", O_WRONLY)) != 4) e(42);
00180   if (read(fd1, buf, 1) != 1) e(43);    /* read one */
00181   if (close(fd1) != 0) e(44);   /* close one */
00182   Stat("hi", &st3);             /* get info */
00183   if (st1.st_uid != st3.st_uid) e(45);
00184   if (st1.st_gid != st3.st_gid) e(46);  /* should be same */
00185   if (st1.st_mode != st3.st_mode) e(47);
00186   if (st1.st_size != st3.st_size) e(48);
00187   if (st1.st_nlink != st3.st_nlink) e(49);
00188   if (st1.st_mtime != st3.st_mtime) e(50);
00189   if (st1.st_ctime != st3.st_ctime) e(51);
00190 #ifndef V1_FILESYSTEM
00191   if (st1.st_atime >= st3.st_atime) e(52);      /* except for atime. */
00192 #endif
00193   if (write(fd2, "Howdy\n", 6) != 6) e(53);     /* Update c & mtime. */
00194   if ((fd1 = open("ha", O_RDWR)) != 3) e(54);
00195   if (read(fd1, buf, 6) != 6) e(55);    /* Update atime. */
00196   if (strncmp(buf, "Howdy\n", 6) != 0) e(56);
00197   if (close(fd1) != 0) e(57);
00198   Stat("ha", &st3);
00199   if (st2.st_uid != st3.st_uid) e(58);
00200   if (st2.st_gid != st3.st_gid) e(59);  /* should be same */
00201   if (st2.st_mode != st3.st_mode) e(60);
00202   if (st2.st_nlink != st3.st_nlink) e(61);
00203   if (st2.st_ctime >= st3.st_ctime) e(62);
00204 #ifndef V1_FILESYSTEM
00205   if (st2.st_atime >= st3.st_atime) e(63);
00206 #endif
00207   if (st2.st_mtime >= st3.st_mtime) e(64);
00208   if (st2.st_size != st3.st_size) e(65);
00209   if (close(fd2) != 0) e(66);
00210 
00211   /* Let's see if RDONLY files are read only. */
00212   if ((fd1 = open("hi", O_RDONLY)) != 3) e(67);
00213   if (write(fd1, " again", 7) != -1) e(68);     /* we can't write */
00214   if (errno != EBADF) e(69);    /* a read only fd */
00215   if (read(fd1, buf, 7) != 6) e(70);    /* but we can read */
00216   if (close(fd1) != 0) e(71);
00217 
00218   /* Let's see if WRONLY files are write only. */
00219   if ((fd1 = open("hi", O_WRONLY)) != 3) e(72);
00220   if (read(fd1, buf, 7) != -1) e(73);   /* we can't read */
00221   if (errno != EBADF) e(74);    /* a write only fd */
00222   if (write(fd1, "hELLO", 6) != 6) e(75);       /* but we can write */
00223   if (close(fd1) != 0) e(76);
00224 
00225   /* Let's see if files are closable only once. */
00226   if (close(fd1) != -1) e(77);
00227   if (errno != EBADF) e(78);
00228 
00229   /* Let's see how calling close() with bad fds is handled. */
00230   if (close(10) != -1) e(79);
00231   if (errno != EBADF) e(80);
00232   if (close(111) != -1) e(81);
00233   if (errno != EBADF) e(82);
00234   if (close(-432) != -1) e(83);
00235   if (errno != EBADF) e(84);
00236 
00237   /* Let's see if RDWR files are read & write able. */
00238   if ((fd1 = open("hi", O_RDWR)) != 3) e(85);
00239   if (read(fd1, buf, 6) != 6) e(86);    /* we can read */
00240   if (strncmp(buf, "hELLO", 6) != 0) e(87);     /* and we can write */
00241   if (write(fd1, "Hello", 6) != 6) e(88);       /* a read write fd */
00242   if (close(fd1) != 0) e(89);
00243 
00244   /* Check if APPENDed files are realy appended */
00245   if ((fd1 = open("hi", O_RDWR | O_APPEND)) != 3) e(90);        /* open hi */
00246 
00247   /* An open should set the file offset to 0. */
00248   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 0) e(91);
00249 
00250   /* Writing 0 bytes should not have an effect. */
00251   if (write(fd1, "", 0) != 0) e(92);
00252   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 0) e(93);      /* the end? */
00253 
00254   /* A seek befor a wirte should not matter with O_APPEND. */
00255   Stat("hi", &st1);
00256   if (lseek(fd1, (off_t) - 3, SEEK_END) != st1.st_size - 3) e(94);
00257 
00258   /* By writing 1 byte, we force the offset to the end of the file */
00259   if (write(fd1, "1", 1) != 1) e(95);
00260   Stat("hi", &st1);
00261   if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(96);
00262   if (write(fd1, "2", 1) != 1) e(97);
00263   Stat("hi", &st1);
00264   if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(98);
00265   if (write(fd1, "3", 1) != 1) e(99);
00266   Stat("hi", &st1);
00267   if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(100);
00268   if (lseek(fd1, (off_t) - 2, SEEK_CUR) <= 0) e(101);
00269   if (write(fd1, "4", 1) != 1) e(102);
00270 
00271   /* Since the mode was O_APPEND, the offset should be reset to EOF */
00272   Stat("hi", &st1);
00273   if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(103);
00274   if (lseek(fd1, (off_t) - 4, SEEK_CUR) != st1.st_size - 4) e(104);
00275   if (read(fd1, buf, BUF_SIZE) != 4) e(105);
00276   if (strncmp(buf, "1234", 4) != 0) e(106);
00277   if (close(fd1) != 0) e(107);
00278 
00279   /* Check the effect of O_CREAT */
00280   Stat("ho", &st1);
00281   fd1 = open("ho", O_RDWR | O_CREAT, 0000);
00282   if (fd1 != 3) e(108);
00283   Stat("ho", &st2);
00284   if (memcmp(&st1, &st2, sizeof(struct stat)) != 0) e(109);
00285   if (read(fd1, buf, 6) != 6) e(110);
00286   if (strncmp(buf, "Hello\n", 6) != 0) e(111);
00287   if (write(fd1, "@", 1) != 1) e(112);
00288   if (close(fd1) != 0) e(113);
00289   (void) umask(0000);
00290   fd1 = open("ho", O_RDWR | O_CREAT | O_EXCL, 0777);
00291   if (fd1 != -1) e(114);        /* ho exists */
00292   System("rm -rf new");
00293   time(&time1);
00294   while (time1 >= time((time_t *)0))    
00295         ;
00296   fd1 = open("new", O_RDWR | O_CREAT, 0716);
00297   if (fd1 != 3) e(115);         /* new file */
00298   Stat("new", &st1);
00299   time(&time2);
00300   while (time2 >= time((time_t *)0))
00301         ;
00302   time(&time2);
00303   if (st1.st_uid != geteuid()) e(116);  /* try this as superuser. */
00304   if (st1.st_gid != getegid()) e(117);
00305   if ((st1.st_mode & 0777) != 0716) e(118);
00306   if (st1.st_nlink != 1) e(119);
00307   if (st1.st_mtime <= time1) e(120);
00308   if (st1.st_mtime >= time2) e(121);
00309 #ifndef V1_FILESYSTEM
00310   if (st1.st_atime != st1.st_mtime) e(122);
00311 #endif
00312   if (st1.st_ctime != st1.st_mtime) e(123);
00313   if (st1.st_size != 0) e(124);
00314   if (write(fd1, "I'm new in town", 16) != 16) e(125);
00315   if (lseek(fd1, (off_t) - 5, SEEK_CUR) != 11) e(126);
00316   if (read(fd1, buf, 5) != 5) e(127);
00317   if (strncmp(buf, "town", 5) != 0) e(128);
00318   if (close(fd1) != 0) e(129);
00319 
00320   /* Let's test the O_TRUNC flag on this new file. */
00321   time(&time1);
00322   while (time1 >= time((time_t *)0));
00323   if ((fd1 = open("new", O_RDWR | O_TRUNC)) != 3) e(130);
00324   Stat("new", &st1);
00325   time(&time2);
00326   while (time2 >= time((time_t *)0));
00327   time(&time2);
00328   if ((st1.st_mode & 0777) != 0716) e(131);
00329   if (st1.st_size != (size_t) 0) e(132);        /* TRUNCed ? */
00330   if (st1.st_mtime <= time1) e(133);
00331   if (st1.st_mtime >= time2) e(134);
00332   if (st1.st_ctime != st1.st_mtime) e(135);
00333   if (close(fd1) != 0) e(136);
00334 
00335   /* Test if file permission bits and the file ownership are unchanged. */
00336   /* So we will see if `O_CREAT' has no effect if the file exists. */
00337   if (superuser) {
00338         System("echo > bar; chmod 077 bar");    /* Make bar 077 */
00339         System("chown daemon bar");
00340         System("chgrp daemon bar");     /* Daemon's bar */
00341         fd1 = open("bar", O_RDWR | O_CREAT | O_TRUNC, 0777);    /* knock knock */
00342         if (fd1 == -1) e(137);
00343         if (write(fd1, "foo", 3) != 3) e(138);  /* rewrite bar */
00344         if (close(fd1) != 0) e(139);
00345         Stat("bar", &st1);
00346         if (st1.st_uid != 1) e(140);    /* bar is still */
00347         if (st1.st_gid != 1) e(141);    /* owned by daemon */
00348         if ((st1.st_mode & 0777) != 077) e(142);        /* mode still is 077 */
00349         if (st1.st_size != (size_t) 3) e(143);  /* 3 bytes long */
00350 
00351         /* We do the whole thing again, but with O_WRONLY */
00352         fd1 = open("bar", O_WRONLY | O_CREAT | O_TRUNC, 0777);
00353         if (fd1 == -1) e(144);
00354         if (write(fd1, "foobar", 6) != 6) e(145);       /* rewrite bar */
00355         if (close(fd1) != 0) e(146);
00356         Stat("bar", &st1);
00357         if (st1.st_uid != 1) e(147);    /* bar is still */
00358         if (st1.st_gid != 1) e(148);    /* owned by daemon */
00359         if ((st1.st_mode & 0777) != 077) e(149);        /* mode still is 077 */
00360         if (st1.st_size != (size_t) 6) e(150);  /* 6 bytes long */
00361   }
00362 }
00363 
00364 void test25c()
00365 {                               /* Test normal operation Part two. */
00366   int fd1, fd2;
00367   char buf[BUF_SIZE];
00368   struct stat st;
00369   int stat_loc;
00370   static int iteration=0;
00371 
00372   subtest = 3;
00373   iteration++;
00374 
00375   System("rm -rf ../DIR_25/*");
00376 
00377   /* Fifo file test here. */
00378   if (mkfifo("fifo", 0777) != 0) e(1);
00379   switch (fork()) {
00380       case -1:  printf("Can't fork\n"); break;
00381       case 0:
00382         alarm(20);              /* Give child 20 seconds to live. */
00383         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(2);
00384         if (read(fd1, buf, BUF_SIZE) != 23) e(3);
00385         if (strncmp(buf, "1 2 3 testing testing\n", 23) != 0) e(4);
00386         if (close(fd1) != 0) e(5);
00387         exit(0);
00388       default:
00389         if ((fd1 = open("fifo", O_WRONLY)) != 3) e(6);
00390         if (write(fd1, "1 2 3 testing testing\n", 23) != 23) e(7);
00391         if (close(fd1) != 0) e(8);
00392         if (wait(&stat_loc) == -1) e(9);
00393         if (stat_loc != 0) e(10);       /* The alarm went off? */
00394   }
00395 
00396   /* Try opening for writing with O_NONBLOCK. */
00397   fd1 = open("fifo", O_WRONLY | O_NONBLOCK);
00398   if (fd1 != -1) e(11);
00399   if (errno != ENXIO) e(12);
00400   close(fd1);
00401 
00402   /* Try opening for writing with O_NONBLOCK and O_CREAT. */
00403   fd1 = open("fifo", O_WRONLY | O_CREAT | O_NONBLOCK, 0777);
00404   if (fd1 != -1) e(13);
00405   if (errno != ENXIO) e(14);
00406   close(fd1);
00407 
00408   /* Both the NONBLOCK and the EXCLusive give raise to error. */
00409   fd1 = open("fifo", O_WRONLY | O_CREAT | O_EXCL | O_NONBLOCK, 0777);
00410   if (fd1 != -1) e(15);
00411   if (errno != EEXIST && errno != ENXIO) e(16);
00412   close(fd1);                   /* Just in case. */
00413 
00414   /* Try opening for reading with O_NONBLOCK. */
00415   fd1 = open("fifo", O_RDONLY | O_NONBLOCK);
00416   if (fd1 != 3) e(17);
00417   if (close(fd1) != 0) e(18);
00418 
00419 /* Nopt runs out of memory. ;-< We just cut out some valid code */
00420   /* FIFO's should always append. (They have no file position.) */
00421   switch (fork()) {
00422       case -1:  printf("Can't fork\n"); break;
00423       case 0:
00424         alarm(20);              /* Give child 20 seconds to live. */
00425         if ((fd1 = open("fifo", O_WRONLY)) != 3) e(19);
00426         if ((fd2 = open("fifo", O_WRONLY)) != 4) e(20);
00427         if (write(fd1, "I did see Elvis.\n", 18) != 18) e(21);
00428         if (write(fd2, "I DID.\n", 8) != 8) e(22);
00429         if (close(fd2) != 0) e(23);
00430         if (close(fd1) != 0) e(24);
00431         exit(0);
00432       default:
00433         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(25);
00434         if (read(fd1, buf, 18) != 18) e(26);
00435         if (strncmp(buf, "I did see Elvis.\n", 18) != 0) e(27);
00436         if (read(fd1, buf, BUF_SIZE) != 8) e(28);
00437         if (strncmp(buf, "I DID.\n", 8) != 0) e(29);
00438         if (close(fd1) != 0) e(30);
00439         if (wait(&stat_loc) == -1) e(31);
00440         if (stat_loc != 0) e(32);       /* The alarm went off? */
00441   }
00442 
00443   /* O_TRUNC should have no effect on FIFO files. */
00444   switch (fork()) {
00445       case -1:  printf("Can't fork\n"); break;
00446       case 0:
00447         alarm(20);              /* Give child 20 seconds to live. */
00448         if ((fd1 = open("fifo", O_WRONLY)) != 3) e(33);
00449         if (write(fd1, "I did see Elvis.\n", 18) != 18) e(34);
00450         if ((fd2 = open("fifo", O_WRONLY | O_TRUNC)) != 4) e(35);
00451         if (write(fd2, "I DID.\n", 8) != 8) e(36);
00452         if (close(fd2) != 0) e(37);
00453         if (close(fd1) != 0) e(38);
00454         exit(0);
00455       default:
00456         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(39);
00457         if (read(fd1, buf, 18) != 18) e(40);
00458         if (strncmp(buf, "I did see Elvis.\n", 18) != 0) e(41);
00459         if (read(fd1, buf, BUF_SIZE) != 8) e(42);
00460         if (strncmp(buf, "I DID.\n", 8) != 0) e(43);
00461         if (close(fd1) != 0) e(44);
00462         if (wait(&stat_loc) == -1) e(45);
00463         if (stat_loc != 0) e(46);       /* The alarm went off? */
00464   }
00465 
00466   /* Closing the last fd should flush all data to the bitbucket. */
00467   System("rm -rf /tmp/sema.25");
00468   switch (fork()) {
00469       case -1:  printf("Can't fork\n"); break;
00470 
00471       case 0:
00472         alarm(20);              /* Give child 20 seconds to live. */
00473         if ((fd1 = open("fifo", O_WRONLY)) != 3) e(47);
00474         if (write(fd1, "I did see Elvis.\n", 18) != 18) e(48);
00475         Creat("/tmp/sema.25");
00476         sleep(2);               /* give parent a chance to open */
00477         /* this was sleep(1), but that's too short: child also sleeps(1) */
00478         if (close(fd1) != 0) e(49);
00479         exit(0);
00480 
00481       default:
00482         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(50);
00483         /* Make `sure' write has closed. */
00484         while (stat("/tmp/sema.25", &st) != 0) sleep(1);
00485         if (close(fd1) != 0) e(51);
00486         if ((fd1 = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(52);
00487         if (read(fd1, buf, BUF_SIZE) != 18) e(53);
00488         if (close(fd1) != 0) e(54);
00489         if (wait(&stat_loc) == -1) e(55);
00490         if (stat_loc != 0) e(56);       /* The alarm went off? */
00491   }
00492 
00493   /* Let's try one too many. */
00494   System("rm -rf /tmp/sema.25");
00495   switch (fork()) {
00496       case -1:  printf("Can't fork\n"); break;
00497       case 0:
00498         alarm(20);              /* Give child 20 seconds to live. */
00499         if ((fd1 = open("fifo", O_WRONLY)) != 3) e(57);
00500         if (write(fd1, "I did see Elvis.\n", 18) != 18) e(58);
00501 
00502         /* Keep open till second reader is opened. */
00503         while (stat("/tmp/sema.25", &st) != 0) sleep(1);
00504         if (close(fd1) != 0) e(59);
00505         exit(0);
00506       default:
00507         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(60);
00508         if (read(fd1, buf, 2) != 2) e(61);
00509         if (strncmp(buf, "I ", 2) != 0) e(62);
00510         if (close(fd1) != 0) e(63);
00511         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(64);
00512 
00513         /* Signal second reader is open. */
00514         Creat("/tmp/sema.25");
00515         if (read(fd1, buf, 4) != 4) e(65);
00516         if (strncmp(buf, "did ", 4) != 0) e(66);
00517         if ((fd2 = open("fifo", O_RDONLY)) != 4) e(67);
00518         if (read(fd2, buf, BUF_SIZE) != 12) e(68);
00519         if (strncmp(buf, "see Elvis.\n", 12) != 0) e(69);
00520         if (close(fd2) != 0) e(70);
00521         if (close(fd1) != 0) e(71);
00522         if (wait(&stat_loc) == -1) e(72);
00523         if (stat_loc != 0) e(73);       /* The alarm went off? */
00524   }
00525   System("rm -rf fifo /tmp/sema.25");
00526 
00527   /* O_TRUNC should have no effect on directroys. */
00528   System("mkdir dir; touch dir/f1 dir/f2 dir/f3");
00529   if ((fd1 = open("dir", O_WRONLY | O_TRUNC)) != -1) e(74);
00530   if (errno != EISDIR) e(75);
00531   close(fd1);
00532 
00533   /* Opening a directory for reading should be possible. */
00534   if ((fd1 = open("dir", O_RDONLY)) != 3) e(76);
00535   if (close(fd1) != 0) e(77);
00536   if (unlink("dir/f1") != 0) e(78);     /* Should still be there. */
00537   if (unlink("dir/f2") != 0) e(79);
00538   if (unlink("dir/f3") != 0) e(80);
00539   if (rmdir("dir") != 0) e(81);
00540 
00541   if (!superuser) {
00542         /* Test if O_CREAT is not usable to open files with the wrong mode */
00543         (void) umask(0200);     /* nono has no */
00544         System("touch nono");   /* write bit */
00545         (void) umask(0000);
00546         fd1 = open("nono", O_RDWR | O_CREAT, 0777);     /* try to open */
00547         if (fd1 != -1) e(82);
00548         if (errno != EACCES) e(83);     /* but no access */
00549   }
00550 }
00551 
00552 void test25d()
00553 {
00554   int fd;
00555 
00556   subtest = 4;
00557 
00558   System("rm -rf ../DIR_25/*");
00559 
00560   /* Test maximal file name length. */
00561   if ((fd = open(MaxName, O_RDWR | O_CREAT, 0777)) != 3) e(1);
00562   if (close(fd) != 0) e(2);
00563   MaxPath[strlen(MaxPath) - 2] = '/';
00564   MaxPath[strlen(MaxPath) - 1] = 'a';   /* make ././.../a */
00565   if ((fd = open(MaxPath, O_RDWR | O_CREAT, 0777)) != 3) e(3);
00566   if (close(fd) != 0) e(4);
00567   MaxPath[strlen(MaxPath) - 1] = '/';   /* make ././.../a */
00568 }
00569 
00570 void test25e()
00571 {
00572   int fd;
00573   char *noread = "noread";      /* Name for unreadable file. */
00574   char *nowrite = "nowrite";    /* Same for unwritable. */
00575   int stat_loc;
00576 
00577   subtest = 5;
00578 
00579   System("rm -rf ../DIR_25/*");
00580 
00581   mkdir("bar", 0777);           /* make bar */
00582 
00583   /* Check if no access on part of path generates the correct error. */
00584   System("chmod 677 bar");      /* rw-rwxrwx */
00585   if (open("bar/nono", O_RDWR | O_CREAT, 0666) != -1) e(1);
00586   if (errno != EACCES) e(2);
00587 
00588   /* Ditto for no write permission. */
00589   System("chmod 577 bar");      /* r-xrwxrwx */
00590   if (open("bar/nono", O_RDWR | O_CREAT, 0666) != -1) e(3);
00591   if (errno != EACCES) e(4);
00592 
00593   /* Clean up bar. */
00594   System("rm -rf bar");
00595 
00596   /* Improper flags set on existing file. */
00597   System("touch noread; chmod 377 noread");     /* noread */
00598   if (open(noread, O_RDONLY) != -1) e(5);
00599   if (open(noread, O_RDWR) != -1) e(6);
00600   if (open(noread, O_RDWR | O_CREAT, 0777) != -1) e(7);
00601   if (open(noread, O_RDWR | O_CREAT | O_TRUNC, 0777) != -1) e(8);
00602   if ((fd = open(noread, O_WRONLY)) != 3) e(9);
00603   if (close(fd) != 0) e(10);
00604   System("touch nowrite; chmod 577 nowrite");   /* nowrite */
00605   if (open(nowrite, O_WRONLY) != -1) e(11);
00606   if (open(nowrite, O_RDWR) != -1) e(12);
00607   if (open(nowrite, O_RDWR | O_CREAT, 0777) != -1) e(13);
00608   if (open(nowrite, O_RDWR | O_CREAT | O_TRUNC, 0777) != -1) e(14);
00609   if ((fd = open(nowrite, O_RDONLY)) != 3) e(15);
00610   if (close(fd) != 0) e(16);
00611   if (superuser) {
00612         /* If we can make a file ownd by some one else, test access again. */
00613         System("chmod 733 noread");
00614         System("chown bin noread");
00615         System("chgrp system noread");
00616         System("chmod 755 nowrite");
00617         System("chown bin nowrite");
00618         System("chgrp system nowrite");
00619         switch (fork()) {
00620             case -1:    printf("Can't fork\n"); break;
00621             case 0:
00622                 setuid(1);
00623                 setgid(1);      /* become daemon */
00624                 if (open(noread, O_RDONLY) != -1) e(17);
00625                 if (open(noread, O_RDWR) != -1) e(18);
00626                 if (open(noread, O_RDWR | O_CREAT, 0777) != -1) e(19);
00627                 fd = open(noread, O_RDWR | O_CREAT | O_TRUNC, 0777);
00628                 if (fd != -1) e(20);
00629                 if ((fd = open(noread, O_WRONLY)) != 3) e(21);
00630                 if (close(fd) != 0) e(22);
00631                 if (open(nowrite, O_WRONLY) != -1) e(23);
00632                 if (open(nowrite, O_RDWR) != -1) e(24);
00633                 if (open(nowrite, O_RDWR | O_CREAT, 0777) != -1) e(25);
00634                 fd = open(nowrite, O_RDWR | O_CREAT | O_TRUNC, 0777);
00635                 if (fd != -1) e(26);
00636                 if ((fd = open(nowrite, O_RDONLY)) != 3) e(27);
00637                 if (close(fd) != 0) e(28);
00638                 exit(0);
00639             default:
00640                 if (wait(&stat_loc) == -1) e(29);
00641         }
00642   }
00643 
00644   /* Clean up the noread and nowrite files. */
00645   System("rm -rf noread nowrite");
00646 
00647   /* Test the O_EXCL flag. */
00648   System("echo > exists");
00649   if (open("exists", O_RDWR | O_CREAT | O_EXCL, 0777) != -1) e(30);
00650   if (errno != EEXIST) e(31);
00651   if (open("exists", O_RDONLY | O_CREAT | O_EXCL, 0777) != -1) e(32);
00652   if (errno != EEXIST) e(33);
00653   if (open("exists", O_WRONLY | O_CREAT | O_EXCL, 0777) != -1) e(34);
00654   if (errno != EEXIST) e(35);
00655   fd = open("exists", O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0777);
00656   if (fd != -1) e(36);
00657   if (errno != EEXIST) e(37);
00658   fd = open("exists", O_RDONLY | O_CREAT | O_EXCL | O_TRUNC, 0777);
00659   if (fd != -1) e(38);
00660   if (errno != EEXIST) e(39);
00661   fd = open("exists", O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0777);
00662   if (fd != -1) e(40);
00663   if (errno != EEXIST) e(41);
00664 
00665   /* Test ToLongName and ToLongPath */
00666   if ((fd = open(ToLongName, O_RDWR | O_CREAT, 0777)) != 3) e(45);
00667   if (close(fd) != 0) e(46);
00668   ToLongPath[PATH_MAX - 2] = '/';
00669   ToLongPath[PATH_MAX - 1] = 'a';
00670   if ((fd = open(ToLongPath, O_RDWR | O_CREAT, 0777)) != -1) e(47);
00671   if (errno != ENAMETOOLONG) e(48);
00672   if (close(fd) != -1) e(49);
00673   ToLongPath[PATH_MAX - 1] = '/';
00674 }
00675 
00676 void makelongnames()
00677 {
00678   register int i;
00679 
00680   memset(MaxName, 'a', NAME_MAX);
00681   MaxName[NAME_MAX] = '\0';
00682   for (i = 0; i < PATH_MAX - 1; i++) {  /* idem path */
00683         MaxPath[i++] = '.';
00684         MaxPath[i] = '/';
00685   }
00686   MaxPath[PATH_MAX - 1] = '\0';
00687 
00688   strcpy(ToLongName, MaxName);  /* copy them Max to ToLong */
00689   strcpy(ToLongPath, MaxPath);
00690 
00691   ToLongName[NAME_MAX] = 'a';
00692   ToLongName[NAME_MAX + 1] = '\0';      /* extend ToLongName by one too many */
00693   ToLongPath[PATH_MAX - 1] = '/';
00694   ToLongPath[PATH_MAX] = '\0';  /* inc ToLongPath by one */
00695 }
00696 
00697 void e(n)
00698 int n;
00699 {
00700   int err_num = errno;          /* Save in case printf clobbers it. */
00701 
00702   printf("Subtest %d,  error %d  errno=%d: ", subtest, n, errno);
00703   errno = err_num;
00704   perror("");
00705   if (errct++ > MAX_ERROR) {
00706         printf("Too many errors; test aborted\n");
00707         chdir("..");
00708         system("rm -rf DIR*");
00709         exit(1);
00710   }
00711   errno = 0;
00712 }
00713 
00714 void quit()
00715 {
00716   Chdir("..");
00717   System("rm -rf DIR_25");
00718 
00719   if (errct == 0) {
00720         printf("ok\n");
00721         exit(0);
00722   } else {
00723         printf("%d errors\n", errct);
00724         exit(1);
00725   }
00726 }

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