Completate pure le fifo.
[gapil.git] / fileunix.tex
index e99db645c82b063a12aba310d51f619567a085b4..56e70435f4d2934b1e1abdeffe54b4ce5e82e703 100644 (file)
@@ -1,6 +1,7 @@
-\chapter{I file: l'interfaccia standard unix}
+\chapter{I file: l'interfaccia standard Unix}
 \label{cha:file_unix_interface}
 
+
 Esamineremo in questo capitolo la prima delle due interfacce di programmazione
 per i file, quella dei \textit{file descriptor}, nativa di Unix. Questa è
 l'interfaccia di basso livello provvista direttamente dalle system call, che
@@ -13,7 +14,7 @@ dallo standard ANSI C che affronteremo al \capref{cha:files_std_interface}.
 \section{L'architettura di base}
 \label{sec:file_base_arch}
 
-In questa sezione faremo una breve introduzione sullarchitettura su cui è
+In questa sezione faremo una breve introduzione sull'architettura su cui è
 basata dell'interfaccia dei \textit{file descriptor}, che, sia pure con
 differenze nella realizzazione pratica, resta sostanzialmente la stessa in
 tutte le implementazione di un sistema unix-like.
@@ -68,7 +69,7 @@ file, fra cui:
   campo \var{f\_pos}).
 \item un puntatore all'inode\footnote{nel kernel 2.4.x si è in realtà passati
     ad un puntatore ad una struttura \var{dentry} che punta a sua volta
-    all'inode passando per la nuova struttura del VFS} del file.
+    all'inode passando per la nuova struttura del VFS.} del file.
 %\item un puntatore alla tabella delle funzioni \footnote{la struttura
 %    \var{f\_op} descritta in \secref{sec:file_vfs_work}} che si possono usare
 %  sul file.
@@ -81,7 +82,7 @@ varie strutture di dati sulla quale essa 
   \centering
   \includegraphics[width=13cm]{img/procfile}
   \caption{Schema della architettura dell'accesso ai file attraverso
-  l'interfaccia dei \textit{file descriptor}}
+  l'interfaccia dei \textit{file descriptor}.}
   \label{fig:file_proc_file}
 \end{figure}
 Ritorneremo su questo schema più volte, dato che esso è fondamentale per
@@ -153,7 +154,7 @@ restano i limiti imposti dall'amministratore (vedi \secref{sec:sys_limits}).
 \section{Le funzioni base}
 \label{sec:file_base_func}
 
-L'interfaccia standard unix per l'input/output sui file è basata su cinque
+L'interfaccia standard Unix per l'input/output sui file è basata su cinque
 funzioni fondamentali: \func{open}, \func{read}, \func{write}, \func{lseek} e
 \func{close}, usate rispettivamente per aprire, leggere, scrivere, spostarsi e
 chiudere un file. 
@@ -220,7 +221,7 @@ sempre il file descriptor con il valore pi
     \hline % modalità di accesso al file
     \macro{O\_RDONLY} & apre il file in sola lettura. \\
     \macro{O\_WRONLY} & apre il file in sola scrittura. \\
-    \macro{O\_RDWR} & apre il file lettura/scrittura. \\
+    \macro{O\_RDWR} & apre il file in lettura/scrittura. \\
     \hline % modalità di apertura del file
     \hline
     \macro{O\_CREAT} & se il file non esiste verrà creato, con le regole di
@@ -231,8 +232,8 @@ sempre il file descriptor con il valore pi
     \func{open} con \macro{EEXIST}. \\
     \macro{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo
     valore specifica anche una modalità di operazione (vedi sotto), e 
-    comporta che \func{open} ritorni immediatamente (torneremo su
-    questo in \secref{sec:file_noblocking}). \\
+    comporta che \func{open} ritorni immediatamente (l'opzione ha senso 
+    solo per le fifo, torneremo questo in \secref{sec:ipc_named_pipe}). \\
     \macro{O\_NOCTTY} & se \var{pathname} si riferisce ad un device di
     terminale, questo non diventerà il terminale di controllo, anche se il
     processo non ne ha ancora uno (si veda \secref{sec:sess_xxx}). \\
@@ -245,7 +246,7 @@ sempre il file descriptor con il valore pi
     zero. Se il file è un terminale o una fifo il flag verrà ignorato, negli
     altri casi il comportamento non è specificato. \\
     \macro{O\_NOFOLLOW} & se \var{pathname} è un link simbolico la chiamata
-    fallisce. Questa è unestensione BSD aggiunta in Linux dal kernel 2.1.126.
+    fallisce. Questa è un'estensione BSD aggiunta in Linux dal kernel 2.1.126.
     Nelle versioni precedenti i link simbolici sono sempre seguiti, e questa
     opzione è ignorata. \\
     \macro{O\_DIRECTORY} & se \var{pathname} non è una directory la chiamata
@@ -264,15 +265,17 @@ sempre il file descriptor con il valore pi
     file. Può causare corruzione del file con NFS se più di un processo scrive
     allo stesso tempo.\footnotemark\\
     \macro{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per
-    le operazioni di I/O: questo significa il fallimento di una \func{read} in
-    assenza di dati da leggere e quello di una \func{write} in caso di 
-    impossibilità di scrivere immediatamente. L'opzione è effettiva solo per
-    le fifo e per alcuni file di dispositivo. \\
+    le operazioni di I/O (che tratteremo in \secref{sec:file_noblocking}): 
+    questo significa il fallimento di \func{read} in assenza di dati da 
+    leggere e quello di \func{write} in caso di impossibilità di scrivere 
+    immediatamente. Questa modalità ha senso solo per le fifo e per alcuni 
+    file di dispositivo. \\
     \macro{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di 
     \macro{O\_NONBLOCK}.\\
-    \macro{O\_ASYNC} & apre il file per l'input/output in modalità
-    asincrona. Quando è settato viene generato un segnale di \macro{SIGIO}
-    tutte le volte che è disponibile dell'input sul file. \\
+    \macro{O\_ASYNC} & apre il file per l'I/O in modalità
+    asincrona (vedi \secref{sec:file_asyncronous_io}). Quando è settato viene
+    generato il segnale \macro{SIGIO} tutte le volte che sono disponibili
+    dati in input sul file. \\ 
     \macro{O\_SYNC} & apre il file per l'input/output sincrono, ogni
     \func{write} bloccherà fino al completamento della scrittura di tutti dati
     sul sull'hardware sottostante.\\
@@ -293,9 +296,9 @@ sempre il file descriptor con il valore pi
   di usare un file con un nome univoco e la funzione \func{link} per
   verificarne l'esistenza.}  
 
-\footnotetext[3]{Denial of Service, si chiamano così attacchi miranti ad
-  impedire un servizio causando una qualche forma di carico eccessivo per il
-  sistema, che resta bloccato nelle risposte all'attacco.}
+\footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti
+  ad impedire un servizio causando una qualche forma di carico eccessivo per
+  il sistema, che resta bloccato nelle risposte all'attacco.}
 
 \footnotetext[4]{il problema è che NFS non supporta la scrittura in append, ed
   il kernel deve simularla, ma questo comporta la possibilità di una race
@@ -303,7 +306,7 @@ sempre il file descriptor con il valore pi
 
 \footnotetext[5]{l'opzione origina da SVr4, dove però causava il ritorno da
   una \func{read} con un valore nullo e non con un errore, questo introduce
-  unambiguità, dato che come vedremo in \secref{sec:file_read} il ritorno di
+  un'ambiguità, dato che come vedremo in \secref{sec:file_read} il ritorno di
   zero da parte di \func{read} ha il significato di una end-of-file.}
 
 Questa caratteristica permette di prevedere qual'è il valore del file
@@ -317,7 +320,7 @@ Il nuovo file descriptor non 
 sulla condivisione dei file, in genere accessibile dopo una \func{fork}, in
 \secref{sec:file_sharing}). Il nuovo file descriptor è settato di default per
 restare aperto attraverso una \func{exec} (come accennato in
-\secref{sec:proc_exec}) ed l'offset è settato all'inizio del file.
+\secref{sec:proc_exec}) e l'offset è settato all'inizio del file.
 
 L'argomento \param{mode} specifica i permessi con cui il file viene
 eventualmente creato; i valori possibili sono gli stessi già visti in
@@ -450,7 +453,7 @@ La nuova posizione 
 sommato al riferimento dato da \param{whence}; quest'ultimo può assumere i
 seguenti valori\footnote{per compatibilità con alcune vecchie notazioni
   questi valori possono essere rimpiazzati rispettivamente con 0, 1 e 2 o con
-  \macro{L\_SET}, \macro{L\_INCR} e \macro{L\_XTND}}:
+  \macro{L\_SET}, \macro{L\_INCR} e \macro{L\_XTND}.}:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
 \item[\macro{SEEK\_SET}] si fa riferimento all'inizio del file: il valore di
   \var{offset} è la nuova posizione.
@@ -480,9 +483,9 @@ essersi spostata, ma noi scriveremo alla posizione settata in precedenza.
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
 questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per
 i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che non
-supportano questa funzione, come ad esempio per le \acr{tty}\footnote{altri
+supportano questa funzione, come ad esempio per le \acr{tty}.\footnote{altri
   sistemi, usando \macro{SEEK\_SET}, in questo caso ritornano il numero di
-  caratteri che vi sono stati scritti}. Lo standard POSIX però non specifica
+  caratteri che vi sono stati scritti.} Lo standard POSIX però non specifica
 niente al proposito. Infine alcuni device, ad esempio \file{/dev/null}, non
 causano un errore ma restituiscono un valore indefinito.
 
@@ -536,44 +539,42 @@ come valore di ritorno.
 Con i \textsl{file regolari} questa è l'unica situazione in cui si può avere
 un numero di byte letti inferiore a quello richiesto, ma questo non è vero
 quando si legge da un terminale, da una fifo o da una pipe. In tal caso
-infatti, se non ci sono dati in ingresso, la \func{read} si blocca e ritorna
-solo quando ne arrivano; se il numero di byte richiesti eccede quelli
-disponibili la funzione ritorna comunque, ma con un numero di byte inferiore a
-quelli richiesti.
+infatti, se non ci sono dati in ingresso, la \func{read} si blocca (a meno di
+non aver selezionato la modalità non bloccante, vedi
+\secref{sec:file_noblocking}) e ritorna solo quando ne arrivano; se il numero
+di byte richiesti eccede quelli disponibili la funzione ritorna comunque, ma
+con un numero di byte inferiore a quelli richiesti.
 
 Lo stesso comportamento avviene caso di lettura dalla rete (cioè su un socket,
-come vedremo in \secref{sec:sock_io_behav}), o per certi dispositivi, come le
-unità a nastro, che restituiscono un singolo blocco di dati alla volta.
+come vedremo in \secref{sec:sock_io_behav}), o per la lettura da certi file di
+dispositivo, come le unità a nastro, che restituiscono sempre i dati ad un
+singolo blocco alla volta.
 
 In realtà anche le due condizioni segnalate dagli errori \macro{EINTR} e
 \macro{EAGAIN} non sono errori. La prima si verifica quando la \func{read} è
 bloccata in attesa di dati in ingresso e viene interrotta da un segnale; in
-tal caso l'azione da prendere è quella di rieseguire la funzione. Torneremo
-sull'argomento in \secref{sec:signal_xxx}. 
-
-La seconda si verifica quando il file è in modalità non bloccante e non ci
-sono dati in ingresso: la funzione allora ritorna immediatamente con un errore
-\macro{EAGAIN}\footnote{sotto BSD questo per questo errore viene usata la
-  costante \macro{EWOULDBLOCK}, in GNU/Linux questa è sinonima di
-  \macro{EAGAIN}.} che nel caso indica soltanto che occorrerà provare a
-ripetere la lettura.
-
-
-Nella seconda versione delle \textit{Single Unix
+tal caso l'azione da prendere è quella di rieseguire la funzione. Torneremo in
+dettaglio sull'argomento in \secref{sec:sig_gen_beha}.
+
+La seconda si verifica quando il file è in modalità non bloccante (vedi
+\secref{sec:file_noblocking}) e non ci sono dati in ingresso: la funzione
+allora ritorna immediatamente con un errore \macro{EAGAIN}\footnote{sotto BSD
+  questo per questo errore viene usata la costante \macro{EWOULDBLOCK}, in
+  Linux, con le glibc, questa è sinonima di \macro{EAGAIN}.} che nel caso
+indica soltanto che occorrerà provare a ripetere la lettura.
+
+La funzione \func{read} è una delle system call fondamentali, esistenti fin
+dagli albori di Unix, ma nella seconda versione delle \textit{Single Unix
   Specification}\footnote{questa funzione, e l'analoga \func{pwrite} sono
   state aggiunte nel kernel 2.1.60, il supporto nelle \acr{glibc}, compresa
   l'emulazione per i vecchi kernel che non hanno la system call, è stato
-  aggiunto con la versione 2.1} (quello che viene chiamato normalmente Unix98,
-vedi \secref{sec:intro_opengroup}) è stata introdotta la definizione di
-un'altra funzione di lettura, \func{pread}, che diventa accessibile con la
-definizione:
-\begin{verbatim}
-       #define _XOPEN_SOURCE 500
-\end{verbatim}
-il prototipo di questa funzione è:
+  aggiunto con la versione 2.1, in versioni precedenti sia del kernel che
+  delle librerie la funzione non è disponibile.} (quello che viene chiamato
+normalmente Unix98, vedi \secref{sec:intro_opengroup}) è stata introdotta la
+definizione di un'altra funzione di lettura, \func{pread}, il cui prototipo è:
 \begin{prototype}{unistd.h}
 {ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)}
-  
+
 Cerca di leggere \var{count} byte dal file \var{fd}, a partire dalla posizione
 \var{offset}, nel buffer \var{buf}.
   
@@ -581,10 +582,15 @@ Cerca di leggere \var{count} byte dal file \var{fd}, a partire dalla posizione
   in caso di errore, nel qual caso \var{errno} viene settata secondo i valori
   già visti per \func{read} e \func{lseek}.}
 \end{prototype}
+\noindent che però diventa accessibile solo con la definizione della macro:
+\begin{verbatim}
+       #define _XOPEN_SOURCE 500
+\end{verbatim}
 
 Questa funzione serve quando si vogliono leggere dati dal file senza
 modificarne la posizione corrente. È equivalente alla esecuzione di una
-\func{read} e una \func{lseek}, ma permette di eseguire l'operazione
+\func{read} seguita da una \func{lseek} che riporti al valore precedente la
+posizione corrente sul file, ma permette di eseguire l'operazione
 atomicamente. Questo può essere importante quando la posizione sul file viene
 condivisa da processi diversi (vedi \secref{sec:file_sharing}).  Il valore di
 \var{offset} fa sempre riferimento all'inizio del file.
@@ -636,7 +642,7 @@ i file ordinari il numero di byte scritti 
 da \var{count}, a meno di un errore. Negli altri casi si ha lo stesso
 comportamento di \func{read}.
 
-Anche per \func{write} lo standard Unix98 definisce unanaloga \func{pwrite}
+Anche per \func{write} lo standard Unix98 definisce un'analoga \func{pwrite}
 per scrivere alla posizione indicata senza modificare la posizione corrente
 nel file, il suo prototipo è:
 \begin{prototype}{unistd.h}
@@ -731,7 +737,7 @@ corrente nel file varier
 Si noti inoltre che anche i flag di stato del file (quelli settati
 dall'argomento \param{flag} di \func{open}) essendo tenuti nella voce della
 \textit{file table}\footnote{per la precisione nel campo \var{f\_flags} di
-  \var{file}}, vengono in questo caso condivisi. Ai file però sono associati
+  \var{file}.}, vengono in questo caso condivisi. Ai file però sono associati
 anche altri flag, dei quali l'unico usato al momento è \macro{FD\_CLOEXEC},
 detti \textit{file descriptor flags}. Questi ultimi sono tenuti invece in
 \var{file\_struct}, e perciò sono specifici di ciascun processo e non vengono
@@ -765,14 +771,13 @@ file sar
 corrente settata con la \func{lseek} che non corrisponde più alla fine del
 file, e la successiva \func{write} sovrascriverà i dati del secondo processo.
 
-Il problema è che usare due system call in successione non è unoperazione
+Il problema è che usare due system call in successione non è un'operazione
 atomica; il problema è stato risolto introducendo la modalità
 \macro{O\_APPEND}. In questo caso infatti, come abbiamo descritto in
 precedenza, è il kernel che aggiorna automaticamente la posizione alla fine
 del file prima di effettuare la scrittura, e poi estende il file. Tutto questo
 avviene all'interno di una singola system call (la \func{write}) che non
-essendo interrompibile da un altro processo costituisce una operazione
-atomica.
+essendo interrompibile da un altro processo costituisce un'operazione atomica.
 
 Un altro caso tipico in cui è necessaria l'atomicità è quello in cui si vuole
 creare un file di lock, bloccandosi se il file esiste. In questo caso la
@@ -798,10 +803,10 @@ secondo tempo rispetto al momento della esecuzione della \func{write}.
 
 Per questo motivo, quando è necessaria una sincronizzazione dei dati, il
 sistema mette a disposizione delle funzioni che provvedono a forzare lo
-scarico dei dati dai buffer del kernel\footnote{come già accennato neanche
+scarico dei dati dai buffer del kernel.\footnote{come già accennato neanche
   questo da la garanzia assoluta che i dati siano integri dopo la chiamata,
   l'hardware dei dischi è in genere dotato di un suo meccanismo interno che
-  può ritardare ulteriormente la scrittura effettiva.}. La prima di queste
+  può ritardare ulteriormente la scrittura effettiva.} La prima di queste
 funzioni è \func{sync} il cui prototipo è:
 \begin{prototype}{unistd.h}{int sync(void)}
   
@@ -847,10 +852,10 @@ di \var{fstat} come i tempi del file).
 
 Si tenga presente che questo non comporta la sincronizzazione della
 directory che contiene il file (e scrittura della relativa voce su
-disco) che deve essere effettuata esplicitamente\footnote{in realtà per
+disco) che deve essere effettuata esplicitamente.\footnote{in realtà per
   il filesystem \acr{ext2}, quando lo si monta con l'opzione \cmd{sync},
   il kernel provvede anche alla sincronizzazione automatica delle voci
-  delle directory.}.
+  delle directory.}
 
 
 \subsection{La funzioni \func{dup} e \func{dup2}}
@@ -880,7 +885,8 @@ interscambiati nell'uso. Per capire meglio il funzionamento della funzione si
 può fare riferimento a \figref{fig:file_dup}: l'effetto della funzione è
 semplicemente quello di copiare il valore nella struttura \var{file\_struct},
 cosicché anche il nuovo file descriptor fa riferimento alla stessa voce
-nella \textit{file table}.
+nella \textit{file table}; per questo si dice che il nuovo file descriptor è
+\textsl{duplicato}, da cui il nome della funzione.
 
 \begin{figure}[htb]
   \centering \includegraphics[width=13cm]{img/filedup}
@@ -888,18 +894,30 @@ nella \textit{file table}.
   \label{fig:file_dup}
 \end{figure}
 
-In questo modo entrambi i file condivideranno eventuali lock, \textit{file
-  status flag}, e posizione corrente: se ad esempio \func{lseek} modifica la
-posizione su uno dei due file descriptor essa sarà modificata anche sull'altro
-(al solito viene modificato lo stesso campo nella voce della \textit{file
-  table} a cui entrambi fanno riferimento).
-
-L'unica differenza fra i due file descriptor è che ciascuno avrà il suo
-\textit{file descriptor flag}: nel caso di \func{dup} il flag di \textit{close
-  on exec} viene sempre cancellato nella copia.  
-
-Una diversa versione della funzione, \func{dup2} viene utilizzata per
-specificare esplicitamente il nuovo file descriptor; il suo prototipo è:
+Si noti che per quanto illustrato in\figref{fig:file_dup} i file descriptor
+duplicati condivideranno eventuali lock, \textit{file status flag}, e
+posizione corrente. Se ad esempio si esegue una \func{lseek} per modificare la
+posizione su uno dei due file descriptor, essa risulterà modificata anche
+sull'altro (dato che quello che viene modificato è lo stesso campo nella voce
+della \textit{file table} a cui entrambi fanno riferimento). L'unica
+differenza fra due file descriptor duplicati è che ciascuno avrà il suo
+\textit{file descriptor flag}; a questo proposito va specificato che nel caso
+di \func{dup} il flag di \textit{close on exec} viene sempre cancellato nella
+copia.
+
+L'uso principale di questa funzione è per la redirezione dell'input e
+dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec};
+diventa così possibile associare un file (o una pipe) allo standard input o
+allo standard output (torneremo sull'argomento in \secref{sec:ipc_pipe_use},
+quando tratteremo le pipe). Per fare questo in genere occorre prima chiudere
+il file che si vuole sostituire, cossicché il suo file descriptor possa esser
+restituito alla chiamata di \func{dup}, come primo file descriptor
+disponibile.
+
+Dato che questa è l'operazione più comune, è prevista una diversa versione
+della funzione, \func{dup2}, che permette di specificare esplicitamente qual'è
+il valore di file descriptor che si vuole avere come duplicato; il suo
+prototipo è:
 \begin{prototype}{unistd.h}{int dup2(int oldfd, int newfd)}
   
   Rende \param{newfd} una copia del file descriptor \param{oldfd}.
