From: Simone Piccardi Date: Mon, 16 Aug 2021 16:49:12 +0000 (+0200) Subject: Sistemati alcuni nomi, l'inserimento dell'indice analitico e della X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=c2e762abed93fe970c6c4d019a8bfe95fadb4efa Sistemati alcuni nomi, l'inserimento dell'indice analitico e della bibliografia nell'indice, e documentati i gestori in forma sa_sigaction --- diff --git a/gapil.tex b/gapil.tex index 4439b5b..3b1d0c9 100644 --- a/gapil.tex +++ b/gapil.tex @@ -136,7 +136,7 @@ hyperfootnotes=false]{hyperref} \begin{quote} - Copyright \copyright\ 2000-2019 Simone Piccardi. Permission is granted to + Copyright \copyright\ 2000-2021 Simone Piccardi. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being ``Un preambolo'' @@ -225,11 +225,17 @@ hyperfootnotes=false]{hyperref} \include{ringraziamenti} \include{fdl-1.3} -% at the end put the bibliography +% at the end put index and bibliography \backmatter +\cleardoublepage +\phantomsection +\addcontentsline{toc}{chapter}{Indice analitico} \printindex %\bibliographystyle{phaip} %\bibliographystyle{ieeetr} +\cleardoublepage +\phantomsection +\addcontentsline{toc}{chapter}{Bibliografia} \bibliographystyle{abstract} \bibliography{biblio} diff --git a/listati/Signal.c b/listati/Signal.c index 855faa0..4ba6fae 100644 --- a/listati/Signal.c +++ b/listati/Signal.c @@ -1,13 +1,13 @@ -typedef void SigFunc(int); -inline SigFunc * Signal(int signo, SigFunc *func) +typedef void SigHandler(int); +inline SigHandler * Signal(int signo, SigHandler *func) { struct sigaction new_handl, old_handl; + new_handl.sa_flags=0; /* init to 0 all flags */ new_handl.sa_handler = func; /* clear signal mask: no signal blocked during execution of func */ if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ return SIG_ERR; } - new_handl.sa_flags=0; /* init to 0 all flags */ /* change action for signo signal */ if (sigaction(signo, &new_handl, &old_handl)){ return SIG_ERR; diff --git a/listati/SignalRestart.c b/listati/SignalRestart.c index 89bc502..faa3904 100644 --- a/listati/SignalRestart.c +++ b/listati/SignalRestart.c @@ -1,8 +1,8 @@ -inline SigFunc * SignalRestart(int signo, SigFunc *func) +inline SigHandler * SignalRestart(int signo, SigHandler *func) { struct sigaction new_handl, old_handl; - new_handl.sa_handler = func; /* set signal handler */ new_handl.sa_flags = SA_RESTART; /* restart system call */ + new_handl.sa_handler = func; /* set signal handler */ /* clear signal mask: no signal blocked during execution of func */ if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ return SIG_ERR; diff --git a/listati/siginfo_t.h b/listati/siginfo_t.h index 3e9b488..a010075 100644 --- a/listati/siginfo_t.h +++ b/listati/siginfo_t.h @@ -17,11 +17,11 @@ siginfo_t { void * si_addr; /* Memory location which caused fault */ long si_band; /* Band event (was int before glibc 2.3.2) */ int si_fd; /* File descriptor */ - short si_addr_lsb;/* Least significant bit of address (since Linux 2.6.32) */ - void *si_lower; /* Lower bound when address violation occurred (since Linux 3.19) */ - void *si_upper; /* Upper bound when address violation occurred (since Linux 3.19) */ - int si_pkey; /* Protection key on PTE that caused fault (since Linux 4.6) */ - void *si_call_addr; /* Address of system call instruction (since Linux 3.5) */ - int si_syscall; /* Number of attempted system call (since Linux 3.5) */ - unsigned int si_arch;/* Architecture of attempted system call (since Linux 3.5) */ - } + short si_addr_lsb;/* Least significant bit of address (since 2.6.32) */ + void *si_lower; /* Lower bound when addr violation occurred (3.19) */ + void *si_upper; /* Upper bound when addr violation occurred (3.19) */ + int si_pkey; /* Protection key on PTE that caused fault (4.6) */ + void *si_call_addr; /* Address of system call instruction (3.5) */ + int si_syscall; /* Number of attempted system call (since 3.5) */ + unsigned int si_arch;/* Architecture of attempted system call (3.5) */ +} diff --git a/signal.tex b/signal.tex index a7aaa3f..78d5080 100644 --- a/signal.tex +++ b/signal.tex @@ -2198,7 +2198,7 @@ in tab.~\ref{tab:sig_si_code_generic}. \begin{table}[!htb] \footnotesize \centering - \begin{tabular}[c]{|l|p{10cm}|} + \begin{tabular}[c]{|l|p{8cm}|} \hline \textbf{Valore} & \textbf{Significato} \\ \hline @@ -2242,16 +2242,10 @@ che si tratta di costanti, e non di una maschera binaria, i valori numerici vengono riutilizzati e ciascuno di essi avrà un significato diverso a seconda del segnale a cui è associato. -L'elenco dettagliato dei nomi di queste costanti è riportato nelle diverse -sezioni di tab.~\ref{tab:sig_si_code_special} che sono state ordinate nella -sequenza in cui si sono appena citati i rispettivi segnali, il prefisso del -nome indica comunque in maniera diretta il segnale a cui le costanti fanno -riferimento. - \begin{table}[!htb] \footnotesize \centering - \begin{tabular}[c]{|l|p{10cm}|} + \begin{tabular}[c]{|l|p{8cm}|} \hline \textbf{Valore} & \textbf{Significato} \\ \hline @@ -2323,6 +2317,12 @@ riferimento. \label{tab:sig_si_code_special} \end{table} +L'elenco dettagliato dei nomi di queste costanti è riportato nelle diverse +sezioni di tab.~\ref{tab:sig_si_code_special} che sono state ordinate nella +sequenza in cui si sono appena citati i rispettivi segnali, il prefisso del +nome indica comunque in maniera diretta il segnale a cui le costanti fanno +riferimento. + Il resto della struttura \struct{siginfo\_t} è definito come una \dirct{union} ed i valori eventualmente presenti dipendono dal segnale ricevuto, così \signal{SIGCHLD} ed i segnali \textit{real-time} (vedi @@ -2344,18 +2344,19 @@ Benché sia possibile usare nello stesso programma sia \func{sigaction} che \func{signal} occorre molta attenzione, in quanto le due funzioni possono interagire in maniera anomala. Infatti l'azione specificata con \struct{sigaction} contiene un maggior numero di informazioni rispetto al -semplice indirizzo del gestore restituito da \func{signal}. Per questo motivo -se si usa quest'ultima per installare un gestore sostituendone uno +semplice indirizzo del gestore restituito da \func{signal}, e questo comporta +che se si usa quest'ultima per installare un gestore sostituendone uno precedentemente installato con \func{sigaction}, non sarà possibile effettuare un ripristino corretto dello stesso. -Per questo è sempre opportuno usare \func{sigaction}, che è in grado di +Per questo motivo è opportuno usare sempre \func{sigaction} che è in grado di ripristinare correttamente un gestore precedente, anche se questo è stato installato con \func{signal}. In generale poi non è il caso di usare il valore di ritorno di \func{signal} come campo \var{sa\_handler}, o viceversa, dato -che in certi sistemi questi possono essere diversi. In definitiva dunque, a -meno che non si sia vincolati all'aderenza stretta allo standard ISO C, è -sempre il caso di evitare l'uso di \func{signal} a favore di \func{sigaction}. +che in certi sistemi questi valori possono essere diversi. In definitiva +dunque, a meno che non si sia vincolati all'aderenza stretta allo standard ISO +C, è sempre il caso di evitare l'uso di \func{signal} a favore di +\func{sigaction}. \begin{figure}[!htbp] \footnotesize \centering @@ -2368,14 +2369,14 @@ sempre il caso di evitare l'uso di \func{signal} a favore di \func{sigaction}. \label{fig:sig_Signal_code} \end{figure} -Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata -che abbia le stesse caratteristiche di \func{signal}, a definire attraverso -\func{sigaction} una funzione equivalente \func{Signal}, il cui codice è -riportato in fig.~\ref{fig:sig_Signal_code} (il codice completo si trova nel -file \file{SigHand.c} nei sorgenti allegati). Anche in questo caso, per -semplificare la definizione si è poi definito un apposito tipo -\texttt{SigFunc} per esprimere in modo più comprensibile la forma di un -gestore di segnale. +Come primo esmpio si è allora provveduto, per mantenere un'interfaccia +semplificata che abbia le stesse caratteristiche di \func{signal}, a definire +attraverso \func{sigaction} una funzione equivalente, \func{Signal}, il cui +codice è riportato in fig.~\ref{fig:sig_Signal_code} (il codice completo si +trova nel file \file{SigHand.c} nei sorgenti allegati). Anche in questo caso, +per semplificare la definizione si è poi definito un apposito tipo +\texttt{SigHandler} per esprimere in modo più semplice la forma di un gestore +di segnale. Si noti come, essendo la funzione estremamente semplice, essa è definita come \dirct{inline}. Questa direttiva viene usata per dire al compilatore di @@ -2394,6 +2395,72 @@ comportamento veniva ottenuto con delle macro, ma queste hanno tutta una serie di problemi di sintassi nel passaggio degli argomenti (si veda ad esempio \cite{PratC}) che in questo modo possono essere evitati. +La funzione \func{Signal} appena illustrata continua però ad utilizzare la +forma tradizionale del gestore di segnali, mentre abbiamo visto come +\func{sigaction} preveda la possibilità di indicare, attivando il flag +\const{SA\_SIGINFO}, un gestore nella forma avanzata \param{sa\_sigaction}, in +grado di ricevere molte più informazioni, che prevede l'utilizzo di tre +argomenti. Di nuovo facciamo un esempio di come usare \func{sigaction} in +questo caso, partendo col definire un apposito tipo, \texttt{SigAction}, per +semplificare l'indicazione del nuovo tipo di gestore: +\includecodesnip{listati/SigAction.c} + +Un gestore di segnali definito nella forma \val{sa\_sigaction} infatti, oltre +al numero di segnale ricevuto come primo argomento, otterrà dal kernel un +puntatore ad una struttura \struct{siginfo\_t} con le relative informazioni +attienti l'origine del segnale nel secondo argomento, ed infine un puntatore a +delle informazioni di contesto ad uso delle librerie del C nel terzo +argomento, che non vengono mai utilizzate nel gestore, attenendo al +funzionamento a basso livello della gestione dei segnali.\footnote{il kernel + tutte le volte che c'è un segnale pendente gestisce l'esecuzione del + relativo gestore caricando nello stack i dati del contesto di esecuzione del + processo e facendo sì che al ritorno in \textit{user-space} sia eseguito il + gestore, una volta che questo ritorna il controllo viene passato a dello + specifico codice in \textit{user-space}, detto \itindex{signal~trampoline} + \textit{signal trampoline}, che con la funzione di sistema \funcm{sigreturn} + usa le informazioni di contesto disponibili in questo argomento per far + riprendere l'esecuzione del processo al punto in cui si era stata interrotta + dal segnale; tutto ciò è gestito dal kernel e dalle librerie del C e non + interessa la programmazione ordinaria.} + +Si è riportato in fig.~\ref{fig:sig_Action_code} un equivalente della +precedente \func{Signal} che però installa un gestore di segnali di tipo +\param{sa\_sigaction}. Si noti come la funzione, una volta definito come sopra +il tipo \texttt{SigAction} per il gestore di segnali, sia praticamente +identica all'altra. + +\begin{figure}[!htbp] + \footnotesize \centering + \begin{minipage}[c]{\codesamplewidth} + \includecodesample{listati/Action.c} + \end{minipage} + \normalsize + \caption{La funzione \func{Action}, analoga alla precedente \func{Signal} + per l'uso dei gestori di segnali avanzati con \func{sigaction}.} + \label{fig:sig_Action_code} +\end{figure} + +Quello che cambia in questo caso è occorre indicare (\texttt{\small 4}) nel +campo \var{sa\_flags} della struttura \struct{sigaction} il valore +\const{SA\_SIGINFO}, perché poi si passerà (\texttt{\small 5}) l'indirizzo il +del gestore nel campo \var{sa\_sigaction} invece che in \var{sa\_handler} come +nel caso precedente. + +Inoltre in questo caso, ritornando la funzione l'indirizzo del gestore che è +nella nuova forma, non si può terminare in caso di errore riportanto il valore +\const{SIG\_ERR} (che è di tipo \type{sighandler\_t} e fa riferimento ad un +gestore ordinario) come in precedenza. Per questo motivo si è scelto di +ritornare come indicazione di errore il valore \val{NULL}, ma in questo caso +si deve tenere presente che questo valore non è più distinto da quello che si +utilizza per indicare la eventuale reimpostazione del gestore di default (come +era \const{SIG\_ERR} rispetto a \const{SIG\_DFL}). + +Per questo motivo questa funzione viene illustrata solo a scopo di primo +esempio, vedremo più avanti, in sez.~\ref{sec:sig_real_time}, nel contesto +dell'uso dei segnali \textit{real-time} per i quali è nata questa nuova +interfaccia, un esempio più completo dell'uso di \func{sigaction} con un +gestore in questa nuova forma, e di come utilizzare le informazioni ottenute +nella struttura \struct{siginfo\_t}. \subsection{La gestione della \textsl{maschera dei segnali} o @@ -2431,19 +2498,22 @@ quando si devono eseguire più operazioni su delle variabili (nell'esempio citato un controllo ed una assegnazione) o comunque eseguire una serie di istruzioni, l'atomicità non è più possibile. -In questo caso, se si vuole essere sicuri di non poter essere interrotti da -uno o più segnali durante l'esecuzione di una sezione di codice, li si possono -bloccare esplicitamente modificando la maschera dei segnali del processo -usando la funzione di sistema \funcd{sigprocmask},\footnote{in realtà quello - che viene usato normalmente è il \textit{wrapper} omonimo delle \acr{glibc} - dato che con l'introduzione dei segnali \textit{real time} nel kernel 2.2 le - dimensioni del tipo \type{sigset\_t} sono cambiate e la \textit{system call} - sottostante è diventata \funcm{rt\_sigprocmask} che richiede un quarto - argomento di tipo \ctyp{size\_t} per indicare questa dimensione; il - \textit{wrapper} maschera questi dettagli ed inoltre ignora in maniera - silente i tentativi di bloccare i segnali \textit{real time} impiegati per - la gestione dei \textit{thread} dalla \textit{Native Thread Posix Library} - (vedi sez.~\ref{sec:linux_ntpl}).} il cui prototipo è: +In questo caso, quando si vuole essere sicuri di non essere interrotti da uno +o più segnali durante l'esecuzione di una sezione di codice, diventa +necessario bloccarli esplicitamente. Questo si fa modificando la maschera dei +segnali del processo e per fare questa operazione con lo standard POSIX-1.2001 +è stata introdotta una apposita funzione di sistema, +\funcd{sigprocmask},\footnote{in realtà quello che viene usato normalmente è + il \textit{wrapper} omonimo delle \acr{glibc} dato che con l'introduzione + dei segnali \textit{real time} nel kernel 2.2 le dimensioni del tipo + \type{sigset\_t} sono cambiate e la \textit{system call} sottostante è + diventata \funcm{rt\_sigprocmask} che richiede un quarto argomento di tipo + \ctyp{size\_t} per indicare questa dimensione; la vecchia funzione di + sistema continua ad esistere ma è deprecata, il \textit{wrapper} maschera + questi dettagli ed inoltre ignora in maniera silente i tentativi di bloccare + i segnali \textit{real time} impiegati per la gestione dei \textit{thread} + dalla \textit{Native Thread Posix Library} (vedi + sez.~\ref{sec:linux_ntpl}).} il cui prototipo è: \begin{funcproto}{ \fhead{signal.h} @@ -2462,12 +2532,13 @@ usando la funzione di sistema \funcd{sigprocmask},\footnote{in realtà quello La funzione usa l'insieme di segnali posto all'indirizzo passato nell'argomento \param{set} per modificare la maschera dei segnali del processo -corrente. La modifica viene effettuata a seconda del valore -dell'argomento \param{how}, secondo le modalità specificate in -tab.~\ref{tab:sig_procmask_how}. Qualora si specifichi un valore non nullo -per \param{oldset} la maschera dei segnali corrente viene salvata a -quell'indirizzo. Se è nullo \param{set} non viene eseguito nessun cambiamento -e si può usare la funzione per leggere la maschera corrente in \param{oldset}. +corrente. La modifica viene effettuata a seconda del valore dell'argomento +\param{how}, secondo le modalità specificate in +tab.~\ref{tab:sig_procmask_how}. Qualora si specifichi un indirizzo non nullo +per il puntatore \param{oldset} la maschera dei segnali corrente viene salvata +a quell'indirizzo. Se invece è nullo il puntatore \param{set} non viene +eseguito nessun cambiamento e si può usare la funzione per leggere la maschera +corrente in \param{oldset}. \begin{table}[htb] \footnotesize @@ -2494,8 +2565,9 @@ e si può usare la funzione per leggere la maschera corrente in \param{oldset}. La funzione consente di proteggere delle sezioni di codice bloccando l'insieme di segnali voluto per poi riabilitarli alla fine della sezione critica e risolvere problemi come quelli mostrati in fig.~\ref{fig:sig_event_wrong}, -proteggendo la sezione fra il controllo del flag e la sua cancellazione. La -funzione può essere usata anche all'interno di un gestore, ad esempio per +proteggendo la sezione fra il controllo del flag e la sua cancellazione. + +La funzione può essere usata anche all'interno di un gestore, ad esempio per riabilitare la consegna del segnale che l'ha invocato, in questo caso però occorre ricordare che qualunque modifica alla maschera dei segnali viene perduta al ritorno dallo stesso. @@ -2506,10 +2578,12 @@ all'uso di \func{pause}. Il caso è simile a quello del problema illustrato nell'esempio di fig.~\ref{fig:sig_sleep_incomplete}, e cioè la possibilità che il processo riceva il segnale che si intende usare per uscire dallo stato di attesa invocato con \func{pause} immediatamente prima dell'esecuzione di -quest'ultima. Per poter effettuare atomicamente la modifica della maschera dei -segnali (di solito attivandone uno specifico) insieme alla sospensione del -processo lo standard POSIX ha previsto la funzione di sistema -\funcd{sigsuspend}, il cui prototipo è: +quest'ultima. + +Per poter effettuare atomicamente la modifica della maschera dei segnali (di +solito attivandone uno specifico) insieme alla sospensione del processo lo +standard POSIX ha previsto la funzione di sistema \funcd{sigsuspend}, il cui +prototipo è: \begin{funcproto}{ \fhead{signal.h} @@ -3996,7 +4070,7 @@ tipo \type{sigjmp\_buf}, è assolutamente identica a \func{longjmp}. % LocalWords: ILL ILLOPC ILLOPN ILLADR ILLTRP PRVOPC PRVREG COPROC BADSTK FPE % LocalWords: INTDIV INTOVF FLTDIV FLTOVF FLTUND underflow FLTRES FLTINV SEGV % LocalWords: FLTSUB MAPERR ACCERR ADRALN ADRERR OBJERR BRKPT CLD EXITED MSG -% LocalWords: KILLED DUMPED TRAPPED STOPPED CONTINUED PRI HUP SigFunc jiffies +% LocalWords: KILLED DUMPED TRAPPED STOPPED CONTINUED PRI HUP SigHandler % LocalWords: SEC unsafe sockatmark execl execv faccessat fchmodat fchownat % LocalWords: fexecve fstatat futimens linkat mkdirat mkfifoat mknod mknodat % LocalWords: openat readlinkat renameat symlinkat unlinkat utimensat utimes @@ -4007,7 +4081,7 @@ tipo \type{sigjmp\_buf}, è assolutamente identica a \func{longjmp}. % LocalWords: epoch multiplexing overrun res lpthread sec nsec curr one shot % LocalWords: delete stopped gdb alpha mips emulation locking ppoll epoll PGID % LocalWords: pwait msgrcv msgsnd semop semtimedop runnable sigisemptyset HRT -% LocalWords: sigorset sigandset BOOTTIME Android request remain cap dell' +% LocalWords: sigorset sigandset BOOTTIME Android request remain cap jiffies %%% Local Variables: diff --git a/sources/Gapil.h b/sources/Gapil.h index 429fc6f..b46672d 100644 --- a/sources/Gapil.h +++ b/sources/Gapil.h @@ -89,13 +89,19 @@ int UnlockFile(const char* path_name); /* * Signal Handling Functions */ -typedef void SigFunc(int); +typedef void SigHandler(int); +typedef void SigAction(int, siginfo_t *, void *); /* Function Signal: Initialize a signal handler. See SigHand.c */ -SigFunc * Signal(int signo, SigFunc *func); +SigHandler * Signal(int signo, SigHandler *func); /* Function SignalRestart: restart system calls. See SigHand.c */ -SigFunc * SignalRestart(int signo, SigFunc *func); +SigHandler * SignalRestart(int signo, SigHandler *func); /* Function HandSigCHLD: to handle SIGCHILD. See SigHand.c */ void HandSigCHLD(int sig); +/* Function Action: Initialize a sa_sigaction handler. See SigHand.c */ +SigAction * Action(int signo, SigAction *func); +/* Function Action: Initialize a sa_sigaction handler. See SigHand.c */ +SigAction * ActionRestart(int signo, SigAction *func); + /* * Socket/Files service functions */ diff --git a/sources/SigHand.c b/sources/SigHand.c index a37fac5..605493d 100644 --- a/sources/SigHand.c +++ b/sources/SigHand.c @@ -37,22 +37,22 @@ * Initialize a signal handler. * To enable the signal handling a process we need to tell it to * kernel; this is done writing all needed info to a sigaction structure - * named sigact, and then callind sigaction() system call passing the + * named sigact, and then calling sigaction() system call passing the * information stored in the sigact structure variable. * * Input: the signal to handle * the signal handler function - * Return: the previous sigaction structure + * Return: the previous signal handler */ -inline SigFunc * Signal(int signo, SigFunc *func) +inline SigHandler * Signal(int signo, SigHandler *func) { struct sigaction new_handl, old_handl; + new_handl.sa_flags=0; /* init to 0 all flags */ new_handl.sa_handler = func; /* set signal handler */ /* clear signal mask: no signal blocked during execution of func */ if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ return SIG_ERR; } - new_handl.sa_flags=0; /* init to 0 all flags */ /* change action for signo signal */ if (sigaction(signo, &new_handl, &old_handl)){ return SIG_ERR; @@ -65,19 +65,19 @@ inline SigFunc * Signal(int signo, SigFunc *func) * Initialize a signal handler. * To enable the signal handling a process we need to tell it to * kernel; this is done writing all needed info to a sigaction structure - * named sigact, and then callind sigaction() system call passing the + * named sigact, and then calling sigaction() system call passing the * information stored in the sigact structure variable. * This version enable BSD semantics with SA_RESTART * * Input: the signal to handle * the signal handler function - * Return: the previous sigaction structure + * Return: the previous signal handler */ -inline SigFunc * SignalRestart(int signo, SigFunc *func) +inline SigHandler * SignalRestart(int signo, SigHandler *func) { struct sigaction new_handl, old_handl; - new_handl.sa_handler = func; /* set signal handler */ new_handl.sa_flags = SA_RESTART; /* restart system call */ + new_handl.sa_handler = func; /* set signal handler */ /* clear signal mask: no signal blocked during execution of func */ if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ return SIG_ERR; @@ -89,10 +89,64 @@ inline SigFunc * SignalRestart(int signo, SigFunc *func) return (old_handl.sa_handler); } +/* + * Function Action + * Initialize a sa_sigaction signal handler. + * To enable the signal handling a process we need to tell it to + * kernel; this is done writing all needed info to a sigaction structure + * named sigact, and then calling sigaction() system call passing the + * information stored in the sigact structure variable. + * + * Input: the signal to handle + * the signal handler function (sa_sigaction type) + * Return: the previous signal handler + */ +inline SigAction * Action(int signo, SigAction *func) +{ + struct sigaction new_handl, old_handl; + new_handl.sa_flags=SA_SIGINFO; /* we use sa_sigaction handler */ + new_handl.sa_sigaction = func; /* set signal handler */ + /* clear signal mask: no signal blocked during execution of func */ + if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ + return NULL; + } + /* change action for signo signal */ + if (sigaction(signo, &new_handl, &old_handl)){ + return NULL; + } + return (old_handl.sa_sigaction); +} +/* + * Function Action + * Initialize a sa_sigaction signal handler. + * To enable the signal handling a process we need to tell it to + * kernel; this is done writing all needed info to a sigaction structure + * named sigact, and then calling sigaction() system call passing the + * information stored in the sigact structure variable. + * + * Input: the signal to handle + * the signal handler function (sa_sigaction type) + * Return: the previous signal handler + */ +inline SigAction * ActionRestart(int signo, SigAction *func) +{ + struct sigaction new_handl, old_handl; + new_handl.sa_flags=SA_SIGINFO|SA_RESTART;/* flag setup */ + new_handl.sa_sigaction = func; /* set signal handler */ + /* clear signal mask: no signal blocked during execution of func */ + if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ + return NULL; + } + /* change action for signo signal */ + if (sigaction(signo, &new_handl, &old_handl)){ + return NULL; + } + return (old_handl.sa_sigaction); +} /* * Functions: HandSigCHLD - * Generic handler for SIGCHLD signal + * Generic simple handler for SIGCHLD signal * * Simone Piccardi Dec. 2002 */ diff --git a/sources/rtsigvalsend.c b/sources/rtsigvalsend.c index a9c156d..a1e022d 100644 --- a/sources/rtsigvalsend.c +++ b/sources/rtsigvalsend.c @@ -1,4 +1,4 @@ -/* test_fopen.c +/* rtsigvalsend.c * * Copyright (C) 2021 Simone Piccardi * diff --git a/sources/testsignalcgi.c b/sources/testsignalcgi.c index b021b2f..010cef5 100644 --- a/sources/testsignalcgi.c +++ b/sources/testsignalcgi.c @@ -40,9 +40,9 @@ #include void sig_hand(int, siginfo_t *, void *); -typedef void SigFunc(int, siginfo_t *, void *); +typedef void SigAction(int, siginfo_t *, void *); /* Function Signal: Initialize a signal handler. See SigHand.c */ -SigFunc * Signal(int signo, SigFunc *func); +SigAction * Signal(int signo, SigAction *func); FILE * file; @@ -95,7 +95,7 @@ void sig_hand(int sig, siginfo_t * siginfo, void *ptr) { fprintf(file, "Printed time: %s", ctime(&t)); } -inline SigFunc * Signal(int signo, SigFunc *func) +inline SigAction * Signal(int signo, SigAction *func) { struct sigaction new_handl, old_handl; new_handl.sa_sigaction = func; /* set signal handler */