Correzioni varie alle note (uniformate in stile) e trattazione di
[gapil.git] / fileadv.tex
index a7851b65ab0347b71be5be874181dce85a6225a7..14e10b8af985199c54470814e0862c08685d43b9 100644 (file)
@@ -1363,7 +1363,7 @@ flag della prima parte.
   \footnotesize
   \begin{tabular}[c]{|l|c|p{10cm}|}
     \hline
-    \textbf{Flag}  & & \textbf{Significato} \\
+    \textbf{Valore}  & & \textbf{Significato} \\
     \hline
     \hline
     \const{IN\_ACCESS}        &$\bullet$& C'è stato accesso al file in
@@ -1403,7 +1403,7 @@ flag della prima parte.
                                           possibili.\\
     \hline    
   \end{tabular}
-  \caption{Le costanti che identificano i valori per la maschera binaria
+  \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}
@@ -1424,7 +1424,7 @@ contrario dei precedenti non vengono mai impostati nei risultati in uscita.
   \footnotesize
   \begin{tabular}[c]{|l|p{10cm}|}
     \hline
-    \textbf{Flag}  & \textbf{Significato} \\
+    \textbf{Valore}  & \textbf{Significato} \\
     \hline
     \hline
     \const{IN\_DONT\_FOLLOW}& Non dereferenzia \param{pathname} se questo è un
@@ -1440,7 +1440,7 @@ contrario dei precedenti non vengono mai impostati nei risultati in uscita.
                               quelli per i file che contiene.\\ 
     \hline    
   \end{tabular}
-  \caption{Le costanti che identificano i valori per la maschera binaria
+  \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}
@@ -1554,7 +1554,7 @@ aggiuntivi\footnote{questi compaiono solo nel campo \var{mask} di
   \footnotesize
   \begin{tabular}[c]{|l|p{10cm}|}
     \hline
-    \textbf{Flag}  & \textbf{Significato} \\
+    \textbf{Valore}  & \textbf{Significato} \\
     \hline
     \hline
     \const{IN\_IGNORED}    & L'osservatore è stato rimosso, sia in maniera 
@@ -1574,7 +1574,7 @@ aggiuntivi\footnote{questi compaiono solo nel campo \var{mask} di
                              osservazione è stato smontato.\\
     \hline    
   \end{tabular}
-  \caption{Le costanti che identificano i flag aggiuntivi usati nella maschera
+  \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}
@@ -1859,11 +1859,11 @@ appena descritta; i rispettivi prototipi sono:
   \bodydesc{Le funzioni restituiscono 0 in caso di successo, e -1 in caso di
     errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato.
-  \item[\errcode{ENOSYS}] La funzione non è implementata.
-  \item[\errcode{EINVAL}] Si è specificato un valore non valido per i campi
+  \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato.
+  \item[\errcode{ENOSYS}] la funzione non è implementata.
+  \item[\errcode{EINVAL}] si è specificato un valore non valido per i campi
     \var{aio\_offset} o \var{aio\_reqprio} di \param{aiocbp}.
-  \item[\errcode{EAGAIN}] La coda delle richieste è momentaneamente piena.
+  \item[\errcode{EAGAIN}] la coda delle richieste è momentaneamente piena.
   \end{errlist}
 }
 \end{functions}
@@ -2030,10 +2030,10 @@ specifica operazione; il suo prototipo 
     completate, e -1 in caso di errore nel qual caso \var{errno} assumerà uno
     dei valori:
     \begin{errlist}
-    \item[\errcode{EAGAIN}] Nessuna operazione è stata completata entro
+    \item[\errcode{EAGAIN}] nessuna operazione è stata completata entro
       \param{timeout}.
-    \item[\errcode{ENOSYS}] La funzione non è implementata.
-    \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
+    \item[\errcode{ENOSYS}] la funzione non è implementata.
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
     \end{errlist}
   }
 \end{prototype}
@@ -2061,13 +2061,13 @@ lettura o scrittura; il suo prototipo 
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore, nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EAGAIN}] Nessuna operazione è stata completata entro
+    \item[\errcode{EAGAIN}] nessuna operazione è stata completata entro
       \param{timeout}.
-    \item[\errcode{EINVAL}] Si è passato un valore di \param{mode} non valido
+    \item[\errcode{EINVAL}] si è passato un valore di \param{mode} non valido
       o un numero di operazioni \param{nent} maggiore di
       \const{AIO\_LISTIO\_MAX}.
-    \item[\errcode{ENOSYS}] La funzione non è implementata.
-    \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
+    \item[\errcode{ENOSYS}] la funzione non è implementata.
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
     \end{errlist}
   }
 \end{prototype}
@@ -2177,29 +2177,29 @@ eseguire la mappatura in memoria di un file, 
     in caso di successo, e \const{MAP\_FAILED} (-1) in caso di errore, nel
     qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EBADF}] Il file descriptor non è valido, e non si è usato
+    \item[\errcode{EBADF}] il file descriptor non è valido, e non si è usato
       \const{MAP\_ANONYMOUS}.
     \item[\errcode{EACCES}] o \param{fd} non si riferisce ad un file regolare,
       o si è usato \const{MAP\_PRIVATE} ma \param{fd} non è aperto in lettura,
       o si è usato \const{MAP\_SHARED} e impostato \const{PROT\_WRITE} ed
       \param{fd} non è aperto in lettura/scrittura, o si è impostato
       \const{PROT\_WRITE} ed \param{fd} è in \textit{append-only}.
-    \item[\errcode{EINVAL}] I valori di \param{start}, \param{length} o
+    \item[\errcode{EINVAL}] i valori di \param{start}, \param{length} o
       \param{offset} non sono validi (o troppo grandi o non allineati sulla
       dimensione delle pagine).
-    \item[\errcode{ETXTBSY}] Si è impostato \const{MAP\_DENYWRITE} ma
+    \item[\errcode{ETXTBSY}] si è impostato \const{MAP\_DENYWRITE} ma
       \param{fd} è aperto in scrittura.
-    \item[\errcode{EAGAIN}] Il file è bloccato, o si è bloccata troppa memoria
+    \item[\errcode{EAGAIN}] il file è bloccato, o si è bloccata troppa memoria
       rispetto a quanto consentito dai limiti di sistema (vedi
       sez.~\ref{sec:sys_resource_limit}).
-    \item[\errcode{ENOMEM}] Non c'è memoria o si è superato il limite sul
+    \item[\errcode{ENOMEM}] non c'è memoria o si è superato il limite sul
       numero di mappature possibili.
-    \item[\errcode{ENODEV}] Il filesystem di \param{fd} non supporta il memory
+    \item[\errcode{ENODEV}] il filesystem di \param{fd} non supporta il memory
       mapping.
-    \item[\errcode{EPERM}] L'argomento \param{prot} ha richiesto
+    \item[\errcode{EPERM}] l'argomento \param{prot} ha richiesto
       \const{PROT\_EXEC}, ma il filesystem di \param{fd} è montato con
       l'opzione \texttt{noexec}.
-    \item[\errcode{ENFILE}] Si è superato il limite del sistema sul numero di
+    \item[\errcode{ENFILE}] si è superato il limite del sistema sul numero di
       file aperti (vedi sez.~\ref{sec:sys_resource_limit}).
     \end{errlist}
   }
@@ -2230,7 +2230,6 @@ multiplo della dimensione di una pagina di memoria.
   \label{tab:file_mmap_prot}
 \end{table}
 
-
 Il valore dell'argomento \param{prot} indica la protezione\footnote{in Linux
   la memoria reale è divisa in pagine: ogni processo vede la sua memoria
   attraverso uno o più segmenti lineari di memoria virtuale.  Per ciascuno di
@@ -2240,7 +2239,7 @@ Il valore dell'argomento \param{prot} indica la protezione\footnote{in Linux
   che si chiama una \textit{segment violation}, e la relativa emissione del
   segnale \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
 specificato come maschera binaria ottenuta dall'OR di uno o più dei valori
-riportati in tab.~\ref{tab:file_mmap_flag}; il valore specificato deve essere
+riportati in tab.~\ref{tab:file_mmap_prot}; il valore specificato deve essere
 compatibile con la modalità di accesso con cui si è aperto il file.
 
 L'argomento \param{flags} specifica infine qual è il tipo di oggetto mappato,
@@ -2343,10 +2342,10 @@ eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una
 pagina, ed in generale queste potranno non corrispondere alle dimensioni
 effettive del file o della sezione che si vuole mappare.
 
-\footnotetext[20]{Dato che tutti faranno riferimento alle stesse pagine di
+\footnotetext[68]{dato che tutti faranno riferimento alle stesse pagine di
   memoria.}  
 
-\footnotetext[21]{L'uso di questo flag con \const{MAP\_SHARED} è stato
+\footnotetext[69]{l'uso di questo flag con \const{MAP\_SHARED} è stato
   implementato in Linux a partire dai kernel della serie 2.4.x; esso consente
   di creare segmenti di memoria condivisa e torneremo sul suo utilizzo in
   sez.~\ref{sec:ipc_mmap_anonymous}.}
@@ -2457,10 +2456,10 @@ memoria mappata con il file su disco; il suo prototipo 
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EINVAL}] O \param{start} non è multiplo di
+    \item[\errcode{EINVAL}] o \param{start} non è multiplo di
       \const{PAGE\_SIZE}, o si è specificato un valore non valido per
       \param{flags}.
-    \item[\errcode{EFAULT}] L'intervallo specificato non ricade in una zona
+    \item[\errcode{EFAULT}] l'intervallo specificato non ricade in una zona
       precedentemente mappata.
     \end{errlist}
   }
@@ -2487,7 +2486,8 @@ del file aggiornato.
                             siano invalidate.\\
     \hline    
   \end{tabular}
-  \caption{Valori dell'argomento \param{flag} di \func{msync}.}
+  \caption{Le costanti che identificano i bit per la maschera binaria
+    dell'argomento \param{flag} di \func{msync}.}
   \label{tab:file_mmap_rsync}
 \end{table}
 
@@ -2514,7 +2514,7 @@ mappatura della memoria usando la funzione \funcd{munmap}, il suo prototipo 
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EINVAL}] L'intervallo specificato non ricade in una zona
+    \item[\errcode{EINVAL}] l'intervallo specificato non ricade in una zona
       precedentemente mappata.
     \end{errlist}
   }
@@ -2671,7 +2671,7 @@ nuova system call, \funcd{remap\_file\_pages}, il cui prototipo 
   \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
     errore, nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EINVAL}] Si è usato un valore non valido per uno degli
+    \item[\errcode{EINVAL}] si è usato un valore non valido per uno degli
       argomenti o \param{start} non fa riferimento ad un \textit{memory
         mapping} valido creato con \const{MAP\_SHARED}.
     \end{errlist}
@@ -2842,7 +2842,7 @@ questo tipo di situazioni.
 La prima funzione che si pone l'obiettivo di ottimizzare il trasferimento dei
 dati fra due file descriptor è \funcd{sendfile};\footnote{la funzione è stata
   introdotta con i kernel della serie 2.2, e disponibile dalle \acr{glibc}
-  2.1..} la funzione è presente in diverse versioni di Unix,\footnote{la si
+  2.1.} la funzione è presente in diverse versioni di Unix,\footnote{la si
   ritrova ad esempio in FreeBSD, HPUX ed altri Unix.} ma non è presente né in
 POSIX.1-2001 né in altri standard,\footnote{pertanto si eviti di utilizzarla
   se si devono scrivere programmi portabili.} per cui per essa vengono
@@ -2882,101 +2882,111 @@ funzione ritorna il numero di byte effettivamente copiati da \param{in\_fd} a
 
 Se il puntatore \param{offset} è nullo la funzione legge i dati a partire
 dalla posizione corrente su \param{in\_fd}, altrimenti verrà usata la
-posizione indicata dal valore puntato da \param{offset}. In questo caso detto
+posizione indicata dal valore puntato da \param{offset}; in questo caso detto
 valore sarà aggiornato, come \textit{value result argument}, per indicare la
 posizione del byte successivo all'ultimo che è stato letto, mentre la
-posizione corrente sul file non sarà modificata. Se invece  \param{offset} è
+posizione corrente sul file non sarà modificata. Se invece \param{offset} è
 nullo la posizione corrente sul file sarà aggiornata tenendo conto dei byte
 letti da \param{in\_fd}.
 
 Fino ai kernel della serie 2.4 la funzione è utilizzabile su un qualunque file
 descriptor, e permette di sostituire la invocazione successiva di una
-\func{read} ed una \func{write} (e l'allocazione del relativo buffer) con una
+\func{read} e una \func{write} (e l'allocazione del relativo buffer) con una
 sola chiamata a \funcd{sendfile}. In questo modo si può diminuire il numero di
 chiamate al sistema e risparmiare in trasferimenti di dati da kernel space a
 user space e viceversa.  La massima utilità della funzione si ha comunque per
-il trasferimento di dati da un file su disco ad socket di rete,\footnote{il
-  caso classico del lavoro un server web, ed infatti Apache ha una opzione per
-  il supporto esplicito di questa funzione.} dato che in questo caso diventa
-possibile effettuare il trasferimento diretto via DMA dal controller del disco
-alla scheda di rete, senza neanche allocare un buffer nel kernel.\footnote{il
-  meccanismo è detto \textit{zerocopy} in quanto i dati non vengono mai
-  copiati dal kernel, che si limita a programmare solo le operazioni di
-  lettura e scrittura via DMA.}
-
-Con i kernel della serie 2.6 ci si è accorti però che, a parte quest'ultimo
-caso, l'uso di \func{sendfile} non sempre portava significativi miglioramenti
-delle prestazioni rispetto all'uso in sequenza di \func{read} e \func{write},
-\footnote{nel caso generico infatti il kernel deve comunque allocare un buffer
-  ed effettuare la copia dei dati, e in tal caso spesso il guadagno ottenibile
-  nel ridurre il numero di chiamate al sistema non compensa le ottimizzazioni
-  che possono essere fatte da una applicazione in user space che ha una
-  maggiore conoscenza su come questi sono strutturati.} e che anzi in certi
-casi si avevano dei peggioramenti, questo ha portato alla
-decisione\footnote{per alcune motivazioni di questa scelta si può fare
-  riferimento a quanto illustrato da Linus Torvalds in
-  \href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}
+il trasferimento di dati da un file su disco ad un socket di
+rete,\footnote{questo è il caso classico del lavoro eseguito da un server web,
+  ed infatti Apache ha una opzione per il supporto esplicito di questa
+  funzione.} dato che in questo caso diventa possibile effettuare il
+trasferimento diretto via DMA dal controller del disco alla scheda di rete,
+senza neanche allocare un buffer nel kernel,\footnote{il meccanismo è detto
+  \textit{zerocopy} in quanto i dati non vengono mai copiati dal kernel, che
+  si limita a programmare solo le operazioni di lettura e scrittura via DMA.}
+ottenendo la massima efficienza possibile senza pesare neanche sul processore.
+
+In seguito però ci si è accorti che, fatta eccezione per il trasferimento
+diretto da file a socket, non sempre \func{sendfile} comportava miglioramenti
+significativi delle prestazioni rispetto all'uso in sequenza di \func{read} e
+\func{write},\footnote{nel caso generico infatti il kernel deve comunque
+  allocare un buffer ed effettuare la copia dei dati, e in tal caso spesso il
+  guadagno ottenibile nel ridurre il numero di chiamate al sistema non
+  compensa le ottimizzazioni che possono essere fatte da una applicazione in
+  user space che ha una conoscenza diretta su come questi sono strutturati.} e
+che anzi in certi casi si potevano avere anche dei peggioramenti.  Questo ha
+portato, per i kernel della serie 2.6,\footnote{per alcune motivazioni di
+  questa scelta si può fare riferimento a quanto illustrato da Linus Torvalds
+  in \href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}
   {\texttt{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}.}
-di consentire l'uso della funzione soltanto quando il file da cui si legge
-supporta le operazioni di \textit{memory mapping} (vale a dire non è un
-socket) e quello su cui si scrive è un socket; in tutti gli altri casi si avrà
-un errore di \errcode{EINVAL}.
-
-Nonostante i limiti illustrati resta comunque il dubbio se la scelta di
-disabilitare \func{sendfile} per il trasferimento di dati fra file di dati sia
-davvero corretta; la funzione infatti se non altro consentirebbe di
-semplificare l'interfaccia per la copia dei dati, evitando di dover gestire
-l'allocazione di un buffer temporaneo per il loro trasferimento in tutti quei
-casi in cui non c'è necessità di fare controlli sugli stessi.  Inoltre essa
-avrebbe comunque il vantaggio di evitare trasferimenti di dati da e verso
-l'user space.
-
-Il dubbio è stato rimosso con l'introduzione della system call
-\func{splice},\footnote{avvenuto a partire dal kernel 2.6.17.}  il cui scopo è
-appunto quello di fornire un meccanismo generico per il trasferimento di dati
-da o verso un file utilizzando un buffer intermedio gestito direttamente dal
-kernel. Lo scopo della funzione può sembrare lo stesso di \func{sendfile}, ma
-in realtà esse sono profondamente diverse nel loro meccanismo di
-funzionamento; \func{sendfile} infatti, come accennato, non necessita affatto
-(anzi nel caso di Linux viene sostanzialmente usata solo in questo caso) di
-avere a disposizione un buffer interno, perché esegue un trasferimento diretto
-di dati; questo la rende in generale molto più efficiente, ma anche limitata
-nelle sue applicazioni.
+alla decisione di consentire l'uso della funzione soltanto quando il file da
+cui si legge supporta le operazioni di \textit{memory mapping} (vale a dire
+non è un socket) e quello su cui si scrive è un socket; in tutti gli altri
+casi l'uso di \func{sendfile} darà luogo ad un errore di \errcode{EINVAL}.
+
+Nonostante ci possano essere casi in cui \func{sendfile} non migliora le
+prestazioni, le motivazioni addotte non convincono del tutto e resta il dubbio
+se la scelta di disabilitarla sempre per il trasferimento di dati fra file di
+dati sia davvero corretta. Se ci sono peggioramenti di prestazioni infatti si
+può sempre fare ricorso all'uso successivo di, ma lasciare a disposizione la
+funzione consentirebbe se non altro, anche in assenza di guadagni di
+prestazioni, di semplificare la gestione della copia dei dati fra file,
+evitando di dover gestire l'allocazione di un buffer temporaneo per il loro
+trasferimento; inoltre si avrebbe comunque il vantaggio di evitare inutili
+trasferimenti di dati da kernel space a user space e viceversa.
+
+Questo dubbio si può comunque ritenere superato con l'introduzione, avvenuto a
+partire dal kernel 2.6.17, della nuova system call \func{splice}. Lo scopo di
+questa funzione è quello di fornire un meccanismo generico per il
+trasferimento di dati da o verso un file utilizzando un buffer gestito
+internamente dal kernel. Descritta in questi termini \func{splice} sembra
+semplicemente un ``\textsl{dimezzamento}'' di \func{sendfile}.\footnote{nel
+  senso che un trasferimento di dati fra due file con \func{sendfile} non
+  sarebbe altro che la lettura degli stessi su un buffer seguita dalla
+  relativa scrittura, cosa che in questo caso si dovrebbe eseguire con due
+  chiamate a \func{splice}.} In realtà le due system call sono profondamente
+diverse nel loro meccanismo di funzionamento; \func{sendfile} infatti, come
+accennato, non necessita affatto di avere a disposizione un buffer interno,
+perché esegue un trasferimento diretto di dati; questo la rende in generale
+molto più efficiente, ma anche limitata nelle sue applicazioni, dato che
+questo tipo di trasferimento è possibile solo in casi specifici.\footnote{e
+  nel caso di Linux questi sono anche solo quelli in cui essa può essere
+  effettivamente utilizzata.}
 
 Il concetto che sta dietro a \func{splice} invece è diverso,\footnote{in
-  realtà la proposta originale di Larry Mc Voy non ne differisce poi tanto,
-  quello che la rende davvero diversa è stata la reinterpretazione che ne è
-  stata fatta nell'implementazione su Linux realizzata da Jens Anxboe, di cui
-  si può trovare un buon riassunto in \href{http://kerneltrap.org/node/6505}
+  realtà la proposta originale di Larry Mc Voy non differisce poi tanto negli
+  scopi da \func{sendfile}, quello che rende \func{splice} davvero diversa è
+  stata la reinterpretazione che ne è stata fatta nell'implementazione su
+  Linux realizzata da Jens Anxboe, concetti che sono esposti sinteticamente
+  dallo stesso Linus Torvalds in \href{http://kerneltrap.org/node/6505}
   {\texttt{http://kerneltrap.org/node/6505}}.} si tratta semplicemente di una
-funzione che consente di fare delle operazioni di trasferimento dati da e
-verso un buffer interamente gestito in kernel space, in maniera del tutto
-generica. In questo caso il cuore della funzione (e delle affini
-\func{vmsplice} e \func{tee}, che tratteremo più avanti) è appunto il buffer
-in kernel space; questo è anche quello che ne ha semplificato
-l'adozione,\footnote{la funzione infatti non è definita in nessuno standard,
-  e, allo stato attuale è disponibile soltanto su Linux.} perché
-l'infrastruttura per la gestione di un buffer in kernel space è presente fin
-dagli albori di Unix per la realizzazione delle \textit{pipe} (tratteremo
-l'argomento in sez.~\ref{sec:ipc_unix}). Dal punto di vista concettuale allora
-\func{splice} non è che un'altra interfaccia con cui esporre in userspace
-l'oggetto \textsl{buffer in kernel space}.
+funzione che consente di fare in maniera del tutto generica delle operazioni
+di trasferimento di dati fra un file e un buffer gestito interamente in kernel
+space. In questo caso il cuore della funzione (e delle affini \func{vmsplice}
+e \func{tee}, che tratteremo più avanti) è appunto l'uso di un buffer in
+kernel space, e questo è anche quello che ne ha semplificato l'adozione,
+perché l'infrastruttura per la gestione di un tale buffer è presente fin dagli
+albori di Unix per la realizzazione delle \textit{pipe} (vedi
+sez.~\ref{sec:ipc_unix}). Dal punto di vista concettuale allora \func{splice}
+non è altro che una diversa interfaccia (rispetto alle \textit{pipe}) con cui
+utilizzare in user space l'oggetto ``\textsl{buffer in kernel space}''.
 
 Così se per una \textit{pipe} o una \textit{fifo} il buffer viene utilizzato
-come area di memoria dove appoggiare i dati che vengono trasferiti da un capo
-all'altro della stessa (vedi fig.~\ref{fig:ipc_pipe_singular}) per creare un
-meccanismo di comunicazione fra processi, nel caso di \funcd{splice} il buffer
+come area di memoria (vedi fig.~\ref{fig:ipc_pipe_singular}) dove appoggiare i
+dati che vengono trasferiti da un capo all'altro della stessa per creare un
+meccanismo di comunicazione fra processi, nel caso di \func{splice} il buffer
 viene usato o come fonte dei dati che saranno scritti su un file, o come
-destinazione dei dati che vengono letti da un file. La funzione infatti è una
-interfaccia generica che consente di trasferire dati da un buffer ad un file o
-viceversa; il suo prototipo, accessibile solo avendo definito
-\macro{\_GNU\_SOURCE},\footnote{ovviamente, essendo come detto la funzione
-  totalmente specifica di Linux, essa non è prevista da nessuno standard e
-  deve essere evitata se si vogliono scrivere programmi portabili.} è:
+destinazione dei dati che vengono letti da un file. La funzione \funcd{splice}
+fornisce quindi una interfaccia generica che consente di trasferire dati da un
+buffer ad un file o viceversa; il suo prototipo, accessibile solo dopo aver
+definito la macro \macro{\_GNU\_SOURCE},\footnote{si ricordi che questa
+  funzione non è contemplata da nessuno standard, è presente solo su Linux, e
+  pertanto deve essere evitata se si vogliono scrivere programmi portabili.}
+è il seguente:
 \begin{functions}  
   \headdecl{fcntl.h} 
 
-  \funcdecl{}
+  \funcdecl{long splice(int fd\_in, off\_t *off\_in, int fd\_out, off\_t
+    *off\_out, size\_t len, unsigned int flags)}
   
   Trasferisce dati da un file verso una pipe o viceversa.
 
@@ -2984,19 +2994,79 @@ viceversa; il suo prototipo, accessibile solo avendo definito
     successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno
     dei valori:
     \begin{errlist}
-    \item[\errcode{EAGAIN}] si è impostata la modalità non bloccante su
-      \param{out\_fd} e la scrittura si bloccherebbe.
-    \item[\errcode{EINVAL}] i file descriptor non sono validi, o sono bloccati
-      (vedi sez.~\ref{sec:file_locking}), o \func{mmap} non è disponibile per
-      \param{in\_fd}.
-    \item[\errcode{EIO}] si è avuto un errore di lettura da \param{in\_fd}.
-    \item[\errcode{ENOMEM}] non c'è memoria sufficiente per la lettura da
-      \param{in\_fd}.
+    \item[\errcode{EBADF}] uno o entrambi fra \param{fd\_in} e \param{fd\_out}
+      non sono file descriptor validi o, rispettivamente, non sono stati
+      aperti in lettura o scrittura.
+    \item[\errcode{EINVAL}] il filesystem su cui si opera non supporta
+      \func{splice}, oppure nessuno dei file descriptor è una pipe, oppure si
+      è dato un valore a \param{off\_in} o \param{off\_out} ma il
+      corrispondente file è un dispositivo che non supporta la funzione
+      \func{seek}.
+    \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'operazione
+      richiesta.
+    \item[\errcode{ESPIPE}] o \param{off\_in} o \param{off\_out} non sono
+      \const{NULL} ma il corrispondente file descriptor è una \textit{pipe}.
     \end{errlist}
-    ed inoltre \errcode{EBADF} e \errcode{EFAULT}.
   }
 \end{functions}
 
+La funzione esegue un trasferimento di \param{count} byte dal file descriptor
+\param{fd\_in} al file descriptor \param{fd\_out}, uno dei quali deve essere
+una \textit{pipe}; l'altro file descriptor può essere
+qualunque.\footnote{questo significa che può essere, oltre che un file di
+  dati, anche un altra \textit{pipe}, o un socket.}  Come accennato una
+\textit{pipe} non è altro che un buffer in kernel space, per cui a seconda che
+essa sia usata per \param{fd\_in} o \param{fd\_out} si avrà rispettivamente la
+copia dei dati dal buffer al file o viceversa. 
+
+In caso di successo la funzione ritorna il numero di byte trasferiti, che può
+essere, come per le normali funzioni di lettura e scrittura su file, inferiore
+a quelli richiesti; un valore negativo indicherà un errore mentre un valore
+nullo indicherà che non ci sono dati da trasferire (ad esempio si è giunti
+alla fine del file in lettura). Si tenga presente che, a seconda del verso del
+trasferimento dei dati, la funzione si comporta nei confronti del file
+descriptor che fa riferimento al file ordinario, come \func{read} o
+\func{write}, e pertanto potrà anche bloccarsi (a meno che non si sia aperto
+il suddetto file in modalità non bloccante).
+
+I due argomenti \param{off\_in} e \param{off\_out} consentono di specificare,
+come per l'analogo \param{offset} di \func{sendfile}, la posizione all'interno
+del file da cui partire per il trasferimento dei dati. Come per
+\func{sendfile} un valore nullo indica di usare la posizione corrente sul
+file, ed essa sarà aggiornata automaticamente secondo il numero di byte
+trasferiti. Un valore non nullo invece deve essere un puntatore ad una
+variabile intera che indica la posizione da usare; questa verrà aggiornata, al
+ritorno della funzione, al byte successivo all'ultimo byte trasferito.
+Ovviamente soltanto uno di questi due argomenti, e più precisamente quello che
+fa riferimento al file descriptor non associato alla \textit{pipe}, può essere
+specificato come valore non nullo.
+
+Infine l'argomento \param{flag} consente di controllare alcune caratteristiche
+del funzionamento della funzione; il contenuto è una maschera binaria e deve
+essere specificato come OR aritmetico dei valori riportati in
+tab.~\ref{tab:splice_flag}.
+
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{SPLICE\_F\_MOVE}    & .\\
+    \const{SPLICE\_F\_NONBLOCK}& .\\
+    \const{SPLICE\_F\_MORE}    & .\\
+    \const{SPLICE\_F\_GIFT}    & .\\
+    \hline
+  \end{tabular}
+  \caption{Le costanti che identificano i bit della maschera binaria
+    dell'argomento \param{flag} di \func{slice}, \func{vmslice} e \func{tee}.}
+  \label{tab:splice_flag}
+\end{table}
+
+
 
 
 % TODO documentare le funzioni tee e splice
@@ -3177,7 +3247,7 @@ rimuovere un \textit{file lock} 
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore, nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EWOULDBLOCK}] Il file ha già un blocco attivo, e si è
+    \item[\errcode{EWOULDBLOCK}] il file ha già un blocco attivo, e si è
       specificato \const{LOCK\_NB}.
     \end{errlist}
   }
@@ -3313,17 +3383,17 @@ essa viene usata solo secondo il prototipo:
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore, nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EACCES}] L'operazione è proibita per la presenza di
+    \item[\errcode{EACCES}] l'operazione è proibita per la presenza di
       \textit{file lock} da parte di altri processi.
-    \item[\errcode{ENOLCK}] Il sistema non ha le risorse per il locking: ci
+    \item[\errcode{ENOLCK}] il sistema non ha le risorse per il locking: ci
       sono troppi segmenti di lock aperti, si è esaurita la tabella dei lock,
       o il protocollo per il locking remoto è fallito.
-    \item[\errcode{EDEADLK}] Si è richiesto un lock su una regione bloccata da
+    \item[\errcode{EDEADLK}] si è richiesto un lock su una regione bloccata da
       un altro processo che è a sua volta in attesa dello sblocco di un lock
       mantenuto dal processo corrente; si avrebbe pertanto un
       \itindex{deadlock} \textit{deadlock}. Non è garantito che il sistema
       riconosca sempre questa situazione.
-    \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale prima
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale prima
       di poter acquisire un lock.
     \end{errlist}
     ed inoltre \errval{EBADF}, \errval{EFAULT}.
@@ -3755,10 +3825,10 @@ che utilizza la funzione \funcd{lockf}, il cui prototipo 
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore, nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EWOULDBLOCK}] Non è possibile acquisire il lock, e si è
+    \item[\errcode{EWOULDBLOCK}] non è possibile acquisire il lock, e si è
       selezionato \const{LOCK\_NB}, oppure l'operazione è proibita perché il
       file è mappato in memoria.
-    \item[\errcode{ENOLCK}] Il sistema non ha le risorse per il locking: ci
+    \item[\errcode{ENOLCK}] il sistema non ha le risorse per il locking: ci
       sono troppi segmenti di lock aperti, si è esaurita la tabella dei lock.
     \end{errlist}
     ed inoltre \errval{EBADF}, \errval{EINVAL}.