\end{table}
L'interfaccia fornita da \func{signalfd} prevede che la ricezione dei segnali
-sia eseguita leggendo dal file descriptor restituito dalla funzione. La
-lettura fornisce nel buffer indicato come secondo argomento alla funzione
-\func{read} una o più strutture \struct{signalfd\_siginfo} a seconda della
-dimensione dello stesso e del numero di segnali pendenti. Pertanto il buffer
-deve essere almeno di dimensione pari a \code{sizeof(signalfd\_siginfo)}; se
-di dimensione maggiore potranno essere letti in unica soluzione
-
-% TODO trattare qui eventfd, signalfd e timerfd introdotte con il 2.6.22
+sia eseguita leggendo i dati relativi ai segnali pendenti dal file descriptor
+restituito dalla funzione con una normalissima \func{read}. Questi dati
+vengono scritti sul buffer indicato come secondo argomento di \func{read} in
+forma di una sequenza di una o più strutture \struct{signalfd\_siginfo} (la
+cui definizione si è riportata in fig.~\ref{fig:signalfd_siginfo}) a seconda
+sia della dimensione del buffer che del numero di segnali pendenti. Per questo
+motivo il buffer deve essere almeno di dimensione pari a quella di
+\struct{signalfd\_siginfo}, qualora sia di dimensione maggiore potranno essere
+letti in unica soluzione i dati relativi ad eventuali più segnali pendenti,
+fino al numero massimo di strutture \struct{signalfd\_siginfo} che possono
+rientrare nel buffer.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/signalfd_siginfo.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{signalfd\_siginfo}, restituita in lettura da
+ un file descriptor creato con \func{signalfd}.}
+ \label{fig:signalfd_siginfo}
+\end{figure}
+
+Si tenga presente che lettura di una struttura \struct{signalfd\_siginfo}
+relativa ad un segnale pendente è equivalente alla esecuzione di un gestore,
+vale a dire che una volta letta il segnale non sarà più pendente e non potrà
+essere ricevuto, qualora si ripristino le normali condizioni di gestione, né
+da un gestore né dalla funzione \func{sigwaitinfo}.
+
+% TODO trattare qui eventfd, timerfd introdotte con il 2.6.22
% timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25
% vedi: http://lwn.net/Articles/233462/
% http://lwn.net/Articles/245533/
% http://lwn.net/Articles/267331/
-\begin{figure}[!phtb]
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/FifoReporter-init.c}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione di inizializzazione del codice del programma
+ \file{FifoReporter.c}.}
+ \label{fig:fiforeporter_code}
+\end{figure}
+
+
+
+\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \includecodesample{listati/FifoReporter.c}
+ \includecodesample{listati/FifoReporter-main.c}
\end{minipage}
\normalsize
- \caption{Sezione principale del codice del programma \file{FifoReporter.c}.}
+ \caption{Ciclo principale del codice del programma \file{FifoReporter.c}.}
\label{fig:fiforeporter_code}
\end{figure}
...
-#include <sys/epoll.h> /* Linux epoll interface */
-#include <sys/signalfd.h>/* Linux signalfd interface */
-
-/* Subroutines declaration */
-void usage(void);
-void die(char *);
-
-/* default name for the input fifo */
-char *fifoname = "/tmp/reporter.fifo";
+#include <sys/epoll.h> /* Linux epoll interface */
+#include <sys/signalfd.h> /* Linux signalfd interface */
+void die(char *); /* print error and exit function */
#define MAX_EPOLL_EV 10
-
int main(int argc, char *argv[])
{
/* Variables definition */
char buffer[4096];
int fifofd, epfd, sigfd;
sigset_t sigmask;
+ char *fifoname = "/tmp/reporter.fifo";
struct epoll_event epev, events[MAX_EPOLL_EV];
struct signalfd_siginfo siginf;
...
/* Initial setup */
- if ((epfd=epoll_create(5)) < 0) // epoll init
+ if ((epfd=epoll_create(5)) < 0) // epoll init
die("Failing on epoll_create");
/* Signal setup for signalfd and epoll use */
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGINT);
sigaddset(&sigmask, SIGQUIT);
sigaddset(&sigmask, SIGTERM);
- if (sigprocmask(SIG_BLOCK, &sigmask, NULL) == -1) // block signals
+ if (sigprocmask(SIG_BLOCK, &sigmask, NULL) == -1) // block signals
die("Failing in sigprocmask");
if ((sigfd=signalfd(-1, &sigmask, SFD_NONBLOCK)) == -1) // take a signalfd
die("Failing in signalfd");
- epev.data.fd = sigfd; // add fd to epoll
+ epev.data.fd = sigfd; // add fd to epoll
epev.events = EPOLLIN;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, sigfd, &epev))
die("Failing in signal epoll_ctl");
}
if ((fifofd = open(fifoname, O_RDWR|O_NONBLOCK)) < 0) // open fifo
die("Cannot open read only well known fifo");
- epev.data.fd = fifofd; // add fifofd to epoll
+ epev.data.fd = fifofd; // add fd to epoll
epev.events = EPOLLIN;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fifofd, &epev))
die("Failing in fifo epoll_ctl");
--- /dev/null
+struct signalfd_siginfo {
+ uint32_t ssi_signo; /* Signal number */
+ int32_t ssi_errno; /* Error number (unused) */
+ int32_t ssi_code; /* Signal code */
+ uint32_t ssi_pid; /* PID of sender */
+ uint32_t ssi_uid; /* Real UID of sender */
+ int32_t ssi_fd; /* File descriptor (SIGIO) */
+ uint32_t ssi_tid; /* Kernel timer ID (POSIX timers)
+ uint32_t ssi_band; /* Band event (SIGIO) */
+ uint32_t ssi_overrun; /* POSIX timer overrun count */
+ uint32_t ssi_trapno; /* Trap number that caused signal */
+ int32_t ssi_status; /* Exit status or signal (SIGCHLD) */
+ int32_t ssi_int; /* Integer sent by sigqueue(2) */
+ uint64_t ssi_ptr; /* Pointer sent by sigqueue(2) */
+ uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */
+ uint64_t ssi_stime; /* System CPU time consumed (SIGCHLD) */
+ uint64_t ssi_addr; /* Address that generated signal
+ (for hardware-generated signals) */
+ uint8_t pad[X]; /* Pad size to 128 bytes (allow for
+ additional fields in the future) */
+};