+Per superare il problema di dover usare il \textit{polling} per controllare la
+possibilità di effettuare operazioni su un file aperto in modalità non
+bloccante, sia BSD che System V hanno introdotto delle nuove funzioni in grado
+di sospendere l'esecuzione di un processo in attesa che l'accesso diventi
+possibile. Il primo ad introdurre questa modalità di operazione, chiamata
+usualmente \textit{I/O multiplexing}, è stato BSD,\footnote{la funzione è
+ apparsa in BSD4.2 e standardizzata in BSD4.4, ma è stata portata su tutti i
+ sistemi che supportano i \textit{socket}, compreso le varianti di System V.}
+con la funzione \func{select}, il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/time.h}
+ \headdecl{sys/types.h}
+ \headdecl{unistd.h}
+ \funcdecl{int select(int n, fd\_set *readfds, fd\_set *writefds, fd\_set
+ *exceptfds, struct timeval *timeout)}
+
+ Attende che uno dei file descriptor degli insiemi specificati diventi
+ attivo.
+
+ \bodydesc{La funzione in caso di successo restituisce il numero di file
+ descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
+ caso \var{errno} viene settata ai valori:
+ \begin{errlist}
+ \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
+ degli insiemi.
+ \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
+ \item[\macro{EINVAL}] Si è specificato per \param{n} un valore negativo.
+ \end{errlist}
+ ed inoltre \macro{ENOMEM}.
+}
+\end{functions}
+
+La funzione mette il processo in stato di \textit{sleep} (vedi
+\tabref{tab:proc_proc_states}) fintanto che almeno uno dei file descriptor
+degli insiemo specificati (\param{readfds}, \param{writefds} e
+\param{exceptfds}), non diventa attivo, per un tempo massimo specificato da
+\param{timeout}.
+
+Per specificare quali file descriptor si intende \textsl{selezionare}, la
+funzione usa un particolare oggetto, il \textit{file descriptor set},
+identificato dal tipo \type{fd\_set}, che serve ad identificare un insieme di
+file descriptor, (in maniera analoga a come un \textit{signal set}, vedi
+\secref{sec:sig_sigset}, identifica un insieme di segnali). Per la
+manipolazione di questi \textit{file descriptor set} si possono usare delle
+opportune macro di preprocessore:
+\begin{functions}
+ \headdecl{sys/time.h}
+ \headdecl{sys/types.h}
+ \headdecl{unistd.h}
+ \funcdecl{FD\_ZERO(fd\_set *set)}
+ Inizializza l'insieme (vuoto).
+
+ \funcdecl{FD\_SET(int fd, fd\_set *set)}
+ Inserisce il file descriptor \param{fd} nell'insieme.
+
+ \funcdecl{FD\_CLR(int fd, fd\_set *set)}
+ Rimuove il file descriptor \param{fd} nell'insieme.
+
+ \funcdecl{FD\_ISSET(int fd, fd\_set *set)}
+ Controlla se il file descriptor \param{fd} è nell'insieme.
+\end{functions}
+
+In genere un \textit{file descriptor set} può contenere fino ad un massimo di
+\macro{FD\_SETSIZE} file descriptor. Questo valore in origine corrispondeva
+al limite per il numero massimo di file aperti\footnote{ad esempio in Linux,
+ fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma
+quando, come nelle versioni più recenti del kernel, non c'è più un limite
+massimo, esso indica le dimensioni massime dei numeri usati nei \textit{file
+ descriptor set}.
+
+La funzione richiede di specificare tre insiemi distinti di file descriptor;
+il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
+effettuare una lettura, il secondo, \param{writefds}, per verificare la
+possibilità effettuare una scrittura ed il terzo, \param{exceptfds}, per
+verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su
+un \textit{socket}\index{socket}, vedi \secref{sec:xxx_urgent}).
+
+La funzione inoltre richiede anche di specificare, tramite l'argomento
+\param{n}, un valore massimo del numero dei file descriptor usati
+nell'insieme; si può usare il già citato \macro{FD\_SETSIZE}, oppure il numero
+più alto dei file descriptor usati nei tre insiemi, aumentato di uno.
+
+Infine l'argomento \param{timeout}, specifica un tempo massimo di
+attesa\footnote{il tempo è valutato come \textit{elapsed time}.} prima che la
+funzione ritorni; se settato a \macro{NULL} la funzione attende
+indefinitamente. Si può specificare anche un tempo nullo (cioè una \var{struct
+ timeval} con i campi settati a zero), qualora si voglia semplicemente
+controllare lo stato corrente dei file descriptor.
+
+La funzione restituisce il totale dei file descriptor pronti nei tre insiemi,
+il valore zero indica sempre che si è raggiunto un timeout. Ciascuno dei tre
+insiemi viene sovrascritto per indicare quale file descriptor è pronto per le
+operazioni ad esso relative, in modo da poterlo controllare con la macro
+\macro{FD\_ISSET}. In caso di errore la funzione restituisce -1 e gli insiemi
+non vengono toccati.
+
+In Linux \func{select} modifica anche il valore di \param{timeout}, settandolo
+al tempo restante; questo è utile quando la funzione viene interrotta da un
+segnale, in tal caso infatti si ha un errore di \macro{EINTR}, ed occorre
+rilanciare la funzione; in questo modo non è necessario ricalcolare tutte le
+volte il tempo rimanente.\footnote{questo può causare problemi di portabilità
+ sia quando si trasporta codice scritto su Linux che legge questo valore, sia
+ quando si usano programmi scritti per altri sistemi che non dispongono di
+ questa caratteristica e ricalcolano \param{timeout} tutte le volte. In
+ genere la caratteristica è disponibile nei sistemi che derivano da System V
+ e non disponibile per quelli che derivano da BSD.}
+
+Come accennato l'interfaccia di \func{select} è una estensione di BSD; anche
+System V ha introdotto una sua interfaccia per gestire l'\textit{I/O
+ multiplexing}, basata sulla funzione \func{poll},\footnote{la funzione è
+ prevista dallo standard XPG4, ed è stata introdotta in Linux come system
+ call a partire dal kernel 2.1.23 e dalle libc 5.4.28.} il cui prototipo è:
+\begin{prototype}{sys/poll.h}
+ {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
+
+La funzione attente un cambiamento di stato per uno dei file descriptor
+specificati da \param{ufds}.
+
+\bodydesc{La funzione restituisce il numero di file descriptor con attività in
+ caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
+ restituito -1 ed \var{errno} viene settata ai valori:
+ \begin{errlist}
+ \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
+ degli insiemi.
+ \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
+ \end{errlist}
+ ed inoltre \macro{EFAULT} e \macro{ENOMEM}.}
+\end{prototype}
+
+La funzione tiene sotto controllo un numero \param{ndfs} di file descriptor
+specificati attraverso un vettore di puntatori a strutture di tipo
+\type{pollfd}, la cui definizione è riportata in \figref{fig:file_pollfd}.
+Come \func{select} anche \func{poll} permette di interrompere l'attesa dopo un
+certo tempo, che va specificato attraverso \param{timeout} in numero di
+millesecondi (un valore negativo indica un'attesa indefinita).
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct pollfd {
+ int fd; /* file descriptor */
+ short events; /* requested events */
+ short revents; /* returned events */
+};
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \type{pollfd}, utilizzata per specificare le modalità
+ di controllo di un file descriptor alla funzione \func{poll}.}
+ \label{fig:file_pollfd}
+\end{figure}
+
+Per ciascun file da controllare deve essere opportunamente predisposta una
+struttura \type{pollfd}; nel campo \var{fd} deve essere specificato il file
+descriptor, mentre nel campo \var{events} il tipo di evento su cui si vuole
+attendere; quest'ultimo deve essere specificato come maschera binaria dei
+primi tre valori riportati in \tabref{tab:file_pollfd_flags} (gli altri
+vengono utilizzati solo per \var{revents} come valori in uscita).
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|l|}
+ \hline
+ \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \macro{POLLIN} & 0x001 & È possibile la lettura immediata.\\
+ \macro{POLLPRI} & 0x002 & Sono presenti dati urgenti.\\
+ \macro{POLLOUT} & 0x004 & È possibile la scrittura immediata.\\
+ \hline
+ \macro{POLLERR} & 0x008 & C'è una condizione di errore.\\
+ \macro{POLLHUP} & 0x010 & Si è vericato un hung-up.\\
+ \macro{POLLNVAL} & 0x020 & Il file descriptor non è aperto.\\
+ \hline
+ \macro{POLLRDNORM}& 0x040 & Sono disponibili in lettura dati normali.\\
+ \macro{POLLRDBAND}& 0x080 & Sono disponibili in lettura dati ad alta
+ priorità. \\
+ \macro{POLLWRNORM}& 0x100 & È possibile la scrittura di dati normali. \\
+ \macro{POLLWRBAND}& 0x200 & È possibile la scrittura di dati ad
+ alta priorità. \\
+ \macro{POLLMSG} & 0x400 & Estensione propria di Linux.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti per l'identificazione dei vari bit dei campi
+ \var{events} e \var{revents} di \type{pollfd}.}
+ \label{tab:file_pollfd_flags}
+\end{table}
+
+La funzione ritorna, restituendo il numero di file per i quali si è verificata
+una delle condizioni di attesa richieste o un errore. Lo stato dei file
+all'uscita della funzione viene restituito nel campo \var{revents} della
+relativa struttura \type{pollfd}, che viene settato alla maschera binaria dei
+valori riportati in \tabref{tab:file_pollfd_flags}, ed oltre alle tre
+condizioni specificate tramite \var{events} può riportare anche l'occorrere di
+una condizione di errore.
+
+Lo standard POSIX è rimasto a lungo senza primitive per l'\textit{I/O
+ multiplexing}, che è stata introdotto con le ultime revisioni dello standard
+(POSIX 1003.1g-2000 e POSIX 1003.1-2001). Esso prevede che tutte le funzioni
+ad esso relative vengano dichiarate nell'header \file{sys/select.h}, che
+sostituisce i precedenti, ed aggiunge a \func{select} una nuova funzione
+\func{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed
+ l'header \file{sys/select.h}, compaiono in Linux a partire dalle \acr{glibc}
+ 2.0. Le \acr{libc4} e \acr{libc5} non contengono questo header, le
+ \acr{glibc} 2.0 contengono una definizione sbagliata di \func{psignal},
+ senza l'argomento \param{sigmask}, la definizione corretta è presente dalle
+ \acr{glibc} 2.1-2.2.1 se si è definito \macro{\_GNU\_SOURCE} e nelle
+ \acr{glibc} 2.2.2-2.2.4 se si è definito \macro{\_XOPEN\_SOURCE} con valore
+ maggiore di 600.} il cui prototipo è:
+\begin{prototype}{sys/select.h}
+ {int pselect(int n, fd\_set *readfds, fd\_set *writefds, fd\_set *exceptfds,
+ struct timespec *timeout, sigset\_t *sigmask)}
+
+ Attende che uno dei file descriptor degli insiemi specificati diventi
+ attivo.
+
+ \bodydesc{La funzione in caso di successo restituisce il numero di file
+ descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
+ caso \var{errno} viene settata ai valori:
+ \begin{errlist}
+ \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
+ degli insiemi.
+ \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
+ \item[\macro{EINVAL}] Si è specificato per \param{n} un valore negativo.
+ \end{errlist}
+ ed inoltre \macro{ENOMEM}.}
+\end{prototype}
+
+La funzione è sostanzialmente identica a \func{select}, solo che usa una
+struttura \type{timespec} per indicare con maggiore precisione il timeout e
+non ne aggiorna il valore in caso di interruzione, inoltre prende un argomento
+aggiuntivo \param{sigmask} che è il puntatore ad una maschera di segnali (si
+veda \secref{sec:sig_sigmask}). La maschera corrente viene sostituita da
+questa immediatamente prima di eseguire l'attesa, e ripristinata al ritorno
+della funzione.
+
+L'uso di \param{sigmask} è stato introdotto allo scopo di prevenire possibili
+race condition\footnote{in Linux però, non esistendo una system call apposita,
+ la funzione è implementata nelle \acr{glibc} usando \func{select}, e la
+ possibilità di una race condition resta.} quando si deve eseguire un test su
+una variabile settata da un manipolatore sulla base dell'occorrenza di un
+segnale per decidere se lanciare \func{select}. Fra il test e l'esecuzione è
+presente una finestra in cui potrebbe arrivare il segnale che non sarebbe
+rilevato; la race condition diventa superabile disabilitando il segnale prima
+del test e riabilitandolo poi grazie all'uso di \param{sigmask}.
+
+
+
+\subsection{L'\textsl{I/O asincrono}}