test5.c

Go to the documentation of this file.
00001 /* test 5 */
00002 
00003 #include <sys/types.h>
00004 #include <sys/wait.h>
00005 #include <errno.h>
00006 #include <fcntl.h>
00007 #include <signal.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <stdio.h>
00011 #include <string.h>
00012 
00013 #define ITERATIONS 2
00014 #define MAX_ERROR 4
00015 
00016 int errct;
00017 int subtest;
00018 int zero[1024];
00019 
00020 int sigmap[5] = {9, 10, 11};
00021 
00022 _PROTOTYPE(int main, (int argc, char *argv[]));
00023 _PROTOTYPE(void test5a, (void));
00024 _PROTOTYPE(void parent, (int childpid));
00025 _PROTOTYPE(void child, (int parpid));
00026 _PROTOTYPE(void func1, (int s));
00027 _PROTOTYPE(void func8, (int s));
00028 _PROTOTYPE(void func10, (int s));
00029 _PROTOTYPE(void func11, (int s));
00030 _PROTOTYPE(void test5b, (void));
00031 _PROTOTYPE(void test5c, (void));
00032 _PROTOTYPE(void test5d, (void));
00033 _PROTOTYPE(void test5e, (void));
00034 _PROTOTYPE(void test5f, (void));
00035 _PROTOTYPE(void test5g, (void));
00036 _PROTOTYPE(void funcalrm, (int s));
00037 _PROTOTYPE(void test5h, (void));
00038 _PROTOTYPE(void test5i, (void));
00039 _PROTOTYPE(void ex, (void));
00040 _PROTOTYPE(void e, (int n));
00041 _PROTOTYPE(void quit, (void));
00042 
00043 #ifdef _ANSI
00044 void (*Signal(int _sig, void (*_func)(int)))(int);
00045 #define SIG_ZERO        ((void (*)(int))0)      /* default signal handling */
00046 #else
00047 sighandler_t Signal();
00048 /* void (*Signal()) (); */
00049 #define SIG_ZERO        ((void (*)())0)         /* default signal handling */
00050 #endif
00051 
00052 _VOLATILE int childsigs, parsigs, alarms;
00053 
00054 int main(argc, argv)
00055 int argc;
00056 char *argv[];
00057 {
00058   int i, m = 0x7777;
00059 
00060   printf("Test  5 ");
00061   fflush(stdout);               /* have to flush for child's benefit */
00062 
00063   system("rm -rf DIR_05; mkdir DIR_05");
00064   chdir("DIR_05");
00065 
00066   for (i = 0; i < ITERATIONS; i++) {
00067         if (m & 0001) test5a();
00068         if (m & 0002) test5b();
00069         if (m & 0004) test5c();
00070         if (m & 0010) test5d();
00071         if (m & 0020) test5e();
00072         if (m & 0040) test5f();
00073         if (m & 0100) test5g();
00074         if (m & 0200) test5h();
00075         if (m & 0400) test5i();
00076   }
00077   quit();
00078   return(-1);                   /* impossible */
00079 }
00080 
00081 void test5a()
00082 {
00083   int parpid, childpid, flag, *zp;
00084 
00085   subtest = 0;
00086   flag = 0;
00087   for (zp = &zero[0]; zp < &zero[1024]; zp++)
00088         if (*zp != 0) flag = 1;
00089   if (flag) e(0);               /* check if bss is cleared to 0 */
00090   if (Signal(1, func1) ==  SIG_ERR) e(1);
00091   if (Signal(10, func10) < SIG_ZERO) e(2);
00092   parpid = getpid();
00093   if (childpid = fork()) {
00094         if (childpid < 0) ex();
00095         parent(childpid);
00096   } else {
00097         child(parpid);
00098   }
00099   if (Signal(1, SIG_DFL) <  SIG_ZERO) e(4);
00100   if (Signal(10, SIG_DFL) < SIG_ZERO) e(5);
00101 }
00102 
00103 void parent(childpid)
00104 int childpid;
00105 {
00106   int i, pid;
00107 
00108   for (i = 0; i < 3; i++) {
00109         if (kill(childpid, 1) < 0) e(6);
00110         while (parsigs == 0);
00111         parsigs--;
00112   }
00113   if ( (pid = wait(&i)) < 0) e(7);
00114   if (i != 256 * 6) e(8);
00115 }
00116 
00117 void child(parpid)
00118 int parpid;
00119 {
00120 
00121   int i;
00122 
00123   for (i = 0; i < 3; i++) {
00124         while (childsigs == 0);
00125         childsigs--;
00126         if (kill(parpid, 10) < 0) e(9);
00127   }
00128   exit(6);
00129 }
00130 
00131 void func1(s)
00132 int s;                          /* for ANSI */
00133 {
00134   if (Signal(1, func1) < SIG_ZERO) e(10);
00135   childsigs++;
00136 }
00137 
00138 void func8(s)
00139 int s;
00140 {
00141 }
00142 
00143 void func10(s)
00144 int s;                          /* for ANSI */
00145 {
00146   if (Signal(10, func10) < SIG_ZERO) e(11);
00147   parsigs++;
00148 }
00149 
00150 void func11(s)
00151 int s;                          /* for ANSI */
00152 {
00153   e(38);
00154 }
00155 
00156 void test5b()
00157 {
00158   int cpid, n, pid;
00159 
00160   subtest = 1;
00161   if ((pid = fork())) {
00162         if (pid < 0) ex();
00163         if ((pid = fork())) {
00164                 if (pid < 0) ex();
00165                 if (cpid = fork()) {
00166                         if (cpid < 0) ex();
00167                         if (kill(cpid, 9) < 0) e(12);
00168                         if (wait(&n) < 0) e(13);
00169                         if (wait(&n) < 0) e(14);
00170                         if (wait(&n) < 0) e(15);
00171                 } else {
00172                         pause();
00173                         while (1);
00174                 }
00175         } else {
00176                 exit(0);
00177         }
00178   } else {
00179         exit(0);
00180   }
00181 }
00182 
00183 void test5c()
00184 {
00185   int n, i, pid, wpid;
00186 
00187   /* Test exit status codes for processes killed by signals. */
00188   subtest = 3;
00189   for (i = 0; i < 2; i++) {
00190         if (pid = fork()) {
00191                 if (pid < 0) ex();
00192                 sleep(2);       /* wait for child to pause */
00193                 if (kill(pid, sigmap[i]) < 0) {
00194                         e(20);
00195                         exit(1);
00196                 }
00197                 if ((wpid = wait(&n)) < 0) e(21);
00198                 if ((n & 077) != sigmap[i]) e(22);
00199                 if (pid != wpid) e(23);
00200         } else {
00201                 pause();
00202                 exit(0);
00203         }
00204   }
00205 }
00206 
00207 void test5d()
00208 {
00209 /* Test alarm */
00210 
00211   int i;
00212 
00213   subtest = 4;
00214   alarms = 0;
00215   for (i = 0; i < 8; i++) {
00216         Signal(SIGALRM, funcalrm);
00217         alarm(1);
00218         pause();
00219         if (alarms != i + 1) e(24);
00220   }
00221 }
00222 
00223 void test5e()
00224 {
00225 /* When a signal knocks a processes out of WAIT or PAUSE, it is supposed to
00226  * get EINTR as error status.  Check that.
00227  */
00228   int n, j;
00229 
00230   subtest = 5;
00231   if (Signal(8, func8) < SIG_ZERO) e(25);
00232   if (n = fork()) {
00233         /* Parent must delay to give child a chance to pause. */
00234         if (n < 0) ex();
00235         sleep(1);
00236         if (kill(n, 8) < 0) e(26);
00237         if (wait(&n) < 0) e(27);
00238         if (Signal(8, SIG_DFL) < SIG_ZERO) e(28);
00239   } else {
00240         j = pause();
00241         if (errno != EINTR && -errno != EINTR) e(29);
00242         exit(0);
00243   }
00244 }
00245 
00246 void test5f()
00247 {
00248   int i, j, k, n;
00249 
00250   subtest = 6;
00251   if (getuid() != 0) return;
00252   n = fork();
00253   if (n < 0) ex();
00254   if (n) {
00255         wait(&i);
00256         i = (i >> 8) & 0377;
00257         if (i != (n & 0377)) e(30);
00258   } else {
00259         i = getgid();
00260         j = getegid();
00261         k = (i + j + 7) & 0377;
00262         if (setgid(k) < 0) e(31);
00263         if (getgid() != k) e(32);
00264         if (getegid() != k) e(33);
00265         i = getuid();
00266         j = geteuid();
00267         k = (i + j + 1) & 0377;
00268         if (setuid(k) < 0) e(34);
00269         if (getuid() != k) e(35);
00270         if (geteuid() != k) e(36);
00271         i = getpid() & 0377;
00272         if (wait(&j) != -1) e(37);
00273         exit(i);
00274   }
00275 }
00276 
00277 void test5g()
00278 {
00279   int n;
00280 
00281   subtest = 7;
00282   Signal(11, func11);
00283   Signal(11, SIG_IGN);
00284   n = getpid();
00285   if (kill(n, 11) != 0) e(1);
00286   Signal(11, SIG_DFL);
00287 }
00288 
00289 void funcalrm(s)
00290 int s;                          /* for ANSI */
00291 {
00292   alarms++;
00293 }
00294 
00295 void test5h()
00296 {
00297 /* When a signal knocks a processes out of PIPE, it is supposed to
00298  * get EINTR as error status.  Check that.
00299  */
00300   int n, j, fd[2];
00301 
00302   subtest = 8;
00303   unlink("XXX.test5");
00304   if (Signal(8, func8) < SIG_ZERO) e(1);
00305   pipe(fd);
00306   if (n = fork()) {
00307         /* Parent must delay to give child a chance to pause. */
00308         if (n < 0) ex();
00309         while (access("XXX.test5", 0) != 0) /* just wait */ ;
00310         sleep(1);
00311         unlink("XXX.test5");
00312         if (kill(n, 8) < 0) e(2);
00313         if (wait(&n) < 0) e(3);
00314         if (Signal(8, SIG_DFL) < SIG_ZERO) e(4);
00315         if (close(fd[0]) != 0) e(5);
00316         if (close(fd[1]) != 0) e(6);
00317   } else {
00318         if (creat("XXX.test5", 0777) < 0) e(7);
00319         j = read(fd[0], (char *) &n, 1);
00320         if (errno != EINTR) e(8);
00321         exit(0);
00322   }
00323 }
00324 
00325 void test5i()
00326 {
00327   int fd[2], pid, buf[10], n;
00328 
00329   subtest = 9;
00330   pipe(fd);
00331   unlink("XXXxxxXXX");
00332 
00333   if ( (pid = fork())) {
00334         /* Parent */
00335         /* Wait until child has started and has created the XXXxxxXXX file. */
00336         while (access("XXXxxxXXX", 0) != 0) /* loop */ ;
00337         sleep(1);
00338         if (kill(pid, SIGKILL) != 0) e(1);
00339         if (wait(&n) < 0) e(2);
00340         if (close(fd[0]) != 0) e(3);
00341         if (close(fd[1]) != 0) e(4);
00342   } else {
00343         if (creat("XXXxxxXXX", 0777) < 0) e(5);
00344         read(fd[0], (char *) buf, 1);
00345         e(5);           /* should be killed by signal and not get here */
00346   }
00347   unlink("XXXxxxXXX");
00348 }
00349 
00350 void ex()
00351 {
00352   int e = errno;
00353   printf("Fork failed: %s (%d)\n", strerror(e), e);
00354   exit(1);
00355 }
00356 
00357 void e(n)
00358 int n;
00359 {
00360   int err_num = errno;          /* save errno in case printf clobbers it */
00361 
00362   printf("Subtest %d,  error %d  errno=%d  ", subtest, n, errno);
00363   errno = err_num;              /* restore errno, just in case */
00364   perror("");
00365   if (errct++ > MAX_ERROR) {
00366         printf("Too many errors; test aborted\n");
00367         chdir("..");
00368         system("rm -rf DIR*");
00369         exit(1);
00370   }
00371 }
00372 
00373 #ifdef _ANSI
00374 void (*Signal(int a, void (*b)(int)))(int)
00375 #else
00376 sighandler_t Signal(a, b)
00377 int a;
00378 void (*b)();
00379 #endif
00380 {
00381   if (signal(a, (void (*) ()) b) == (void (*)()) -1)
00382         return(SIG_ERR);
00383   else
00384         return(SIG_ZERO);
00385 }
00386 
00387 void quit()
00388 {
00389 
00390   chdir("..");
00391   system("rm -rf DIR*");
00392 
00393   if (errct == 0) {
00394         printf("ok\n");
00395         exit(0);
00396   } else {
00397         printf("%d errors\n", errct);
00398         exit(1);
00399   }
00400 }

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