/* sig7.c (emx+gcc) */

/* Test POSIX.1 signal handling. */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>

static char flag;
static sigjmp_buf jump;

static void handler (int sig)
{
  printf ("%d", sig);
  switch (flag)
    {
    case 'i':
      flag = 0;
      raise (SIGINT);
      putchar ('i');
      break;
    case 'j':
      flag = 0;
      siglongjmp (jump, 1);
      break;
    case 'u':
      flag = 0;
      putchar ('.');
      raise (SIGUSR1);
      putchar ('u');
      break;
    case 'r':
      flag = 0;
      raise (sig);
      putchar ('r');
      break;
    }
}


int main (int argc, char *argv[])
{
  struct sigaction sa;
  sigset_t set;

  setvbuf (stdout, NULL, _IONBF, 0);

  sa.sa_handler = handler;
  sa.sa_flags = 0;
  sigemptyset (&sa.sa_mask);
  if (sigaction (SIGINT, &sa, NULL) != 0)
    perror ("sigaction");

  sa.sa_handler = handler;
  sa.sa_flags = 0;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGINT);
  if (sigaction (SIGUSR1, &sa, NULL) != 0)
    perror ("sigaction");

  printf ("Expected output: +%d+%d+%dr%d!%d.%du!%di%d!-+%d+%d-+%d+%d+%d!\n",
          SIGINT, SIGINT, SIGINT, SIGINT, SIGINT, SIGUSR1, SIGUSR1, SIGINT,
          SIGINT, SIGINT, SIGINT, SIGINT, SIGINT);
  printf ("Actual output:   ");
  flag = 0;
  putchar ('+');
  raise (SIGINT);
  putchar ('+');
  raise (SIGINT);
  putchar ('+');
  flag = 'r';
  raise (SIGINT);
  putchar ('!');
  flag = 'u';
  raise (SIGINT);
  putchar ('!');
  flag = 'i';
  raise (SIGUSR1);
  putchar ('!');
  sigemptyset (&set);
  sigaddset (&set, SIGINT);
  sigprocmask (SIG_BLOCK, &set, NULL);
  flag = 0;
  putchar ('-');
  raise (SIGINT);
  putchar ('+');
  sigprocmask (SIG_UNBLOCK, &set, NULL);

  flag = 'j';
  putchar ('+');
  if (sigsetjmp (jump, 0) == 0)
    {
      raise (SIGINT);
      abort ();
    }
  putchar ('-');
  raise (SIGINT);
  putchar ('+');
  sigprocmask (SIG_UNBLOCK, &set, NULL);

  flag = 'j';
  putchar ('+');
  if (sigsetjmp (jump, 1) == 0)
    {
      raise (SIGINT);
      abort ();
    }
  putchar ('+');
  raise (SIGINT);

  putchar ('!');
  putchar ('\n');
  return 0;
}
