]> Zhao Yanbai Git Server - minix.git/commitdiff
Swap test8 and test37
authorBen Gras <ben@minix3.org>
Mon, 19 Sep 2005 13:39:27 +0000 (13:39 +0000)
committerBen Gras <ben@minix3.org>
Mon, 19 Sep 2005 13:39:27 +0000 (13:39 +0000)
test/test37.c
test/test8.c

index 45e2a40d0cc108f95f8ae76ceec6dcf571881c4d..90de497019c2b36e7e58ef6055587d0efbd66369 100644 (file)
-/* test37: pipe()              Author: Jan-Mark Wams (jms@cs.vu.nl) */
+/* test 37 - signals */
 
 #include <sys/types.h>
-#include <sys/stat.h>
+#include <sys/times.h>
+#ifdef _MINIX
+#include <sys/sigcontext.h>
+#endif
 #include <sys/wait.h>
+#include <errno.h>
+#include <signal.h>
+#include <setjmp.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <errno.h>
-#include <time.h>
 #include <stdio.h>
 
-#define MAX_ERROR      4
-#define ITERATIONS     60
+#define ITERATIONS 2
+#define SIGS 14
+#define MAX_ERROR 4
 
-#define Fstat(a,b)     if (fstat(a,b) != 0) printf("Can't fstat %d\n", a)
-#define Time(t)                if (time(t) == (time_t)-1) printf("Time error\n")
+int iteration, cumsig, subtest, errct = 0, sig1, sig2;
 
-int errct = 0;
-int subtest = 1;
-char MaxName[NAME_MAX + 1];    /* Name of maximum length */
-char MaxPath[PATH_MAX];                /* Same for path */
-char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
-char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
+int sigarray[SIGS] = {SIGHUP, SIGILL, SIGTRAP, SIGABRT, SIGIOT, SIGUNUSED,
+             SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM,
+             SIGTERM};
 
-_PROTOTYPE(void main, (int argc, char *argv[]));
+/* Prototypes produced automatically by mkptypes. */
+_PROTOTYPE(int main, (int argc, char *argv []));
 _PROTOTYPE(void test37a, (void));
+_PROTOTYPE(void func1, (int sig));
+_PROTOTYPE(void func2, (int sig));
 _PROTOTYPE(void test37b, (void));
-_PROTOTYPE(void e, (int number));
+_PROTOTYPE(void catch1, (int signo));
+_PROTOTYPE(void catch2, (int signo));
+_PROTOTYPE(void test37c, (void));
+_PROTOTYPE(void catch3, (int signo));
+_PROTOTYPE(void test37d, (void));
+_PROTOTYPE(void catch4, (int signo));
+_PROTOTYPE(void test37e, (void));
+_PROTOTYPE(void catch5, (int signo));
+_PROTOTYPE(void test37f, (void));
+_PROTOTYPE(void sigint_handler, (int signo));
+_PROTOTYPE(void sigpipe_handler, (int signo));
+_PROTOTYPE(void test37g, (void));
+_PROTOTYPE(void sighup8, (int signo));
+_PROTOTYPE(void sigpip8, (int signo));
+_PROTOTYPE(void sigter8, (int signo));
+_PROTOTYPE(void test37h, (void));
+_PROTOTYPE(void sighup9, (int signo));
+_PROTOTYPE(void sigter9, (int signo));
+_PROTOTYPE(void test37i, (void));
+_PROTOTYPE(void sighup10, (int signo));
+_PROTOTYPE(void sigalrm_handler10, (int signo));
+_PROTOTYPE(void test37j, (void));
+_PROTOTYPE(void test37k, (void));
+_PROTOTYPE(void test37l, (void));
+_PROTOTYPE(void func_m1, (void));
+_PROTOTYPE(void func_m2, (void));
+_PROTOTYPE(void test37m, (void));
+_PROTOTYPE(void longjerr, (void));
+_PROTOTYPE(void catch14, (int signo, int code, struct sigcontext * scp));
+_PROTOTYPE(void test37n, (void));
+_PROTOTYPE(void catch15, (int signo));
+_PROTOTYPE(void test37o, (void));
+_PROTOTYPE(void clearsigstate, (void));
 _PROTOTYPE(void quit, (void));
+_PROTOTYPE(void wait_for, (int pid));
+_PROTOTYPE(void e, (int n));
 
-void main(argc, argv)
+int main(argc, argv)
 int argc;
 char *argv[];
 {
   int i, m = 0xFFFF;
 
   sync();
+
   if (argc == 2) m = atoi(argv[1]);
+
   printf("Test 37 ");
-  fflush(stdout);
+  fflush(stdout);              /* have to flush for child's benefit */
+
+  system("rm -rf DIR_37; mkdir DIR_37");
+  chdir("DIR_37");
 
   for (i = 0; i < ITERATIONS; i++) {
-       if (m & 0001) test37a();
-       if (m & 0002) test37b();
+       iteration = i;
+       if (m & 0000001) test37a();
+       if (m & 0000002) test37b();
+       if (m & 0000004) test37c();
+       if (m & 0000010) test37d();
+       if (m & 0000020) test37e();
+       if (m & 0000040) test37f();
+       if (m & 0000100) test37g();
+       if (m & 0000200) test37h();
+       if (m & 0000400) test37i();
+       if (m & 0001000) test37j();
+       if (m & 0002000) test37k();
+       if (m & 0004000) test37l();
+       if (m & 0010000) test37m();
+       if (m & 0020000) test37n();
+       if (m & 0040000) test37o();
   }
+
   quit();
+  return(-1);                  /* impossible */
 }
 
 void test37a()
-{                              /* Test fcntl flags. */
-  int tube[2], t1[2], t2[2], t3[2];
-  time_t time1, time2;
-  char buf[128];
-  struct stat st1, st2;
-  int stat_loc, flags;
+{
+/* Test signal set management. */
+
+  sigset_t s;
 
   subtest = 1;
+  clearsigstate();
 
-  /* Check if lowest fds are returned. */
-  if (pipe(tube) != 0) e(1);
-  if (tube[0] != 3 && tube[1] != 3) e(2);
-  if (tube[1] != 4 && tube[0] != 4) e(3);
-  if (tube[1] == tube[0]) e(4);
-  if (pipe(t1) != 0) e(5);
-  if (t1[0] != 5 && t1[1] != 5) e(6);
-  if (t1[1] != 6 && t1[0] != 6) e(7);
-  if (t1[1] == t1[0]) e(8);
-  if (close(t1[0]) != 0) e(9);
-  if (close(tube[0]) != 0) e(10);
-  if (pipe(t2) != 0) e(11);
-  if (t2[0] != tube[0] && t2[1] != tube[0]) e(12);
-  if (t2[1] != t1[0] && t2[0] != t1[0]) e(13);
-  if (t2[1] == t2[0]) e(14);
-  if (pipe(t3) != 0) e(15);
-  if (t3[0] != 7 && t3[1] != 7) e(16);
-  if (t3[1] != 8 && t3[0] != 8) e(17);
-  if (t3[1] == t3[0]) e(18);
-  if (close(tube[1]) != 0) e(19);
-  if (close(t1[1]) != 0) e(20);
-  if (close(t2[0]) != 0) e(21);
-  if (close(t2[1]) != 0) e(22);
-  if (close(t3[0]) != 0) e(23);
-  if (close(t3[1]) != 0) e(24);
-
-  /* All time fields should be marked for update. */
-  Time(&time1);
-  if (pipe(tube) != 0) e(25);
-  Fstat(tube[0], &st1);
-  Fstat(tube[1], &st2);
-  Time(&time2);
-  if (st1.st_atime < time1) e(26);
-  if (st1.st_ctime < time1) e(27);
-  if (st1.st_mtime < time1) e(28);
-  if (st1.st_atime > time2) e(29);
-  if (st1.st_ctime > time2) e(30);
-  if (st1.st_mtime > time2) e(31);
-  if (st2.st_atime < time1) e(32);
-  if (st2.st_ctime < time1) e(33);
-  if (st2.st_mtime < time1) e(34);
-  if (st2.st_atime > time2) e(35);
-  if (st2.st_ctime > time2) e(36);
-  if (st2.st_mtime > time2) e(37);
-
-  /* Check the file characteristics. */
-  if ((flags = fcntl(tube[0], F_GETFD)) != 0) e(38);
-  if ((flags & FD_CLOEXEC) != 0) e(39);
-  if ((flags = fcntl(tube[0], F_GETFL)) != 0) e(40);
-  if ((flags & O_RDONLY) != O_RDONLY) e(41);
-  if ((flags & O_NONBLOCK) != 0) e(42);
-  if ((flags & O_RDWR) != 0) e(43);
-  if ((flags & O_WRONLY) != 0) e(44);
-
-  if ((flags = fcntl(tube[1], F_GETFD)) != 0) e(45);
-  if ((flags & FD_CLOEXEC) != 0) e(46);
-  if ((flags = fcntl(tube[1], F_GETFL)) == -1) e(47);
-  if ((flags & O_WRONLY) != O_WRONLY) e(48);
-  if ((flags & O_NONBLOCK) != 0) e(49);
-  if ((flags & O_RDWR) != 0) e(50);
-  if ((flags & O_RDONLY) != 0) e(51);
-
-  /* Check if we can read and write. */
-  switch (fork()) {
-      case -1: printf("Can't fork\n"); break;
-      case 0:
-       alarm(20);
-       if (close(tube[0]) != 0) e(52);
-       if (write(tube[1], "Hello", 6) != 6) e(53);
-       if (close(tube[1]) != 0) e(54);
-       exit(0);
-      default:
-       if (read(tube[0], buf, sizeof(buf)) != 6) e(55);
-       if (strncmp(buf, "Hello", 6) != 0) e(56);
-       wait(&stat_loc);
-       if (stat_loc != 0) e(57);       /* Alarm? */
-  }
-  if (close(tube[0]) != 0) e(58);
-  if (close(tube[1]) != 0) e(59);
+  /* Create an empty set and see if any bits are on. */
+  if (sigemptyset(&s) != 0) e(1);
+  if (sigismember(&s, SIGHUP) != 0) e(2);
+  if (sigismember(&s, SIGINT) != 0) e(3);
+  if (sigismember(&s, SIGQUIT) != 0) e(4);
+  if (sigismember(&s, SIGILL) != 0) e(5);
+  if (sigismember(&s, SIGTRAP) != 0) e(6);
+  if (sigismember(&s, SIGABRT) != 0) e(7);
+  if (sigismember(&s, SIGIOT) != 0) e(8);
+  if (sigismember(&s, SIGUNUSED) != 0) e(9);
+  if (sigismember(&s, SIGFPE) != 0) e(10);
+  if (sigismember(&s, SIGKILL) != 0) e(11);
+  if (sigismember(&s, SIGUSR1) != 0) e(12);
+  if (sigismember(&s, SIGSEGV) != 0) e(13);
+  if (sigismember(&s, SIGUSR2) != 0) e(14);
+  if (sigismember(&s, SIGPIPE) != 0) e(15);
+  if (sigismember(&s, SIGALRM) != 0) e(16);
+  if (sigismember(&s, SIGTERM) != 0) e(17);
+
+  /* Create a full set and see if any bits are off. */
+  if (sigfillset(&s) != 0) e(19);
+  if (sigemptyset(&s) != 0) e(20);
+  if (sigfillset(&s) != 0) e(21);
+  if (sigismember(&s, SIGHUP) != 1) e(22);
+  if (sigismember(&s, SIGINT) != 1) e(23);
+  if (sigismember(&s, SIGQUIT) != 1) e(24);
+  if (sigismember(&s, SIGILL) != 1) e(25);
+  if (sigismember(&s, SIGTRAP) != 1) e(26);
+  if (sigismember(&s, SIGABRT) != 1) e(27);
+  if (sigismember(&s, SIGIOT) != 1) e(28);
+  if (sigismember(&s, SIGUNUSED) != 1) e(29);
+  if (sigismember(&s, SIGFPE) != 1) e(30);
+  if (sigismember(&s, SIGKILL) != 1) e(31);
+  if (sigismember(&s, SIGUSR1) != 1) e(32);
+  if (sigismember(&s, SIGSEGV) != 1) e(33);
+  if (sigismember(&s, SIGUSR2) != 1) e(34);
+  if (sigismember(&s, SIGPIPE) != 1) e(35);
+  if (sigismember(&s, SIGALRM) != 1) e(36);
+  if (sigismember(&s, SIGTERM) != 1) e(37);
+
+  /* Create an empty set, then turn on bits individually. */
+  if (sigemptyset(&s) != 0) e(39);
+  if (sigaddset(&s, SIGHUP) != 0) e(40);
+  if (sigaddset(&s, SIGINT) != 0) e(41);
+  if (sigaddset(&s, SIGQUIT) != 0) e(42);
+  if (sigaddset(&s, SIGILL) != 0) e(43);
+  if (sigaddset(&s, SIGTRAP) != 0) e(44);
+
+  /* See if the bits just turned on are indeed on. */
+  if (sigismember(&s, SIGHUP) != 1) e(45);
+  if (sigismember(&s, SIGINT) != 1) e(46);
+  if (sigismember(&s, SIGQUIT) != 1) e(47);
+  if (sigismember(&s, SIGILL) != 1) e(48);
+  if (sigismember(&s, SIGTRAP) != 1) e(49);
+
+  /* The others should be turned off. */
+  if (sigismember(&s, SIGABRT) != 0) e(50);
+  if (sigismember(&s, SIGIOT) != 0) e(51);
+  if (sigismember(&s, SIGUNUSED) != 0) e(52);
+  if (sigismember(&s, SIGFPE) != 0) e(53);
+  if (sigismember(&s, SIGKILL) != 0) e(54);
+  if (sigismember(&s, SIGUSR1) != 0) e(55);
+  if (sigismember(&s, SIGSEGV) != 0) e(56);
+  if (sigismember(&s, SIGUSR2) != 0) e(57);
+  if (sigismember(&s, SIGPIPE) != 0) e(58);
+  if (sigismember(&s, SIGALRM) != 0) e(59);
+  if (sigismember(&s, SIGTERM) != 0) e(60);
+
+  /* Now turn them off and see if all are off. */
+  if (sigdelset(&s, SIGHUP) != 0) e(62);
+  if (sigdelset(&s, SIGINT) != 0) e(63);
+  if (sigdelset(&s, SIGQUIT) != 0) e(64);
+  if (sigdelset(&s, SIGILL) != 0) e(65);
+  if (sigdelset(&s, SIGTRAP) != 0) e(66);
+
+  if (sigismember(&s, SIGHUP) != 0) e(67);
+  if (sigismember(&s, SIGINT) != 0) e(68);
+  if (sigismember(&s, SIGQUIT) != 0) e(69);
+  if (sigismember(&s, SIGILL) != 0) e(70);
+  if (sigismember(&s, SIGTRAP) != 0) e(71);
+  if (sigismember(&s, SIGABRT) != 0) e(72);
+  if (sigismember(&s, SIGIOT) != 0) e(73);
+  if (sigismember(&s, SIGUNUSED) != 0) e(74);
+  if (sigismember(&s, SIGFPE) != 0) e(75);
+  if (sigismember(&s, SIGKILL) != 0) e(76);
+  if (sigismember(&s, SIGUSR1) != 0) e(77);
+  if (sigismember(&s, SIGSEGV) != 0) e(78);
+  if (sigismember(&s, SIGUSR2) != 0) e(79);
+  if (sigismember(&s, SIGPIPE) != 0) e(80);
+  if (sigismember(&s, SIGALRM) != 0) e(81);
+  if (sigismember(&s, SIGTERM) != 0) e(82);
+}
+
+void func1(sig)
+int sig;
+{
+  sig1++;
+}
+
+void func2(sig)
+int sig;
+{
+  sig2++;
 }
 
 void test37b()
 {
-  int tube[2], child2parent[2], parent2child[2];
-  int i, nchild = 0, nopen = 3, stat_loc;
-  int fd;
-  int forkfailed = 0;
-  char c;
+/* Test sigprocmask and sigpending. */
+  int i;
+  pid_t p;
+  sigset_t s, s1, s_empty, s_full, s_ill, s_ill_pip, s_nokill;
+  struct sigaction sa, osa;
 
   subtest = 2;
+  clearsigstate();
 
-  /* Take all the pipes we can get. */
-  while (nopen < OPEN_MAX - 2) {
-       if (pipe(tube) != 0) {
-               /* We have not reached OPEN_MAX yet, so we have ENFILE. */
-               if (errno != ENFILE) e(1);
-               sleep(2);       /* Wait for others to (maybe) closefiles. */
-               break;
-       }
-       nopen += 2;
+  /* Construct s_ill = {SIGILL} and s_ill_pip {SIGILL | SIGPIP}, etc. */
+  if (sigemptyset(&s_empty) != 0) e(1);
+  if (sigemptyset(&s_ill) != 0) e(2);
+  if (sigemptyset(&s_ill_pip) != 0) e(3);
+  if (sigaddset(&s_ill, SIGILL) != 0) e(4);
+  if (sigaddset(&s_ill_pip, SIGILL) != 0) e(5);
+  if (sigaddset(&s_ill_pip, SIGPIPE) != 0) e(6);
+  if (sigfillset(&s_full) != 0) e(7);
+  s_nokill = s_full;
+  if (sigdelset(&s_nokill, SIGKILL) != 0) e(8);
+#ifndef _MINIX /* XXX - should unsupported signals be <= _NSIG? */
+  if (SIGSTOP > _NSIG) e(666);
+  if (SIGSTOP <= _NSIG && sigdelset(&s_nokill, SIGSTOP) != 0) e(888);
+#endif /* _MINIX */
+
+  /* Now get most of the signals into default state.  Don't change SIGINT
+  * or SIGQUIT, so this program can be killed.  SIGKILL is also special.
+  */
+  sa.sa_handler = SIG_DFL;
+  sa.sa_mask = s_empty;
+  sa.sa_flags = 0;
+  for (i = 0; i < SIGS; i++) sigaction(i, &sa, &osa);
+
+  /* The second argument may be zero.  See if it wipes out the system. */
+  for (i = 0; i < SIGS; i++) sigaction(i, (struct sigaction *) NULL, &osa);
+
+  /* Install a signal handler. */
+  sa.sa_handler = func1;
+  sa.sa_mask = s_ill;
+  sa.sa_flags = SA_NODEFER | SA_NOCLDSTOP;
+  osa.sa_handler = SIG_IGN;
+  osa.sa_mask = s_empty;
+  osa.sa_flags = 0;
+  if (sigaction(SIGHUP, &sa, &osa) != 0) e(9);
+  if (osa.sa_handler != SIG_DFL) e(10);
+  if (osa.sa_mask != 0) e(11);
+  if (osa.sa_flags != s_empty) e(12);
+
+  /* Replace action and see if old value is read back correctly. */
+  sa.sa_handler = func2;
+  sa.sa_mask = s_ill_pip;
+  sa.sa_flags = SA_RESETHAND | SA_NODEFER;
+  osa.sa_handler = SIG_IGN;
+  osa.sa_mask = s_empty;
+  osa.sa_flags = 0;
+  if (sigaction(SIGHUP, &sa, &osa) != 0) e(13);
+  if (osa.sa_handler != func1) e(14);
+  if (osa.sa_mask != s_ill) e(15);
+  if (osa.sa_flags != SA_NODEFER
+      && osa.sa_flags != (SA_NODEFER | SA_NOCLDSTOP)) e(16);
+
+  /* Replace action once more and check what is read back. */
+  sa.sa_handler = SIG_DFL;
+  sa.sa_mask = s_empty;
+  osa.sa_handler = SIG_IGN;
+  osa.sa_mask = s_empty;
+  osa.sa_flags = 0;
+  if (sigaction(SIGHUP, &sa, &osa) != 0) e(17);
+  if (osa.sa_handler != func2) e(18);
+  if (osa.sa_mask != s_ill_pip) e(19);
+  if (osa.sa_flags != (SA_RESETHAND | SA_NODEFER)) e(20);
+
+  /* Test sigprocmask(SIG_SETMASK, ...). */
+  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(18);    /* block all */
+  if (sigemptyset(&s1) != 0) e(19);
+  if (sigprocmask(SIG_SETMASK, &s_empty, &s1) != 0) e(20);   /* block none */
+  if (s1 != s_nokill) e(21);
+  if (sigprocmask(SIG_SETMASK, &s_ill, &s1) != 0) e(22);     /* block SIGILL */
+  if (s1 != s_empty) e(23);
+  if (sigprocmask(SIG_SETMASK, &s_ill_pip, &s1) != 0) e(24); /* SIGILL+PIP */
+  if (s1 != s_ill) e(25);
+  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(26);    /* block all */
+  if (s1 != s_ill_pip) e(27);
+
+  /* Test sigprocmask(SIG_UNBLOCK, ...) */
+  if (sigprocmask(SIG_UNBLOCK, &s_ill, &s1) != 0) e(28);
+  if (s1 != s_nokill) e(29);
+  if (sigprocmask(SIG_UNBLOCK, &s_ill_pip, &s1) != 0) e(30);
+  s = s_nokill;
+  if (sigdelset(&s, SIGILL) != 0) e(31);
+  if (s != s1) e(32);
+  if (sigprocmask(SIG_UNBLOCK, &s_empty, &s1) != 0) e(33);
+  s = s_nokill;
+  if (sigdelset(&s, SIGILL) != 0) e(34);
+  if (sigdelset(&s, SIGPIPE) != 0) e(35);
+  if (s != s1) e(36);
+  s1 = s_nokill;
+  if (sigprocmask(SIG_SETMASK, &s_empty, &s1) != 0) e(37);
+  if (s != s1) e(38);
+
+  /* Test sigprocmask(SIG_BLOCK, ...) */
+  if (sigprocmask(SIG_BLOCK, &s_ill, &s1) != 0) e(39);
+  if (s1 != s_empty) e(40);
+  if (sigprocmask(SIG_BLOCK, &s_ill_pip, &s1) != 0) e(41);
+  if (s1 != s_ill) e(42);
+  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(43);
+  if (s1 != s_ill_pip) e(44);
+
+  /* Check error condition. */
+  errno = 0;
+  if (sigprocmask(20000, &s_full, &s1) != -1) e(45);
+  if (errno != EINVAL) e(46);
+  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(47);
+  if (s1 != s_nokill) e(48);
+
+  /* If second arg is 0, nothing is set. */
+  if (sigprocmask(SIG_SETMASK, (sigset_t *) NULL, &s1) != 0) e(49);
+  if (s1 != s_nokill) e(50);
+  if (sigprocmask(SIG_SETMASK, &s_ill_pip, &s1) != 0) e(51);
+  if (s1 != s_nokill) e(52);
+  if (sigprocmask(SIG_SETMASK, (sigset_t *) NULL, &s1) != 0) e(53);
+  if (s1 != s_ill_pip) e(54);
+  if (sigprocmask(SIG_BLOCK, (sigset_t *) NULL, &s1) != 0) e(55);
+  if (s1 != s_ill_pip) e(56);
+  if (sigprocmask(SIG_UNBLOCK, (sigset_t *) NULL, &s1) != 0) e(57);
+  if (s1 != s_ill_pip) e(58);
+
+  /* Trying to block SIGKILL is not allowed, but is not an error, either. */
+  s = s_empty;
+  if (sigaddset(&s, SIGKILL) != 0) e(59);
+  if (sigprocmask(SIG_BLOCK, &s, &s1) != 0) e(60);
+  if (s1 != s_ill_pip) e(61);
+  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(62);
+  if (s1 != s_ill_pip) e(63);
+
+  /* Test sigpending. At this moment, all signals are blocked. */
+  sa.sa_handler = func2;
+  sa.sa_mask = s_empty;
+  if (sigaction(SIGHUP, &sa, &osa) != 0) e(64);
+  p = getpid();
+  kill(p, SIGHUP);             /* send SIGHUP to self */
+  if (sigpending(&s) != 0) e(65);
+  if (sigemptyset(&s1) != 0) e(66);
+  if (sigaddset(&s1, SIGHUP) != 0) e(67);
+  if (s != s1) e(68);
+  sa.sa_handler = SIG_IGN;
+  if (sigaction(SIGHUP, &sa, &osa) != 0) e(69);
+  if (sigpending(&s) != 0) e(70);
+  if (s != s_empty) e(71);
+}
+
+/*---------------------------------------------------------------------------*/
+int x;
+sigset_t glo_vol_set;
+
+void catch1(signo)
+int signo;
+{
+  x = 42;
+}
+
+void catch2(signo)
+int signo;
+{
+  if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, (sigset_t *) &glo_vol_set) != 0)
+       e(1);
+}
+
+/* Verify that signal(2), which is now built on top of sigaction(2), still
+* works.
+*/
+void test37c()
+{
+  pid_t pid;
+  sigset_t sigset_var;
+
+  subtest = 3;
+  clearsigstate();
+  x = 0;
+
+  /* Verify an installed signal handler persists across a fork(2). */
+  if (signal(SIGTERM, catch1) == SIG_ERR) e(1);
+  switch (pid = fork()) {
+      case 0:                  /* child */
+       errct = 0;
+       while (x == 0);
+       if (x != 42) e(2);
+       exit(errct == 0 ? 0 : 1);
+      case -1: e(3);   break;
+      default:                 /* parent */
+       sleep(1);
+       if (kill(pid, SIGTERM) != 0) e(4);
+       wait_for(pid);
+       break;
   }
 
-  if (nopen < OPEN_MAX - 2) {
-       if (pipe(tube) != -1) e(2);
-       switch (errno) {
-           case EMFILE:        /* Errno value is ok. */
-               break;
-           case ENFILE:        /* No process can open files any more. */
-               switch (fork()) {
-                   case -1:
-                       printf("Can't fork\n");
-                       break;
-                   case 0:
-                       alarm(20);
-                       if (open("/", O_RDONLY) != -1) e(3);
-                       if (errno != ENFILE) e(4);
-                       exit(0);
-                   default:
-                       wait(&stat_loc);
-                       if (stat_loc != 0) e(5);        /* Alarm? */
-               }
-               break;
-           default:            /* Wrong value for errno. */
-               e(6);
-       }
+  /* Verify that the return value is the previous handler. */
+  signal(SIGINT, SIG_IGN);
+  if (signal(SIGINT, catch2) != SIG_IGN) e(5);
+  if (signal(SIGINT, catch1) != catch2) e(6);
+  if (signal(SIGINT, SIG_DFL) != catch1) e(7);
+  if (signal(SIGINT, catch1) != SIG_DFL) e(8);
+  if (signal(SIGINT, SIG_DFL) != catch1) e(9);
+  if (signal(SIGINT, SIG_DFL) != SIG_DFL) e(10);
+  if (signal(SIGINT, catch1) != SIG_DFL) e(11);
+
+  /* Verify that SIG_ERR is correctly generated. */
+  if (signal(_NSIG + 1, catch1) != SIG_ERR) e(12);
+  if (signal(0, catch1) != SIG_ERR) e(13);
+  if (signal(-1, SIG_DFL) != SIG_ERR) e(14);
+
+  /* Verify that caught signals are automatically reset to the default,
+   * and that further instances of the same signal are not blocked here
+   * or in the signal handler.
+   */
+  if (signal(SIGTERM, catch1) == SIG_ERR) e(15);
+  switch ((pid = fork())) {
+      case 0:                  /* child */
+       errct = 0;
+       while (x == 0);
+       if (x != 42) e(16);
+       if (sigismember((sigset_t *) &glo_vol_set, SIGTERM)) e(17);
+       if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &sigset_var) != 0) e(18);
+       if (sigismember(&sigset_var, SIGTERM)) e(19);
+
+#if 0
+/* Use this if you have compiled signal() to have the broken SYSV behaviour. */
+       if (signal(SIGTERM, catch1) != SIG_DFL) e(20);
+#else
+       if (signal(SIGTERM, catch1) != catch1) e(20);
+#endif
+       exit(errct == 0 ? 0 : 1);
+      default:                 /* parent */
+       sleep(1);
+       if (kill(pid, SIGTERM) != 0) e(21);
+       wait_for(pid);
+       break;
+      case -1: e(22);  break;
   }
