/* Prova UNIX del 22 luglio 2008 Si realizzi un programma in C che abbia il seguente comportamento: - Il processo iniziale (P0) crea due figli, P1 e P2, che visualizzano il loro pid a video ; - Il processo tra P1 e P2 che ha il numero di pid maggiore invia al padre e all'altro processo un segnale SIGUSR1 e poi termina ; - L'arrivo del segnale SIGUSR1 genera comportamenti diversi nei due processi riceventi: il secondo figlio muore istantaneamente, mentre il processo padre, una volta ricevuto il segnale, attende 5 secondi e poi termina. Si richiede l'utilizzo della gestione affidabile dei segnali. */ #include #include #include #include #define N_FIGLI 2 int piped[2]; sigset_t sigmask, zeromask; void sigusr1_handler(int signo) { printf("\nProcesso padre ha ricevuto il segnale SIGUSR1 e inizia attesa di 5 secondi\n"); sleep(5); printf("\nProcesso padre ha finito l'attesa e termina\n"); exit(0); } void body_proc(int i, int pidprimofiglio) { int mio_pid, pid_fratello; struct sigaction act; mio_pid = getpid(); printf("Processo %d PID %d\n",i,mio_pid); /* Non si puņ assumere che il PID del secondo figlio sia consecutivo a quello del primo (in Linux i PID sono rappresentati da soli 16 bit mentre in CYGWIN sono numeri casuali : e' necessaria una comunicazione esplicita da P2 a P1 */ if(i==0) { /* il primo figlio non puo' conoscere il PID del secondo fratello creato successivamente */ read(piped[0], &pid_fratello, sizeof(int)); } else /* il secondo figlio conosce gia' il pid del fratello */ { write(piped[1], &mio_pid, sizeof(int)); pid_fratello = pidprimofiglio; } if(mio_pid < pid_fratello) { act.sa_handler= SIG_DFL; sigemptyset( &act.sa_mask); act.sa_flags= 0; sigaction(SIGUSR1, &act, NULL); sigsuspend(&zeromask); } else { kill(pid_fratello,SIGUSR1); kill(getppid(),SIGUSR1); printf("Processo %d PID %d ha inviato SIGUSR1 a padre e fratello (PID %d)\n",i,mio_pid,pid_fratello); } } int main(void) { int i,tabpid[N_FIGLI]; struct sigaction act; /* GESTIONE SEGNALI */ sigemptyset( &zeromask); sigemptyset( &sigmask); sigaddset(&sigmask, SIGUSR1); /* Blocco dei segnali SIGUSR1 */ sigprocmask(SIG_BLOCK, &sigmask, NULL); act.sa_handler= sigusr1_handler; sigemptyset( &act.sa_mask); act.sa_flags= 0; sigaction(SIGUSR1, &act, NULL); /* L'intera politica di gestione dei segnali verra' ereditata dai figli */ /* CREAZIONE PIPE */ if(pipe(piped)<0) { perror("Creazione pipe :"); exit(-1); } /* CREAZIONE FIGLI */ for(i=0;i