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

#include <signal.h>


#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>


#include <errno.h>



int segnale_ricevuto=0 ;
sigset_t zeromask;

void sig_handler(int signo)
{

  segnale_ricevuto= signo ;

}



main()
{
  struct sigaction act;
  sigset_t sigmask, oldmask ;
  int pid1,pid2,pipe_p2p1[2];
  


  /* Processo padre */


  /* Gestione segnali : p1 e p2 la ereditano  */

  act.sa_handler= sig_handler ;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0 ;


  /* Gestione di SIGUSR1 */

  /* Per il segnale SIGUSR1 che solo p2 ricevera' */

  if(sigaction(SIGUSR1,&act,NULL)<0)
    {
      perror("errore sigaction: ");
      exit(2);
    }


  /* Gestione di SIGUSR2 */

  /* Per il segnale SIGUSR2 che solo p2 ricevera' */
  if(sigaction(SIGUSR2,&act,NULL)<0)
    {
      perror("errore sigaction: ");
      exit(2);
    }

  /* Blocco di SIGUSR1 che i figli aspetteranno con la sigsuspend */

  sigemptyset( &sigmask);
  sigaddset(&sigmask, SIGUSR1);
  sigprocmask(SIG_BLOCK, &sigmask, &oldmask);

  /* Blocco di SIGUSR2 */

  sigemptyset( &sigmask);
  sigaddset(&sigmask, SIGUSR2);
  sigprocmask(SIG_BLOCK, &sigmask, &oldmask);


  /* Per l'invocazione di sigsuspend serve una maschera che non blocchi SIGUSR1 e SIGUSR2: una maschera vuota andra' benissimo */

  sigemptyset( &zeromask);

  /* Creazione della pipe per la comunicazione del pid da p2 a p1 */

  if(pipe(pipe_p2p1)<0)
    {
      perror("creazione pipe: ");
      exit(-3);
    }


  /* Creazione dei figli */

  if((pid1=fork())<0)
    {
      perror("creazione p1: ");
      exit(-2);
    }
  else if (pid1 == 0)
    {
      /* p1 */
      printf ("Processo p1 con pid %d\n",getpid());
      
      read(pipe_p2p1[0],&pid2,sizeof(pid2));      

      /* Invio del segnale */
	 
      srand(getpid());
  
      if (rand()%2)
	{
	kill(pid2, SIGUSR1);
	printf("Processo p1 : inviato segnale SIGUSR1 a p2 (%d)\n",pid2);
	}

      else
	{
	kill(pid2, SIGUSR2);
	printf("Processo p1 : inviato segnale SIGUSR2 a p2 (%d)\n",pid2);
	}

      exit(0);

    }
  
  /* Padre */

/* inizializzazione del generatore di numeri casuali con seme diverso ogni volta */



  srand(getpid()); 		
  /* attesa tra 1 e 10 secondi */
  sleep(1+rand()%10);

  if((pid2=fork())<0)
    {
      perror("creazione p2: ");
      exit(-2);
    }
  else if (pid2 == 0)
    {
      /* p2 */
      printf ("Processo p2 con pid %d\n",getpid());

      pid2 = getpid();

      write(pipe_p2p1[1],&pid2,sizeof(pid2));

      /* Attesa di un segnale */

      sigsuspend(&zeromask);
      if(segnale_ricevuto == SIGUSR1)
	printf("Processo p2 : ricevuto segnale SIGUSR1\n");
      else
	if(segnale_ricevuto == SIGUSR2)
	  printf("Processo p2 : ricevuto segnale SIGUSR2\n");

      exit(0);
    }


  /* Padre  */
  wait(NULL);
  wait(NULL);


}
 
  
