+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{EPOLLIN} & Il file è pronto per le operazioni di lettura
+ (analogo di \const{POLLIN}).\\
+ \const{EPOLLOUT} & Il file è pronto per le operazioni di scrittura
+ (analogo di \const{POLLOUT}).\\
+ \const{EPOLLRDHUP} & L'altro capo di un socket di tipo
+ \const{SOCK\_STREAM} (vedi sez.~\ref{sec:sock_type})
+ ha chiuso la connessione o il capo in scrittura
+ della stessa (vedi sez.~\ref{sec:TCP_shutdown}).\\
+ \const{EPOLLPRI} & Ci sono \itindex{out-of-band} dati urgenti
+ disponibili in lettura (analogo di
+ \const{POLLPRI}); questa condizione viene comunque
+ riportata in uscita, e non è necessaria impostarla
+ in ingresso.\\
+ \const{EPOLLERR} & Si è verificata una condizione di errore
+ (analogo di \const{POLLERR}); questa condizione
+ viene comunque riportata in uscita, e non è
+ necessaria impostarla in ingresso.\\
+ \const{EPOLLHUP} & Si è verificata una condizione di hung-up.\\
+ \const{EPOLLET} & Imposta la notifica in modalità \textit{edge
+ triggered} per il file descriptor associato.\\
+ \const{EPOLLONESHOT}& Imposta la modalità \textit{one-shot} per il file
+ descriptor associato.\footnotemark\\
+ \hline
+ \end{tabular}
+ \caption{Costanti che identificano i bit del campo \param{events} di
+ \struct{epoll\_event}.}
+ \label{tab:epoll_events}
+\end{table}
+
+\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.2.}
+
+Le modalità di utilizzo di \textit{epoll} prevedono che si definisca qual'è
+l'insieme dei file descriptor da tenere sotto controllo tramite un certo
+\textit{epoll descriptor} \param{epfd} attraverso una serie di chiamate a
+\const{EPOLL\_CTL\_ADD}.\footnote{un difetto dell'interfaccia è che queste
+ chiamate devono essere ripetute per ciascun file descriptor, incorrendo in
+ una perdita di prestazioni qualora il numero di file descriptor sia molto
+ grande; per questo è stato proposto di introdurre come estensione una
+ funzione \func{epoll\_ctlv} che consenta di effettuare con una sola chiamata
+ le impostazioni per un blocco di file descriptor.} L'uso di
+\const{EPOLL\_CTL\_MOD} consente in seguito di modificare le modalità di
+osservazione di un file descriptor che sia già stato aggiunto alla lista di
+osservazione.
+
+Le impostazioni di default prevedono che la notifica degli eventi richiesti
+sia effettuata in modalità \textit{level triggered}, a meno che sul file
+descriptor non si sia impostata la modalità \textit{edge triggered},
+registrandolo con \const{EPOLLET} attivo nel campo \var{events}. Si tenga
+presente che è possibile tenere sotto osservazione uno stesso file descriptor
+su due \textit{epoll descriptor} diversi, ed entrambi riceveranno le
+notifiche, anche se questa pratica è sconsigliata.
+
+Qualora non si abbia più interesse nell'osservazione di un file descriptor lo
+si può rimuovere dalla lista associata a \param{epfd} con
+\const{EPOLL\_CTL\_DEL}; si tenga conto inoltre che i file descriptor sotto
+osservazione che vengono chiusi sono eliminati dalla lista automaticamente e
+non è necessario usare \const{EPOLL\_CTL\_DEL}.
+
+Infine una particolare modalità di notifica è quella impostata con
+\const{EPOLLONESHOT}: a causa dell'implementazione di \textit{epoll} infatti
+quando si è in modalità \textit{edge triggered} l'arrivo in rapida successione
+di dati in blocchi separati\footnote{questo è tipico con i socket di rete, in
+ quanto i dati arrivano a pacchetti.} può causare una generazione di eventi
+(ad esempio segnalazioni di dati in lettura disponibili) anche se la
+condizione è già stata rilevata.\footnote{si avrebbe cioè una rottura della
+ logica \textit{edge triggered}.}
+
+Anche se la situazione è facile da gestire, la si può evitare utilizzando
+\const{EPOLLONESHOT} per impostare la modalità \textit{one-shot}, in cui la
+notifica di un evento viene effettuata una sola volta, dopo di che il file
+descriptor osservato, pur restando nella lista di osservazione, viene
+automaticamente disattivato,\footnote{la cosa avviene contestualmente al
+ ritorno di \func{epoll\_wait} a causa dell'evento in questione.} e per
+essere riutilizzato dovrà essere riabilitato esplicitamente con una successiva
+chiamata con \const{EPOLL\_CTL\_MOD}.
+
+Una volta impostato l'insieme di file descriptor che si vogliono osservare con
+i relativi eventi, la funzione che consente di attendere l'occorrenza di uno
+di tali eventi è \funcd{epoll\_wait}, il cui prototipo è:
+\begin{prototype}{sys/epoll.h}
+ {int epoll\_wait(int epfd, struct epoll\_event * events, int maxevents, int
+ timeout)}
+
+ Attende che uno dei file descriptor osservati sia pronto.
+
+ \bodydesc{La funzione restituisce il numero di file descriptor pronti in
+ caso di successo o $-1$ in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] il file descriptor \param{epfd} non è valido.
+ \item[\errcode{EFAULT}] il puntatore \param{events} non è valido.
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale prima
+ della scadenza di \param{timeout}.
+ \item[\errcode{EINVAL}] il file descriptor \param{epfd} non è stato ottenuto
+ con \func{epoll\_create}, o \param{maxevents} non è maggiore di zero.
+ \end{errlist}
+}
+\end{prototype}
+
+La funzione si blocca in attesa di un evento per i file descriptor registrati
+nella lista di osservazione di \param{epfd} fino ad un tempo massimo
+specificato in millisecondi tramite l'argomento \param{timeout}. Gli eventi
+registrati vengono riportati in un vettore di strutture \struct{epoll\_event}
+(che deve essere stato allocato in precedenza) all'indirizzo indicato
+dall'argomento \param{events}, fino ad un numero massimo di eventi impostato
+con l'argomento \param{maxevents}.
+
+La funzione ritorna il numero di eventi rilevati, o un valore nullo qualora
+sia scaduto il tempo massimo impostato con \param{timeout}. Per quest'ultimo,
+oltre ad un numero di millisecondi, si può utilizzare il valore nullo, che
+indica di non attendere e ritornare immediatamente,\footnote{anche in questo
+ caso il valore di ritorno sarà nullo.} o il valore $-1$, che indica
+un'attesa indefinita. L'argomento \param{maxevents} dovrà invece essere sempre
+un intero positivo.
+
+Come accennato la funzione restituisce i suoi risultati nel vettore di
+strutture \struct{epoll\_event} puntato da \param{events}; in tal caso nel
+campo \param{events} di ciascuna di esse saranno attivi i flag relativi agli
+eventi accaduti, mentre nel campo \var{data} sarà restituito il valore che era
+stato impostato per il file descriptor per cui si è verificato l'evento quando
+questo era stato registrato con le operazioni \const{EPOLL\_CTL\_MOD} o
+\const{EPOLL\_CTL\_ADD}, in questo modo il campo \var{data} consente di
+identificare il file descriptor.\footnote{ed è per questo che, come accennato,
+ è consuetudine usare per \var{data} il valore del file descriptor stesso.}
+
+Si ricordi che le occasioni per cui \func{epoll\_wait} ritorna dipendono da
+come si è impostata la modalità di osservazione (se \textit{level triggered} o
+\textit{edge triggered}) del singolo file descriptor. L'interfaccia assicura
+che se arrivano più eventi fra due chiamate successive ad \func{epoll\_wait}
+questi vengano combinati. Inoltre qualora su un file descriptor fossero
+presenti eventi non ancora notificati, e si effettuasse una modifica
+dell'osservazione con \const{EPOLL\_CTL\_MOD} questi verrebbero riletti alla
+luce delle modifiche.
+
+Si tenga presente infine che con l'uso della modalità \textit{edge triggered}
+il ritorno di \func{epoll\_wait} indica un file descriptor è pronto e resterà
+tale fintanto che non si sono completamente esaurite le operazioni su di esso.
+Questa condizione viene generalmente rilevata dall'occorrere di un errore di
+\errcode{EAGAIN} al ritorno di una \func{read} o una \func{write},\footnote{è
+ opportuno ricordare ancora una volta che l'uso dell'\textit{I/O multiplexing}
+ richiede di operare sui file in modalità non bloccante.} ma questa non è la
+sola modalità possibile, ad esempio la condizione può essere riconosciuta
+anche con il fatto che sono stati restituiti meno dati di quelli richiesti.
+
+Come già per \func{select} e \func{poll} anche per l'interfaccia di
+\textit{epoll} si pone il problema di gestire l'attesa di segnali e di dati
+contemponeamente, per far questo di nuovo è necessaria una variante della
+funzione di attesa che consenta di reimpostare all'uscita una maschera di
+segnali, analoga alle precedenti estensioni \func{pselect} e \func{ppoll}; in
+questo caso la funzione si chiama \funcd{epoll\_pwait}\footnote{introdotta a
+ partire dal kernel 2.6.19.} ed il suo prototipo è:
+\begin{prototype}{sys/epoll.h}
+ {int epoll\_pwait(int epfd, struct epoll\_event * events, int maxevents,
+ int timeout, const sigset\_t *sigmask)}
+
+ Attende che uno dei file descriptor osservati sia pronto, mascherando i
+ segnali.
+
+ \bodydesc{La funzione restituisce il numero di file descriptor pronti in
+ caso di successo o $-1$ in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori già visti con \funcd{epoll\_wait}.
+}
+\end{prototype}
+
+La funzione è del tutto analoga \funcd{epoll\_wait}, soltanto che alla sua
+uscita viene ripristinata la maschera di segnali originale, sostituita durante
+l'esecuzione da quella impostata con l'argomento \param{sigmask}; in sostanza
+la chiamata a questa funzione è equivalente al seguente codice, eseguito però
+in maniera atomica:
+\includecodesnip{listati/epoll_pwait_means.c}
+
+Si tenga presente che come le precedenti funzioni di \textit{I/O multiplexing}
+anche le funzioni dell'interfaccia di \textit{epoll} vengono utilizzate
+prevalentemente con i server di rete, quando si devono tenere sotto
+osservazione un gran numero di socket; per questo motivo rimandiamo di nuovo
+la trattazione di un esempio concreto a quando avremo esaminato in dettaglio
+le caratteristiche dei socket, in particolare si potrà trovare un programma
+che utilizza questa interfaccia in sez.~\ref{sec:TCP_sock_multiplexing}.
+
+\itindend{epoll}
+
+
+\section{L'accesso \textsl{asincrono} ai file}
+\label{sec:file_asyncronous_access}
+
+Benché l'\textit{I/O multiplexing} sia stata la prima, e sia tutt'ora una fra
+le più diffuse modalità di gestire l'I/O in situazioni complesse in cui si
+debba operare su più file contemporaneamente, esistono altre modalità di
+gestione delle stesse problematiche. In particolare sono importanti in questo
+contesto le modalità di accesso ai file eseguibili in maniera
+\textsl{asincrona}, quelle cioè in cui un processo non deve bloccarsi in
+attesa della disponibilità dell'accesso al file, ma può proseguire
+nell'esecuzione utilizzando invece un meccanismo di notifica asincrono (di
+norma un segnale, ma esistono anche altre interfacce, come \itindex{inotify}
+\textit{inotify}), per essere avvisato della possibilità di eseguire le
+operazioni di I/O volute.
+
+
+\subsection{Il \textit{Signal driven I/O}}
+\label{sec:file_asyncronous_operation}
+
+\itindbeg{signal~driven~I/O}
+
+Abbiamo accennato in sez.~\ref{sec:file_open} che è possibile, attraverso
+l'uso del flag \const{O\_ASYNC},\footnote{l'uso del flag di \const{O\_ASYNC} e
+ dei comandi \const{F\_SETOWN} e \const{F\_GETOWN} per \func{fcntl} è
+ specifico di Linux e BSD.} aprire un file in modalità asincrona, così come è
+possibile attivare in un secondo tempo questa modalità impostando questo flag
+attraverso l'uso di \func{fcntl} con il comando \const{F\_SETFL} (vedi
+sez.~\ref{sec:file_fcntl}). In realtà parlare di apertura in modalità
+asincrona non significa che le operazioni di lettura o scrittura del file
+vengono eseguite in modo asincrono (tratteremo questo, che è ciò che più
+propriamente viene chiamato \textsl{I/O asincrono}, in
+sez.~\ref{sec:file_asyncronous_io}), quanto dell'attivazione un meccanismo di
+notifica asincrona delle variazione dello stato del file descriptor aperto in
+questo modo.
+
+Quello che succede è che per tutti i file posti in questa modalità\footnote{si
+ tenga presente però che essa non è utilizzabile con i file ordinari ma solo
+ con socket, file di terminale o pseudo terminale, ed anche, a partire dal
+ kernel 2.6, anche per fifo e pipe.} il sistema genera un apposito segnale,
+\const{SIGIO}, tutte le volte che diventa possibile leggere o scrivere dal
+file descriptor che si è posto in questa modalità. Inoltre è possibile, come
+illustrato in sez.~\ref{sec:file_fcntl}, selezionare con il comando
+\const{F\_SETOWN} di \func{fcntl} quale processo o quale gruppo di processi
+dovrà ricevere il segnale. In questo modo diventa possibile effettuare le
+operazioni di I/O in risposta alla ricezione del segnale, e non ci sarà più la
+necessità di restare bloccati in attesa della disponibilità di accesso ai
+file.
+
+% TODO: per i thread l'uso di F_SETOWN ha un significato diverso
+
+Per questo motivo Stevens, ed anche le pagine di manuale di Linux, chiamano
+questa modalità ``\textit{Signal driven I/O}''. Si tratta di un'altra
+modalità di gestione dell'I/O, alternativa all'uso di \itindex{epoll}
+\textit{epoll},\footnote{anche se le prestazioni ottenute con questa tecnica
+ sono inferiori, il vantaggio è che questa modalità è utilizzabile anche con
+ kernel che non supportano \textit{epoll}, come quelli della serie 2.4,
+ ottenendo comunque prestazioni superiori a quelle che si hanno con
+ \func{poll} e \func{select}.} che consente di evitare l'uso delle funzioni
+\func{poll} o \func{select} che, come illustrato in sez.~\ref{sec:file_epoll},
+quando vengono usate con un numero molto grande di file descriptor, non hanno
+buone prestazioni.
+
+Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
+presenta notevoli problemi, dato che non è possibile determinare, quando i
+file descriptor sono più di uno, qual è quello responsabile dell'emissione del
+segnale. Inoltre dato che i segnali normali non si accodano (si ricordi quanto
+illustrato in sez.~\ref{sec:sig_notification}), in presenza di più file
+descriptor attivi contemporaneamente, più segnali emessi nello stesso momento
+verrebbero notificati una volta sola.
+
+Linux però supporta le estensioni POSIX.1b dei segnali real-time, che vengono
+accodati e che permettono di riconoscere il file descriptor che li ha emessi.
+In questo caso infatti si può fare ricorso alle informazioni aggiuntive
+restituite attraverso la struttura \struct{siginfo\_t}, utilizzando la forma
+estesa \var{sa\_sigaction} del gestore installata con il flag
+\const{SA\_SIGINFO} (si riveda quanto illustrato in
+sez.~\ref{sec:sig_sigaction}).
+
+Per far questo però occorre utilizzare le funzionalità dei segnali real-time
+(vedi sez.~\ref{sec:sig_real_time}) impostando esplicitamente con il comando
+\const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
+I/O asincrono (il segnale predefinito è \const{SIGIO}). In questo caso il
+gestore, tutte le volte che riceverà \const{SI\_SIGIO} come valore del campo
+\var{si\_code}\footnote{il valore resta \const{SI\_SIGIO} qualunque sia il
+ segnale che si è associato all'I/O, ed indica appunto che il segnale è stato
+ generato a causa di attività di I/O.} di \struct{siginfo\_t}, troverà nel
+campo \var{si\_fd} il valore del file descriptor che ha generato il segnale.
+
+Un secondo vantaggio dell'uso dei segnali real-time è che essendo questi
+ultimi dotati di una coda di consegna ogni segnale sarà associato ad uno solo
+file descriptor; inoltre sarà possibile stabilire delle priorità nella
+risposta a seconda del segnale usato, dato che i segnali real-time supportano
+anche questa funzionalità. In questo modo si può identificare immediatamente
+un file su cui l'accesso è diventato possibile evitando completamente l'uso di
+funzioni come \func{poll} e \func{select}, almeno fintanto che non si satura
+la coda.
+
+Se infatti si eccedono le dimensioni di quest'ultima, il kernel, non potendo
+più assicurare il comportamento corretto per un segnale real-time, invierà al
+suo posto un solo \const{SIGIO}, su cui si saranno accumulati tutti i segnali
+in eccesso, e si dovrà allora determinare con un ciclo quali sono i file
+diventati attivi. L'unico modo per essere sicuri che questo non avvenga è di
+impostare la lunghezza della coda dei segnali real-time ad una dimensione
+identica al valore massimo del numero di file descriptor
+utilizzabili.\footnote{vale a dire impostare il contenuto di
+ \procfile{/proc/sys/kernel/rtsig-max} allo stesso valore del contenuto di
+ \procfile{/proc/sys/fs/file-max}.}
+
+% TODO fare esempio che usa O_ASYNC
+
+\itindend{signal~driven~I/O}
+
+
+
+\subsection{I meccanismi di notifica asincrona.}
+\label{sec:file_asyncronous_lease}
+
+Una delle domande più frequenti nella programmazione in ambiente unix-like è
+quella di come fare a sapere quando un file viene modificato. La
+risposta\footnote{o meglio la non risposta, tanto che questa nelle Unix FAQ
+ \cite{UnixFAQ} viene anche chiamata una \textit{Frequently Unanswered
+ Question}.} è che nell'architettura classica di Unix questo non è
+possibile. Al contrario di altri sistemi operativi infatti un kernel unix-like
+classico non prevedeva alcun meccanismo per cui un processo possa essere
+\textsl{notificato} di eventuali modifiche avvenute su un file. Questo è il
+motivo per cui i demoni devono essere \textsl{avvisati} in qualche
+modo\footnote{in genere questo vien fatto inviandogli un segnale di
+ \const{SIGHUP} che, per una convenzione adottata dalla gran parte di detti
+ programmi, causa la rilettura della configurazione.} se il loro file di
+configurazione è stato modificato, perché possano rileggerlo e riconoscere le
+modifiche.
+
+Questa scelta è stata fatta perché provvedere un simile meccanismo a livello
+generico per qualunque file comporterebbe un notevole aumento di complessità
+dell'architettura della gestione dei file, il tutto per fornire una
+funzionalità che serve soltanto in alcuni casi particolari. Dato che
+all'origine di Unix i soli programmi che potevano avere una tale esigenza
+erano i demoni, attenendosi a uno dei criteri base della progettazione, che
+era di far fare al kernel solo le operazioni strettamente necessarie e
+lasciare tutto il resto a processi in user space, non era stata prevista
+nessuna funzionalità di notifica.
+
+Visto però il crescente interesse nei confronti di una funzionalità di questo
+tipo, che è molto richiesta specialmente nello sviluppo dei programmi ad
+interfaccia grafica, quando si deve presentare all'utente lo stato del
+filesystem, sono state successivamente introdotte delle estensioni che
+permettessero la creazione di meccanismi di notifica più efficienti dell'unica
+soluzione disponibile con l'interfaccia tradizionale, che è quella del
+\itindex{polling} \textit{polling}.
+
+Queste nuove funzionalità sono delle estensioni specifiche, non
+standardizzate, che sono disponibili soltanto su Linux (anche se altri kernel
+supportano meccanismi simili). Alcune di esse sono realizzate, e solo a
+partire dalla versione 2.4 del kernel, attraverso l'uso di alcuni
+\textsl{comandi} aggiuntivi per la funzione \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl}), che divengono disponibili soltanto se si è
+definita la macro \macro{\_GNU\_SOURCE} prima di includere \file{fcntl.h}.
+
+\index{file!lease|(}
+
+La prima di queste funzionalità è quella del cosiddetto \textit{file lease};
+questo è un meccanismo che consente ad un processo, detto \textit{lease
+ holder}, di essere notificato quando un altro processo, chiamato a sua volta
+\textit{lease breaker}, cerca di eseguire una \func{open} o una
+\func{truncate} sul file del quale l'\textit{holder} detiene il
+\textit{lease}.
+La notifica avviene in maniera analoga a come illustrato in precedenza per
+l'uso di \const{O\_ASYNC}: di default viene inviato al \textit{lease holder}
+il segnale \const{SIGIO}, ma questo segnale può essere modificato usando il
+comando \const{F\_SETSIG} di \func{fcntl}.\footnote{anche in questo caso si
+ può rispecificare lo stesso \const{SIGIO}.} Se si è fatto questo\footnote{è
+ in genere è opportuno farlo, come in precedenza, per utilizzare segnali
+ real-time.} e si è installato il gestore del segnale con \const{SA\_SIGINFO}
+si riceverà nel campo \var{si\_fd} della struttura \struct{siginfo\_t} il
+valore del file descriptor del file sul quale è stato compiuto l'accesso; in
+questo modo un processo può mantenere anche più di un \textit{file lease}.
+
+Esistono due tipi di \textit{file lease}: di lettura (\textit{read lease}) e
+di scrittura (\textit{write lease}). Nel primo caso la notifica avviene quando
+un altro processo esegue l'apertura del file in scrittura o usa
+\func{truncate} per troncarlo. Nel secondo caso la notifica avviene anche se
+il file viene aperto in lettura; in quest'ultimo caso però il \textit{lease}
+può essere ottenuto solo se nessun altro processo ha aperto lo stesso file.
+
+Come accennato in sez.~\ref{sec:file_fcntl} il comando di \func{fcntl} che
+consente di acquisire un \textit{file lease} è \const{F\_SETLEASE}, che viene
+utilizzato anche per rilasciarlo. In tal caso il file descriptor \param{fd}
+passato a \func{fcntl} servirà come riferimento per il file su cui si vuole
+operare, mentre per indicare il tipo di operazione (acquisizione o rilascio)
+occorrerà specificare come valore dell'argomento \param{arg} di \func{fcntl}
+uno dei tre valori di tab.~\ref{tab:file_lease_fctnl}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{F\_RDLCK} & Richiede un \textit{read lease}.\\
+ \const{F\_WRLCK} & Richiede un \textit{write lease}.\\
+ \const{F\_UNLCK} & Rilascia un \textit{file lease}.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti per i tre possibili valori dell'argomento \param{arg} di
+ \func{fcntl} quando usata con i comandi \const{F\_SETLEASE} e
+ \const{F\_GETLEASE}.}
+ \label{tab:file_lease_fctnl}
+\end{table}
+
+Se invece si vuole conoscere lo stato di eventuali \textit{file lease}
+occorrerà chiamare \func{fcntl} sul relativo file descriptor \param{fd} con il
+comando \const{F\_GETLEASE}, e si otterrà indietro nell'argomento \param{arg}
+uno dei valori di tab.~\ref{tab:file_lease_fctnl}, che indicheranno la
+presenza del rispettivo tipo di \textit{lease}, o, nel caso di
+\const{F\_UNLCK}, l'assenza di qualunque \textit{file lease}.
+
+Si tenga presente che un processo può mantenere solo un tipo di \textit{lease}
+su un file, e che un \textit{lease} può essere ottenuto solo su file di dati
+(pipe e dispositivi sono quindi esclusi). Inoltre un processo non privilegiato
+può ottenere un \textit{lease} soltanto per un file appartenente ad un
+\acr{uid} corrispondente a quello del processo. Soltanto un processo con
+privilegi di amministratore (cioè con la \itindex{capabilities} capability
+\const{CAP\_LEASE}, vedi sez.~\ref{sec:proc_capabilities}) può acquisire
+\textit{lease} su qualunque file.
+
+Se su un file è presente un \textit{lease} quando il \textit{lease breaker}
+esegue una \func{truncate} o una \func{open} che confligge con
+esso,\footnote{in realtà \func{truncate} confligge sempre, mentre \func{open},
+ se eseguita in sola lettura, non confligge se si tratta di un \textit{read
+ lease}.} la funzione si blocca\footnote{a meno di non avere aperto il file
+ con \const{O\_NONBLOCK}, nel qual caso \func{open} fallirebbe con un errore
+ di \errcode{EWOULDBLOCK}.} e viene eseguita la notifica al \textit{lease
+ holder}, così che questo possa completare le sue operazioni sul file e
+rilasciare il \textit{lease}. In sostanza con un \textit{read lease} si
+rilevano i tentativi di accedere al file per modificarne i dati da parte di un
+altro processo, mentre con un \textit{write lease} si rilevano anche i
+tentativi di accesso in lettura. Si noti comunque che le operazioni di
+notifica avvengono solo in fase di apertura del file e non sulle singole
+operazioni di lettura e scrittura.
+
+L'utilizzo dei \textit{file lease} consente al \textit{lease holder} di
+assicurare la consistenza di un file, a seconda dei due casi, prima che un
+altro processo inizi con le sue operazioni di scrittura o di lettura su di
+esso. In genere un \textit{lease holder} che riceve una notifica deve
+provvedere a completare le necessarie operazioni (ad esempio scaricare
+eventuali buffer), per poi rilasciare il \textit{lease} così che il
+\textit{lease breaker} possa eseguire le sue operazioni. Questo si fa con il
+comando \const{F\_SETLEASE}, o rimuovendo il \textit{lease} con
+\const{F\_UNLCK}, o, nel caso di \textit{write lease} che confligge con una
+operazione di lettura, declassando il \textit{lease} a lettura con
+\const{F\_RDLCK}.
+
+Se il \textit{lease holder} non provvede a rilasciare il \textit{lease} entro
+il numero di secondi specificato dal parametro di sistema mantenuto in
+\procfile{/proc/sys/fs/lease-break-time} sarà il kernel stesso a rimuoverlo (o
+declassarlo) automaticamente.\footnote{questa è una misura di sicurezza per
+ evitare che un processo blocchi indefinitamente l'accesso ad un file
+ acquisendo un \textit{lease}.} Una volta che un \textit{lease} è stato
+rilasciato o declassato (che questo sia fatto dal \textit{lease holder} o dal
+kernel è lo stesso) le chiamate a \func{open} o \func{truncate} eseguite dal
+\textit{lease breaker} rimaste bloccate proseguono automaticamente.
+
+
+\index{file!dnotify|(}
+
+Benché possa risultare utile per sincronizzare l'accesso ad uno stesso file da
+parte di più processi, l'uso dei \textit{file lease} non consente comunque di
+risolvere il problema di rilevare automaticamente quando un file o una
+directory vengono modificati, che è quanto necessario ad esempio ai programma
+di gestione dei file dei vari desktop grafici.
+
+Per risolvere questo problema a partire dal kernel 2.4 è stata allora creata
+un'altra interfaccia,\footnote{si ricordi che anche questa è una interfaccia
+ specifica di Linux che deve essere evitata se si vogliono scrivere programmi
+ portabili, e che le funzionalità illustrate sono disponibili soltanto se è
+ stata definita la macro \macro{\_GNU\_SOURCE}.} chiamata \textit{dnotify},
+che consente di richiedere una notifica quando una directory, o uno qualunque
+dei file in essa contenuti, viene modificato. Come per i \textit{file lease}
+la notifica avviene di default attraverso il segnale \const{SIGIO}, ma se ne
+può utilizzare un altro.\footnote{e di nuovo, per le ragioni già esposte in
+ precedenza, è opportuno che si utilizzino dei segnali real-time.} Inoltre,
+come in precedenza, si potrà ottenere nel gestore del segnale il file
+descriptor che è stato modificato tramite il contenuto della struttura
+\struct{siginfo\_t}.
+
+\index{file!lease|)}
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{DN\_ACCESS} & Un file è stato acceduto, con l'esecuzione di una fra
+ \func{read}, \func{pread}, \func{readv}.\\
+ \const{DN\_MODIFY} & Un file è stato modificato, con l'esecuzione di una
+ fra \func{write}, \func{pwrite}, \func{writev},
+ \func{truncate}, \func{ftruncate}.\\
+ \const{DN\_CREATE} & È stato creato un file nella directory, con
+ l'esecuzione di una fra \func{open}, \func{creat},
+ \func{mknod}, \func{mkdir}, \func{link},
+ \func{symlink}, \func{rename} (da un'altra
+ directory).\\
+ \const{DN\_DELETE} & È stato cancellato un file dalla directory con
+ l'esecuzione di una fra \func{unlink}, \func{rename}
+ (su un'altra directory), \func{rmdir}.\\
+ \const{DN\_RENAME} & È stato rinominato un file all'interno della
+ directory (con \func{rename}).\\
+ \const{DN\_ATTRIB} & È stato modificato un attributo di un file con
+ l'esecuzione di una fra \func{chown}, \func{chmod},
+ \func{utime}.\\
+ \const{DN\_MULTISHOT}& Richiede una notifica permanente di tutti gli
+ eventi.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano le varie classi di eventi per i quali
+ si richiede la notifica con il comando \const{F\_NOTIFY} di \func{fcntl}.}
+ \label{tab:file_notify}
+\end{table}
+
+Ci si può registrare per le notifiche dei cambiamenti al contenuto di una
+certa directory eseguendo la funzione \func{fcntl} su un file descriptor
+associato alla stessa con il comando \const{F\_NOTIFY}. In questo caso
+l'argomento \param{arg} di \func{fcntl} serve ad indicare per quali classi
+eventi si vuole ricevere la notifica, e prende come valore una maschera
+binaria composta dall'OR aritmetico di una o più delle costanti riportate in
+tab.~\ref{tab:file_notify}.
+
+A meno di non impostare in maniera esplicita una notifica permanente usando il
+valore \const{DN\_MULTISHOT}, la notifica è singola: viene cioè inviata una
+sola volta quando si verifica uno qualunque fra gli eventi per i quali la si è
+richiesta. Questo significa che un programma deve registrarsi un'altra volta
+se desidera essere notificato di ulteriori cambiamenti. Se si eseguono diverse
+chiamate con \const{F\_NOTIFY} e con valori diversi per \param{arg} questi
+ultimi si \textsl{accumulano}; cioè eventuali nuovi classi di eventi
+specificate in chiamate successive vengono aggiunte a quelle già impostate
+nelle precedenti. Se si vuole rimuovere la notifica si deve invece
+specificare un valore nullo.
+
+\index{file!inotify|(}
+
+Il maggiore problema di \textit{dnotify} è quello della scalabilità: si deve
+usare un file descriptor per ciascuna directory che si vuole tenere sotto
+controllo, il che porta facilmente ad avere un eccesso di file aperti. Inoltre
+quando la directory che si controlla è all'interno di un dispositivo
+rimovibile, mantenere il relativo file descriptor aperto comporta
+l'impossibilità di smontare il dispositivo e di rimuoverlo, il che in genere
+complica notevolmente la gestione dell'uso di questi dispositivi.
+
+Un altro problema è che l'interfaccia di \textit{dnotify} consente solo di
+tenere sotto controllo il contenuto di una directory; la modifica di un file
+viene segnalata, ma poi è necessario verificare di quale file si tratta
+(operazione che può essere molto onerosa quando una directory contiene un gran
+numero di file). Infine l'uso dei segnali come interfaccia di notifica
+comporta tutti i problemi di gestione visti in sez.~\ref{sec:sig_management} e
+sez.~\ref{sec:sig_adv_control}. Per tutta questa serie di motivi in generale
+quella di \textit{dnotify} viene considerata una interfaccia di usabilità
+problematica.
+
+\index{file!dnotify|)}
+
+Per risolvere i problemi appena illustrati è stata introdotta una nuova
+interfaccia per l'osservazione delle modifiche a file o directory, chiamata
+\textit{inotify}.\footnote{l'interfaccia è disponibile a partire dal kernel
+ 2.6.13, le relative funzioni sono state introdotte nelle glibc 2.4.} Anche
+questa è una interfaccia specifica di Linux (pertanto non deve essere usata se
+si devono scrivere programmi portabili), ed è basata sull'uso di una coda di
+notifica degli eventi associata ad un singolo file descriptor, il che permette
+di risolvere il principale problema di \itindex{dnotify} \textit{dnotify}. La
+coda viene creata attraverso la funzione \funcd{inotify\_init}, il cui
+prototipo è:
+\begin{prototype}{sys/inotify.h}
+ {int inotify\_init(void)}
+
+ Inizializza una istanza di \textit{inotify}.
+
+ \bodydesc{La funzione restituisce un file descriptor in caso di successo, o
+ $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EMFILE}] si è raggiunto il numero massimo di istanze di
+ \textit{inotify} consentite all'utente.
+ \item[\errcode{ENFILE}] si è raggiunto il massimo di file descriptor aperti
+ nel sistema.
+ \item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel per creare
+ l'istanza.
+ \end{errlist}
+}
+\end{prototype}
+
+La funzione non prende alcun argomento; inizializza una istanza di
+\textit{inotify} e restituisce un file descriptor attraverso il quale verranno
+effettuate le operazioni di notifica;\footnote{per evitare abusi delle risorse
+ di sistema è previsto che un utente possa utilizzare un numero limitato di
+ istanze di \textit{inotify}; il valore di default del limite è di 128, ma
+ questo valore può essere cambiato con \func{sysctl} o usando il file
+ \procfile{/proc/sys/fs/inotify/max\_user\_instances}.} si tratta di un file
+descriptor speciale che non è associato a nessun file su disco, e che viene
+utilizzato solo per notificare gli eventi che sono stati posti in
+osservazione. Dato che questo file descriptor non è associato a nessun file o
+directory reale, l'inconveniente di non poter smontare un filesystem i cui
+file sono tenuti sotto osservazione viene completamente
+eliminato.\footnote{anzi, una delle capacità dell'interfaccia di
+ \textit{inotify} è proprio quella di notificare il fatto che il filesystem
+ su cui si trova il file o la directory osservata è stato smontato.}
+
+Inoltre trattandosi di un file descriptor a tutti gli effetti, esso potrà
+essere utilizzato come argomento per le funzioni \func{select} e \func{poll} e
+con l'interfaccia di \textit{epoll};\footnote{ed a partire dal kernel 2.6.25 è
+ stato introdotto anche il supporto per il \itindex{signal~driven~I/O}
+ \texttt{signal-driven I/O} trattato in
+ sez.~\ref{sec:file_asyncronous_operation}.} siccome gli eventi vengono
+notificati come dati disponibili in lettura, dette funzioni ritorneranno tutte
+le volte che si avrà un evento di notifica. Così, invece di dover utilizzare i
+segnali,\footnote{considerati una pessima scelta dal punto di vista
+ dell'interfaccia utente.} si potrà gestire l'osservazione degli eventi con
+una qualunque delle modalità di \textit{I/O multiplexing} illustrate in
+sez.~\ref{sec:file_multiplexing}. Qualora si voglia cessare l'osservazione,
+sarà sufficiente chiudere il file descriptor e tutte le risorse allocate
+saranno automaticamente rilasciate.
+
+Infine l'interfaccia di \textit{inotify} consente di mettere sotto
+osservazione, oltre che una directory, anche singoli file. Una volta creata
+la coda di notifica si devono definire gli eventi da tenere sotto
+osservazione; questo viene fatto attraverso una \textsl{lista di osservazione}
+(o \textit{watch list}) che è associata alla coda. Per gestire la lista di
+osservazione l'interfaccia fornisce due funzioni, la prima di queste è
+\funcd{inotify\_add\_watch}, il cui prototipo è:
+\begin{prototype}{sys/inotify.h}
+ {int inotify\_add\_watch(int fd, const char *pathname, uint32\_t mask)}
+
+ Aggiunge un evento di osservazione alla lista di osservazione di \param{fd}.
+
+ \bodydesc{La funzione restituisce un valore positivo in caso di successo, o
+ $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCESS}] non si ha accesso in lettura al file indicato.
+ \item[\errcode{EINVAL}] \param{mask} non contiene eventi legali o \param{fd}
+ non è un file descriptor di \textit{inotify}.
+ \item[\errcode{ENOSPC}] si è raggiunto il numero massimo di voci di
+ osservazione o il kernel non ha potuto allocare una risorsa necessaria.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{ENOMEM} e \errval{EBADF}.}
+\end{prototype}
+
+La funzione consente di creare un ``\textsl{osservatore}'' (il cosiddetto
+``\textit{watch}'') nella lista di osservazione di una coda di notifica, che
+deve essere indicata specificando il file descriptor ad essa associato
+nell'argomento \param{fd}.\footnote{questo ovviamente dovrà essere un file
+ descriptor creato con \func{inotify\_init}.} Il file o la directory da
+porre sotto osservazione vengono invece indicati per nome, da passare
+nell'argomento \param{pathname}. Infine il terzo argomento, \param{mask},
+indica che tipo di eventi devono essere tenuti sotto osservazione e le
+modalità della stessa. L'operazione può essere ripetuta per tutti i file e le
+directory che si vogliono tenere sotto osservazione,\footnote{anche in questo
+ caso c'è un limite massimo che di default è pari a 8192, ed anche questo
+ valore può essere cambiato con \func{sysctl} o usando il file
+ \procfile{/proc/sys/fs/inotify/max\_user\_watches}.} e si utilizzerà sempre
+un solo file descriptor.
+
+Il tipo di evento che si vuole osservare deve essere specificato
+nell'argomento \param{mask} come maschera binaria, combinando i valori delle
+costanti riportate in tab.~\ref{tab:inotify_event_watch} che identificano i
+singoli bit della maschera ed il relativo significato. In essa si sono marcati
+con un ``$\bullet$'' gli eventi che, quando specificati per una directory,
+vengono osservati anche su tutti i file che essa contiene. Nella seconda
+parte della tabella si sono poi indicate alcune combinazioni predefinite dei
+flag della prima parte.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|p{10cm}|}
+ \hline
+ \textbf{Valore} & & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{IN\_ACCESS} &$\bullet$& C'è stato accesso al file in
+ lettura.\\
+ \const{IN\_ATTRIB} &$\bullet$& Ci sono stati cambiamenti sui dati
+ dell'inode (o sugli attributi
+ estesi, vedi
+ sez.~\ref{sec:file_xattr}).\\
+ \const{IN\_CLOSE\_WRITE} &$\bullet$& È stato chiuso un file aperto in
+ scrittura.\\
+ \const{IN\_CLOSE\_NOWRITE}&$\bullet$& È stato chiuso un file aperto in
+ sola lettura.\\
+ \const{IN\_CREATE} &$\bullet$& È stato creato un file o una
+ directory in una directory sotto
+ osservazione.\\
+ \const{IN\_DELETE} &$\bullet$& È stato cancellato un file o una
+ directory in una directory sotto
+ osservazione.\\
+ \const{IN\_DELETE\_SELF} & -- & È stato cancellato il file (o la
+ directory) sotto osservazione.\\
+ \const{IN\_MODIFY} &$\bullet$& È stato modificato il file.\\
+ \const{IN\_MOVE\_SELF} & & È stato rinominato il file (o la
+ directory) sotto osservazione.\\
+ \const{IN\_MOVED\_FROM} &$\bullet$& Un file è stato spostato fuori dalla
+ directory sotto osservazione.\\
+ \const{IN\_MOVED\_TO} &$\bullet$& Un file è stato spostato nella
+ directory sotto osservazione.\\
+ \const{IN\_OPEN} &$\bullet$& Un file è stato aperto.\\
+ \hline
+ \const{IN\_CLOSE} & & Combinazione di
+ \const{IN\_CLOSE\_WRITE} e
+ \const{IN\_CLOSE\_NOWRITE}.\\
+ \const{IN\_MOVE} & & Combinazione di
+ \const{IN\_MOVED\_FROM} e
+ \const{IN\_MOVED\_TO}.\\
+ \const{IN\_ALL\_EVENTS} & & Combinazione di tutti i flag
+ possibili.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano i bit della maschera binaria
+ dell'argomento \param{mask} di \func{inotify\_add\_watch} che indicano il
+ tipo di evento da tenere sotto osservazione.}
+ \label{tab:inotify_event_watch}
+\end{table}
+
+Oltre ai flag di tab.~\ref{tab:inotify_event_watch}, che indicano il tipo di
+evento da osservare e che vengono utilizzati anche in uscita per indicare il
+tipo di evento avvenuto, \func{inotify\_add\_watch} supporta ulteriori
+flag,\footnote{i flag \const{IN\_DONT\_FOLLOW}, \const{IN\_MASK\_ADD} e
+ \const{IN\_ONLYDIR} sono stati introdotti a partire dalle glibc 2.5, se si
+ usa la versione 2.4 è necessario definirli a mano.} riportati in
+tab.~\ref{tab:inotify_add_watch_flag}, che indicano le modalità di
+osservazione (da passare sempre nell'argomento \param{mask}) e che al
+contrario dei precedenti non vengono mai impostati nei risultati in uscita.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{IN\_DONT\_FOLLOW}& Non dereferenzia \param{pathname} se questo è un
+ link simbolico.\\
+ \const{IN\_MASK\_ADD} & Aggiunge a quelli già impostati i flag indicati
+ nell'argomento \param{mask}, invece di
+ sovrascriverli.\\
+ \const{IN\_ONESHOT} & Esegue l'osservazione su \param{pathname} per una
+ sola volta, rimuovendolo poi dalla \textit{watch
+ list}.\\
+ \const{IN\_ONLYDIR} & Se \param{pathname} è una directory riporta
+ soltanto gli eventi ad essa relativi e non
+ quelli per i file che contiene.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano i bit della maschera binaria
+ dell'argomento \param{mask} di \func{inotify\_add\_watch} che indicano le
+ modalità di osservazione.}
+ \label{tab:inotify_add_watch_flag}
+\end{table}
+
+Se non esiste nessun \textit{watch} per il file o la directory specificata
+questo verrà creato per gli eventi specificati dall'argomento \param{mask},
+altrimenti la funzione sovrascriverà le impostazioni precedenti, a meno che
+non si sia usato il flag \const{IN\_MASK\_ADD}, nel qual caso gli eventi
+specificati saranno aggiunti a quelli già presenti.
+
+Come accennato quando si tiene sotto osservazione una directory vengono
+restituite le informazioni sia riguardo alla directory stessa che ai file che
+essa contiene; questo comportamento può essere disabilitato utilizzando il
+flag \const{IN\_ONLYDIR}, che richiede di riportare soltanto gli eventi
+relativi alla directory stessa. Si tenga presente inoltre che quando si
+osserva una directory vengono riportati solo gli eventi sui file che essa
+contiene direttamente, non quelli relativi a file contenuti in eventuali
+sottodirectory; se si vogliono osservare anche questi sarà necessario creare
+ulteriori \textit{watch} per ciascuna sottodirectory.
+
+Infine usando il flag \const{IN\_ONESHOT} è possibile richiedere una notifica
+singola;\footnote{questa funzionalità però è disponibile soltanto a partire dal
+ kernel 2.6.16.} una volta verificatosi uno qualunque fra gli eventi
+richiesti con \func{inotify\_add\_watch} l'\textsl{osservatore} verrà
+automaticamente rimosso dalla lista di osservazione e nessun ulteriore evento
+sarà più notificato.
+
+In caso di successo \func{inotify\_add\_watch} ritorna un intero positivo,
+detto \textit{watch descriptor}, che identifica univocamente un
+\textsl{osservatore} su una coda di notifica; esso viene usato per farvi
+riferimento sia riguardo i risultati restituiti da \textit{inotify}, che per
+la eventuale rimozione dello stesso.
+
+La seconda funzione per la gestione delle code di notifica, che permette di
+rimuovere un \textsl{osservatore}, è \funcd{inotify\_rm\_watch}, ed il suo
+prototipo è:
+\begin{prototype}{sys/inotify.h}
+ {int inotify\_rm\_watch(int fd, uint32\_t wd)}
+
+ Rimuove un \textsl{osservatore} da una coda di notifica.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo, o $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] non si è specificato in \param{fd} un file descriptor
+ valido.
+ \item[\errcode{EINVAL}] il valore di \param{wd} non è corretto, o \param{fd}
+ non è associato ad una coda di notifica.
+ \end{errlist}
+}
+\end{prototype}
+
+La funzione rimuove dalla coda di notifica identificata dall'argomento
+\param{fd} l'osservatore identificato dal \textit{watch descriptor}
+\param{wd};\footnote{ovviamente deve essere usato per questo argomento un
+ valore ritornato da \func{inotify\_add\_watch}, altrimenti si avrà un errore
+ di \errval{EINVAL}.} in caso di successo della rimozione, contemporaneamente
+alla cancellazione dell'osservatore, sulla coda di notifica verrà generato un
+evento di tipo \const{IN\_IGNORED} (vedi
+tab.~\ref{tab:inotify_read_event_flag}). Si tenga presente che se un file
+viene cancellato o un filesystem viene smontato i relativi osservatori vengono
+rimossi automaticamente e non è necessario utilizzare
+\func{inotify\_rm\_watch}.
+
+Come accennato l'interfaccia di \textit{inotify} prevede che gli eventi siano
+notificati come dati presenti in lettura sul file descriptor associato alla
+coda di notifica. Una applicazione pertanto dovrà leggere i dati da detto file
+con una \func{read}, che ritornerà sul buffer i dati presenti nella forma di
+una o più strutture di tipo \struct{inotify\_event} (la cui definizione è
+riportata in fig.~\ref{fig:inotify_event}). Qualora non siano presenti dati la
+\func{read} si bloccherà (a meno di non aver impostato il file descriptor in
+modalità non bloccante) fino all'arrivo di almeno un evento.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/inotify_event.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{inotify\_event} usata dall'interfaccia di
+ \textit{inotify} per riportare gli eventi.}
+ \label{fig:inotify_event}
+\end{figure}
+
+Una ulteriore caratteristica dell'interfaccia di \textit{inotify} è che essa
+permette di ottenere con \func{ioctl}, come per i file descriptor associati ai
+socket (si veda sez.~\ref{sec:sock_ioctl_IP}) il numero di byte disponibili in
+lettura sul file descriptor, utilizzando su di esso l'operazione
+\const{FIONREAD}.\footnote{questa è una delle operazioni speciali per i file
+ (vedi sez.~\ref{sec:file_ioctl}), che è disponibile solo per i socket e per
+ i file descriptor creati con \func{inotify\_init}.} Si può così utilizzare
+questa operazione, oltre che per predisporre una operazione di lettura con un
+buffer di dimensioni adeguate, anche per ottenere rapidamente il numero di
+file che sono cambiati.
+
+Una volta effettuata la lettura con \func{read} a ciascun evento sarà
+associata una struttura \struct{inotify\_event} contenente i rispettivi dati.
+Per identificare a quale file o directory l'evento corrisponde viene
+restituito nel campo \var{wd} il \textit{watch descriptor} con cui il relativo
+osservatore è stato registrato. Il campo \var{mask} contiene invece una
+maschera di bit che identifica il tipo di evento verificatosi; in essa
+compariranno sia i bit elencati nella prima parte di
+tab.~\ref{tab:inotify_event_watch}, che gli eventuali valori
+aggiuntivi\footnote{questi compaiono solo nel campo \var{mask} di
+ \struct{inotify\_event}, e non utilizzabili in fase di registrazione
+ dell'osservatore.} di tab.~\ref{tab:inotify_read_event_flag}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{IN\_IGNORED} & L'osservatore è stato rimosso, sia in maniera
+ esplicita con l'uso di \func{inotify\_rm\_watch},
+ che in maniera implicita per la rimozione
+ dell'oggetto osservato o per lo smontaggio del
+ filesystem su cui questo si trova.\\
+ \const{IN\_ISDIR} & L'evento avvenuto fa riferimento ad una directory
+ (consente così di distinguere, quando si pone
+ sotto osservazione una directory, fra gli eventi
+ relativi ad essa e quelli relativi ai file che
+ essa contiene).\\
+ \const{IN\_Q\_OVERFLOW}& Si sono eccedute le dimensioni della coda degli
+ eventi (\textit{overflow} della coda); in questo
+ caso il valore di \var{wd} è $-1$.\footnotemark\\
+ \const{IN\_UNMOUNT} & Il filesystem contenente l'oggetto posto sotto
+ osservazione è stato smontato.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano i bit aggiuntivi usati nella maschera
+ binaria del campo \var{mask} di \struct{inotify\_event}.}
+ \label{tab:inotify_read_event_flag}
+\end{table}
+
+\footnotetext{la coda di notifica ha una dimensione massima specificata dal
+ parametro di sistema \procfile{/proc/sys/fs/inotify/max\_queued\_events} che
+ indica il numero massimo di eventi che possono essere mantenuti sulla
+ stessa; quando detto valore viene ecceduto gli ulteriori eventi vengono
+ scartati, ma viene comunque generato un evento di tipo
+ \const{IN\_Q\_OVERFLOW}.}
+
+Il campo \var{cookie} contiene invece un intero univoco che permette di
+identificare eventi correlati (per i quali avrà lo stesso valore), al momento
+viene utilizzato soltanto per rilevare lo spostamento di un file, consentendo
+così all'applicazione di collegare la corrispondente coppia di eventi
+\const{IN\_MOVED\_TO} e \const{IN\_MOVED\_FROM}.
+
+Infine due campi \var{name} e \var{len} sono utilizzati soltanto quando
+l'evento è relativo ad un file presente in una directory posta sotto
+osservazione, in tal caso essi contengono rispettivamente il nome del file
+(come pathname relativo alla directory osservata) e la relativa dimensione in
+byte. Il campo \var{name} viene sempre restituito come stringa terminata da
+NUL, con uno o più zeri di terminazione, a seconda di eventuali necessità di
+allineamento del risultato, ed il valore di \var{len} corrisponde al totale
+della dimensione di \var{name}, zeri aggiuntivi compresi. La stringa con il
+nome del file viene restituita nella lettura subito dopo la struttura
+\struct{inotify\_event}; questo significa che le dimensioni di ciascun evento
+di \textit{inotify} saranno pari a \code{sizeof(\struct{inotify\_event}) +
+ len}.
+
+Vediamo allora un esempio dell'uso dell'interfaccia di \textit{inotify} con un
+semplice programma che permette di mettere sotto osservazione uno o più file e
+directory. Il programma si chiama \texttt{inotify\_monitor.c} ed il codice
+completo è disponibile coi sorgenti allegati alla guida, il corpo principale
+del programma, che non contiene la sezione di gestione delle opzioni e le
+funzioni di ausilio è riportato in fig.~\ref{fig:inotify_monitor_example}.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/inotify_monitor.c}
+ \end{minipage}
+ \normalsize
+ \caption{Esempio di codice che usa l'interfaccia di \textit{inotify}.}
+ \label{fig:inotify_monitor_example}
+\end{figure}
+
+Una volta completata la scansione delle opzioni il corpo principale del
+programma inizia controllando (\texttt{\small 11--15}) che sia rimasto almeno
+un argomento che indichi quale file o directory mettere sotto osservazione (e
+qualora questo non avvenga esce stampando la pagina di aiuto); dopo di che
+passa (\texttt{\small 16--20}) all'inizializzazione di \textit{inotify}
+ottenendo con \func{inotify\_init} il relativo file descriptor (oppure usce in
+caso di errore).
+
+Il passo successivo è aggiungere (\texttt{\small 21--30}) alla coda di
+notifica gli opportuni osservatori per ciascuno dei file o directory indicati
+all'invocazione del comando; questo viene fatto eseguendo un ciclo
+(\texttt{\small 22--29}) fintanto che la variabile \var{i}, inizializzata a
+zero (\texttt{\small 21}) all'inizio del ciclo, è minore del numero totale di
+argomenti rimasti. All'interno del ciclo si invoca (\texttt{\small 23})
+\func{inotify\_add\_watch} per ciascuno degli argomenti, usando la maschera
+degli eventi data dalla variabile \var{mask} (il cui valore viene impostato
+nella scansione delle opzioni), in caso di errore si esce dal programma
+altrimenti si incrementa l'indice (\texttt{\small 29}).
+
+Completa l'inizializzazione di \textit{inotify} inizia il ciclo principale
+(\texttt{\small 32--56}) del programma, nel quale si resta in attesa degli
+eventi che si intendono osservare. Questo viene fatto eseguendo all'inizio del
+ciclo (\texttt{\small 33}) una \func{read} che si bloccherà fintanto che non
+si saranno verificati eventi.
+
+Dato che l'interfaccia di \textit{inotify} può riportare anche più eventi in
+una sola lettura, si è avuto cura di passare alla \func{read} un buffer di
+dimensioni adeguate, inizializzato in (\texttt{\small 7}) ad un valore di
+approssimativamente 512 eventi.\footnote{si ricordi che la quantità di dati
+ restituita da \textit{inotify} è variabile a causa della diversa lunghezza
+ del nome del file restituito insieme a \struct{inotify\_event}.} In caso di
+errore di lettura (\texttt{\small 35--40}) il programma esce con un messaggio
+di errore (\texttt{\small 37--39}), a meno che non si tratti di una
+interruzione della system call, nel qual caso (\texttt{\small 36}) si ripete la
+lettura.
+
+Se la lettura è andata a buon fine invece si esegue un ciclo (\texttt{\small
+ 43--52}) per leggere tutti gli eventi restituiti, al solito si inizializza
+l'indice \var{i} a zero (\texttt{\small 42}) e si ripetono le operazioni
+(\texttt{\small 43}) fintanto che esso non supera il numero di byte restituiti
+in lettura. Per ciascun evento all'interno del ciclo si assegna\footnote{si
+ noti come si sia eseguito un opportuno \textit{casting} del puntatore.} alla
+variabile \var{event} l'indirizzo nel buffer della corrispondente struttura
+\struct{inotify\_event} (\texttt{\small 44}), e poi si stampano il numero di
+\textit{watch descriptor} (\texttt{\small 45}) ed il file a cui questo fa
+riferimento (\texttt{\small 46}), ricavato dagli argomenti passati a riga di
+comando sfruttando il fatto che i \textit{watch descriptor} vengono assegnati
+in ordine progressivo crescente a partire da 1.
+
+Qualora sia presente il riferimento ad un nome di file associato all'evento lo
+si stampa (\texttt{\small 47--49}); si noti come in questo caso si sia
+utilizzato il valore del campo \var{event->len} e non al fatto che
+\var{event->name} riporti o meno un puntatore nullo.\footnote{l'interfaccia
+ infatti, qualora il nome non sia presente, non avvalora il campo
+ \var{event->name}, che si troverà a contenere quello che era precedentemente
+ presente nella rispettiva locazione di memoria, nel caso più comune il
+ puntatore al nome di un file osservato in precedenza.} Si utilizza poi
+(\texttt{\small 50}) la funzione \code{printevent}, che interpreta il valore
+del campo \var{event->mask} per stampare il tipo di eventi
+accaduti.\footnote{per il relativo codice, che non riportiamo in quanto non
+ essenziale alla comprensione dell'esempio, si possono utilizzare direttamente
+ i sorgenti allegati alla guida.} Infine (\texttt{\small 51}) si provvede ad
+aggiornare l'indice \var{i} per farlo puntare all'evento successivo.
+
+Se adesso usiamo il programma per mettere sotto osservazione una directory, e
+da un altro terminale eseguiamo il comando \texttt{ls} otterremo qualcosa del
+tipo di:
+\begin{verbatim}
+piccardi@gethen:~/gapil/sources$ ./inotify_monitor -a /home/piccardi/gapil/
+Watch descriptor 1
+Observed event on /home/piccardi/gapil/
+IN_OPEN,
+Watch descriptor 1
+Observed event on /home/piccardi/gapil/
+IN_CLOSE_NOWRITE,
+\end{verbatim}