/* TESTO A

Si realizzi una coppia client/server, senza utilizzare socket, che abbia il seguente
comportamento:

- il server rimane in attesa;
- il client, una volta invocato con parametro numerico n (con 0 < n < 10), crea n figli;
- ogni figlio attende un tempo casuale tra 1 e 5 secondi, terminato il quale genera un
numero casuale nel range [1-5], lo visualizza a video e lo invia al server;
- Il server accumula tutti i valori che gli vengono inviati, stampando il valore
accumulato ad ogni ricezione di un nuovo valore.
- Il server, inoltre, alla ricezione di un segnale SIGUSR1 visualizza a video il valore
accumulato.

*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <arpa/inet.h>

int somma=0;

void handler(int signo)
{
  if(signo==SIGUSR1)
    {
      printf("Ricevuto segnale SIGUSR1: somma accumulata %d\n",somma);
    }
}


int main()
{
  int buffer;
  struct sigaction sig;
  int f,r;

  //SEGNALI ///////////////////
  sig.sa_handler = handler; //gestore del segnale
  sigemptyset(&sig.sa_mask);

  sigaction(SIGUSR1,&sig,NULL);
  /////////////////////////////

  //FIFO //////////////////////
  printf("Sono server %d\n",getpid());
  fflush(NULL);

  if(mkfifo("pippo",S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | S_IWOTH)<0)
    perror("mkfifo");

  //open bloccante: resta qui fino all'aperturea della stessa fifo da parte di un client
  if((f=open("pippo",O_RDONLY))<0)
    {
      perror("open fifo server");
      exit(0);
    }
  ////////////////////////////

  do
    {
      //bloccante, almeno quando c'e' un altro processo che ha aperto la stessa pipe
      if((r=read(f,&buffer,sizeof(buffer)))<=0)
	{
	  perror("read");
	  //non lo faccio uscire... vedi sotto
	}
      else
	{
	  printf("Server: ho ricevuto %d\n",buffer);
	  fflush(NULL);
	}

      //se la read esce con zero chiudiamo e riapriamo la fifo
      //
      //esce con 0 quando il client (o i client) che hanno
      //aperto la fifo sono usciti. L'unico modo che mi e' venuto in mente
      //per poter permettere al server di restare in attesa di nuove connessioni
      //e' questo
      if(!r)
	{
	  close(f);

	  //mi blocco in attesa che qualcuno apra la pipe...
	  if((f=open("pippo",O_RDONLY))<0)
	    {
	      perror("re-open fifo server");
	      exit(0);
	    }
	}

      //incremento la somma dei numeri ricevuti dai client
      somma+=buffer;
    }
  while(1);

  close(f);

  return 0;
}
