X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=signal.tex;h=7d3751b5c58e048b1e61eb5e81d80e8e331fe3d3;hb=18598db8d7f2ea072ae8f77ffdbefad1384cbcae;hp=edbc674a269a802be44392f4542287b56a155fbe;hpb=ff76d56c6a2c280cbe4f153173488871d7b12336;p=gapil.git diff --git a/signal.tex b/signal.tex index edbc674..7d3751b 100644 --- a/signal.tex +++ b/signal.tex @@ -904,18 +904,20 @@ e che prende un argomento di tipo \ctyp{int}.\footnote{si devono usare le operatori del C, senza di esse si sarebbe definita una funzione che ritorna un puntatore a \ctyp{void} e non un puntatore ad una funzione \ctyp{void}.} La funzione \func{signal} quindi restituisce e prende come secondo argomento -un puntatore a una funzione di questo tipo, che è appunto il gestore del -segnale. - -Il numero di segnale passato in \param{signum} può essere indicato -direttamente con una delle costanti definite in sez.~\ref{sec:sig_standard}. Il -gestore \param{handler} invece, oltre all'indirizzo della funzione da chiamare -all'occorrenza del segnale, può assumere anche i due valori costanti -\const{SIG\_IGN} con cui si dice di ignorare il segnale e \const{SIG\_DFL} per -reinstallare l'azione predefinita.\footnote{si ricordi però che i due segnali +un puntatore a una funzione di questo tipo, che è appunto la funzione che +verrà usata come gestore del segnale. + +Il numero di segnale passato nell'argomento \param{signum} può essere indicato +direttamente con una delle costanti definite in sez.~\ref{sec:sig_standard}. +L'argomento \param{handler} che indica il gestore invece, oltre all'indirizzo +della funzione da chiamare all'occorrenza del segnale, può assumere anche i +due valori costanti \const{SIG\_IGN} e \const{SIG\_DFL}; il primo indica che +il segnale deve essere ignorato,\footnote{si ricordi però che i due segnali \const{SIGKILL} e \const{SIGSTOP} non possono essere né ignorati né intercettati; l'uso di \const{SIG\_IGN} per questi segnali non ha alcun - effetto.} + effetto.} mentre il secondo ripristina l'azione predefinita.\footnote{e + serve a tornare al comportamento di default quando non si intende più + gestire direttamente un segnale.} La funzione restituisce l'indirizzo dell'azione precedente, che può essere salvato per poterlo ripristinare (con un'altra chiamata a \func{signal}) in un @@ -954,9 +956,10 @@ questi segnali pu \subsection{Le funzioni \func{kill} e \func{raise}} \label{sec:sig_kill_raise} -Come accennato in sez.~\ref{sec:sig_types}, un segnale può essere generato -direttamente da un processo attraverso una opportuna system call. Le funzioni -che si usano di solito per inviare un segnale generico sono due, \func{raise} e +Come precedentemente accennato in sez.~\ref{sec:sig_types}, un segnale può +anche essere generato direttamente nell'esecuzione di un programma, attraverso +la chiamata ad una opportuna system call. Le funzioni che si utilizzano di +solito per inviare un segnale generico ad un processo sono due: \func{raise} e \func{kill}. La prima funzione è \funcd{raise}, che è definita dallo standard ANSI C, e @@ -2224,11 +2227,88 @@ parte l'uso di \type{sigjmp\_buf} per \param{env}, \func{longjmp}. +\subsection{Criteri di programmazione per i gestori dei segnali} +\label{sec:sig_signal_handler} + +Abbiamo finora parlato dei gestori dei segnali come funzioni chiamate in +corrispondenza della consegna di un segnale. In realtà un gestore non può +essere una funzione qualunque, in quanto esso può essere eseguito in +corrispondenza all'interruzione in un punto qualunque del programma principale, +ed ad esempio può essere problematico chiamare all'interno di un gestore di +segnali la stessa funzione che dal segnale è stata interrotta. + +\index{funzioni~sicure|(} + +Il concetto è comunque più generale e porta ad una distinzione fra quelle che +che POSIX chiama \textsl{funzioni insicure} (\textit{n'Usane function}) e +\textsl{funzioni sicure} (\textit{safe function}); quando un segnale +interrompe una funzione insicura ed il gestore chiama al suo interno una +funzione insicura il sistema può dare luogo ad un comportamento indefinito. + +Tutto questo significa che un gestore di segnale deve essere programmato con +molta cura per evitare questa evenienza, pertanto è non è possibile chiamare +al suo interno una funzione qualunque, e si può ricorrere soltanto all'uso di +funzioni sicure. + +L'elenco delle funzioni sicure varia a secondo dello standard a cui si fa +riferimento, secondo quanto riportato dallo standard POSIX 1003.1 nella +revisione del 2003, le ``\textit{signal safe function}'' che possono essere +chiamate anche all'interno di un gestore di segnali sono quelle della lista +riportata in fig.~\ref{fig:sig_safe_functions}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \func{\_exit}, \func{abort}, \func{accept}, \func{access}, + \func{aio\_error} \func{aio\_return}, \func{aio\_suspend}, \func{alarm}, + \func{bind}, \func{cfgetispeed}, \func{cfgetospeed}, \func{cfsetispeed}, + \func{cfsetospeed}, \func{chdir}, \func{chmod}, \func{chown}, + \func{clock\_gettime}, \func{close}, \func{connect}, \func{creat}, + \func{dup}, \func{dup2}, \func{execle}, \func{execve}, \func{fchmod}, + \func{fchown}, \func{fcntl}, \func{fdatasync}, \func{fork}, + \func{fpathconf}, \func{fstat}, \func{fsync}, \func{ftruncate}, + \func{getegid}, \func{geteuid}, \func{getgid}, \func{getgroups}, + \func{getpeername}, \func{getpgrp}, \func{getpid}, \func{getppid}, + \func{getsockname}, \func{getsockopt}, \func{getuid}, \func{kill}, + \func{link}, \func{listen}, \func{lseek}, \func{lstat}, \func{mkdir}, + \func{mkfifo}, \func{open}, \func{pathconf}, \func{pause}, \func{pipe}, + \func{poll}, \func{posix\_trace\_event}, \func{pselect}, \func{raise}, + \func{read}, \func{readlink}, \func{recv}, \func{recvfrom}, + \func{recvmsg}, \func{rename}, \func{rmdir}, \func{select}, + \func{sem\_post}, \func{send}, \func{sendmsg}, \func{sendto}, + \func{setgid}, \func{setpgid}, \func{setsid}, \func{setsockopt}, + \func{setuid}, \func{shutdown}, \func{sigaction}, \func{sigaddset}, + \func{sigdelset}, \func{sigemptyset}, \func{sigfillset}, + \func{sigismember}, \func{signal}, \func{sigpause}, \func{sigpending}, + \func{sigprocmask}, \func{sigqueue}, \func{sigset}, \func{sigsuspend}, + \func{sleep}, \func{socket}, \func{socketpair}, \func{stat}, + \func{symlink}, \func{sysconf}, \func{tcdrain}, \func{tcflow}, + \func{tcflush}, \func{tcgetattr}, \func{tcgetgrp}, \func{tcsendbreak}, + \func{tcsetattr}, \func{tcsetpgrp}, \func{time}, \func{timer\_getoverrun}, + \func{timer\_gettime}, \func{timer\_settime}, \func{times}, \func{umask}, + \func{uname}, \func{unlink}, \func{utime}, \func{wait}, \func{waitpid}, + \func{write}. + \end{minipage} + \normalsize + \caption{Elenco delle funzioni sicure secondo lo standard POSIX + 1003.1-2003.} + \label{fig:sig_safe_functions} +\end{figure} + +\index{funzioni~sicure|)} + +Per questo motivo è opportuno mantenere al minimo indispensabile le operazioni +effettuate all'interno di un gestore di segnali, qualora si debbano compiere +operazioni complesse è sempre preferibile utilizzare la tecnica in cui si usa +il gestore per impostare il valore di una qualche variabile globale, e poi si +eseguono le operazioni complesse nel programma verificando (con tutti gli +accorgimenti visti in precedenza) il valore di questa variabile tutte le volte +che si è rilevata una interruzione dovuta ad un segnale. + \subsection{I segnali real-time} \label{sec:sig_real_time} - Lo standard POSIX.1b, nel definire una serie di nuove interfacce per i servizi real-time, ha introdotto una estensione del modello classico dei segnali che presenta dei significativi miglioramenti,\footnote{questa estensione è stata @@ -2462,10 +2542,7 @@ questa maniera devono essere mascherati per tutti i thread, compreso quello dedicato alla gestione, che potrebbe riceverlo fra due chiamate successive. -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "gapil" -%%% End: + % LocalWords: kernel POSIX timer shell control ctrl kill raise signal handler % LocalWords: reliable unreliable fig race condition sez struct process table @@ -2497,5 +2574,22 @@ dedicato alla gestione, che potrebbe riceverlo fra due chiamate successive. % LocalWords: how oldset BLOCK UNBLOCK SETMASK sigsuspend sigaltstack malloc % LocalWords: SIGSTKSZ MINSIGSTKSZ ss oss ENOMEM flags DISABLE sp setrlimit LB % LocalWords: RLIMIT rlim sigsetjmp siglongjmp sigjmp buf env savesigs jmp ptr -% LocalWords: SIGRTMIN SIGRTMAX sigval sival sigevent sigqueue EAGAIN sysctl -% LocalWords: QUEUE thread sigwait sigwaitinfo sigtimedwait info DEF SLB +% LocalWords: SIGRTMIN SIGRTMAX sigval sigevent sigqueue EAGAIN sysctl safe +% LocalWords: QUEUE thread sigwait sigwaitinfo sigtimedwait info DEF SLB bind +% LocalWords: function accept return cfgetispeed cfgetospeed cfsetispeed chdir +% LocalWords: cfsetospeed chmod chown gettime close connect creat dup execle +% LocalWords: execve fchmod fchown fdatasync fpathconf fstat fsync ftruncate +% LocalWords: getegid geteuid getgid getgroups getpeername getpgrp getppid sem +% LocalWords: getsockname getsockopt getuid listen lseek lstat mkdir mkfifo +% LocalWords: pathconf poll posix pselect read readlink recv recvfrom recvmsg +% LocalWords: rename rmdir select send sendmsg sendto setgid setpgid setsid +% LocalWords: setsockopt setuid shutdown sigpause socketpair stat symlink +% LocalWords: sysconf tcdrain tcflow tcflush tcgetattr tcgetgrp tcsendbreak +% LocalWords: tcsetattr tcsetpgrp getoverrun times umask uname unlink utime +% LocalWords: write sival + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: