Newsgroup: it.comp.os.linux.development
Titolo: sigaction() e gestione dei segnali sotto UNIX in C

Ciao a tutti, sto studiando la gestione dei segnali sotto UNIX in C (non
mi è molto chiaro come utilizzare nella pratica sigaction() nonostante
l'abbondante documentazione che ho consultato... forse perchè non ho
esempi esaustivi) e mi chiedevo quale fosse il modo migliore per
ottenere un risultato di questo tipo:
dal main() apro un blocco e faccio una fork(); subito prima di farla,
dentro al blocco, imposto il padre per ignorare determinati segnali
(SIGSTOP, SIGTSTP, SIGQUIT, SIGTERM, ecc.): il figlio dovrebbe non
essere affetto da questa serie di impostazioni (l'ignorare determinati
segnali). Terminato il figlio, il padre dovrebbe tornare ad adottare
l'azione di default per quei segnali. Pensavo di usare sigaction() dato
che sui testi ho appreso che signal() non gestisce i segnali in modo
robusto.
Mi sapreste proporre frammenti di codice che facciano al caso mio?
Non ho poi ben capito come funzionino (se ne creo uno tale set contiene 
già tutti i segnali di default? come posso usare sigaction() per 
impostare un'azione a qualche segnale mantenendo gli altri invariati?) i 
set di segnali gestiti da sigaction().
	ciao e grazie, rz
-- 
http://mrzac.altervista.org

 impostare un'azione a qualche segnale mantenendo gli altri invariati?)
Con sigaction() configuri un solo segnale alla volta (quello che
specifichi come primo parametro) e dici cosa fare se al processo arriva
quel segnale. Se vuoi cambiare il comportamento di più segnali, devi
invocare sigaction() più volte.
I set di segnali si manipolano con sigemptyset(), sigaddset(),
sigfillset(), sigdelset(), etc. 
A te dovrebbe interessare solo per inizializzare il membro sa_mask della
struct sigaction che passi a sigaction(): probabilmente ti basta un
sigemptyset( &(my_action.sa_mask) ).
-- 
  |   \    \  | ___|_  |_  |  ianezz a casa sua... :-)
  |  _ \  | \ | _|    /   /   Verba volant, scripta
 _|_/  _\_|  _|____|___|___|  manent, data corrupted

 set di segnali gestiti da sigaction().
dipende cosa usi...in BSD (signal blocking) ci sono sigmask() (puoi 
usare sigmask in or) e sigblock() per settare e bloccare i segnali. In 
system 5 c'è sighold() e sigrelease().
Per sbloccarli e gestirli c'è la funzione sigpause() (l'unico parametro 
è la maschera dei segnali che si vogliono rilasciare: se tutti = 0).

 
Alla fine per far si che un processo padre generasse un figlio e che 
successivamente, per tutta la vita del figlio, tale padre ignorasse 
SIGINT e SIGSTP ho usato questo codice:
	   act.sa_handler=SIG_IGN;
	   sigemptyset(&act.sa_mask);
	   act.sa_flags=0;
	   sigaction( SIGINT, &act, NULL );
	   sigaction( SIGTSTP, &act, NULL );
act è una struttura opportunamente dichiarata. Tale codice l'ho messo 
nell'else della fork dove solo il padre "entra":
if( (pid=fork())<0 ){
	   puts("\nfork error");
	   exit(0);
	 }
	 else if( pid==0 ){   /* child's section */
	   [........................]
	 }             /* end of child's section */
	 else{             /* parent's section */
	   act.sa_handler=SIG_IGN;
	   sigemptyset(&act.sa_mask);
	   act.sa_flags=0;
	   sigaction( SIGINT, &act, NULL );
	   sigaction( SIGTSTP, &act, NULL );
	   if( wait(NULL)!=pid ){
	     puts("\nerror with wait()");
	     exit(0);
	   }
	 }
Successivamente, nella porzione di codice eseguita ESCLUSIVAMENTE dal 
padre al termine del figlio, riabilito tali segnali con il seguente codice:
	   act.sa_handler=SIG_DFL;
	   sigaction( SIGINT, &act, NULL );
	   sigaction( SIGTSTP, &act, NULL );
Ho fatto bene? Sembra funzionare...
