X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=fileadv.tex;h=9a717f2e9b76b4370dd2d4ec1c24b1674f628221;hb=3dbc1b59f029f1ae890d56f209e8ddacaf468a73;hp=87e7bc144e4a2bbc5429780b4f2c0101e1b201cf;hpb=18598db8d7f2ea072ae8f77ffdbefad1384cbcae;p=gapil.git diff --git a/fileadv.tex b/fileadv.tex index 87e7bc1..9a717f2 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1,4 +1,4 @@ -%% fileadv.tex +gb%% fileadv.tex %% %% Copyright (C) 2000-2007 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free @@ -71,17 +71,18 @@ eseguire in continuazione delle system call che nella gran parte dei casi falliranno. Per superare questo problema è stato introdotto il concetto di \textit{I/O - multiplexing}, una nuova modalità di operazioni che consenta di tenere sotto + multiplexing}, una nuova modalità di operazioni che consente di tenere sotto controllo più file descriptor in contemporanea, permettendo di bloccare un processo quando le operazioni volute non sono possibili, e di riprenderne -l'esecuzione una volta che almeno una di quelle richieste sia disponibile, in +l'esecuzione una volta che almeno una di quelle richieste sia effettuabile, in modo da poterla eseguire con la sicurezza di non restare bloccati. Dato che, come abbiamo già accennato, per i normali file su disco non si ha mai un accesso bloccante, l'uso più comune delle funzioni che esamineremo nei prossimi paragrafi è per i server di rete, in cui esse vengono utilizzate per tenere sotto controllo dei socket; pertanto ritorneremo su di esse con -ulteriori dettagli e qualche esempio in sez.~\ref{sec:TCP_sock_multiplexing}. +ulteriori dettagli e qualche esempio di utilizzo concreto in +sez.~\ref{sec:TCP_sock_multiplexing}. \subsection{Le funzioni \func{select} e \func{pselect}} @@ -96,7 +97,7 @@ Il primo kernel unix-like ad introdurre una interfaccia per l'\textit{I/O \headdecl{sys/time.h} \headdecl{sys/types.h} \headdecl{unistd.h} - \funcdecl{int select(int n, fd\_set *readfds, fd\_set *writefds, fd\_set + \funcdecl{int select(int ndfs, fd\_set *readfds, fd\_set *writefds, fd\_set *exceptfds, struct timeval *timeout)} Attende che uno dei file descriptor degli insiemi specificati diventi @@ -109,8 +110,8 @@ Il primo kernel unix-like ad introdurre una interfaccia per l'\textit{I/O \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno degli insiemi. \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale. - \item[\errcode{EINVAL}] Si è specificato per \param{n} un valore negativo o - un valore non valido per \param{timeout}. + \item[\errcode{EINVAL}] Si è specificato per \param{ndfs} un valore negativo + o un valore non valido per \param{timeout}. \end{errlist} ed inoltre \errval{ENOMEM}. } @@ -158,7 +159,9 @@ massimo, esso indica le dimensioni massime dei numeri usati nei \textit{file 1003.1-2001, è definito in \file{sys/select.h}, ed è pari a 1024.} Si tenga presente che i \textit{file descriptor set} devono sempre essere inizializzati con \macro{FD\_ZERO}; passare a \func{select} un valore non inizializzato può -dar luogo a comportamenti non prevedibili. +dar luogo a comportamenti non prevedibili; allo stesso modo usare +\macro{FD\_SET} o \macro{FD\_CLR} con un file descriptor il cui valore eccede +\const{FD\_SETSIZE} può dare luogo ad un comportamento indefinito. La funzione richiede di specificare tre insiemi distinti di file descriptor; il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di @@ -176,19 +179,19 @@ sez.~\ref{sec:TCP_urgent_data}). Dato che in genere non si tengono mai sotto controllo fino a \const{FD\_SETSIZE} file contemporaneamente la funzione richiede di -specificare qual è il numero massimo dei file descriptor indicati nei tre +specificare qual è il valore più alto fra i file descriptor indicati nei tre insiemi precedenti. Questo viene fatto per efficienza, per evitare di passare e far controllare al kernel una quantità di memoria superiore a quella -necessaria. Questo limite viene indicato tramite l'argomento \param{n}, che -deve corrispondere al valore massimo aumentato di uno.\footnote{i file - descriptor infatti sono contati a partire da zero, ed il valore indica il - numero di quelli da tenere sotto controllo; dimenticarsi di aumentare di uno - il valore di \param{n} è un errore comune.} Infine l'argomento -\param{timeout}, specifica un tempo massimo di attesa prima che la funzione -ritorni; se impostato a \val{NULL} la funzione attende indefinitamente. Si può -specificare anche un tempo nullo (cioè una struttura \struct{timeval} con i -campi impostati a zero), qualora si voglia semplicemente controllare lo stato -corrente dei file descriptor. +necessaria. Questo limite viene indicato tramite l'argomento \param{ndfs}, che +deve corrispondere al valore massimo aumentato di uno.\footnote{si ricordi che + i file descriptor sono numerati progressivamente a partire da zero, ed il + valore indica il numero più alto fra quelli da tenere sotto controllo; + dimenticarsi di aumentare di uno il valore di \param{ndfs} è un errore + comune.} Infine l'argomento \param{timeout} specifica un tempo massimo di +attesa prima che la funzione ritorni; se impostato a \val{NULL} la funzione +attende indefinitamente. Si può specificare anche un tempo nullo (cioè una +struttura \struct{timeval} con i campi impostati a zero), qualora si voglia +semplicemente controllare lo stato corrente dei file descriptor. La funzione restituisce il numero di file descriptor pronti,\footnote{questo è il comportamento previsto dallo standard, ma la standardizzazione della @@ -203,6 +206,15 @@ contenuto. \itindend{file~descriptor~set} +Una volta ritornata la funzione si potrà controllare quali sono i file +descriptor pronti ed operare su di essi, si tenga presente però che si tratta +solo di un suggerimento, esistono infatti condizioni\footnote{ad esempio + quando su un socket arrivano dei dati che poi vengono scartati perché + corrotti.} in cui \func{select} può riportare in maniera spuria che un file +descriptor è pronto in lettura, quando una successiva lettura si bloccherebbe. +Per questo quando si usa \textit{I/O multiplexing} è sempre raccomandato l'uso +delle funzioni di lettura e scrittura in modalità non bloccante. + In Linux \func{select} modifica anche il valore di \param{timeout}, impostandolo al tempo restante in caso di interruzione prematura; questo è utile quando la funzione viene interrotta da un segnale, in tal caso infatti @@ -217,10 +229,10 @@ rimanente.\footnote{questo pu Uno dei problemi che si presentano con l'uso di \func{select} è che il suo comportamento dipende dal valore del file descriptor che si vuole tenere sotto -controllo. Infatti il kernel riceve con \param{n} un valore massimo per tale -valore, e per capire quali sono i file descriptor da tenere sotto controllo -dovrà effettuare una scansione su tutto l'intervallo, che può anche essere -anche molto ampio anche se i file descriptor sono solo poche unità; tutto ciò +controllo. Infatti il kernel riceve con \param{ndfs} un limite massimo per +tale valore, e per capire quali sono i file descriptor da tenere sotto +controllo dovrà effettuare una scansione su tutto l'intervallo, che può anche +essere molto ampio anche se i file descriptor sono solo poche unità; tutto ciò ha ovviamente delle conseguenze ampiamente negative per le prestazioni. Inoltre c'è anche il problema che il numero massimo dei file che si possono @@ -258,8 +270,8 @@ precedenti, ed inoltre aggiunge a \func{select} una nuova funzione \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno degli insiemi. \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale. - \item[\errcode{EINVAL}] Si è specificato per \param{n} un valore negativo o - un valore non valido per \param{timeout}. + \item[\errcode{EINVAL}] Si è specificato per \param{ndfs} un valore negativo + o un valore non valido per \param{timeout}. \end{errlist} ed inoltre \errval{ENOMEM}.} \end{prototype} @@ -446,7 +458,7 @@ tramite \var{errno}. L'uso di \func{poll} consente di superare alcuni dei problemi illustrati in precedenza per \func{select}; anzitutto, dato che in questo caso si usa un vettore di strutture \struct{pollfd} di dimensione arbitraria, non esiste il -limite introdotto dalle dimesioni massime di un \itindex{file~descriptor~set} +limite introdotto dalle dimensioni massime di un \itindex{file~descriptor~set} \textit{file descriptor set} e la dimensione dei dati passati al kernel dipende solo dal numero dei file descriptor che si vogliono controllare, non dal loro valore.\footnote{anche se usando dei bit un \textit{file descriptor @@ -534,22 +546,278 @@ diventati attivi. In una situazione come questa l'uso delle funzioni classiche dell'interfaccia dell'\textit{I/O multiplexing} viene a costituire un collo di bottiglia che degrada irrimediabilmente le prestazioni. -Per risolvere questo tipo di situazioni è stata creata una nuova -interfaccia,\footnote{l'interfaccia è stata creata da Davide Libernzi, ed è - stata introdotta per la prima volta nel kernel 2.5.44, ma la sua forma - definitiva è stata raggiunta nel kernel 2.5.66.} detta \textit{epoll}, il -cui concetto fondamentale è quello di restituire solamente le informazioni -relative ai file descriptor osservati che presentano una attività, evitando -così tutti le problematiche appena illustrate. +Per risolvere questo tipo di situazioni sono state ideate delle interfacce +specialistiche\footnote{come \texttt{/dev/poll} in Solaris, o \texttt{kqueue} + in BSD.} il cui scopo fondamentale è quello di restituire solamente le +informazioni relative ai file descriptor osservati che presentano una +attività, evitando così le problematiche appena illustrate. In genere queste +prevedono che si registrino una sola volta i file descriptor da tenere sotto +osservazione, e forniscono un meccanismo che notifica quali di questi +presentano attività. + +Le modalità con cui avviene la notifica sono due, la prima è quella classica +(quella usata da \func{poll} e \func{select}) che viene chiamata \textit{level + triggered}.\footnote{la nomenclatura è stata introdotta da Jonathan Lemon in + un articolo su \texttt{kqueue} al BSDCON 2000, e deriva da quella usata + nell'elettronica digitale.} In questa modalità vengono notificati i file +descriptor che sono \textsl{pronti} per l'operazione richiesta, e questo +avviene indipendentemente dalle operazioni che possono essere state fatte su +di essi a partire dalla precedente notifica. Per chiarire meglio il concetto +ricorriamo ad un esempio: se su un file descriptor sono diventati disponibili +in lettura 2000 byte ma dopo la notifica ne sono letti solo 1000 (ed è quindi +possibile eseguire una ulteriore lettura dei restanti 1000), in modalità +\textit{level triggered} questo sarà nuovamente notificato come +\textsl{pronto}. + +La seconda modalità, è detta \textit{edge triggered}, e prevede che invece +vengano notificati solo i file descriptor che hanno subito una transizione da +\textsl{non pronti} a \textsl{pronti}. Questo significa che in modalità +\textit{edge triggered} nel caso del precedente esempio il file descriptor +diventato pronto da cui si sono letti solo 1000 byte non verrà nuovamente +notificato come pronto, nonostante siano ancora disponibili in lettura 1000 +byte. Solo una volta che si saranno esauriti tutti i byte disponibili, e che +il file descriptor sia tornato non essere pronto, si potrà ricevere una +ulteriore notifica qualora ritornasse pronto. + +Nel caso di Linux al momento la sola interfaccia che fornisce questo tipo di +servizio è \textit{epoll},\footnote{l'interfaccia è stata creata da Davide + Libenzi, ed è stata introdotta per la prima volta nel kernel 2.5.44, ma la + sua forma definitiva è stata raggiunta nel kernel 2.5.66.} anche se sono in +discussione altre interfacce con le quali si potranno effettuare lo stesso +tipo di operazioni;\footnote{al momento della stesura di queste note (Giugno + 2007) un'altra interfaccia proposta è quella di \textit{kevent}, che + fornisce un sistema di notifica di eventi generico in grado di fornire le + stesse funzionalità di \textit{epoll}, esiste però una forte discussione + intorno a tutto ciò e niente di definito.} \textit{epoll} è in grado di +operare sia in modalità \textit{level triggered} che \textit{edge triggered}. + +La prima versione \textit{epoll} prevedeva l'apertura di uno speciale file di +dispositivo, \texttt{/dev/epoll}, per ottenere un file descriptor da +utilizzare con le funzioni dell'interfaccia,\footnote{il backporting + dell'interfaccia per il kernel 2.4, non ufficiale, utilizza sempre questo + file.} ma poi si è passati all'uso una apposita \textit{system call}. Il +primo passo per usare l'interfaccia di \textit{epoll} è pertanto quello di +chiamare la funzione \funcd{epoll\_create}, il cui prototipo è: +\begin{prototype}{sys/epoll.h} + {int epoll\_create(int size)} + + Apre un file descriptor per \textit{epoll}. + + \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{EINVAL}] si è specificato un valore di \param{size} non + positivo. + \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 restituisce un file descriptor speciale,\footnote{esso non è + associato a nessun file su disco, inoltre a differenza dei normali file + descriptor non può essere inviato ad un altro processo attraverso un socket + locale (vedi sez.~\ref{sec:sock_fd_passing}).} detto anche \textit{epoll + descriptor}, che viene associato alla infrastruttura utilizzata dal kernel +per gestire la notifica degli eventi; l'argomento \param{size} serve a dare +l'indicazione del numero di file descriptor che si vorranno tenere sotto +controllo, ma costituisce solo un suggerimento per semplificare l'allocazione +di risorse sufficienti, non un valore massimo. + +Una volta ottenuto un file descriptor per \textit{epoll} il passo successivo è +indicare quali file descriptor mettere sotto osservazione e quali operazioni +controllare, per questo si deve usare la seconda funzione dell'interfaccia, +\funcd{epoll\_ctl}, il cui prototipo è: +\begin{prototype}{sys/epoll.h} + {int epoll\_ctl(int epfd, int op, int fd, struct epoll\_event *event)} + + Esegue le operazioni di controllo di \textit{epoll}. + + \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}] il file descriptor \param{epfd} o \param{fd} non sono + validi. + \item[\errcode{EEXIST}] l'operazione richiesta è \const{EPOLL\_CTL\_ADD} ma + \param{fd} è già stato inserito in \param{epfd}. + \item[\errcode{EINVAL}] il file descriptor \param{epfd} non è stato ottenuto + con \func{epoll\_create}, o \param{fd} è lo stesso \param{epfd} o + l'operazione richiesta con \param{op} non è supportata. + \item[\errcode{ENOENT}] l'operazione richiesta è \const{EPOLL\_CTL\_MOD} o + \const{EPOLL\_CTL\_DEL} ma \param{fd} non è inserito in \param{epfd}. + \item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel gestire + l'operazione richiesta. + \item[\errcode{EPERM}] il file \param{fd} non supporta \textit{epoll}. + \end{errlist} +} +\end{prototype} +Il comportamento della funzione viene controllato dal valore dall'argomento +\param{op} che consente di specificare quale operazione deve essere eseguita. +Le costanti che definiscono i valori utilizzabili per \param{op} +sono riportate in tab.~\ref{tab:epoll_ctl_operation}, assieme al significato +delle operazioni cui fanno riferimento. +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \const{EPOLL\_CTL\_ADD}& aggiunge un nuovo file descriptor da osservare + \param{fd} alla lista dei file descriptor + controllati tramite \param{epfd}, in + \param{event} devono essere specificate le + modalità di osservazione.\\ + \const{EPOLL\_CTL\_MOD}& modifica le modalità di osservazione del file + descriptor \param{fd} secondo il contenuto di + \param{event}.\\ + \const{EPOLL\_CTL\_DEL}& rimuove il file descriptor \param{fd} dalla lista + dei file controllati tramite \param{epfd}.\\ + \hline + \end{tabular} + \caption{Valori dell'argomento \param{op} che consentono di scegliere quale + operazione di controllo effettuare con la funzione \func{epoll\_ctl}.} + \label{tab:epoll_ctl_operation} +\end{table} +La funzione prende sempre come primo argomento un file descriptor di +\textit{epoll}, \param{epfd}, che deve essere stato ottenuto in precedenza con +una chiamata a \func{epoll\_create}. L'argomento \param{fd} indica invece il +file descriptor che si vuole tenere sotto controllo, quest'ultimo può essere +un qualunque file descriptor utilizzabile con \func{poll}, ed anche un altro +file descriptor di \textit{epoll}, ma non lo stesso \param{epfd}. + +L'ultimo argomento, \param{event}, deve essere un puntatore ad una struttura +di tipo \struct{epoll\_event}, ed ha significato solo con le operazioni +\const{EPOLL\_CTL\_MOD} e \const{EPOLL\_CTL\_ADD} per le quali serve ad +indicare quale tipo di evento relativo ad \param{fd} si vuole che sia tenuto +sotto controllo. L'argomento viene ignorato con +\const{EPOLL\_CTL\_DEL}.\footnote{fino al kernel 2.6.9 era comunque richiesto + che questo fosse un puntatore valido, anche se poi veniva ignorato, a + partire dal 2.6.9 si può specificare anche anche un valore \texttt{NULL}.} -\itindend{epoll} +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/epoll_event.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{epoll\_event}, che consente di specificare + gli eventi associati ad un file descriptor controllato con + \textit{epoll}.} + \label{fig:epoll_event} +\end{figure} + +La struttura \struct{epoll\_event} è l'analoga di \struct{pollfd} e come +quest'ultima serve sia in ingresso (quando usata con \func{epoll\_ctl}) ad +impostare quali eventi osservare, che in uscita (nei risultati ottenuti con +\func{epoll\_wait}) per ricevere le notifiche degli eventi avvenuti. La sua +definizione è riportata in fig.~\ref{fig:epoll_event}; il primo campo, +\var{events}, è una maschera binaria in cui ciascun bit corrisponde o ad un +tipo di evento, o una modalità di notifica. Detto campo deve essere +specificato come OR aritmetico delle costanti riportate in +tab.~\ref{tab:epoll_events}. Il secondo campo, \var{data}, serve ad indicare a +quale file descriptor si intende fare riferimento, ed in astratto può +contenere un valore qualsiasi che permetta di identificarlo, di norma comunque +si usa come valore lo stesso \param{fd}. + +\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{Valori 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} prevedano che si definisca un +insieme di file descriptor da tenere sotto controllo su un \textit{epoll + descriptor} \param{epfd} con una serie di chiamate a +\const{EPOLL\_CTL\_ADD}. Il default prevede la notifica in modalità +\textit{level triggered}, a meno che sul file descriptor non si sia impostata +la modalità \textit{edge triggered} con \const{EPOLLET}. Si tenga presente +che è possibile tenere sotto osservazione uno stesso file descriptor su due +\textit{epoll descriptor} diversi, ed entrambi riceveranno le notifiche, ma la +pratica è sconsigliata. + +Una particolare modalità di notifica è quella impostata con +\const{EPOLLONESHOT}: quando si è in modalità \textit{edge triggered} l'arrivo +in rapida successione di dati in blocchi separati causa la generazione di una +serie di eventi multipli; in questo caso si può utilizzare la modalità +\textit{one-shot} in cui la notifica viene effettuata solo la prima volta, +dopo di che il file descriptor osservato, pur restando nella lista di +\param{epfd}, viene disattivato, e per essere riutilizzato dovrà essere +riabilitato con una successiva chiamata con \const{EPOLL\_CTL\_MOD}. + + +Infine qualora un file descriptor posto sotto osservazione dovesse essere +chiuso, esso sarà automaticamente eliminato dall'insieme dei file descriptor +osservati. + + + +La funzione che consente di attendere è \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{fd} è lo stesso \param{epfd} o + l'operazione richiesta con \param{op} non è supportata. + \end{errlist} +} +\end{prototype} + + +\itindend{epoll} % TODO epoll -% +% \section{L'accesso \textsl{asincrono} ai file} \label{sec:file_asyncronous_access} @@ -873,7 +1141,7 @@ specificare un valore nullo. 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 un eccesso di file aperti. Inoltre -quando la directory è su un dispositivo rimuovibile, mantenere un file +quando la directory è su un dispositivo rimovibile, mantenere un file descriptor aperto comporta l'impossibilità di smontare il dispositivo e rimuoverlo, complicando la gestione. @@ -2152,13 +2420,6 @@ NdA % e http://en.wikipedia.org/wiki/Splice_(system_call) -% i raw device -%\subsection{I \textit{raw} device} -%\label{sec:file_raw_device} -% -% TODO i raw device - - %\subsection{L'utilizzo delle porte di I/O} %\label{sec:file_io_port} % @@ -3054,8 +3315,10 @@ possibilit % LocalWords: switch bsd lockf mandatory SVr sgid group root mount mand TRUNC % LocalWords: SVID UX Documentation sendfile dnotify inotify NdA ppoll fds add % LocalWords: init EMFILE FIONREAD ioctl watch char pathname uint mask ENOSPC -% LocalWords: dell'inode CLOSE NOWRITE MOVE MOVED FROM TO rm wd event page -% LocalWords: attribute Universe +% LocalWords: dell'inode CLOSE NOWRITE MOVE MOVED FROM TO rm wd event page ctl +% LocalWords: attribute Universe epoll Solaris kqueue level triggered Jonathan +% LocalWords: Lemon BSDCON edge Libenzi kevent backporting epfd EEXIST ENOENT +% LocalWords: MOD %%% Local Variables: