//  Pour la gestion des signaux a travers des exceptions
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include "psighand.h"
#include "pexceptions.h"

static bool sigprstate[6] = {false, false, false, false, false, false};

void PeidaProcessSignal(int s);

/* Nouvelle-Fonction */
void PeidaConfigureSignalhandling(bool cfpe, bool csegv, bool cint, bool cquit, bool cusr1, bool cusr2) 
{
  struct sigaction ae, ad;

  ae.sa_handler = PeidaProcessSignal;
  ad.sa_handler = SIG_DFL;
  memset( &(ae.sa_mask), 0, sizeof(sigset_t) ); 
  ae.sa_flags = 0;
  memset( &(ad.sa_mask), 0, sizeof(sigset_t) ); 
  ad.sa_flags = 0;
#ifdef  OSF1
  ae.sa_flags = SA_RESTART;
  ad.sa_mask = 0;
#endif

// SIGFPE 
  if (sigprstate[0] != cfpe) {
    if (cfpe)   { 
      sigaction(SIGFPE, &ae, NULL);
      puts("PeidaConfigureSignalhandling(): Activating SIGFPE handling (-> throw) ...");
      }
    else  { 
      sigaction(SIGFPE, &ad, NULL);
      puts("PeidaConfigureSignalhandling(): Back to default SIGFPE handling ...");
      }
    sigprstate[0] = cfpe;
    }
// SIGSEGV 
  if (sigprstate[1] != csegv) {
    if (csegv)   { 
      sigaction(SIGSEGV, &ae, NULL);
      puts("PeidaConfigureSignalhandling(): Activating SIGSEGV handling (-> throw) ...");
      }
    else  { 
      sigaction(SIGSEGV, &ad, NULL);
      puts("PeidaConfigureSignalhandling(): Back to default SIGSEGV handling ...");
      }
    sigprstate[1] = csegv;
    }

// SIGINT
  if (sigprstate[2] != cint) {
    if (cquit)   { 
      sigaction(SIGINT, &ae, NULL);
      puts("PeidaConfigureSignalhandling(): Activating SIGINT handling (-> throw) ...");
      }
    else  { 
      sigaction(SIGINT, &ad, NULL);
      puts("PeidaConfigureSignalhandling(): Back to default SIGINT handling ...");
      }
    sigprstate[2] = cint; 
    }
  
// SIGQUIT
  if (sigprstate[3] != cquit) {
    if (cquit)   { 
      sigaction(SIGQUIT, &ae, NULL);
      puts("PeidaConfigureSignalhandling(): Activating SIGQUIT handling (-> throw) ...");
      }
    else  { 
      sigaction(SIGQUIT, &ad, NULL);
      puts("PeidaConfigureSignalhandling(): Back to default SIGQUIT handling ...");
      }
    sigprstate[3] = cquit; 
    }
  
// SIGUSR1
  if (sigprstate[4] != cusr1) {
    if (cusr1)   { 
      sigaction(SIGUSR1, &ae, NULL);
      puts("PeidaConfigureSignalhandling(): Activating SIGUSR1 handling (-> throw) ...");
      }
    else  { 
      sigaction(SIGUSR1, &ad, NULL);
      puts("PeidaConfigureSignalhandling(): Back to default SIGUSR1 handling ...");
      }
    sigprstate[4] = cusr1;
    }
// SIGUSR2
  if (sigprstate[5] != cusr2) {
    if (cusr2)   { 
      sigaction(SIGUSR2, &ae, NULL);
      puts("PeidaConfigureSignalhandling(): Activating SIGUSR2 handling (-> throw) ...");
      }
    else  { 
      sigaction(SIGUSR2, &ad, NULL);
      puts("PeidaConfigureSignalhandling(): Back to default SIGUSR2 handling ...");
      }
    sigprstate[5] = cusr2;
    }    
}
/* Nouvelle-Fonction */
void PeidaProcessSignal(int s)
{
string msg;
switch(s)
  {
  case SIGFPE :
    puts("PeidaProcessSignal: ###Signal SIGFPE catched, throw catchedSIGFPE ###");
    msg = "Caught SIGFPE";
    throw ( CaughtSignalExc(msg, s) );
  case SIGSEGV :
    puts("PeidaProcessSignal: ###Signal SIGSEGV catched, throw catchedSIGSEGV ###");
    msg = "Caught SIGSEGV";
    throw ( CaughtSignalExc(msg, s) );
  case SIGINT :
    puts("PeidaProcessSignal: ###Signal SIGINT catched, throw catchedSIGINT ###");
    msg = "Caught SIGINT";
    throw ( CaughtSignalExc(msg, s) );
  case SIGQUIT :
    puts("PeidaProcessSignal: ###Signal SIGQUIT catched, throw catchedSIGQUIT ###");
    msg = "Caught SIGQUIT";
    throw ( CaughtSignalExc(msg, s) );
  case SIGUSR1 :
    puts("PeidaProcessSignal: ###Signal SIGUSR1 catched, throw catchedSIGUSR1 ###");
    msg = "Caught SIGUSR1";
    throw ( CaughtSignalExc(msg, s) );
  case SIGUSR2 :
    puts("PeidaProcessSignal: ###Signal SIGUSR2 catched, throw catchedSIGUSR2 ###");
    msg = "Caught SIGUSR2";
    throw ( CaughtSignalExc(msg, s) );
  default :
    printf("PeidaProcessSignal: ###Signal %d catched, throw  inconsistentErr ### \n", s);
    msg = "Caught SIG???";
    throw ( CaughtSignalExc(msg, s) );
  }

// return;
}
