Mi pare che mi sono spiegato un pò male...
Rilevare la morte del figlio mi serve solo perchè non rimanga uno zombie...
Non posso bloccare il padre con la wait o con la waitpid senza usare l'opzione WNOHANG perchè se lo blocco finchè il figlio non muore il server rimane inattivo...
Se io uso un codice come il seguente (quello che sto usando attualmente)
codice:
while ( 1 ) {
fd2 = accept ( fd, (struct sockaddr *) &client, (socklen_t *) &sin_size );
if ( fd2 == -1 ) {
printf( "accept() error: %s", strerror ( errno ) );
exit( -1 );
}
pid = fork();
if ( pid < 0 ) {
printf ( "Impossibile creare un figlio: %s.\n", strerror ( errno ) );
}
if ( pid == 0 ) { // figlio
close ( fd );
printf( "Connection received from %s, port: %d\n", inet_ntoa( client.sin_addr ), client.sin_port );
printf("New Process created for the Client\n");
HandleClient ( );
} /*else {*/
rc_pid = waitpid( -1, &chld_state, WNOHANG);
printf ( "rimosso il cadavere %d\n", rc_pid );
close ( fd2 );
}
Succede questo:
quando il server riceve una richiesta crea un figlio e contolla che non ci siano figli morti (se li trova li rimuove, così non figurano più come zombie)...
Il problema è che tra una connessione ed un altra rimane sempre un processo zombie perchè il padre potrà verificare la sua morte solo quando riceverà un'altra richiesta, ma allora il figlio che fa nascere per la seconda richiesta non lo potrà verificare finchè non riceve una terza richiesta e così via all'infinito...
Non avevo pensato che la morte di un processo invia un segnale (grazie Ed_Bunker)
Gestendo il segnale ho risolto il problema...
Se può interessare a qualcuno il segnale lo gestisco con
codice:
void sigchld_handler(int sig) {
pid_t pid = waitpid(-1, NULL, WNOHANG);
printf("child %d\n",pid);
if ( pid < 0 ) {
if ( errno == ECHILD )
puts("errno=ECHILD");
error_exit("waitpid");
}
if ( signal(SIGCHLD, sigchld_handler) == SIG_ERR )
error_exit("signal");
}
è sufficiente mettere nel main "signal(SIGCHLD, sigchld_handler)" e così ogni qual volta che muore un processo figlio il programma lo rileva e lo rimuove, così non rimane un morto vivente
Grazie a tutti