From: Simone Piccardi Date: Mon, 16 Aug 2021 10:56:21 +0000 (+0200) Subject: Aggiunto programmino di prova per i segnali real time. X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=21e461fe379f4875729fcfe1ac1876f5f166e827 Aggiunto programmino di prova per i segnali real time. --- diff --git a/signal.tex b/signal.tex index c2446f1..a7aaa3f 100644 --- a/signal.tex +++ b/signal.tex @@ -2168,7 +2168,7 @@ definiti come una \direct{union}.\footnote{la direttiva \direct{union} del cui campi indicano i diversi tipi di valori che possono essere salvati, in maniera alternativa, all'interno della stessa.} -Installando un gestore di tipo \var{sa\_sigaction} diventa possibile +Installando un gestore di tipo \var{sa\_sigaction} diventa possibile accedere alle informazioni restituite attraverso il puntatore a questa struttura. Tutti i segnali impostano i campi \var{si\_signo}, che riporta il numero del segnale ricevuto, \var{si\_errno}, che riporta, quando diverso da @@ -2694,11 +2694,11 @@ ulteriori funzioni in fig.~\ref{fig:sig_safe_functions_posix_2008}. Nella successiva revisione di POSIX.1-2013 sono poi state aggiunte le ulteriori funzioni \func{fchdir}, \func{pthread\_kill}, \func{pthread\_self}, \func{pthread\_sigmask}. L'ultima revisione dello standard alla data della -scrittura di questa sezione è la POSIX.1-2016,\footnote{un elenco è comunque - ottenibile dalla documentazione di sistema, accessibile con \texttt{man - signal-safety}, da cui si sono estratti questi elenchi.} che ha aggiunto -alle \textit{signal safe function} le ulteriori funzioni di -fig.~\ref{fig:sig_safe_functions_posix_2016}. +scrittura di questa sezione è la POSIX.1-2016,\footnote{una lista più + aggiornata può comunque essere ottenuto dalla documentazione di sistema, + accessibile con \texttt{man signal-safety}, da cui si sono estratti questi + elenchi.} che ha aggiunto alle \textit{signal safe function} le ulteriori +funzioni di fig.~\ref{fig:sig_safe_functions_posix_2016}. \begin{figure}[!htb] @@ -2723,8 +2723,8 @@ fig.~\ref{fig:sig_safe_functions_posix_2016}. \end{figure} Rispetto a questi elenchi occorre precisare che prima della versione 2.24 -delle \acr{glibc} l'implementazione delle funzioni \fork{execl} ed -\fork{execle} non era sicura, e che tuttora non lo è quella di +delle \acr{glibc} l'implementazione delle funzioni \func{execl} ed +\func{execle} non era sicura, e che tuttora non lo è quella di \func{aio\_suspend}. Inoltre è da evitare \func{fork}, che potrebbe essere rimossa in future revisioni dello standard, e che già POSIX-1.2003 indicava come tale se usata in concorrenza con \func{pthread\_atfork}. @@ -2799,52 +2799,57 @@ accessibili in un intervallo di valori specificati dalle due costanti \constd{SIGRTMIN} e \constd{SIGRTMAX}, che specificano il numero minimo e massimo associato ad un segnale \textit{real-time}. -Su Linux di solito il primo valore è 33, mentre il secondo è \code{\_NSIG-1}, -che di norma (vale a dire sulla piattaforma i386) è 64. Questo dà un totale di -32 segnali disponibili, contro gli almeno 8 richiesti da POSIX.1b. Si tenga -presente però che i primi segnali \textit{real-time} disponibili vengono usati -dalla \acr{glibc} per l'implementazione dei \textit{thread} POSIX (vedi -sez.~\ref{sec:thread_posix_intro}), ed il valore di \const{SIGRTMIN} viene -modificato di conseguenza.\footnote{per la precisione vengono usati i primi - tre per la vecchia implementazione dei \textit{LinuxThread} ed i primi due - per la nuova NTPL (\textit{New Thread Posix Library}), il che comporta che - \const{SIGRTMIN} a seconda dei casi può assumere i valori 34 o 35.} +Su Linux i segnali \textit{real-time} vengono numerati a partire da 32, fino +ad un valore massimo di 64, per un totale di 33 segnali disponibili, contro +gli almeno 8 richiesti da POSIX.1b. Si tenga presente però che i primi segnali +\textit{real-time} disponibili vengono usati dalla \acr{glibc} per +l'implementazione dei \textit{thread} POSIX (vedi +sez.~\ref{sec:thread_posix_intro}), ed il valore di \const{SIGRTMIN} fornito +quando si usano le \acr{glibc} viene modificato di conseguenza.\footnote{per + la precisione vengono usati i primi tre per la vecchia implementazione dei + \textit{LinuxThread} ed i primi due per la nuova NTPL (\textit{New Thread + Posix Library}), il che comporta che \const{SIGRTMIN} a seconda dei casi + può assumere i valori 34 o 35.} Per questo motivo nei programmi che usano i segnali \textit{real-time} non si -deve mai usare un valore assoluto dato che si correrebbe il rischio di -utilizzare un segnale in uso alle librerie, ed il numero del segnale deve -invece essere sempre specificato in forma relativa a \const{SIGRTMIN} (come -\code{SIGRTMIN + n}) avendo inoltre cura di controllare di non aver mai -superato \const{SIGRTMAX}. - -I segnali con un numero più basso hanno una priorità maggiore e vengono -consegnati per primi, inoltre i segnali \textit{real-time} non possono -interrompere l'esecuzione di un gestore di un segnale a priorità più alta; la -loro azione predefinita è quella di terminare il programma. I segnali -ordinari hanno tutti la stessa priorità, che è più alta di quella di qualunque -segnale \textit{real-time}. Lo standard non definisce niente al riguardo ma -Linux, come molte altre implementazioni, adotta questa politica. +deve mai usare un valore numerico assoluto, dato che si potrebbe correre il +rischio di utilizzare un segnale già in uso alle librerie; il numero del +segnale deve invece essere sempre specificato in forma relativa a +\const{SIGRTMIN}, con qualcosa come \code{SIGRTMIN + n}, avendo sempre cura di +controllare di non aver indicato un valore maggiore di \const{SIGRTMAX}. + +I segnali \textit{real-time} con un numero più basso hanno una priorità +maggiore e vengono consegnati per primi, inoltre i segnali \textit{real-time} +non possono interrompere l'esecuzione di un gestore di un segnale a priorità +più alta. La loro azione predefinita è sempre quella di terminare il +programma. I segnali ordinari invece hanno tutti la stessa priorità, che è +più alta di quella di qualunque segnale \textit{real-time}.\footnote{questa è + però una caratteristica di Linux, presente comunque anche nella gran parte + degli altri kernel \textit{unix-like}, lo standard infatti non definisce + niente al riguardo.} Si tenga presente che questi nuovi segnali non sono associati a nessun evento -specifico, a meno di non richiedere specificamente il loro utilizzo in +specifico, a meno di non avere richiesto l'utilizzo di uno di essi in meccanismi di notifica come quelli per l'I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io}) o per le code di messaggi POSIX (vedi -sez.~\ref{sec:ipc_posix_mq}), pertanto devono essere inviati esplicitamente. +sez.~\ref{sec:ipc_posix_mq}), pertanto nell'uso ordinario devono essere +inviati esplicitamente. -Inoltre, per poter usufruire della capacità di restituire dei dati, i relativi -gestori devono essere installati con \func{sigaction}, specificando per -\var{sa\_flags} la modalità \const{SA\_SIGINFO} che permette di utilizzare la -forma estesa \var{sa\_sigaction} del gestore (vedi +Inoltre, per poter usufruire della loro capacità di restituire dei dati, i +relativi gestori devono essere installati con \func{sigaction}, specificando +per \var{sa\_flags} la modalità \const{SA\_SIGINFO} che permette di utilizzare +la forma estesa \var{sa\_sigaction} del gestore (vedi sez.~\ref{sec:sig_sigaction}). In questo modo tutti i segnali \textit{real-time} possono restituire al gestore una serie di informazioni aggiuntive attraverso l'argomento \struct{siginfo\_t}, la cui definizione è stata già vista in fig.~\ref{fig:sig_siginfo_t}, nella trattazione dei gestori in forma estesa. -In particolare i campi utilizzati dai segnali \textit{real-time} sono -\var{si\_pid} e \var{si\_uid} in cui vengono memorizzati rispettivamente il -\ids{PID} e l'\ids{UID} effettivo del processo che ha inviato il segnale, -mentre per la restituzione dei dati viene usato il campo \var{si\_value}. +In particolare i campi di \struct{siginfo\_t} utilizzati dai segnali +\textit{real-time} sono \var{si\_pid} e \var{si\_uid} in cui vengono +memorizzati rispettivamente il \ids{PID} e l'\ids{UID} effettivo del processo +che ha inviato il segnale, ed il campo \var{si\_value} che viene usato +appositamente per poter restituire dei dati al gestore. \begin{figure}[!htb] \footnotesize \centering @@ -2857,15 +2862,17 @@ mentre per la restituzione dei dati viene usato il campo \var{si\_value}. \label{fig:sig_sigval} \end{figure} -Detto campo, identificato con il tipo di dato \type{sigval\_t}, è una -\dirct{union} di tipo \struct{sigval} (la sua definizione è in -fig.~\ref{fig:sig_sigval}) in cui può essere memorizzato o un valore numerico, -se usata nella forma \var{sival\_int}, o un puntatore, se usata nella forma -\var{sival\_ptr}. L'unione viene usata dai segnali \textit{real-time} e da -vari meccanismi di notifica per restituire dati al gestore del segnale in -\var{si\_value}. Un campo di tipo \type{sigval\_t} è presente anche nella -struttura \struct{sigevent} (definita in fig.~\ref{fig:struct_sigevent}) che -viene usata dai meccanismi di notifica come quelli per i timer POSIX (vedi +Detto campo, la cui definizione è riportata in fig.~\ref{fig:sig_sigval}, +viene indicato con il tipo di dato \type{sigval\_t}, che è una \dirct{union} +di tipo \struct{sigval} in cui può essere memorizzato o un valore numerico, se +usata nella forma \var{sival\_int}, o un puntatore, se usata nella forma +\var{sival\_ptr}. + +L'unione viene usata dai segnali \textit{real-time} e da vari meccanismi di +notifica per restituire dati al gestore del segnale in \var{si\_value}. Un +campo di tipo \type{sigval\_t} è presente anche nella struttura +\struct{sigevent} (definita in fig.~\ref{fig:struct_sigevent}) che viene usata +dai meccanismi di notifica come quelli per i timer POSIX (vedi sez.~\ref{sec:sig_timer_adv}), l'I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io}) o le code di messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_mq}). diff --git a/sources/rtsigvalsend.c b/sources/rtsigvalsend.c new file mode 100644 index 0000000..a9c156d --- /dev/null +++ b/sources/rtsigvalsend.c @@ -0,0 +1,76 @@ +/* test_fopen.c + * + * Copyright (C) 2021 Simone Piccardi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/**************************************************************** + * + * Program rtsigvalsend.c: + * Program to test sigqueue and sigval send + * + * Author: Simone Piccardi + * Aug 2021 + * + * Usage: ./rtsigvalsend + **********************************************************/ +/* + * Include needed headers + */ +#include /* unix standard library */ +#include /* standard I/O library */ +#include /* C standard library */ +#include /* C strings library */ +#include /* signal constants, types and functions */ +#include /* error definitions and routines */ +#include + +#define MAXLINE 256 + +void SigHand(int signum, siginfo_t *info, void *ucontext) { + printf("Signal %d\n", signum); + printf("From pid %d\n", info->si_pid); + printf("From user %d\n", info->si_uid); + printf("Value %d\n", info->si_value.sival_int); +} + +int main(int argc, char *argv[], char *envp[]) +{ + char buffer[MAXLINE+1]; + int nread; + sigval_t value; + int signo = SIGRTMIN+1; + + struct sigaction new_handl, old_handl; + new_handl.sa_sigaction = SigHand; + sigemptyset(&new_handl.sa_mask); + new_handl.sa_flags=SA_SIGINFO; + /* change action for signo signal */ + sigaction(signo, &new_handl, &old_handl); + while (1) { + nread = read(STDIN_FILENO, buffer, MAXLINE); + if (nread < 0) { + printf("Errore in lettura: %s\n", strerror(errno)); + return 0; + } + buffer[nread]=0; + value.sival_int = strtol(buffer, NULL, 10); + if (value.sival_int > 0) { + sigqueue(getpid(), signo, value); + } else { + printf("Ignoring invalid input\n"); + } + } +}