test38.c

Go to the documentation of this file.
00001 /* Many of the tests require 1.6.n, n > 16, so we may as well assume that
00002  * POSIX signals are implemented.
00003  */
00004 #define SIGACTION
00005 
00006 /* test38: read(), write()      Author: Jan-Mark Wams (jms@cs.vu.nl) */
00007 
00008 #include <sys/types.h>
00009 #include <sys/stat.h>
00010 #include <sys/wait.h>
00011 #include <stdlib.h>
00012 #include <unistd.h>
00013 #include <string.h>
00014 #include <fcntl.h>
00015 #include <limits.h>
00016 #include <errno.h>
00017 #include <time.h>
00018 #include <signal.h>
00019 #include <stdio.h>
00020 
00021 #define MAX_ERROR       4
00022 #define ITERATIONS      3
00023 #define BUF_SIZE 1024
00024 
00025 #define System(cmd)     if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
00026 #define Chdir(dir)      if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
00027 #define Stat(a,b)       if (stat(a,b) != 0) printf("Can't stat %s\n", a)
00028 
00029 int errct = 0;
00030 int subtest = 1;
00031 int superuser;
00032 int signumber = 0;
00033 
00034 _PROTOTYPE(void main, (int argc, char *argv[]));
00035 _PROTOTYPE(void test38a, (void));
00036 _PROTOTYPE(void test38b, (void));
00037 _PROTOTYPE(void test38c, (void));
00038 _PROTOTYPE(void setsignumber, (int _signumber));
00039 _PROTOTYPE(void e, (int number));
00040 _PROTOTYPE(void quit, (void));
00041 
00042 void main(argc, argv)
00043 int argc;
00044 char *argv[];
00045 {
00046   int i, m = 0xFFFF;
00047 
00048   sync();
00049   if (argc == 2) m = atoi(argv[1]);
00050   printf("Test 38 ");
00051   fflush(stdout);
00052   System("rm -rf DIR_38; mkdir DIR_38");
00053   Chdir("DIR_38");
00054   superuser = (geteuid() == 0);
00055   umask(0000);
00056 
00057   for (i = 0; i < ITERATIONS; i++) {
00058         if (m & 0001) test38a();
00059         if (m & 0002) test38b();
00060         if (m & 0004) test38c();
00061   }
00062   quit();
00063 }
00064 
00065 void test38a()
00066 {                               /* Try normal operation. */
00067   int fd1;
00068   struct stat st1, st2;
00069   time_t time1;
00070   char buf[BUF_SIZE];
00071   int stat_loc;
00072   int i, j;
00073   int tube[2];
00074 
00075   subtest = 1;
00076   System("rm -rf ../DIR_38/*");
00077 
00078   /* Let's open bar. */
00079   if ((fd1 = open("bar", O_RDWR | O_CREAT, 0777)) != 3) e(1);
00080   Stat("bar", &st1);
00081 
00082   /* Writing nothing should not affect the file at all. */
00083   if (write(fd1, "", 0) != 0) e(2);
00084   Stat("bar", &st2);
00085   if (st1.st_uid != st2.st_uid) e(3);
00086   if (st1.st_gid != st2.st_gid) e(4);   /* should be same */
00087   if (st1.st_mode != st2.st_mode) e(5);
00088   if (st1.st_size != st2.st_size) e(6);
00089   if (st1.st_nlink != st2.st_nlink) e(7);
00090   if (st1.st_mtime != st2.st_mtime) e(8);
00091   if (st1.st_ctime != st2.st_ctime) e(9);
00092   if (st1.st_atime != st2.st_atime) e(10);
00093 
00094   /* A write should update some status fields. */
00095   time(&time1);
00096   while (time1 >= time((time_t *)0))
00097         ;
00098   if (write(fd1, "foo", 4) != 4) e(11);
00099   Stat("bar", &st2);
00100   if (st1.st_mode != st2.st_mode) e(12);
00101   if (st1.st_size >= st2.st_size) e(13);
00102   if ((off_t) 4 != st2.st_size) e(14);
00103   if (st1.st_nlink != st2.st_nlink) e(15);
00104   if (st1.st_mtime >= st2.st_mtime) e(16);
00105   if (st1.st_ctime >= st2.st_ctime) e(17);
00106   if (st1.st_atime != st2.st_atime) e(18);
00107 
00108   /* Lseeks should not change the file status. */
00109   if (lseek(fd1, (off_t) - 2, SEEK_END) != 2) e(19);
00110   Stat("bar", &st1);
00111   if (st1.st_mode != st2.st_mode) e(20);
00112   if (st1.st_size != st2.st_size) e(21);
00113   if (st1.st_nlink != st2.st_nlink) e(22);
00114   if (st1.st_mtime != st2.st_mtime) e(23);
00115   if (st1.st_ctime != st2.st_ctime) e(24);
00116   if (st1.st_atime != st2.st_atime) e(25);
00117 
00118   /* Writing should start at the current (2) position. */
00119   if (write(fd1, "foo", 4) != 4) e(26);
00120   Stat("bar", &st2);
00121   if (st1.st_mode != st2.st_mode) e(27);
00122   if (st1.st_size >= st2.st_size) e(28);
00123   if ((off_t) 6 != st2.st_size) e(29);
00124   if (st1.st_nlink != st2.st_nlink) e(30);
00125   if (st1.st_mtime > st2.st_mtime) e(31);
00126   if (st1.st_ctime > st2.st_ctime) e(32);
00127   if (st1.st_atime != st2.st_atime) e(33);
00128 
00129   /* A read of zero bytes should not affect anything. */
00130   if (read(fd1, buf, 0) != 0) e(34);
00131   Stat("bar", &st1);
00132   if (st1.st_uid != st2.st_uid) e(35);
00133   if (st1.st_gid != st2.st_gid) e(36);  /* should be same */
00134   if (st1.st_mode != st2.st_mode) e(37);
00135   if (st1.st_size != st2.st_size) e(38);
00136   if (st1.st_nlink != st2.st_nlink) e(39);
00137   if (st1.st_mtime != st2.st_mtime) e(40);
00138   if (st1.st_ctime != st2.st_ctime) e(41);
00139   if (st1.st_atime != st2.st_atime) e(42);
00140 
00141   /* The file now should contain ``fofoo\0'' Let's check that. */
00142   if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(43);
00143   if (read(fd1, buf, BUF_SIZE) != 6) e(44);
00144   if (strcmp(buf, "fofoo") != 0) e(45);
00145 
00146   /* Only the Access Time should be updated. */
00147   Stat("bar", &st2);
00148   if (st1.st_mtime != st2.st_mtime) e(46);
00149   if (st1.st_ctime != st2.st_ctime) e(47);
00150   if (st1.st_atime >= st2.st_atime) e(48);
00151 
00152   /* A read of zero bytes should do nothing even at the end of the file. */
00153   time(&time1);
00154   while (time1 >= time((time_t *)0))
00155         ;
00156   if (read(fd1, buf, 0) != 0) e(49);
00157   Stat("bar", &st1);
00158   if (st1.st_size != st2.st_size) e(50);
00159   if (st1.st_mtime != st2.st_mtime) e(51);
00160   if (st1.st_ctime != st2.st_ctime) e(52);
00161   if (st1.st_atime != st2.st_atime) e(53);
00162 
00163   /* Reading should be done from the current offset. */
00164   if (read(fd1, buf, BUF_SIZE) != 0) e(54);
00165   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(55);
00166   if (read(fd1, buf, BUF_SIZE) != 4) e(56);
00167   if (strcmp(buf, "foo") != 0) e(57);
00168 
00169   /* Reading should effect the current file position. */
00170   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(58);
00171   if (read(fd1, buf, 1) != 1) e(59);
00172   if (*buf != 'f') e(60);
00173   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(61);
00174   if (read(fd1, buf, 1) != 1) e(62);
00175   if (*buf != 'o') e(63);
00176   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(64);
00177   if (read(fd1, buf, 1) != 1) e(65);
00178   if (*buf != 'o') e(66);
00179   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 5) e(67);
00180   if (read(fd1, buf, 1) != 1) e(68);
00181   if (*buf != '\0') e(69);
00182   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(70);
00183 
00184   /* Read's at EOF should return 0. */
00185   if (read(fd1, buf, BUF_SIZE) != 0) e(71);
00186   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(72);
00187   if (read(fd1, buf, BUF_SIZE) != 0) e(73);
00188   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(74);
00189   if (read(fd1, buf, BUF_SIZE) != 0) e(75);
00190   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(76);
00191   if (read(fd1, buf, BUF_SIZE) != 0) e(77);
00192   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(78);
00193   if (read(fd1, buf, BUF_SIZE) != 0) e(79);
00194   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(80);
00195 
00196   /* Writing should not always change the file size. */
00197   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(81);
00198   if (write(fd1, "ba", 2) != 2) e(82);
00199   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(83);
00200   Stat("bar", &st1);
00201   if (st1.st_size != 6) e(84);
00202 
00203   /* Kill the \0 at the end. */
00204   if (lseek(fd1, (off_t) 5, SEEK_SET) != 5) e(85);
00205   if (write(fd1, "x", 1) != 1) e(86);
00206 
00207   /* And close the bar. */
00208   if (close(fd1) != 0) e(87);
00209 
00210   /* Try some stuff with O_APPEND. Bar contains ``fobaox'' */
00211   if ((fd1 = open("bar", O_RDWR | O_APPEND)) != 3) e(88);
00212 
00213   /* No matter what the file position is. Writes should append. */
00214   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(89);
00215   if (write(fd1, "y", 1) != 1) e(90);
00216   Stat("bar", &st1);
00217   if (st1.st_size != (off_t) 7) e(91);
00218   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 7) e(92);
00219   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(93);
00220   if (write(fd1, "z", 2) != 2) e(94);
00221 
00222   /* The file should contain ``fobaoxyz\0'' == 9 chars long. */
00223   Stat("bar", &st1);
00224   if (st1.st_size != (off_t) 9) e(95);
00225   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(96);
00226 
00227   /* Reading on a O_APPEND flag should be from the current offset. */
00228   if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(97);
00229   if (read(fd1, buf, BUF_SIZE) != 9) e(98);
00230   if (strcmp(buf, "fobaoxyz") != 0) e(99);
00231   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(100);
00232 
00233   if (close(fd1) != 0) e(101);
00234 
00235   /* Let's test fifo writes. First blocking. */
00236   if (mkfifo("fifo", 0777) != 0) e(102);
00237 
00238   /* Read from fifo but no writer. */
00239   System("rm -rf /tmp/sema.38a");
00240   switch (fork()) {
00241       case -1:  printf("Can't fork\n"); break;
00242 
00243       case 0:
00244         alarm(20);
00245         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(103);
00246         system("> /tmp/sema.38a");
00247         system("while test -f /tmp/sema.38a; do sleep 1; done");
00248 errno =0;
00249         if (read(fd1, buf, BUF_SIZE) != 0) e(104);
00250         if (read(fd1, buf, BUF_SIZE) != 0) e(105);
00251         if (read(fd1, buf, BUF_SIZE) != 0) e(106);
00252         if (close(fd1) != 0) e(107);
00253         exit(0);
00254 
00255       default:
00256         if ((fd1 = open("fifo", O_WRONLY)) != 3) e(108);
00257         while (stat("/tmp/sema.38a", &st1) != 0) sleep(1);
00258         if (close(fd1) != 0) e(109);
00259         unlink("/tmp/sema.38a");
00260         if (wait(&stat_loc) == -1) e(110);
00261         if (stat_loc != 0) e(111);      /* Alarm? */
00262   }
00263 
00264   /* Read from fifo should wait for writer. */
00265   switch (fork()) {
00266       case -1:  printf("Can't fork\n"); break;
00267 
00268       case 0:
00269         alarm(20);
00270         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(112);
00271         if (read(fd1, buf, BUF_SIZE) != 10) e(113);
00272         if (strcmp(buf, "Hi reader") != 0) e(114);
00273         if (close(fd1) != 0) e(115);
00274         exit(0);
00275 
00276       default:
00277         if ((fd1 = open("fifo", O_WRONLY)) != 3) e(116);
00278         sleep(1);
00279         if (write(fd1, "Hi reader", 10) != 10) e(117);
00280         if (close(fd1) != 0) e(118);
00281         if (wait(&stat_loc) == -1) e(119);
00282         if (stat_loc != 0) e(120);      /* Alarm? */
00283   }
00284 
00285 #if DEAD_CODE
00286   /* Does this test test what it is supposed to test??? */
00287 
00288   /* Read from fifo should wait for all writers to close. */
00289   switch (fork()) {
00290       case -1:  printf("Can't fork\n"); break;
00291 
00292       case 0:
00293         alarm(60);
00294         switch (fork()) {
00295             case -1:    printf("Can't fork\n"); break;
00296             case 0:
00297                 alarm(20);
00298                 if ((fd1 = open("fifo", O_WRONLY)) != 3) e(121);
00299                 printf("C2 did open\n");
00300                 if (close(fd1) != 0) e(122);
00301                 printf("C2 did close\n");
00302                 exit(0);
00303             default:
00304                 printf("C1 scheduled\n");
00305                 if ((fd1 = open("fifo", O_WRONLY)) != 3) e(123);
00306                 printf("C1 did open\n");
00307                 sleep(2);
00308                 if (close(fd1) != 0) e(124);
00309                 printf("C1 did close\n");
00310                 sleep(1);
00311                 if (wait(&stat_loc) == -1) e(125);
00312                 if (stat_loc != 0) e(126);      /* Alarm? */
00313         }
00314         exit(stat_loc);
00315 
00316       default: {
00317         int wait_status;
00318         printf("Parent running\n");
00319         sleep(1);                               /* open in childs first */
00320         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(127);
00321         if (read(fd1, buf, BUF_SIZE) != 0) e(128);
00322         if (close(fd1) != 0) e(129);
00323         printf("Parent closed\n");
00324         if ((wait_status=wait(&stat_loc)) == -1) e(130);
00325 
00326       printf("wait_status %d, stat_loc %d:", wait_status, stat_loc);
00327       if (WIFSIGNALED(stat_loc)) {
00328           printf(" killed, signal number %d\n", WTERMSIG(stat_loc));
00329       } 
00330       else if (WIFEXITED(stat_loc)) {
00331           printf(" normal exit, status %d\n", WEXITSTATUS(stat_loc));
00332       }
00333 
00334         if (stat_loc != 0) e(131);      /* Alarm? */
00335       }
00336   }
00337 #endif
00338 
00339   /* PIPE_BUF has to have a nice value. */
00340   if (PIPE_BUF < 5) e(132);
00341   if (BUF_SIZE < 1000) e(133);
00342 
00343   /* Writes of blocks smaller than PIPE_BUF should be atomic. */
00344   System("rm -rf /tmp/sema.38b;> /tmp/sema.38b");
00345   switch (fork()) {
00346       case -1:  printf("Can't fork\n"); break;
00347 
00348       case 0:
00349         alarm(20);
00350         switch (fork()) {
00351             case -1:    printf("Can't fork\n"); break;
00352 
00353             case 0:
00354                 alarm(20);
00355                 if ((fd1 = open("fifo", O_WRONLY)) != 3) e(134);
00356                 for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
00357                 system("while test -f /tmp/sema.38b; do sleep 1; done");
00358                 if (close(fd1) != 0) e(135);
00359                 exit(0);
00360 
00361             default:
00362                 if ((fd1 = open("fifo", O_WRONLY)) != 3) e(136);
00363                 for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
00364                 while (stat("/tmp/sema.38b", &st1) == 0) sleep(1);
00365                 if (close(fd1) != 0) e(137);
00366                 if (wait(&stat_loc) == -1) e(138);
00367                 if (stat_loc != 0) e(139);      /* Alarm? */
00368         }
00369         exit(stat_loc);
00370 
00371       default:
00372         if ((fd1 = open("fifo", O_RDONLY)) != 3) e(140);
00373         i = 0;
00374         memset(buf, '\0', BUF_SIZE);
00375 
00376         /* Read buffer full or till EOF. */
00377         do {
00378                 j = read(fd1, buf + i, BUF_SIZE - i);
00379                 if (j > 0) {
00380                         if (j % 5 != 0) e(141);
00381                         i += j;
00382                 }
00383         } while (j > 0 && i < 1000);
00384 
00385         /* Signal the children to close write ends. This should not be */
00386         /* Necessary. But due to a bug in 1.16.6 this is necessary. */
00387         unlink("/tmp/sema.38b");
00388         if (j < 0) e(142);
00389         if (i != 1000) e(143);
00390         if (wait(&stat_loc) == -1) e(144);
00391         if (stat_loc != 0) e(145);      /* Alarm? */
00392 
00393         /* Check 200 times 1234. */
00394         for (i = 0; i < 200; i++)
00395                 if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
00396         if (i != 200) e(146);
00397         if (buf[1000] != '\0') e(147);
00398         if (buf[1005] != '\0') e(148);
00399         if (buf[1010] != '\0') e(149);
00400         if (read(fd1, buf, BUF_SIZE) != 0) e(150);
00401         if (close(fd1) != 0) e(151);
00402   }
00403 
00404   /* Read from pipe should wait for writer. */
00405   if (pipe(tube) != 0) e(152);
00406   switch (fork()) {
00407       case -1:  printf("Can't fork\n"); break;
00408       case 0:
00409         alarm(20);
00410         if (close(tube[1]) != 0) e(153);
00411         if (read(tube[0], buf, BUF_SIZE) != 10) e(154);
00412         if (strcmp(buf, "Hi reader") != 0) e(155);
00413         if (close(tube[0]) != 0) e(156);
00414         exit(0);
00415       default:
00416         if (close(tube[0]) != 0) e(157);
00417         sleep(1);
00418         if (write(tube[1], "Hi reader", 10) != 10) e(158);
00419         if (close(tube[1]) != 0) e(159);
00420         if (wait(&stat_loc) == -1) e(160);
00421         if (stat_loc != 0) e(161);      /* Alarm? */
00422   }
00423 
00424   /* Read from pipe should wait for all writers to close. */
00425   if (pipe(tube) != 0) e(162);
00426   switch (fork()) {
00427       case -1:  printf("Can't fork\n"); break;
00428       case 0:
00429         alarm(20);
00430         if (close(tube[0]) != 0) e(163);
00431         switch (fork()) {
00432             case -1:    printf("Can't fork\n"); break;
00433             case 0:
00434                 alarm(20);
00435                 if (close(tube[1]) != 0) e(164);
00436                 exit(0);
00437             default:
00438                 sleep(1);
00439                 if (close(tube[1]) != 0) e(165);
00440                 if (wait(&stat_loc) == -1) e(166);
00441                 if (stat_loc != 0) e(167);      /* Alarm? */
00442         }
00443         exit(stat_loc);
00444       default:
00445         if (close(tube[1]) != 0) e(168);
00446         if (read(tube[0], buf, BUF_SIZE) != 0) e(169);
00447         if (close(tube[0]) != 0) e(170);
00448         if (wait(&stat_loc) == -1) e(171);
00449         if (stat_loc != 0) e(172);      /* Alarm? */
00450   }
00451 
00452   /* Writes of blocks smaller than PIPE_BUF should be atomic. */
00453   System("rm -rf /tmp/sema.38c;> /tmp/sema.38c");
00454   if (pipe(tube) != 0) e(173);
00455   switch (fork()) {
00456       case -1:  printf("Can't fork\n"); break;
00457       case 0:
00458         alarm(20);
00459         if (close(tube[0]) != 0) e(174);
00460         switch (fork()) {
00461             case -1:    printf("Can't fork\n"); break;
00462             case 0:
00463                 alarm(20);
00464                 for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
00465                 system("while test -f /tmp/sema.38c; do sleep 1; done");
00466                 if (close(tube[1]) != 0) e(175);
00467                 exit(0);
00468             default:
00469                 for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
00470                 while (stat("/tmp/sema.38c", &st1) == 0) sleep(1);
00471                 if (close(tube[1]) != 0) e(176);
00472                 if (wait(&stat_loc) == -1) e(177);
00473                 if (stat_loc != 0) e(178);      /* Alarm? */
00474         }
00475         exit(stat_loc);
00476       default:
00477         i = 0;
00478         if (close(tube[1]) != 0) e(179);
00479         memset(buf, '\0', BUF_SIZE);
00480         do {
00481                 j = read(tube[0], buf + i, BUF_SIZE - i);
00482                 if (j > 0) {
00483                         if (j % 5 != 0) e(180);
00484                         i += j;
00485                 } else
00486                         break;  /* EOF seen. */
00487         } while (i < 1000);
00488         unlink("/tmp/sema.38c");
00489         if (j < 0) e(181);
00490         if (i != 1000) e(182);
00491         if (close(tube[0]) != 0) e(183);
00492         if (wait(&stat_loc) == -1) e(184);
00493         if (stat_loc != 0) e(185);      /* Alarm? */
00494 
00495         /* Check 200 times 1234. */
00496         for (i = 0; i < 200; i++)
00497                 if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
00498         if (i != 200) e(186);
00499   }
00500 }
00501 
00502 void test38b()
00503 {
00504   int i, fd, stat_loc;
00505   char buf[BUF_SIZE];
00506   char buf2[BUF_SIZE];
00507   struct stat st;
00508 
00509   subtest = 2;
00510   System("rm -rf ../DIR_38/*");
00511 
00512   /* Lets try sequential writes. */
00513   system("rm -rf /tmp/sema.38d");
00514   System("> testing");
00515   switch (fork()) {
00516       case -1:  printf("Can't fork\n"); break;
00517       case 0:
00518         alarm(20);
00519         if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(1);
00520         if (write(fd, "one ", 4) != 4) e(2);
00521         if (close(fd) != 0) e(3);
00522         system("> /tmp/sema.38d");
00523         system("while test -f /tmp/sema.38d; do sleep 1; done");
00524         if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(4);
00525         if (write(fd, "three ", 6) != 6) e(5);
00526         if (close(fd) != 0) e(6);
00527         system("> /tmp/sema.38d");
00528         exit(0);
00529       default:
00530         while (stat("/tmp/sema.38d", &st) != 0) sleep(1);
00531         if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(7);
00532         if (write(fd, "two ", 4) != 4) e(8);
00533         if (close(fd) != 0) e(9);
00534         unlink("/tmp/sema.38d");
00535         while (stat("/tmp/sema.38d", &st) != 0) sleep(1);
00536         if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(10);
00537         if (write(fd, "four", 5) != 5) e(11);
00538         if (close(fd) != 0) e(12);
00539         if (wait(&stat_loc) == -1) e(13);
00540         if (stat_loc != 0) e(14);       /* The alarm went off? */
00541         unlink("/tmp/sema.38d");
00542   }
00543   if ((fd = open("testing", O_RDONLY)) != 3) e(15);
00544   if (read(fd, buf, BUF_SIZE) != 19) e(16);
00545   if (strcmp(buf, "one two three four") != 0) e(17);
00546   if (close(fd) != 0) e(18);
00547 
00548   /* Non written bytes in regular files should be zero. */
00549   memset(buf2, '\0', BUF_SIZE);
00550   if ((fd = open("bigfile", O_RDWR | O_CREAT, 0644)) != 3) e(19);
00551   if (lseek(fd, (off_t) 102400, SEEK_SET) != (off_t) 102400L) e(20);
00552   if (read(fd, buf, BUF_SIZE) != 0) e(21);
00553   if (write(fd, ".", 1) != 1) e(22);
00554   Stat("bigfile", &st);
00555   if (st.st_size != (off_t) 102401) e(23);
00556   if (lseek(fd, (off_t) 0, SEEK_SET) != 0) e(24);
00557   for (i = 0; i < 102400 / BUF_SIZE; i++) {
00558         if (read(fd, buf, BUF_SIZE) != BUF_SIZE) e(25);
00559         if (memcmp(buf, buf2, BUF_SIZE) != 0) e(26);
00560   }
00561   if (close(fd) != 0) e(27);
00562 }
00563 
00564 void test38c()
00565 {                               /* Test correct error behavior. */
00566   char buf[BUF_SIZE];
00567   int fd, tube[2], stat_loc;
00568   struct stat st;
00569   pid_t pid;
00570 #ifdef SIGACTION
00571   struct sigaction act, oact;
00572 #else
00573 #if _ANSI
00574   void (*oldfunc) (int);
00575 #else
00576   void (*oldfunc) ();
00577 #endif
00578 #endif
00579 
00580   subtest = 3;
00581   System("rm -rf ../DIR_38/*");
00582 
00583   /* To test if writing processes on closed pipes are signumbered. */
00584 #ifdef SIGACTION
00585   act.sa_handler = setsignumber;
00586   sigemptyset(&act.sa_mask);
00587   act.sa_flags = 0;
00588   if (sigaction(SIGPIPE, &act, &oact) != 0) e(1);
00589 #else
00590   oldfunc = signal(SIGPIPE, setsignumber);
00591 #endif
00592 
00593   /* Non valid file descriptors should be an error. */
00594   for (fd = -111; fd < 0; fd++) {
00595         errno = 0;
00596         if (read(fd, buf, BUF_SIZE) != -1) e(2);
00597         if (errno != EBADF) e(3);
00598   }
00599   for (fd = 3; fd < 111; fd++) {
00600         errno = 0;
00601         if (read(fd, buf, BUF_SIZE) != -1) e(4);
00602         if (errno != EBADF) e(5);
00603   }
00604   for (fd = -111; fd < 0; fd++) {
00605         errno = 0;
00606         if (write(fd, buf, BUF_SIZE) != -1) e(6);
00607         if (errno != EBADF) e(7);
00608   }
00609   for (fd = 3; fd < 111; fd++) {
00610         errno = 0;
00611         if (write(fd, buf, BUF_SIZE) != -1) e(8);
00612         if (errno != EBADF) e(9);
00613   }
00614 
00615   /* Writing a pipe with no readers should trigger SIGPIPE. */
00616   if (pipe(tube) != 0) e(10);
00617   close(tube[0]);
00618   switch (fork()) {
00619       case -1:  printf("Can't fork\n"); break;
00620       case 0:
00621         alarm(20);
00622         signumber = 0;
00623         if (write(tube[1], buf, BUF_SIZE) != -1) e(11);
00624         if (errno != EPIPE) e(12);
00625         if (signumber != SIGPIPE) e(13);
00626         if (close(tube[1]) != 0) e(14);
00627         exit(0);
00628       default:
00629         close(tube[1]);
00630         if (wait(&stat_loc) == -1) e(15);
00631         if (stat_loc != 0) e(16);       /* Alarm? */
00632   }
00633 
00634   /* Writing a fifo with no readers should trigger SIGPIPE. */
00635   System("> /tmp/sema.38e");
00636   if (mkfifo("fifo", 0666) != 0) e(17);
00637   switch (fork()) {
00638       case -1:  printf("Can't fork\n"); break;
00639       case 0:
00640         alarm(20);
00641         if ((fd = open("fifo", O_WRONLY)) != 3) e(18);
00642         system("while test -f /tmp/sema.38e; do sleep 1; done");
00643         signumber = 0;
00644         if (write(fd, buf, BUF_SIZE) != -1) e(19);
00645         if (errno != EPIPE) e(20);
00646         if (signumber != SIGPIPE) e(21);
00647         if (close(fd) != 0) e(22);
00648         exit(0);
00649       default:
00650         if ((fd = open("fifo", O_RDONLY)) != 3) e(23);
00651         if (close(fd) != 0) e(24);
00652         unlink("/tmp/sema.38e");
00653         if (wait(&stat_loc) == -1) e(25);
00654         if (stat_loc != 0) e(26);       /* Alarm? */
00655   }
00656 
00657 #ifdef SIGACTION
00658   /* Restore normal (re)action to SIGPIPE. */
00659   if (sigaction(SIGPIPE, &oact, NULL) != 0) e(27);
00660 #else
00661   signal(SIGPIPE, oldfunc);
00662 #endif
00663 
00664   /* Read from fifo should return -1 and set errno to EAGAIN. */
00665   System("rm -rf /tmp/sema.38[fgh]");
00666   switch (fork()) {
00667       case -1:  printf("Can't fork\n"); break;
00668       case 0:
00669         alarm(20);
00670         system("while test ! -f /tmp/sema.38f; do sleep 1; done");
00671         System("rm -rf /tmp/sema.38f");
00672         if ((fd = open("fifo", O_WRONLY | O_NONBLOCK)) != 3) e(28);
00673         close(creat("/tmp/sema.38g", 0666));
00674         system("while test ! -f /tmp/sema.38h; do sleep 1; done");
00675         if (close(fd) != 0) e(38);
00676         System("rm -rf /tmp/sema.38h");
00677         exit(0);
00678       default:
00679         if ((fd = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(30);
00680         close(creat("/tmp/sema.38f", 0666));
00681         system("while test ! -f /tmp/sema.38g; do sleep 1; done");
00682         System("rm -rf /tmp/sema.38g");
00683         if (read(fd, buf, BUF_SIZE) != -1) e(31);
00684         if (errno != EAGAIN) e(32);
00685         if (read(fd, buf, BUF_SIZE) != -1) e(33);
00686         if (errno != EAGAIN) e(34);
00687         if (read(fd, buf, BUF_SIZE) != -1) e(35);
00688         if (errno != EAGAIN) e(36);
00689         close(creat("/tmp/sema.38h", 0666));
00690         while (stat("/tmp/sema.38h", &st) == 0) sleep(1);
00691         if (read(fd, buf, BUF_SIZE) != 0) e(37);
00692         if (close(fd) != 0) e(38);
00693         if (wait(&stat_loc) == -1) e(39);
00694         if (stat_loc != 0) e(40);       /* Alarm? */
00695   }
00696   System("rm -rf fifo");
00697 
00698   /* If a read is interrupted by a SIGNAL. */
00699   if (pipe(tube) != 0) e(41);
00700   switch (pid = fork()) {
00701       case -1:  printf("Can't fork\n"); break;
00702       case 0:
00703         alarm(20);
00704 #ifdef SIGACTION
00705         act.sa_handler = setsignumber;
00706         sigemptyset(&act.sa_mask);
00707         act.sa_flags = 0;
00708         if (sigaction(SIGUSR1, &act, &oact) != 0) e(42);
00709 #else
00710         oldfunc = signal(SIGUSR1, setsignumber);
00711 #endif
00712         if (read(tube[0], buf, BUF_SIZE) != -1) e(43);
00713         if (errno != EINTR) e(44);
00714         if (signumber != SIGUSR1) e(45);
00715 #ifdef SIGACTION
00716         /* Restore normal (re)action to SIGPIPE. */
00717         if (sigaction(SIGUSR1, &oact, NULL) != 0) e(46);
00718 #else
00719         signal(SIGUSR1, oldfunc);
00720 #endif
00721         close(tube[0]);
00722         close(tube[1]);
00723         exit(0);
00724       default:
00725         /* The sleep 1 should give the child time to start the read. */
00726         sleep(1);
00727         close(tube[0]);
00728         kill(pid, SIGUSR1);
00729         wait(&stat_loc);
00730         if (stat_loc != 0) e(47);       /* Alarm? */
00731         close(tube[1]);
00732   }
00733 }
00734 
00735 void setsignumber(signum)
00736 int signum;
00737 {
00738   signumber = signum;
00739 }
00740 
00741 void e(n)
00742 int n;
00743 {
00744   int err_num = errno;          /* Save in case printf clobbers it. */
00745 
00746   printf("Subtest %d,  error %d  errno=%d: ", subtest, n, errno);
00747   errno = err_num;
00748   perror("");
00749   if (errct++ > MAX_ERROR) {
00750         printf("Too many errors; test aborted\n");
00751         chdir("..");
00752         system("rm -rf DIR*");
00753         exit(1);
00754   }
00755   errno = 0;
00756 }
00757 
00758 void quit()
00759 {
00760   Chdir("..");
00761   System("rm -rf DIR_38");
00762 
00763   if (errct == 0) {
00764         printf("ok\n");
00765         exit(0);
00766   } else {
00767         printf("%d errors\n", errct);
00768         exit(1);
00769   }
00770 }

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