+}
 
-  /* Close all but stdin,out,err. */
-  for (i = 3; i < OPEN_MAX; i++) (void) close(i);
-
-  /* ENFILE test. Have children each grab OPEN_MAX fds. */
-  if (pipe(child2parent) != 0) e(7);
-  if (pipe(parent2child) != 0) e(8);
-  while (!forkfailed && (fd = open("/", O_RDONLY)) != -1) {
-       close(fd);
-       switch (fork()) {
-           case -1:
-               forkfailed = 1;
-               break;
-           case 0:
-               alarm(60);
-
-               /* Grab all the fds. */
-               while (pipe(tube) != -1);
-               while (open("/", O_RDONLY) != -1);
-
-               /* Signal parent OPEN_MAX fds gone. */
-               if (write(child2parent[1], "*", 1) != 1) e(9);
-
-               /* Wait for parent befor freeing all the fds. */
-               if (read(parent2child[0], &c, 1) != 1) e(10);
-               exit(0);
-           default:
-
-               /* Wait for child to grab OPEN_MAX fds. */
-               if (read(child2parent[0], &c, 1) != 1) e(11);
-               nchild++;
-               break;
-       }
+/*---------------------------------------------------------------------------*/
+/* Test that the signal handler can be invoked recursively with the
+* state being properly saved and restored.
+*/
+
+static int y;
+static int z;
+
+void catch3(signo)
+int signo;
+{
+  if (z == 1) {                        /* catching a nested signal */
+       y = 2;
+       return;
   }
+  z = 1;
+  if (kill(getpid(), SIGHUP) != 0) e(1);
+  while (y != 2);
+  y = 1;
+}
+
+void test37d()
+{
+  struct sigaction act;
+
+  subtest = 4;
+  clearsigstate();
+  y = 0;
+  z = 0;
+
+  act.sa_handler = catch3;
+  act.sa_mask = 0;
+  act.sa_flags = SA_NODEFER;   /* Otherwise, nested occurence of
+                                * SIGINT is blocked. */
+  if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) != 0) e(2);
+  if (kill(getpid(), SIGHUP) != 0) e(3);
+  if (y != 1) e(4);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Test that the signal mask in effect for the duration of a signal handler
+* is as specified in POSIX Section 3, lines 718 -724.  Test that the
+* previous signal mask is restored when the signal handler returns.
+*/
+
+void catch4(signo)
+int signo;
+{
+  sigset_t oset;
+  sigset_t set;
+
+  if (sigemptyset(&set) == -1) e(5001);
+  if (sigaddset(&set, SIGTERM) == -1) e(5002);
+  if (sigaddset(&set, SIGHUP) == -1) e(5003);
+  if (sigaddset(&set, SIGINT) == -1) e(5004);
+  if (sigaddset(&set, SIGPIPE) == -1) e(5005);
+  if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset) != 0) e(5006);
+  if (oset != set) e(5007);
+}
+
+void test37e()
+{
+  struct sigaction act, oact;
+  sigset_t set, oset;
+
+  subtest = 5;
+  clearsigstate();
+
+  act.sa_handler = catch4;
+  sigemptyset(&act.sa_mask);
+  sigaddset(&act.sa_mask, SIGTERM);
+  sigaddset(&act.sa_mask, SIGHUP);
+  act.sa_flags = 0;
+  if (sigaction(SIGINT, &act, &oact) == -1) e(2);
+
+  if (sigemptyset(&set) == -1) e(3);
+  if (sigaddset(&set, SIGPIPE) == -1) e(4);
+  if (sigprocmask(SIG_SETMASK, &set, &oset) == -1) e(5);
+  if (kill(getpid(), SIGINT) == -1) e(6);
+  if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset) == -1) e(7);
+  if (sigemptyset(&set) == -1) e(8);
+  if (sigaddset(&set, SIGPIPE) == -1) e(9);
+  if (set != oset) e(10);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Test the basic functionality of sigsuspend(2). */
+
+void catch5(signo)
+int signo;
+{
+  x = 1;
+}
+
+void test37f()
+{
+  sigset_t set;
+  int r;
+  struct sigaction act;
+  pid_t pid;
+
+  subtest = 6;
+  clearsigstate();
+
+  switch (pid = fork()) {
+      case 0:                  /* child */
+       errct = 0;
+       sleep(1);
+       if (kill(getppid(), SIGINT) == -1) e(1);
+       exit(errct == 0 ? 0 : 1);
+      case -1: e(2);   break;
+      default:                 /* parent */
+       if (sigemptyset(&act.sa_mask) == -1) e(3);
+       act.sa_flags = 0;
+       act.sa_handler = catch5;
+       if (sigaction(SIGINT, &act, (struct sigaction *) NULL) == -1) e(4);
 
-  if (!forkfailed) {
-       if (pipe(tube) != -1) e(12);
-       if (errno != ENFILE) e(13);
+       if (sigemptyset(&set) == -1) e(5);
+       r = sigsuspend(&set);
+
+       if (r != -1 || errno != EINTR || x != 1) e(6);
+       wait_for(pid);
+       break;
   }
+}
+
+/*----------------------------------------------------------------------*/
+
+/* Test that sigsuspend() does block the signals specified in its
+* argument, and after sigsuspend returns, the previous signal
+* mask is restored.
+*
+* The child sends two signals to the parent SIGINT and then SIGPIPE,
+* separated by a long delay.  The parent executes sigsuspend() with
+* SIGINT blocked.  It is expected that the parent's SIGPIPE handler
+* will be invoked, then sigsuspend will return restoring the
+* original signal mask, and then the SIGPIPE handler will be
+* invoked.
+*/
+
+void sigint_handler(signo)
+int signo;
+{
+  x = 1;
+  z++;
+}
+
+void sigpipe_handler(signo)
+int signo;
+{
+  x = 2;
+  z++;
+}
+
+void test37g()
+{
+  sigset_t set;
+  int r;
+  struct sigaction act;
+  pid_t pid;
+
+  subtest = 7;
+  clearsigstate();
+  x = 0;
+  z = 0;
+
+  switch (pid = fork()) {
+      case 0:                  /* child */
+       errct = 0;
+       sleep(1);
+       if (kill(getppid(), SIGINT) == -1) e(1);
+       sleep(1);
+       if (kill(getppid(), SIGPIPE) == -1) e(2);
+       exit(errct == 0 ? 0 : 1);
+      case -1: e(3);   break;
+      default:                 /* parent */
+       if (sigemptyset(&act.sa_mask) == -1) e(3);
+       act.sa_flags = 0;
+       act.sa_handler = sigint_handler;
+       if (sigaction(SIGINT, &act, (struct sigaction *) NULL) == -1) e(4);
 
-  /* Signal children to die and wait for it. */
-  while (nchild-- > 0) {
-       if (write(parent2child[1], "*", 1) != 1) e(14);
-       wait(&stat_loc);
-       if (stat_loc != 0) e(15);       /* Alarm? */
+       act.sa_handler = sigpipe_handler;
+       if (sigaction(SIGPIPE, &act, (struct sigaction *) NULL) == -1) e(5);
+
+       if (sigemptyset(&set) == -1) e(6);
+       if (sigaddset(&set, SIGINT) == -1) e(7);
+       r = sigsuspend(&set);
+       if (r != -1) e(8);
+       if (errno != EINTR) e(9);
+       if (z != 2) e(10);
+       if (x != 1) e(11);
+       wait_for(pid);
+       break;
   }
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* Test that sigsuspend() does block the signals specified in its
+* argument, and after sigsuspend returns, the previous signal
+* mask is restored.
+*
+* The child sends three signals to the parent: SIGHUP, then SIGPIPE,
+* and then SIGTERM, separated by a long delay.  The parent executes
+* sigsuspend() with SIGHUP and SIGPIPE blocked.  It is expected that
+* the parent's SIGTERM handler will be invoked first, then sigsuspend()
+* will return restoring the original signal mask, and then the other
+* two handlers will be invoked.
+*/
 
-  /* Close all but stdin,out,err. */
-  for (i = 3; i < OPEN_MAX; i++) (void) close(i);
+void sighup8(signo)
+int signo;
+{
+  x = 1;
+  z++;
 }
 
-void e(n)
-int n;
+void sigpip8(signo)
+int signo;
 {
-  int err_num = errno;         /* Save in case printf clobbers it. */
+  x = 1;
+  z++;
+}
 
-  printf("Subtest %d,  error %d  errno=%d: ", subtest, n, errno);
-  errno = err_num;
-  perror("");
-  if (errct++ > MAX_ERROR) {
-       printf("Too many errors; test aborted\n");
-       chdir("..");
-       system("rm -rf DIR*");
-       exit(1);
+void sigter8(signo)
+int signo;
+{
+  x = 2;
+  z++;
+}
+
+void test37h()
+{
+  sigset_t set;
+  int r;
+  struct sigaction act;
+  pid_t pid;
+
+  subtest = 8;
+  clearsigstate();
+  x = 0;
+  z = 0;
+
+  switch (pid = fork()) {
+      case 0:                  /* child */
+       errct = 0;
+       sleep(1);
+       if (kill(getppid(), SIGHUP) == -1) e(1);
+       sleep(1);
+       if (kill(getppid(), SIGPIPE) == -1) e(2);
+       sleep(1);
+       if (kill(getppid(), SIGTERM) == -1) e(3);
+       exit(errct == 0 ? 0 : 1);
+      case -1: e(5);   break;
+      default:                 /* parent */
+       if (sigemptyset(&act.sa_mask) == -1) e(6);
+       act.sa_flags = 0;
+       act.sa_handler = sighup8;
+       if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(7);
+
+       act.sa_handler = sigpip8;
+       if (sigaction(SIGPIPE, &act, (struct sigaction *) NULL) == -1) e(8);
+
+       act.sa_handler = sigter8;
+       if (sigaction(SIGTERM, &act, (struct sigaction *) NULL) == -1) e(9);
+
+       if (sigemptyset(&set) == -1) e(10);
+       if (sigaddset(&set, SIGHUP) == -1) e(11);
+       if (sigaddset(&set, SIGPIPE) == -1) e(12);
+       r = sigsuspend(&set);
+       if (r != -1) e(13);
+       if (errno != EINTR) e(14);
+       if (z != 3) e(15);
+       if (x != 1) e(16);
+       wait_for(pid);
+       break;
   }
-  errno = 0;
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* Block SIGHUP and SIGTERM with sigprocmask(), send ourself SIGHUP
+* and SIGTERM, unblock these signals with sigprocmask, and verify
+* that these signals are delivered.
+*/
+
+void sighup9(signo)
+int signo;
+{
+  y++;
+}
+
+void sigter9(signo)
+int signo;
+{
+  z++;
+}
+
+void test37i()
+{
+  sigset_t set;
+  struct sigaction act;
+
+  subtest = 9;
+  clearsigstate();
+  y = 0;
+  z = 0;
+
+  if (sigemptyset(&act.sa_mask) == -1) e(1);
+  act.sa_flags = 0;
+
+  act.sa_handler = sighup9;
+  if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(2);
+
+  act.sa_handler = sigter9;
+  if (sigaction(SIGTERM, &act, (struct sigaction *) NULL) == -1) e(3);
+
+  if (sigemptyset(&set) == -1) e(4);
+  if (sigaddset(&set, SIGTERM) == -1) e(5);
+  if (sigaddset(&set, SIGHUP) == -1) e(6);
+  if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(7);
+
+  if (kill(getpid(), SIGHUP) == -1) e(8);
+  if (kill(getpid(), SIGTERM) == -1) e(9);
+  if (y != 0) e(10);
+  if (z != 0) e(11);
+
+  if (sigemptyset(&set) == -1) e(12);
+  if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(12);
+  if (y != 1) e(13);
+  if (z != 1) e(14);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Block SIGINT and then send this signal to ourself.
+*
+* Install signal handlers for SIGALRM and SIGINT.
+*
+* Set an alarm for 6 seconds, then sleep for 7.
+*
+* The SIGALRM should interrupt the sleep, but the SIGINT
+* should remain pending.
+*/
+
+void sighup10(signo)
+int signo;
+{
+  y++;
+}
+
+void sigalrm_handler10(signo)
+int signo;
+{
+  z++;
+}
+
+void test37j()
+{
+  sigset_t set, set2;
+  struct sigaction act;
+
+  subtest = 10;
+  clearsigstate();
+  y = 0;
+  z = 0;
+
+  if (sigemptyset(&act.sa_mask) == -1) e(1);
+  act.sa_flags = 0;
+
+  act.sa_handler = sighup10;
+  if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(2);
+
+  act.sa_handler = sigalrm_handler10;
+  if (sigaction(SIGALRM, &act, (struct sigaction *) NULL) == -1) e(3);
+
+  if (sigemptyset(&set) == -1) e(4);
+  if (sigaddset(&set, SIGHUP) == -1) e(5);
+  if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(6);
+
+  if (kill(getpid(), SIGHUP) == -1) e(7);
+  if (sigpending(&set) == -1) e(8);
+  if (sigemptyset(&set2) == -1) e(9);
+  if (sigaddset(&set2, SIGHUP) == -1) e(10);
+  if (set2 != set) e(11);
+  alarm(6);
+  sleep(7);
+  if (sigpending(&set) == -1) e(12);
+  if (set != set2) e(13);
+  if (y != 0) e(14);
+  if (z != 1) e(15);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void test37k()
+{
+  subtest = 11;
+}
+void test37l()
+{
+  subtest = 12;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Basic test for setjmp/longjmp.  This includes testing that the
+* signal mask is properly restored.
+*/
+
+void test37m()
+{
+  jmp_buf jb;
+  sigset_t ss;
+
+  subtest = 13;
+  clearsigstate();
+
+  ss = 0x32;
+  if (sigprocmask(SIG_SETMASK, &ss, (sigset_t *)NULL) == -1) e(1);
+  if (setjmp(jb)) {
+       if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &ss) == -1) e(2);
+       if (ss != 0x32) e(388);
+       return;
+  }
+  ss = 0x3abc;
+  if (sigprocmask(SIG_SETMASK, &ss, (sigset_t *)NULL) == -1) e(4);
+  longjmp(jb, 1);
+}
+
+void longjerr()
+{
+  e(5);
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* Test for setjmp/longjmp.
+*
+* Catch a signal.  While in signal handler do setjmp/longjmp.
+*/
+
+void catch14(signo, code, scp)
+int signo;
+int code;
+struct sigcontext *scp;
+{
+  jmp_buf jb;
+
+  if (setjmp(jb)) {
+       x++;
+       sigreturn(scp);
+       e(1);
+  }
+  y++;
+  longjmp(jb, 1);
+  e(2);
+}
+
+void test37n()
+{
+  struct sigaction act;
+  typedef _PROTOTYPE( void (*sighandler_t), (int sig) );
+
+  subtest = 14;
+  clearsigstate();
+  x = 0;
+  y = 0;
+
+  act.sa_flags = 0;
+  act.sa_mask = 0;
+  act.sa_handler = (sighandler_t) catch14;     /* fudge */
+  if (sigaction(SIGSEGV, &act, (struct sigaction *) NULL) == -1) e(3);
+  if (kill(getpid(), SIGSEGV) == -1) e(4);
+
+  if (x != 1) e(5);
+  if (y != 1) e(6);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Test for setjmp/longjmp.
+ *
+ * Catch a signal.  Longjmp out of signal handler.
+ */
+jmp_buf glo_jb;
+
+void catch15(signo)
+int signo;
+{
+  z++;
+  longjmp(glo_jb, 7);
+  e(1);
+
+}
+
+void test37o()
+{
+  struct sigaction act;
+  int k;
+
+  subtest = 15;
+  clearsigstate();
+  z = 0;
+
+  act.sa_flags = 0;
+  act.sa_mask = 0;
+  act.sa_handler = catch15;
+  if (sigaction(SIGALRM, &act, (struct sigaction *) NULL) == -1) e(2);
+
+  if ((k = setjmp(glo_jb))) {
+       if (z != 1) e(399);
+       if (k != 7) e(4);
+       return;
+  }
+  if (kill(getpid(), SIGALRM) == -1) e(5);
+}
+
+void clearsigstate()
+{
+  int i;
+  sigset_t sigset_var;
+
+  /* Clear the signal state. */
+  for (i = 1; i <= _NSIG; i++) signal(i, SIG_IGN);
+  for (i = 1; i <= _NSIG; i++) signal(i, SIG_DFL);
+  sigfillset(&sigset_var);
+  sigprocmask(SIG_UNBLOCK, &sigset_var, (sigset_t *)NULL);
 }
 
 void quit()
 {
+
+  chdir("..");
+  system("rm -rf DIR*");
+
   if (errct == 0) {
        printf("ok\n");
        exit(0);
   } else {
        printf("%d errors\n", errct);
+       exit(4);
+  }
+}
+
+void wait_for(pid)
+pid_t pid;
+{
+/* Expect exactly one child, and that it exits with 0. */
+
+  int r;
+  int status;
+
+  errno = 0;
+  while (1) {
+       errno = 0;
+       r = wait(&status);
+       if (r == pid) {
+               errno = 0;
+               if (status != 0) e(90);
+               return;
+       }
+       if (r < 0) {
+               e(91);
+               return;
+       }
+       e(92);
+  }
+}
+
+void e(n)
+int n;
+{
+  char msgbuf[80];
+
+  sprintf(msgbuf, "Subtest %d,  error %d  errno=%d  ", subtest, n, errno);
+  perror(msgbuf);
+  if (errct++ > MAX_ERROR) {
+       fprintf(stderr, "Too many errors;  test aborted\n");
+       chdir("..");
+       system("rm -rf DIR*");
        exit(1);
   }
 }
index f16bdfef36332b47cc0d043336f1dba68d3765c9..9eb215f20324d6c23609e455b3bdbca9a1164952 100644 (file)
-/* test 8 - signals */
+/* test8: pipe()               Author: Jan-Mark Wams (jms@cs.vu.nl) */
 
 #include <sys/types.h>
-#include <sys/times.h>
-#ifdef _MINIX
-#include <sys/sigcontext.h>
-#endif
+#include <sys/stat.h>
 #include <sys/wait.h>
-#include <errno.h>
-#include <signal.h>
-#include <setjmp.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <time.h>
 #include <stdio.h>
 
-#define ITERATIONS 2
-#define SIGS 14
-#define MAX_ERROR 4
+#define MAX_ERROR      4
+#define ITERATIONS     60
 
-int iteration, cumsig, subtest, errct = 0, sig1, sig2;
+#define Fstat(a,b)     if (fstat(a,b) != 0) printf("Can't fstat %d\n", a)
+#define Time(t)                if (time(t) == (time_t)-1) printf("Time error\n")
 
-int sigarray[SIGS] = {SIGHUP, SIGILL, SIGTRAP, SIGABRT, SIGIOT, SIGUNUSED,
-             SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM,
-             SIGTERM};
+int errct = 0;
+int subtest = 1;
+char MaxName[NAME_MAX + 1];    /* Name of maximum length */
+char MaxPath[PATH_MAX];                /* Same for path */
+char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
+char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
 
-/* Prototypes produced automatically by mkptypes. */
-_PROTOTYPE(int main, (int argc, char *argv []));
+_PROTOTYPE(void main, (int argc, char *argv[]));
 _PROTOTYPE(void test8a, (void));
-_PROTOTYPE(void func1, (int sig));
-_PROTOTYPE(void func2, (int sig));
 _PROTOTYPE(void test8b, (void));
-_PROTOTYPE(void catch1, (int signo));
-_PROTOTYPE(void catch2, (int signo));
-_PROTOTYPE(void test8c, (void));
-_PROTOTYPE(void catch3, (int signo));
-_PROTOTYPE(void test8d, (void));
-_PROTOTYPE(void catch4, (int signo));
-_PROTOTYPE(void test8e, (void));
-_PROTOTYPE(void catch5, (int signo));
-_PROTOTYPE(void test8f, (void));
-_PROTOTYPE(void sigint_handler, (int signo));
-_PROTOTYPE(void sigpipe_handler, (int signo));
-_PROTOTYPE(void test8g, (void));
-_PROTOTYPE(void sighup8, (int signo));
-_PROTOTYPE(void sigpip8, (int signo));
-_PROTOTYPE(void sigter8, (int signo));
-_PROTOTYPE(void test8h, (void));
-_PROTOTYPE(void sighup9, (int signo));
-_PROTOTYPE(void sigter9, (int signo));
-_PROTOTYPE(void test8i, (void));
-_PROTOTYPE(void sighup10, (int signo));
-_PROTOTYPE(void sigalrm_handler10, (int signo));
-_PROTOTYPE(void test8j, (void));
-_PROTOTYPE(void test8k, (void));
-_PROTOTYPE(void test8l, (void));
-_PROTOTYPE(void func_m1, (void));
-_PROTOTYPE(void func_m2, (void));
-_PROTOTYPE(void test8m, (void));
-_PROTOTYPE(void longjerr, (void));
-_PROTOTYPE(void catch14, (int signo, int code, struct sigcontext * scp));
-_PROTOTYPE(void test8n, (void));
-_PROTOTYPE(void catch15, (int signo));
-_PROTOTYPE(void test8o, (void));
-_PROTOTYPE(void clearsigstate, (void));
+_PROTOTYPE(void e, (int number));
 _PROTOTYPE(void quit, (void));
-_PROTOTYPE(void wait_for, (int pid));
-_PROTOTYPE(void e, (int n));
 
-int main(argc, argv)
+void main(argc, argv)
 int argc;
 char *argv[];
 {
   int i, m = 0xFFFF;
 
   sync();
-
   if (argc == 2) m = atoi(argv[1]);
-
   printf("Test  8 ");
-  fflush(stdout);              /* have to flush for child's benefit */
-
-  system("rm -rf DIR_08; mkdir DIR_08");
-  chdir("DIR_08");
+  fflush(stdout);
 
   for (i = 0; i < ITERATIONS; i++) {
-       iteration = i;
-       if (m & 0000001) test8a();
-       if (m & 0000002) test8b();
-       if (m & 0000004) test8c();
-       if (m & 0000010) test8d();
-       if (m & 0000020) test8e();
-       if (m & 0000040) test8f();
-       if (m & 0000100) test8g();
-       if (m & 0000200) test8h();
-       if (m & 0000400) test8i();
-       if (m & 0001000) test8j();
-       if (m & 0002000) test8k();
-       if (m & 0004000) test8l();
-       if (m & 0010000) test8m();
-       if (m & 0020000) test8n();
-       if (m & 0040000) test8o();
+       if (m & 0001) test8a();
+       if (m & 0002) test8b();
   }
-
   quit();
-  return(-1);                  /* impossible */
 }
 
 void test8a()
-{
-/* Test signal set management. */
-
-  sigset_t s;
+{                              /* Test fcntl flags. */
+  int tube[2], t1[2], t2[2], t3[2];
+  time_t time1, time2;
+  char buf[128];
+  struct stat st1, st2;
+  int stat_loc, flags;
 
   subtest = 1;
-  clearsigstate();
-
-  /* Create an empty set and see if any bits are on. */
-  if (sigemptyset(&s) != 0) e(1);
-  if (sigismember(&s, SIGHUP) != 0) e(2);
-  if (sigismember(&s, SIGINT) != 0) e(3);
-  if (sigismember(&s, SIGQUIT) != 0) e(4);
-  if (sigismember(&s, SIGILL) != 0) e(5);
-  if (sigismember(&s, SIGTRAP) != 0) e(6);
-  if (sigismember(&s, SIGABRT) != 0) e(7);
-  if (sigismember(&s, SIGIOT) != 0) e(8);
-  if (sigismember(&s, SIGUNUSED) != 0) e(9);
-  if (sigismember(&s, SIGFPE) != 0) e(10);
-  if (sigismember(&s, SIGKILL) != 0) e(11);
-  if (sigismember(&s, SIGUSR1) != 0) e(12);
-  if (sigismember(&s, SIGSEGV) != 0) e(13);
-  if (sigismember(&s, SIGUSR2) != 0) e(14);
-  if (sigismember(&s, SIGPIPE) != 0) e(15);
-  if (sigismember(&s, SIGALRM) != 0) e(16);
-  if (sigismember(&s, SIGTERM) != 0) e(17);
-
-  /* Create a full set and see if any bits are off. */
-  if (sigfillset(&s) != 0) e(19);
-  if (sigemptyset(&s) != 0) e(20);
-  if (sigfillset(&s) != 0) e(21);
-  if (sigismember(&s, SIGHUP) != 1) e(22);
-  if (sigismember(&s, SIGINT) != 1) e(23);
-  if (sigismember(&s, SIGQUIT) != 1) e(24);
-  if (sigismember(&s, SIGILL) != 1) e(25);
-  if (sigismember(&s, SIGTRAP) != 1) e(26);
-  if (sigismember(&s, SIGABRT) != 1) e(27);
-  if (sigismember(&s, SIGIOT) != 1) e(28);
-  if (sigismember(&s, SIGUNUSED) != 1) e(29);
-  if (sigismember(&s, SIGFPE) != 1) e(30);
-  if (sigismember(&s, SIGKILL) != 1) e(31);
-  if (sigismember(&s, SIGUSR1) != 1) e(32);
-  if (sigismember(&s, SIGSEGV) != 1) e(33);
-  if (sigismember(&s, SIGUSR2) != 1) e(34);
-  if (sigismember(&s, SIGPIPE) != 1) e(35);
-  if (sigismember(&s, SIGALRM) != 1) e(36);
-  if (sigismember(&s, SIGTERM) != 1) e(37);
-
-  /* Create an empty set, then turn on bits individually. */
-  if (sigemptyset(&s) != 0) e(39);
-  if (sigaddset(&s, SIGHUP) != 0) e(40);
-  if (sigaddset(&s, SIGINT) != 0) e(41);
-  if (sigaddset(&s, SIGQUIT) != 0) e(42);
-  if (sigaddset(&s, SIGILL) != 0) e(43);
-  if (sigaddset(&s, SIGTRAP) != 0) e(44);
-
-  /* See if the bits just turned on are indeed on. */
-  if (sigismember(&s, SIGHUP) != 1) e(45);
-  if (sigismember(&s, SIGINT) != 1) e(46);
-  if (sigismember(&s, SIGQUIT) != 1) e(47);
-  if (sigismember(&s, SIGILL) != 1) e(48);
-  if (sigismember(&s, SIGTRAP) != 1) e(49);
-
-  /* The others should be turned off. */
-  if (sigismember(&s, SIGABRT) != 0) e(50);
-  if (sigismember(&s, SIGIOT) != 0) e(51);
-  if (sigismember(&s, SIGUNUSED) != 0) e(52);
-  if (sigismember(&s, SIGFPE) != 0) e(53);
-  if (sigismember(&s, SIGKILL) != 0) e(54);
-  if (sigismember(&s, SIGUSR1) != 0) e(55);
-  if (sigismember(&s, SIGSEGV) != 0) e(56);
-  if (sigismember(&s, SIGUSR2) != 0) e(57);
-  if (sigismember(&s, SIGPIPE) != 0) e(58);
-  if (sigismember(&s, SIGALRM) != 0) e(59);
-  if (sigismember(&s, SIGTERM) != 0) e(60);
-
-  /* Now turn them off and see if all are off. */
-  if (sigdelset(&s, SIGHUP) != 0) e(62);
-  if (sigdelset(&s, SIGINT) != 0) e(63);
-  if (sigdelset(&s, SIGQUIT) != 0) e(64);
-  if (sigdelset(&s, SIGILL) != 0) e(65);
-  if (sigdelset(&s, SIGTRAP) != 0) e(66);
 
-  if (sigismember(&s, SIGHUP) != 0) e(67);
-  if (sigismember(&s, SIGINT) != 0) e(68);
-  if (sigismember(&s, SIGQUIT) != 0) e(69);
-  if (sigismember(&s, SIGILL) != 0) e(70);
-  if (sigismember(&s, SIGTRAP) != 0) e(71);
-  if (sigismember(&s, SIGABRT) != 0) e(72);
-  if (sigismember(&s, SIGIOT) != 0) e(73);
-  if (sigismember(&s, SIGUNUSED) != 0) e(74);
-  if (sigismember(&s, SIGFPE) != 0) e(75);
-  if (sigismember(&s, SIGKILL) != 0) e(76);
-  if (sigismember(&s, SIGUSR1) != 0) e(77);
-  if (sigismember(&s, SIGSEGV) != 0) e(78);
-  if (sigismember(&s, SIGUSR2) != 0) e(79);
-  if (sigismember(&s, SIGPIPE) != 0) e(80);
-  if (sigismember(&s, SIGALRM) != 0) e(81);
-  if (sigismember(&s, SIGTERM) != 0) e(82);
-}
-
-void func1(sig)
-int sig;
-{
-  sig1++;
-}
-
-void func2(sig)
-int sig;
-{
-  sig2++;
+  /* Check if lowest fds are returned. */
+  if (pipe(tube) != 0) e(1);
+  if (tube[0] != 3 && tube[1] != 3) e(2);
+  if (tube[1] != 4 && tube[0] != 4) e(3);
+  if (tube[1] == tube[0]) e(4);
+  if (pipe(t1) != 0) e(5);
+  if (t1[0] != 5 && t1[1] != 5) e(6);
+  if (t1[1] != 6 && t1[0] != 6) e(7);
+  if (t1[1] == t1[0]) e(8);
+  if (close(t1[0]) != 0) e(9);
+  if (close(tube[0]) != 0) e(10);
+  if (pipe(t2) != 0) e(11);
+  if (t2[0] != tube[0] && t2[1] != tube[0]) e(12);
+  if (t2[1] != t1[0] && t2[0] != t1[0]) e(13);
+  if (t2[1] == t2[0]) e(14);
+  if (pipe(t3) != 0) e(15);
+  if (t3[0] != 7 && t3[1] != 7) e(16);
+  if (t3[1] != 8 && t3[0] != 8) e(17);
+  if (t3[1] == t3[0]) e(18);
+  if (close(tube[1]) != 0) e(19);
+  if (close(t1[1]) != 0) e(20);
+  if (close(t2[0]) != 0) e(21);
+  if (close(t2[1]) != 0) e(22);
+  if (close(t3[0]) != 0) e(23);
+  if (close(t3[1]) != 0) e(24);
+
+  /* All time fields should be marked for update. */
+  Time(&time1);
+  if (pipe(tube) != 0) e(25);
+  Fstat(tube[0], &st1);
+  Fstat(tube[1], &st2);
+  Time(&time2);
+  if (st1.st_atime < time1) e(26);
+  if (st1.st_ctime < time1) e(27);
+  if (st1.st_mtime < time1) e(28);
+  if (st1.st_atime > time2) e(29);
+  if (st1.st_ctime > time2) e(30);
+  if (st1.st_mtime > time2) e(31);
+  if (st2.st_atime < time1) e(32);
+  if (st2.st_ctime < time1) e(33);
+  if (st2.st_mtime < time1) e(34);
+  if (st2.st_atime > time2) e(35);
+  if (st2.st_ctime > time2) e(36);
+  if (st2.st_mtime > time2) e(37);
+
+  /* Check the file characteristics. */
+  if ((flags = fcntl(tube[0], F_GETFD)) != 0) e(38);
+  if ((flags & FD_CLOEXEC) != 0) e(39);
+  if ((flags = fcntl(tube[0], F_GETFL)) != 0) e(40);
+  if ((flags & O_RDONLY) != O_RDONLY) e(41);
+  if ((flags & O_NONBLOCK) != 0) e(42);
+  if ((flags & O_RDWR) != 0) e(43);
+  if ((flags & O_WRONLY) != 0) e(44);
+
+  if ((flags = fcntl(tube[1], F_GETFD)) != 0) e(45);
+  if ((flags & FD_CLOEXEC) != 0) e(46);
+  if ((flags = fcntl(tube[1], F_GETFL)) == -1) e(47);
+  if ((flags & O_WRONLY) != O_WRONLY) e(48);
+  if ((flags & O_NONBLOCK) != 0) e(49);
+  if ((flags & O_RDWR) != 0) e(50);
+  if ((flags & O_RDONLY) != 0) e(51);
+
+  /* Check if we can read and write. */
+  switch (fork()) {
+      case -1: printf("Can't fork\n"); break;
+      case 0:
+       alarm(20);
+       if (close(tube[0]) != 0) e(52);
+       if (write(tube[1], "Hello", 6) != 6) e(53);
+       if (close(tube[1]) != 0) e(54);
+       exit(0);
+      default:
+       if (read(tube[0], buf, sizeof(buf)) != 6) e(55);
+       if (strncmp(buf, "Hello", 6) != 0) e(56);
+       wait(&stat_loc);
+       if (stat_loc != 0) e(57);       /* Alarm? */
+  }
+  if (close(tube[0]) != 0) e(58);
+  if (close(tube[1]) != 0) e(59);
 }
 
 void test8b()
 {
-/* Test sigprocmask and sigpending. */
-  int i;
-  pid_t p;
-  sigset_t s, s1, s_empty, s_full, s_ill, s_ill_pip, s_nokill;
-  struct sigaction sa, osa;
+  int tube[2], child2parent[2], parent2child[2];
+  int i, nchild = 0, nopen = 3, stat_loc;
+  int fd;
+  int forkfailed = 0;
+  char c;
 
   subtest = 2;
-  clearsigstate();
-
-  /* Construct s_ill = {SIGILL} and s_ill_pip {SIGILL | SIGPIP}, etc. */
-  if (sigemptyset(&s_empty) != 0) e(1);
-  if (sigemptyset(&s_ill) != 0) e(2);
-  if (sigemptyset(&s_ill_pip) != 0) e(3);
-  if (sigaddset(&s_ill, SIGILL) != 0) e(4);
-  if (sigaddset(&s_ill_pip, SIGILL) != 0) e(5);
-  if (sigaddset(&s_ill_pip, SIGPIPE) != 0) e(6);
-  if (sigfillset(&s_full) != 0) e(7);
-  s_nokill = s_full;
-  if (sigdelset(&s_nokill, SIGKILL) != 0) e(8);
-#ifndef _MINIX /* XXX - should unsupported signals be <= _NSIG? */
-  if (SIGSTOP > _NSIG) e(666);
-  if (SIGSTOP <= _NSIG && sigdelset(&s_nokill, SIGSTOP) != 0) e(888);
-#endif /* _MINIX */
-
-  /* Now get most of the signals into default state.  Don't change SIGINT
-  * or SIGQUIT, so this program can be killed.  SIGKILL is also special.
-  */
-  sa.sa_handler = SIG_DFL;
-  sa.sa_mask = s_empty;
-  sa.sa_flags = 0;
-  for (i = 0; i < SIGS; i++) sigaction(i, &sa, &osa);
-
-  /* The second argument may be zero.  See if it wipes out the system. */
-  for (i = 0; i < SIGS; i++) sigaction(i, (struct sigaction *) NULL, &osa);
-
-  /* Install a signal handler. */
-  sa.sa_handler = func1;
-  sa.sa_mask = s_ill;
-  sa.sa_flags = SA_NODEFER | SA_NOCLDSTOP;
-  osa.sa_handler = SIG_IGN;
-  osa.sa_mask = s_empty;
-  osa.sa_flags = 0;
-  if (sigaction(SIGHUP, &sa, &osa) != 0) e(9);
-  if (osa.sa_handler != SIG_DFL) e(10);
-  if (osa.sa_mask != 0) e(11);
-  if (osa.sa_flags != s_empty) e(12);
-
-  /* Replace action and see if old value is read back correctly. */
-  sa.sa_handler = func2;
-  sa.sa_mask = s_ill_pip;
-  sa.sa_flags = SA_RESETHAND | SA_NODEFER;
-  osa.sa_handler = SIG_IGN;
-  osa.sa_mask = s_empty;
-  osa.sa_flags = 0;
-  if (sigaction(SIGHUP, &sa, &osa) != 0) e(13);
-  if (osa.sa_handler != func1) e(14);
-  if (osa.sa_mask != s_ill) e(15);
-  if (osa.sa_flags != SA_NODEFER
-      && osa.sa_flags != (SA_NODEFER | SA_NOCLDSTOP)) e(16);
-
-  /* Replace action once more and check what is read back. */
-  sa.sa_handler = SIG_DFL;
-  sa.sa_mask = s_empty;
-  osa.sa_handler = SIG_IGN;
-  osa.sa_mask = s_empty;
-  osa.sa_flags = 0;
-  if (sigaction(SIGHUP, &sa, &osa) != 0) e(17);
-  if (osa.sa_handler != func2) e(18);
-  if (osa.sa_mask != s_ill_pip) e(19);
-  if (osa.sa_flags != (SA_RESETHAND | SA_NODEFER)) e(20);
-
-  /* Test sigprocmask(SIG_SETMASK, ...). */
-  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(18);    /* block all */
-  if (sigemptyset(&s1) != 0) e(19);
-  if (sigprocmask(SIG_SETMASK, &s_empty, &s1) != 0) e(20);   /* block none */
-  if (s1 != s_nokill) e(21);
-  if (sigprocmask(SIG_SETMASK, &s_ill, &s1) != 0) e(22);     /* block SIGILL */
-  if (s1 != s_empty) e(23);
-  if (sigprocmask(SIG_SETMASK, &s_ill_pip, &s1) != 0) e(24); /* SIGILL+PIP */
-  if (s1 != s_ill) e(25);
-  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(26);    /* block all */
-  if (s1 != s_ill_pip) e(27);
-
-  /* Test sigprocmask(SIG_UNBLOCK, ...) */
-  if (sigprocmask(SIG_UNBLOCK, &s_ill, &s1) != 0) e(28);
-  if (s1 != s_nokill) e(29);
-  if (sigprocmask(SIG_UNBLOCK, &s_ill_pip, &s1) != 0) e(30);
-  s = s_nokill;
-  if (sigdelset(&s, SIGILL) != 0) e(31);
-  if (s != s1) e(32);
-  if (sigprocmask(SIG_UNBLOCK, &s_empty, &s1) != 0) e(33);
-  s = s_nokill;
-  if (sigdelset(&s, SIGILL) != 0) e(34);
-  if (sigdelset(&s, SIGPIPE) != 0) e(35);
-  if (s != s1) e(36);
-  s1 = s_nokill;
-  if (sigprocmask(SIG_SETMASK, &s_empty, &s1) != 0) e(37);
-  if (s != s1) e(38);
-
-  /* Test sigprocmask(SIG_BLOCK, ...) */
-  if (sigprocmask(SIG_BLOCK, &s_ill, &s1) != 0) e(39);
-  if (s1 != s_empty) e(40);
-  if (sigprocmask(SIG_BLOCK, &s_ill_pip, &s1) != 0) e(41);
-  if (s1 != s_ill) e(42);
-  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(43);
-  if (s1 != s_ill_pip) e(44);
-
-  /* Check error condition. */
-  errno = 0;
-  if (sigprocmask(20000, &s_full, &s1) != -1) e(45);
-  if (errno != EINVAL) e(46);
-  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(47);
-  if (s1 != s_nokill) e(48);
-
-  /* If second arg is 0, nothing is set. */
-  if (sigprocmask(SIG_SETMASK, (sigset_t *) NULL, &s1) != 0) e(49);
-  if (s1 != s_nokill) e(50);
-  if (sigprocmask(SIG_SETMASK, &s_ill_pip, &s1) != 0) e(51);
-  if (s1 != s_nokill) e(52);
-  if (sigprocmask(SIG_SETMASK, (sigset_t *) NULL, &s1) != 0) e(53);
-  if (s1 != s_ill_pip) e(54);
-  if (sigprocmask(SIG_BLOCK, (sigset_t *) NULL, &s1) != 0) e(55);
-  if (s1 != s_ill_pip) e(56);
-  if (sigprocmask(SIG_UNBLOCK, (sigset_t *) NULL, &s1) != 0) e(57);
-  if (s1 != s_ill_pip) e(58);
-
-  /* Trying to block SIGKILL is not allowed, but is not an error, either. */
-  s = s_empty;
-  if (sigaddset(&s, SIGKILL) != 0) e(59);
-  if (sigprocmask(SIG_BLOCK, &s, &s1) != 0) e(60);
-  if (s1 != s_ill_pip) e(61);
-  if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(62);
-  if (s1 != s_ill_pip) e(63);
-
-  /* Test sigpending. At this moment, all signals are blocked. */
-  sa.sa_handler = func2;
-  sa.sa_mask = s_empty;
-  if (sigaction(SIGHUP, &sa, &osa) != 0) e(64);
-  p = getpid();
-  kill(p, SIGHUP);             /* send SIGHUP to self */
-  if (sigpending(&s) != 0) e(65);
-  if (sigemptyset(&s1) != 0) e(66);
-  if (sigaddset(&s1, SIGHUP) != 0) e(67);
-  if (s != s1) e(68);
-  sa.sa_handler = SIG_IGN;
-  if (sigaction(SIGHUP, &sa, &osa) != 0) e(69);
-  if (sigpending(&s) != 0) e(70);
-  if (s != s_empty) e(71);
-}
-
-/*---------------------------------------------------------------------------*/
-int x;
-sigset_t glo_vol_set;
-
-void catch1(signo)
-int signo;
-{
-  x = 42;
-}
-
-void catch2(signo)
-int signo;
-{
-  if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, (sigset_t *) &glo_vol_set) != 0)
-       e(1);
-}
-
-/* Verify that signal(2), which is now built on top of sigaction(2), still
-* works.
-*/
-void test8c()
-{
-  pid_t pid;
-  sigset_t sigset_var;
-
-  subtest = 3;
-  clearsigstate();
-  x = 0;
-
-  /* Verify an installed signal handler persists across a fork(2). */
-  if (signal(SIGTERM, catch1) == SIG_ERR) e(1);
-  switch (pid = fork()) {
-      case 0:                  /* child */
-       errct = 0;
-       while (x == 0);
-       if (x != 42) e(2);
-       exit(errct == 0 ? 0 : 1);
-      case -1: e(3);   break;
-      default:                 /* parent */
-       sleep(1);
-       if (kill(pid, SIGTERM) != 0) e(4);
-       wait_for(pid);
-       break;
-  }
-
-  /* Verify that the return value is the previous handler. */
-  signal(SIGINT, SIG_IGN);
-  if (signal(SIGINT, catch2) != SIG_IGN) e(5);
-  if (signal(SIGINT, catch1) != catch2) e(6);
-  if (signal(SIGINT, SIG_DFL) != catch1) e(7);
-  if (signal(SIGINT, catch1) != SIG_DFL) e(8);
-  if (signal(SIGINT, SIG_DFL) != catch1) e(9);
-  if (signal(SIGINT, SIG_DFL) != SIG_DFL) e(10);
-  if (signal(SIGINT, catch1) != SIG_DFL) e(11);
-
-  /* Verify that SIG_ERR is correctly generated. */
-  if (signal(_NSIG + 1, catch1) != SIG_ERR) e(12);
-  if (signal(0, catch1) != SIG_ERR) e(13);
-  if (signal(-1, SIG_DFL) != SIG_ERR) e(14);
-
-  /* Verify that caught signals are automatically reset to the default,
-   * and that further instances of the same signal are not blocked here
-   * or in the signal handler.
-   */
-  if (signal(SIGTERM, catch1) == SIG_ERR) e(15);
-  switch ((pid = fork())) {
-      case 0:                  /* child */
-       errct = 0;
-       while (x == 0);
-       if (x != 42) e(16);
-       if (sigismember((sigset_t *) &glo_vol_set, SIGTERM)) e(17);
-       if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &sigset_var) != 0) e(18);
-       if (sigismember(&sigset_var, SIGTERM)) e(19);
-
-#if 0
-/* Use this if you have compiled signal() to have the broken SYSV behaviour. */
-       if (signal(SIGTERM, catch1) != SIG_DFL) e(20);
-#else
-       if (signal(SIGTERM, catch1) != catch1) e(20);
-#endif
-       exit(errct == 0 ? 0 : 1);
-      default:                 /* parent */
-       sleep(1);
-       if (kill(pid, SIGTERM) != 0) e(21);
-       wait_for(pid);
-       break;
-      case -1: e(22);  break;
-  }
-}
-
-/*---------------------------------------------------------------------------*/
-/* Test that the signal handler can be invoked recursively with the
-* state being properly saved and restored.
-*/
 
-static int y;
-static int z;
-
-void catch3(signo)
-int signo;
-{
-  if (z == 1) {                        /* catching a nested signal */
-       y = 2;
-       return;
-  }
-  z = 1;
-  if (kill(getpid(), SIGHUP) != 0) e(1);
-  while (y != 2);
-  y = 1;
-}
-
-void test8d()
-{
-  struct sigaction act;
-
-  subtest = 4;
-  clearsigstate();
-  y = 0;
-  z = 0;
-
-  act.sa_handler = catch3;
-  act.sa_mask = 0;
-  act.sa_flags = SA_NODEFER;   /* Otherwise, nested occurence of
-                                * SIGINT is blocked. */
-  if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) != 0) e(2);
-  if (kill(getpid(), SIGHUP) != 0) e(3);
-  if (y != 1) e(4);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/* Test that the signal mask in effect for the duration of a signal handler
-* is as specified in POSIX Section 3, lines 718 -724.  Test that the
-* previous signal mask is restored when the signal handler returns.
-*/
-
-void catch4(signo)
-int signo;
-{
-  sigset_t oset;
-  sigset_t set;
-
-  if (sigemptyset(&set) == -1) e(5001);
-  if (sigaddset(&set, SIGTERM) == -1) e(5002);
-  if (sigaddset(&set, SIGHUP) == -1) e(5003);
-  if (sigaddset(&set, SIGINT) == -1) e(5004);
-  if (sigaddset(&set, SIGPIPE) == -1) e(5005);
-  if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset) != 0) e(5006);
-  if (oset != set) e(5007);
-}
-
-void test8e()
-{
-  struct sigaction act, oact;
-  sigset_t set, oset;
-
-  subtest = 5;
-  clearsigstate();
-
-  act.sa_handler = catch4;
-  sigemptyset(&act.sa_mask);
-  sigaddset(&act.sa_mask, SIGTERM);
-  sigaddset(&act.sa_mask, SIGHUP);
-  act.sa_flags = 0;
-  if (sigaction(SIGINT, &act, &oact) == -1) e(2);
-
-  if (sigemptyset(&set) == -1) e(3);
-  if (sigaddset(&set, SIGPIPE) == -1) e(4);
-  if (sigprocmask(SIG_SETMASK, &set, &oset) == -1) e(5);
-  if (kill(getpid(), SIGINT) == -1) e(6);
-  if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset) == -1) e(7);
-  if (sigemptyset(&set) == -1) e(8);
-  if (sigaddset(&set, SIGPIPE) == -1) e(9);
-  if (set != oset) e(10);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/* Test the basic functionality of sigsuspend(2). */
-
-void catch5(signo)
-int signo;
-{
-  x = 1;
-}
-
-void test8f()
-{
-  sigset_t set;
-  int r;
-  struct sigaction act;
-  pid_t pid;
-
-  subtest = 6;
-  clearsigstate();
-
-  switch (pid = fork()) {
-      case 0:                  /* child */
-       errct = 0;
-       sleep(1);
-       if (kill(getppid(), SIGINT) == -1) e(1);
-       exit(errct == 0 ? 0 : 1);
-      case -1: e(2);   break;
-      default:                 /* parent */
-       if (sigemptyset(&act.sa_mask) == -1) e(3);
-       act.sa_flags = 0;
-       act.sa_handler = catch5;
-       if (sigaction(SIGINT, &act, (struct sigaction *) NULL) == -1) e(4);
-
-       if (sigemptyset(&set) == -1) e(5);
-       r = sigsuspend(&set);
-
-       if (r != -1 || errno != EINTR || x != 1) e(6);
-       wait_for(pid);
-       break;
+  /* Take all the pipes we can get. */
+  while (nopen < OPEN_MAX - 2) {
+       if (pipe(tube) != 0) {
+               /* We have not reached OPEN_MAX yet, so we have ENFILE. */
+               if (errno != ENFILE) e(1);
+               sleep(2);       /* Wait for others to (maybe) closefiles. */
+               break;
+       }
+       nopen += 2;
   }
-}
-
-/*----------------------------------------------------------------------*/
-
-/* Test that sigsuspend() does block the signals specified in its
-* argument, and after sigsuspend returns, the previous signal
-* mask is restored.
-*
-* The child sends two signals to the parent SIGINT and then SIGPIPE,
-* separated by a long delay.  The parent executes sigsuspend() with
-* SIGINT blocked.  It is expected that the parent's SIGPIPE handler
-* will be invoked, then sigsuspend will return restoring the
-* original signal mask, and then the SIGPIPE handler will be
-* invoked.
-*/
-
-void sigint_handler(signo)
-int signo;
-{
-  x = 1;
-  z++;
-}
-
-void sigpipe_handler(signo)
-int signo;
-{
-  x = 2;
-  z++;
-}
 
-void test8g()
-{
-  sigset_t set;
-  int r;
-  struct sigaction act;
-  pid_t pid;
-
-  subtest = 7;
-  clearsigstate();
-  x = 0;
-  z = 0;
-
-  switch (pid = fork()) {
-      case 0:                  /* child */
-       errct = 0;
-       sleep(1);
-       if (kill(getppid(), SIGINT) == -1) e(1);
-       sleep(1);
-       if (kill(getppid(), SIGPIPE) == -1) e(2);
-       exit(errct == 0 ? 0 : 1);
-      case -1: e(3);   break;
-      default:                 /* parent */
-       if (sigemptyset(&act.sa_mask) == -1) e(3);
-       act.sa_flags = 0;
-       act.sa_handler = sigint_handler;
-       if (sigaction(SIGINT, &act, (struct sigaction *) NULL) == -1) e(4);
-
-       act.sa_handler = sigpipe_handler;
-       if (sigaction(SIGPIPE, &act, (struct sigaction *) NULL) == -1) e(5);
-
-       if (sigemptyset(&set) == -1) e(6);
-       if (sigaddset(&set, SIGINT) == -1) e(7);
-       r = sigsuspend(&set);
-       if (r != -1) e(8);
-       if (errno != EINTR) e(9);
-       if (z != 2) e(10);
-       if (x != 1) e(11);
-       wait_for(pid);
-       break;
+  if (nopen < OPEN_MAX - 2) {
+       if (pipe(tube) != -1) e(2);
+       switch (errno) {
+           case EMFILE:        /* Errno value is ok. */
+               break;
+           case ENFILE:        /* No process can open files any more. */
+               switch (fork()) {
+                   case -1:
+                       printf("Can't fork\n");
+                       break;
+                   case 0:
+                       alarm(20);
+                       if (open("/", O_RDONLY) != -1) e(3);
+                       if (errno != ENFILE) e(4);
+                       exit(0);
+                   default:
+                       wait(&stat_loc);
+                       if (stat_loc != 0) e(5);        /* Alarm? */
+               }
+               break;
+           default:            /* Wrong value for errno. */
+               e(6);
+       }
   }
-}
 
-/*--------------------------------------------------------------------------*/
-
-/* Test that sigsuspend() does block the signals specified in its
-* argument, and after sigsuspend returns, the previous signal
-* mask is restored.
-*
-* The child sends three signals to the parent: SIGHUP, then SIGPIPE,
-* and then SIGTERM, separated by a long delay.  The parent executes
-* sigsuspend() with SIGHUP and SIGPIPE blocked.  It is expected that
-* the parent's SIGTERM handler will be invoked first, then sigsuspend()
-* will return restoring the original signal mask, and then the other
-* two handlers will be invoked.
-*/
-
-void sighup8(signo)
-int signo;
-{
-  x = 1;
-  z++;
-}
-
-void sigpip8(signo)
-int signo;
-{
-  x = 1;
-  z++;
-}
-
-void sigter8(signo)
-int signo;
-{
-  x = 2;
-  z++;
-}
-
-void test8h()
-{
-  sigset_t set;
-  int r;
-  struct sigaction act;
-  pid_t pid;
-
-  subtest = 8;
-  clearsigstate();
-  x = 0;
-  z = 0;
-
-  switch (pid = fork()) {
-      case 0:                  /* child */
-       errct = 0;
-       sleep(1);
-       if (kill(getppid(), SIGHUP) == -1) e(1);
-       sleep(1);
-       if (kill(getppid(), SIGPIPE) == -1) e(2);
-       sleep(1);
-       if (kill(getppid(), SIGTERM) == -1) e(3);
-       exit(errct == 0 ? 0 : 1);
-      case -1: e(5);   break;
-      default:                 /* parent */
-       if (sigemptyset(&act.sa_mask) == -1) e(6);
-       act.sa_flags = 0;
-       act.sa_handler = sighup8;
-       if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(7);
-
-       act.sa_handler = sigpip8;
-       if (sigaction(SIGPIPE, &act, (struct sigaction *) NULL) == -1) e(8);
-
-       act.sa_handler = sigter8;
-       if (sigaction(SIGTERM, &act, (struct sigaction *) NULL) == -1) e(9);
-
-       if (sigemptyset(&set) == -1) e(10);
-       if (sigaddset(&set, SIGHUP) == -1) e(11);
-       if (sigaddset(&set, SIGPIPE) == -1) e(12);
-       r = sigsuspend(&set);
-       if (r != -1) e(13);
-       if (errno != EINTR) e(14);
-       if (z != 3) e(15);
-       if (x != 1) e(16);
-       wait_for(pid);
-       break;
+  /* Close all but stdin,out,err. */
+  for (i = 3; i < OPEN_MAX; i++) (void) close(i);
+
+  /* ENFILE test. Have children each grab OPEN_MAX fds. */
+  if (pipe(child2parent) != 0) e(7);
+  if (pipe(parent2child) != 0) e(8);
+  while (!forkfailed && (fd = open("/", O_RDONLY)) != -1) {
+       close(fd);
+       switch (fork()) {
+           case -1:
+               forkfailed = 1;
+               break;
+           case 0:
+               alarm(60);
+
+               /* Grab all the fds. */
+               while (pipe(tube) != -1);
+               while (open("/", O_RDONLY) != -1);
+
+               /* Signal parent OPEN_MAX fds gone. */
+               if (write(child2parent[1], "*", 1) != 1) e(9);
+
+               /* Wait for parent befor freeing all the fds. */
+               if (read(parent2child[0], &c, 1) != 1) e(10);
+               exit(0);
+           default:
+
+               /* Wait for child to grab OPEN_MAX fds. */
+               if (read(child2parent[0], &c, 1) != 1) e(11);
+               nchild++;
+               break;
+       }
   }
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* Block SIGHUP and SIGTERM with sigprocmask(), send ourself SIGHUP
-* and SIGTERM, unblock these signals with sigprocmask, and verify
-* that these signals are delivered.
-*/
-
-void sighup9(signo)
-int signo;
-{
-  y++;
-}
-
-void sigter9(signo)
-int signo;
-{
-  z++;
-}
-
-void test8i()
-{
-  sigset_t set;
-  struct sigaction act;
-
-  subtest = 9;
-  clearsigstate();
-  y = 0;
-  z = 0;
-
-  if (sigemptyset(&act.sa_mask) == -1) e(1);
-  act.sa_flags = 0;
-
-  act.sa_handler = sighup9;
-  if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(2);
-
-  act.sa_handler = sigter9;
-  if (sigaction(SIGTERM, &act, (struct sigaction *) NULL) == -1) e(3);
-
-  if (sigemptyset(&set) == -1) e(4);
-  if (sigaddset(&set, SIGTERM) == -1) e(5);
-  if (sigaddset(&set, SIGHUP) == -1) e(6);
-  if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(7);
-
-  if (kill(getpid(), SIGHUP) == -1) e(8);
-  if (kill(getpid(), SIGTERM) == -1) e(9);
-  if (y != 0) e(10);
-  if (z != 0) e(11);
 
-  if (sigemptyset(&set) == -1) e(12);
-  if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(12);
-  if (y != 1) e(13);
-  if (z != 1) e(14);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/* Block SIGINT and then send this signal to ourself.
-*
-* Install signal handlers for SIGALRM and SIGINT.
-*
-* Set an alarm for 6 seconds, then sleep for 7.
-*
-* The SIGALRM should interrupt the sleep, but the SIGINT
-* should remain pending.
-*/
-
-void sighup10(signo)
-int signo;
-{
-  y++;
-}
-
-void sigalrm_handler10(signo)
-int signo;
-{
-  z++;
-}
-
-void test8j()
-{
-  sigset_t set, set2;
-  struct sigaction act;
-
-  subtest = 10;
-  clearsigstate();
-  y = 0;
-  z = 0;
-
-  if (sigemptyset(&act.sa_mask) == -1) e(1);
-  act.sa_flags = 0;
-
-  act.sa_handler = sighup10;
-  if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(2);
-
-  act.sa_handler = sigalrm_handler10;
-  if (sigaction(SIGALRM, &act, (struct sigaction *) NULL) == -1) e(3);
-
-  if (sigemptyset(&set) == -1) e(4);
-  if (sigaddset(&set, SIGHUP) == -1) e(5);
-  if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(6);
-
-  if (kill(getpid(), SIGHUP) == -1) e(7);
-  if (sigpending(&set) == -1) e(8);
-  if (sigemptyset(&set2) == -1) e(9);
-  if (sigaddset(&set2, SIGHUP) == -1) e(10);
-  if (set2 != set) e(11);
-  alarm(6);
-  sleep(7);
-  if (sigpending(&set) == -1) e(12);
-  if (set != set2) e(13);
-  if (y != 0) e(14);
-  if (z != 1) e(15);
-}
-
-/*--------------------------------------------------------------------------*/
-
-void test8k()
-{
-  subtest = 11;
-}
-void test8l()
-{
-  subtest = 12;
-}
-
-/*---------------------------------------------------------------------------*/
-
-/* Basic test for setjmp/longjmp.  This includes testing that the
-* signal mask is properly restored.
-*/
-
-void test8m()
-{
-  jmp_buf jb;
-  sigset_t ss;
-
-  subtest = 13;
-  clearsigstate();
-
-  ss = 0x32;
-  if (sigprocmask(SIG_SETMASK, &ss, (sigset_t *)NULL) == -1) e(1);
-  if (setjmp(jb)) {
-       if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &ss) == -1) e(2);
-       if (ss != 0x32) e(388);
-       return;
+  if (!forkfailed) {
+       if (pipe(tube) != -1) e(12);
+       if (errno != ENFILE) e(13);
   }
-  ss = 0x3abc;
-  if (sigprocmask(SIG_SETMASK, &ss, (sigset_t *)NULL) == -1) e(4);
-  longjmp(jb, 1);
-}
-
-void longjerr()
-{
-  e(5);
-}
-
-/*--------------------------------------------------------------------------*/
 
-/* Test for setjmp/longjmp.
-*
-* Catch a signal.  While in signal handler do setjmp/longjmp.
-*/
-
-void catch14(signo, code, scp)
-int signo;
-int code;
-struct sigcontext *scp;
-{
-  jmp_buf jb;
-
-  if (setjmp(jb)) {
-       x++;
-       sigreturn(scp);
-       e(1);
+  /* Signal children to die and wait for it. */
+  while (nchild-- > 0) {
+       if (write(parent2child[1], "*", 1) != 1) e(14);
+       wait(&stat_loc);
+       if (stat_loc != 0) e(15);       /* Alarm? */
   }
-  y++;
-  longjmp(jb, 1);
-  e(2);
-}
-
-void test8n()
-{
-  struct sigaction act;
-  typedef _PROTOTYPE( void (*sighandler_t), (int sig) );
-
-  subtest = 14;
-  clearsigstate();
-  x = 0;
-  y = 0;
-
-  act.sa_flags = 0;
-  act.sa_mask = 0;
-  act.sa_handler = (sighandler_t) catch14;     /* fudge */
-  if (sigaction(SIGSEGV, &act, (struct sigaction *) NULL) == -1) e(3);
-  if (kill(getpid(), SIGSEGV) == -1) e(4);
-
-  if (x != 1) e(5);
-  if (y != 1) e(6);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/* Test for setjmp/longjmp.
- *
- * Catch a signal.  Longjmp out of signal handler.
- */
-jmp_buf glo_jb;
-
-void catch15(signo)
-int signo;
-{
-  z++;
-  longjmp(glo_jb, 7);
-  e(1);
 
+  /* Close all but stdin,out,err. */
+  for (i = 3; i < OPEN_MAX; i++) (void) close(i);
 }
 
-void test8o()
+void e(n)
+int n;
 {
-  struct sigaction act;
-  int k;
-
-  subtest = 15;
-  clearsigstate();
-  z = 0;
-
-  act.sa_flags = 0;
-  act.sa_mask = 0;
-  act.sa_handler = catch15;
-  if (sigaction(SIGALRM, &act, (struct sigaction *) NULL) == -1) e(2);
+  int err_num = errno;         /* Save in case printf clobbers it. */
 
-  if ((k = setjmp(glo_jb))) {
-       if (z != 1) e(399);
-       if (k != 7) e(4);
-       return;
+  printf("Subtest %d,  error %d  errno=%d: ", subtest, n, errno);
+  errno = err_num;
+  perror("");
+  if (errct++ > MAX_ERROR) {
+       printf("Too many errors; test aborted\n");
+       chdir("..");
+       system("rm -rf DIR*");
+       exit(1);
   }
-  if (kill(getpid(), SIGALRM) == -1) e(5);
-}
-
-void clearsigstate()
-{
-  int i;
-  sigset_t sigset_var;
-
-  /* Clear the signal state. */
-  for (i = 1; i <= _NSIG; i++) signal(i, SIG_IGN);
-  for (i = 1; i <= _NSIG; i++) signal(i, SIG_DFL);
-  sigfillset(&sigset_var);
-  sigprocmask(SIG_UNBLOCK, &sigset_var, (sigset_t *)NULL);
+  errno = 0;
 }
 
 void quit()
 {
-
-  chdir("..");
-  system("rm -rf DIR*");
-
   if (errct == 0) {
        printf("ok\n");
        exit(0);
   } else {
        printf("%d errors\n", errct);
-       exit(4);
-  }
-}
-
-void wait_for(pid)
-pid_t pid;
-{
-/* Expect exactly one child, and that it exits with 0. */
-
-  int r;
-  int status;
-
-  errno = 0;
-  while (1) {
-       errno = 0;
-       r = wait(&status);
-       if (r == pid) {
-               errno = 0;
-               if (status != 0) e(90);
-               return;
-       }
-       if (r < 0) {
-               e(91);
-               return;
-       }
-       e(92);
-  }
-}
-
-void e(n)
-int n;
-{
-  char msgbuf[80];
-
-  sprintf(msgbuf, "Subtest %d,  error %d  errno=%d  ", subtest, n, errno);
-  perror(msgbuf);
-  if (errct++ > MAX_ERROR) {
-       fprintf(stderr, "Too many errors;  test aborted\n");
-       chdir("..");
-       system("rm -rf DIR*");
        exit(1);
   }
 }