Newsgroup: it.comp.os.linux.development
Titolo: segnali UNIX

Buon giorno a tutti.
Mi rivolgo a questo newsgroup per un preblema che riguarda una applicazione
in C per UNIX che non gestisce correttamente i segnali.
L'applicazione è un demone che genera N figli, con N che dipende dal
contenuto di un file di configurazione, e deve soddisfare, tra gli altri,  i
seguenti requisiti funzionali:
a) rigenerare un figlio (respawn) che termini l'esecuzione
    per vari motivi
b) rileggere il file di configurazione, terminando i figli in
    esecuzione e rigenerandone nuovi
Per il requisito a) ho implementato un handler del segnale SIG_CHLD,
correttamente funzionante.
Ho implementato il requisito b) tramite il segnale SIG_HUP, che il padre
intercetta e gestisce con un opportuno handler.
Quest'ultimo opera come segue:
1) invoca signal() per ignorare il segnale SIG_CHLD;
2) inoltra SIG_HUP ai figli (kill()), utilizzando un array che
    ne mantiene i pid;
3) rilegge la configurazione
4) rigenera i figli
5) ripristina il gestore del segnale SIG_CHLD
I passi 1) e 5) sono necessari perchè l'handler per SIG_CHLD rigenererebbe
un figlio sulla base della vecchia configurazione.
Il corpo di ogni figlio è una funzione della forma:
    figlio()
    {
        while(!hupFlag)
        {
            /* attività */
        }
        /* istruzioni di chiusura pulita */
    }
L'handler per SIG_HUP dei figli si limita a modificare il valore di hupFlag
da 0 a 1; l'installazione di tale handler come gestore di SIG_HUP è la prima
operazione eseguita da ogni figlio.
Il corpo del padre è main() che, dopo avere operazioni di inizializzazione
(lettura della configurazione, installazione handler dei segnali,
generazione dei figli, ..) esegue banalmente
    while(1) pause();
Il problema
Il problema si manifesta come segue:  l'applicazione esibisce il
comportamento desiderato (i passi 1-5) solo alla prima occorrenza del
segnale SIG_HUP.
Ogni altra occorrenze viene intercettata dal padre ma non
dai figli, con il risultato che restano in esecuzione istanze indesiderate
del demone.
Osservazioni
i) i figli del demone gestiscono correttamente SIG_HUP:
    in altre parole, se invio SIG_HUP  ad un figlio,
    scavalcando il padre (e il meccanismo di inoltro),
    il segnale viene intercettato e gestito;
ii) il contenuto dell'array dei pid viene correttamente
   aggiornato: al passo 2) il padre inoltra SIG_HUP
   ai figli "giusti" (ho verificato che kill() non restituisca -1)
iii) il problema non dipende dal segnale: se implemento il
    requisito b) gestendo il segnale SIG_TERM, invece
    che SIG_HUP, il problema si manifesta allo stesso
    modo
iv) il problema non è risolto dalla seguente varianti della applicazione:
     - l'handler di SIG_HUP del padre non ignora SIG_CHLD (non esegue i
       passi 1 e 5); i figli eseguono sleep() prima di terminare; il padre
       intercetta SIG_CHLD ma non rigenera i figli (attività che,in questo
caso, è
       svolta dall'handler di SIG_HUP)
v) il problema non si risolve neppure inviando SIG_HUP dalla linea di
    comando tramite
        killall -HUP <nome_applicazione>
Domanda.
A vostro avviso, il problema dipende da un errore di programmazione (una
variabile non inizializzata,
un errore logico) oppure da un mia ignoranza sulla gestione dei segnali.
Il mio sospetto è che si tratti di una combinazione delle due possibilità.
Il codice che troverete in allegato riproduce in piccolo il demone che, per
questioni
di sicurezza, non posso fornire.
Nota: sig-01.c fuziona.
La principale differenza tra le due implementazioni è la chiamata di di
sistema nella
quale il padre (implementato dalla funzione parent()) si sospende: in
sig-01.c
è wait().
Notate che se nel codice del figlio (funzione child()) rimuovete il commento
dalla sleep(),
il meccanismo di inoltro del segnale non funziona.
Ringrazio in anticipo per qualsiasi aiuto.
Davide L.

 5) ripristina il gestore del segnale SIG_CHLD
Prova con
  6) ripristina il proprio handler per SIGHUP
Ciao
 David
-- 
<d.santinoli presso mi. flashnet. it>

Innanzitutto grazie per aver letto il mio lungo messaggio.
Vediamo se ho capito.
Mi dici di aggiungere all'handler  del segnale SIG_HUP del padre (la
funzione parentSigHupHandler()) l'istruzione
    signal(SIG_HUP, parentSigHupHandler ).
Ogni volta che devo implementare l'handler F per un segnale X, la prima
istruzione che predispongo è proprio signal(X, F).
Ciò perchè ho saputo di alcuni compilatori C che, dopo l'occorrenza di un
segnale, ripristinano l'handler di default.
Purtroppo, in questo caso, la posizione della signal() che mi suggerisci  è
indifferente.
Comunque, continuerò a fare prove per scovare il bug e, appena risolto,
svelerò l'arcano al news group.
Ciao
Grazie
Davide L.
"David Santinoli" <sant...@aidi.milano> ha scritto nel messaggio
news:3BB9C1B7...@aidi.milano...


segnale SIG_HUP.
Forse ti dimentichi di riazzerare il "hupFlag"?
-- 
Saluti,
    Mardy
http://castellina.org/interlingua

 ha scritto nel messaggio
news:20011002194723....@pupilla.local...



Scusa ma perche` non usi sempre sigaction, e lasci perdere la semantica non 
affidabile (cioe` quella di reintallare tutte le volte l'handler).
Ciao
Simone