@@ -914,11 +932,13 @@ specificare esplicitamente il nuovo file descriptor; il suo prototipo 
     descriptor aperti.
   \end{errlist}}
 \end{prototype}
-\noindent la funzione chiude il file descriptor \param{newfd} se è aperto.
+\noindent e qualora il file descriptor \param{newfd} sia già aperto (come
+avviene ad esempio nel caso della duplicazione di uno dei file standard) esso
+sarà prima chiuso e poi duplicato.
 
 La duplicazione dei file descriptor può essere effettuata anche usando la
 funzione di controllo dei file \func{fnctl} (che esamineremo in
-\secref{sec:file_fcntl}) con il parametro \macro{F\_DUPFD}. 
+\secref{sec:file_fcntl}) con il parametro \macro{F\_DUPFD}.
 
 L'operazione ha la sintassi \code{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0
 come valore per \param{newfd} diventa equivalente a \func{dup}. La sola
@@ -927,12 +947,6 @@ se 
 superiore, per cui per poterla usare come \func{dup2} occorrerebbe prima
 effettuare una \func{close}, perdendo l'atomicità dell'operazione.
 
-L'uso principale di queste funzioni è per la redirezione dell'input e
-dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec};
-diventa così possibile associare un file (o una pipe) allo standard input o
-allo standard output, torneremo su questo uso in \secref{sec:ipc_pipes} quando
-tratteremo le pipe.
-
 
 \subsection{La funzione \func{fcntl}}
 \label{sec:file_fcntl}
@@ -983,7 +997,8 @@ valori 
   di \tabref{tab:file_open_flags}). 
 \item[\macro{F\_SETFL}] setta il \textit{file status flag} al valore
   specificato da \param{arg}, possono essere settati solo i bit riportati
-  nella terza sezione di \tabref{tab:file_open_flags} (da verificare).
+  nella terza sezione di \tabref{tab:file_open_flags}.\footnote{NdA da
+    verificare.}
 \item[\macro{F\_GETLK}] se un file lock è attivo restituisce nella struttura
   \param{lock} la struttura \type{flock} che impedisce l'acquisizione del
   blocco, altrimenti setta il campo \var{l\_type} a \macro{F\_UNLCK} (per i
@@ -1006,17 +1021,21 @@ valori 
 \item[\macro{F\_SETOWN}] setta il processo o process group che riceverà i
   segnali \macro{SIGIO} e \macro{SIGURG} per gli eventi associati al file
   descriptor \var{fd}.  I process group sono settati usando valori negativi.
-\item[\macro{F\_GETSIG}] restituisce il segnale mandato quando ci sono dati
-  disponibili in input sul file descriptor. Il valore 0 indica il default (che
-  è \macro{SIGIO}), un valore diverso da zero indica il segnale richiesto,
-  (che può essere lo stesso \macro{SIGIO}), nel qual caso al manipolatore del
-  segnale, se installato con \macro{SA\_SIGINFO}, vengono rese disponibili
-  informazioni ulteriori informazioni.
+\item[\macro{F\_GETSIG}] restituisce il valore del segnale mandato quando ci
+  sono dati disponibili in input su un file descriptor aperto o settato in I/O
+  asincrono. Il valore 0 indica il valore default (che è \macro{SIGIO}), un
+  valore diverso da zero indica il segnale richiesto, (che può essere lo
+  stesso \macro{SIGIO}).
 \item[\macro{F\_SETSIG}] setta il segnale da inviare quando diventa possibile
-  effettuare I/O sul file descriptor. Il valore zero indica il default
-  (\macro{SIGIO}), ogni altro valore permette di rendere disponibile al
-  manipolatore del segnale ulteriori informazioni se si è usata
-  \macro{SA\_SIGINFO}.
+  effettuare I/O sul file descriptor in caso di I/O asincrono. Il valore zero
+  indica di usare il segnale di default, \macro{SIGIO}. Un altro valore
+  (compreso lo stesso \macro{SIGIO}) specifica il segnale voluto; l'uso di un
+  valore diverso da zero permette inoltre, se si è installato il manipolatore
+  del segnale come \var{sa\_sigaction} usando \macro{SA\_SIGINFO}, (vedi
+  \secref{sec:sig_sigaction}), di rendere disponibili al manipolatore
+  informazioni ulteriori informazioni riguardo il file che ha generato il
+  segnale attraverso i valori restituiti in \var{siginfo\_t} (come vedremo in
+  \secref{sec:file_asyncronous_io}).
 \end{basedescript}
 
 La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per
@@ -1026,7 +1045,7 @@ avanti quando affronteremo le problematiche ad esse relative.
 Per determinare le modalità di accesso inoltre è necessario estrarre i bit di
 accesso (ottenuti con il comando \macro{F\_GETFL}); infatti la definizione
 corrente non assegna bit separati a \macro{O\_RDONLY}, \macro{O\_WRONLY} e
-\macro{O\_RDWR}\footnote{posti rispettivamente ai valori 0, 1 e 2}, per cui il
+\macro{O\_RDWR},\footnote{posti rispettivamente ai valori 0, 1 e 2.} per cui il
 valore si ottiene eseguendo un AND binario del valore di ritorno di
 \func{fcntl} con la maschera \macro{O\_ACCMODE} anch'essa definita in
 \file{fcntl.h}.
@@ -1050,14 +1069,16 @@ per ogni singolo dispositivo.  Il prototipo di questa funzione 
 \begin{prototype}{sys/ioctl.h}{int ioctl(int fd, int request, ...)}  
   Manipola il dispositivo sottostante, usando il parametro \param{request} per
   specificare l'operazione richiesta e il terzo parametro (usualmente di tipo
-  \param{char * argp}) per il trasferimento dell'informazione necessaria.
+  \param{char * argp} o \param{int argp}) per il trasferimento
+  dell'informazione necessaria.
   
   \bodydesc{La funzione nella maggior parte dei casi ritorna 0, alcune
     operazioni usano però il valore di ritorno per restituire informazioni. In
     caso di errore viene sempre restituito -1 e \var{errno} viene settata ad
     uno dei valori seguenti:
   \begin{errlist}
-  \item[\macro{ENOTTY}] il file \param{fd} non è associato con un device.
+  \item[\macro{ENOTTY}] il file \param{fd} non è associato con un device, o la
+    richiesta non è applicabile all'oggetto a cui fa riferimento \param{fd}.
   \item[\macro{EINVAL}] gli argomenti \param{request} o \param{argp} non sono
     validi.
   \end{errlist}
@@ -1066,9 +1087,45 @@ per ogni singolo dispositivo.  Il prototipo di questa funzione 
 
 La funzione serve in sostanza per fare tutte quelle operazioni che non si
 adattano al design dell'architettura dei file e che non è possibile effettuare
-con le funzioni esaminate finora. Per questo motivo non è possibile fare altro
-che darne una descrizione generica; torneremo ad esaminarla in seguito, quando
-si tratterà di applicarla ad alcune problematiche specifiche.
+con le funzioni esaminate finora. Esse vengono selezionate attraverso il
+valore di \param{request} e gli eventuali risultati possono essere restituiti
+sia attraverso il valore di ritorno che attraverso il terzo argomento
+\param{argp}. Sono esempi delle operazioni gestite con una \func{ioctl}:
+\begin{itemize*}
+\item il cambiamento dei font di un terminale.
+\item l'esecuzione di una traccia audio di un CDROM.
+\item i comandi di avanti veloce e riavvolgimento di un nastro.
+\item il comando di espulsione di un dispositivo rimovibile.
+\item il settaggio della velocità trasmissione di una linea seriale.
+\item il settaggio della frequenza e della durata dei suoni emessi dallo
+  speaker.
+\end{itemize*}
+
+In generale ogni dispositivo ha un suo insieme di possibili diverse operazioni
+effettuabili attraverso \func{ioctl}, che sono definite nell'header file
+\file{sys/ioctl.h}, e devono essere usate solo sui dispositivi cui fanno
+riferimento. Infatti anche se in genere i valori di \param{request} sono
+opportunamente differenziati a seconda del dispositivo\footnote{il kernel usa
+  un apposito \textit{magic number} per distinguere ciascun dispositivo nella
+  definizione delle macro da usare per \param{request}, in modo da essere
+  sicuri che essi siano sempre diversi, ed il loro uso causi al più un errore.
+  Si veda il capitolo quinto di \cite{LinDevDri} per una trattazione
+  dettagliata dell'argomento.} in alcuni casi, relativi a valori assegnati
+prima che questa differenziazione diventasse pratica corrente si potrebbe
+avere
+
+Per questo motivo non è possibile fare altro che darne una descrizione
+generica; torneremo ad esaminare in seguito quelle relative ad alcuni casi
+specifici (ad esempio la gestione dei terminali è effettuata attraverso
+\func{ioctl} in quasi tutte le implementazioni di Unix), qui riportiamo solo i
+valori che sono definiti per ogni file:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{FIOCLEX}] Setta il bit di \textit{close on exec}.
+\item[\macro{FIONCLEX}] Cancella il bit di \textit{close on exec}.
+\item[\macro{FIOASYNC}] Abilita l'I/O asincrono.
+\item[\macro{FIONBIO}] Abilità l'I/O in modalità non bloccante.
+\end{basedescript}
+relativi ad operazioni comunque eseguibili anche attraverso \func{fcntl}.
 
 
 %%% Local Variables: