Ancora pipe e fifo
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 2b9a0e9c4959e9f8a93e2e42a20c10a2f511d4b6..550b323eca806729ecb7c4dd869b433afc51fc64 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,6 +1,6 @@
 %% ipc.tex
 %%
-%% Copyright (C) 2000-2012 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2013 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -22,9 +22,9 @@ diversi, come quelli tradizionali che coinvolgono \textit{pipe} e
 Tralasceremo invece tutte le problematiche relative alla comunicazione
 attraverso la rete (e le relative interfacce) che saranno affrontate in
 dettaglio in un secondo tempo.  Non affronteremo neanche meccanismi più
-complessi ed evoluti come le RPC (\textit{Remote Procedure Calls}) e CORBA
-(\textit{Common Object Request Brocker Architecture}) che in genere sono
-implementati con un ulteriore livello sopra i meccanismi elementari.
+complessi ed evoluti come le RPC (\textit{Remote Procedure Calls}) che in
+genere sono implementati da un ulteriore livello di librerie sopra i
+meccanismi elementari.
 
 
 \section{L'intercomunicazione fra processi tradizionale}
@@ -42,157 +42,212 @@ ne gestiscono l'uso e le varie forme in cui si è evoluto.
 
 Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, e tuttora
 uno dei più usati, meccanismi di comunicazione fra processi. Si tratta in
-sostanza di una coppia di file descriptor\footnote{si tenga presente che
-  le pipe sono oggetti creati dal kernel e non risiedono su disco.} connessi
-fra di loro in modo che se quanto scrive su di uno si può rileggere
-dall'altro. Si viene così a costituire un canale di comunicazione tramite i
-due file descriptor, nella forma di un \textsl{tubo} (da cui il nome)
-attraverso cui fluiscono i dati.
-
-La funzione che permette di creare questa speciale coppia di file descriptor
-associati ad una \textit{pipe} è appunto \funcd{pipe}, ed il suo prototipo è:
-\begin{prototype}{unistd.h}
-{int pipe(int filedes[2])} 
-  
-Crea una coppia di file descriptor associati ad una \textit{pipe}.
-  
-  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
-    errore, nel qual caso \var{errno} potrà assumere i valori \errval{EMFILE},
-    \errval{ENFILE} e \errval{EFAULT}.}
-\end{prototype}
+sostanza di una coppia di file descriptor connessi fra di loro in modo che
+quanto scrive su di uno si può rileggere dall'altro.  Si viene così a
+costituire un canale di comunicazione realizzato tramite i due file
+descriptor, che costituisce appunto una sorta di \textsl{tubo} (che appunto il
+significato del termine inglese \textit{pipe}) attraverso cui si possono far
+passare i dati.
+
+In pratica si tratta di un buffer circolare in memoria in cui il kernel
+appoggia i dati immessi nel file descriptor su cui si scrive per farli poi
+riemergere dal file descriptor da cui si legge. Si tenga ben presente che in
+questo passaggio di dati non è previsto nessun tipo di accesso al disco e che
+nonostante l'uso dei file descriptor le \textit{pipe} non han nulla a che fare
+con i file di dati di cui si è parlato al cap.~\ref{cha:file_IO_interface}.
+
+La funzione di sistema che permette di creare questa speciale coppia di file
+descriptor associati ad una \textit{pipe} è appunto \funcd{pipe}, ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int pipe(int filedes[2])}
+\fdesc{Crea la coppia di file descriptor di una \textit{pipe}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+  \item[\errcode{EFAULT}] \param{filedes} non è un indirizzo valido.
+  \end{errlist}
+  ed inoltre \errval{EMFILE} e \errval{ENFILE} nel loro significato generico.}
+\end{funcproto}
 
 La funzione restituisce la coppia di file descriptor nel vettore
-\param{filedes}; il primo è aperto in lettura ed il secondo in scrittura. Come
-accennato concetto di funzionamento di una pipe è semplice: quello che si
-scrive nel file descriptor aperto in scrittura viene ripresentato tale e quale
-nel file descriptor aperto in lettura. I file descriptor infatti non sono
-connessi a nessun file reale, ma, come accennato in
-sez.~\ref{sec:file_sendfile_splice}, ad un buffer nel kernel, la cui
-dimensione è specificata dal parametro di sistema \const{PIPE\_BUF}, (vedi
-sez.~\ref{sec:sys_file_limits}). Lo schema di funzionamento di una pipe è
-illustrato in fig.~\ref{fig:ipc_pipe_singular}, in cui sono illustrati i due
-capi della pipe, associati a ciascun file descriptor, con le frecce che
-indicano la direzione del flusso dei dati.
-
-% TODO: la dimensione è cambiata a 64k (vedi man 7 pipe) e può essere
-% modificata con F_SETPIPE_SZ dal 2.6.35 (vedi fcntl)
+\param{filedes}, il primo è aperto in lettura ed il secondo in scrittura. Come
+accennato concetto di funzionamento di una \textit{pipe} è semplice: quello
+che si scrive nel file descriptor aperto in scrittura viene ripresentato tale
+e quale nel file descriptor aperto in lettura. 
+
+I file descriptor infatti non sono connessi a nessun file reale, ma, come
+accennato, ad un buffer nel kernel la cui dimensione è specificata dal
+parametro di sistema \const{PIPE\_BUF}, (vedi
+sez.~\ref{sec:sys_file_limits}). Lo schema di funzionamento di una
+\textit{pipe} è illustrato in fig.~\ref{fig:ipc_pipe_singular}, in cui sono
+indicati i due capi della \textit{pipe}, associati a ciascun file descriptor,
+con le frecce che indicano la direzione del flusso dei dati.
 
 \begin{figure}[!htb]
   \centering
   \includegraphics[height=5cm]{img/pipe}
-  \caption{Schema della struttura di una pipe.}
+  \caption{Schema della struttura di una \textit{pipe}.}
   \label{fig:ipc_pipe_singular}
 \end{figure}
 
-Chiaramente creare una pipe all'interno di un singolo processo non serve a
-niente; se però ricordiamo quanto esposto in sez.~\ref{sec:file_shared_access}
-riguardo al comportamento dei file descriptor nei processi figli, è immediato
-capire come una pipe possa diventare un meccanismo di intercomunicazione. Un
-processo figlio infatti condivide gli stessi file descriptor del padre,
-compresi quelli associati ad una pipe (secondo la situazione illustrata in
+Della funzione di sistema esiste una seconda versione, \funcd{pipe2},
+introdotta con il kernel 2.6.27 e le \acr{glibc} 2.9 e specifica di Linux
+(utilizzabile solo definendo la macro \macro{\_GNU\_SOURCE}), che consente di
+impostare atomicamente le caratteristiche dei file descriptor restituiti, il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{fcntl.h}
+\fdecl{int pipe2(int pipefd[2], int flags)}
+\fdesc{Crea la coppia di file descriptor di una \textit{pipe}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+  \item[\errcode{EINVAL}] il valore di \param{flags} non valido.
+  \end{errlist}
+  e gli altri già visti per \func{pipe} con lo stesso significato.}
+\end{funcproto}
+
+Utilizzando un valore nullo per \param{flags} la funzione è identica a
+\func{pipe}, si può però passare come valore l'OR aritmetico di uno qualunque
+fra \const{O\_NONBLOCK} o \const{O\_CLOEXEC} che hanno l'effetto di impostare
+su entrambi i file descriptor restituiti dalla funzione i relativi flag, già
+descritti per \func{open} in tab.~\ref{tab:open_operation_flag}, che attivano
+rispettivamente la modalità di accesso \textsl{non-bloccante} ed il
+\textit{close-on-exec} \itindex{close-on-exec}.
+
+Chiaramente creare una \textit{pipe} all'interno di un singolo processo non
+serve a niente; se però ricordiamo quanto esposto in
+sez.~\ref{sec:file_shared_access} riguardo al comportamento dei file
+descriptor nei processi figli, è immediato capire come una \textit{pipe} possa
+diventare un meccanismo di intercomunicazione. Un processo figlio infatti
+condivide gli stessi file descriptor del padre, compresi quelli associati ad
+una \textit{pipe} (secondo la situazione illustrata in
 fig.~\ref{fig:ipc_pipe_fork}). In questo modo se uno dei processi scrive su un
-capo della pipe, l'altro può leggere.
+capo della \textit{pipe}, l'altro può leggere.
 
 \begin{figure}[!htb]
   \centering
   \includegraphics[height=5cm]{img/pipefork}
-  \caption{Schema dei collegamenti ad una pipe, condivisi fra processo padre e
-    figlio dopo l'esecuzione \func{fork}.}
+  \caption{Schema dei collegamenti ad una \textit{pipe}, condivisi fra
+    processo padre e figlio dopo l'esecuzione \func{fork}.}
   \label{fig:ipc_pipe_fork}
 \end{figure}
 
 Tutto ciò ci mostra come sia immediato realizzare un meccanismo di
-comunicazione fra processi attraverso una pipe, utilizzando le proprietà
-ordinarie dei file, ma ci mostra anche qual è il principale\footnote{Stevens
-  in \cite{APUE} riporta come limite anche il fatto che la comunicazione è
-  unidirezionale, ma in realtà questo è un limite facilmente superabile usando
-  una coppia di pipe.} limite nell'uso delle pipe. È necessario infatti che i
-processi possano condividere i file descriptor della pipe, e per questo essi
-devono comunque essere \textsl{parenti} (dall'inglese \textit{siblings}), cioè
-o derivare da uno stesso processo padre in cui è avvenuta la creazione della
-pipe, o, più comunemente, essere nella relazione padre/figlio.
-
-A differenza di quanto avviene con i file normali, la lettura da una pipe può
-essere bloccante (qualora non siano presenti dati), inoltre se si legge da una
-pipe il cui capo in scrittura è stato chiuso, si avrà la ricezione di un EOF
-(vale a dire che la funzione \func{read} ritornerà restituendo 0).  Se invece
-si esegue una scrittura su una pipe il cui capo in lettura non è aperto il
-processo riceverà il segnale \signal{SIGPIPE}, e la funzione di scrittura
-restituirà un errore di \errcode{EPIPE} (al ritorno del gestore, o qualora il
-segnale sia ignorato o bloccato).
-
-La dimensione del buffer della pipe (\const{PIPE\_BUF}) ci dà inoltre un'altra
-importante informazione riguardo il comportamento delle operazioni di lettura
-e scrittura su di una pipe; esse infatti sono atomiche fintanto che la
-quantità di dati da scrivere non supera questa dimensione. Qualora ad esempio
-si effettui una scrittura di una quantità di dati superiore l'operazione verrà
-effettuata in più riprese, consentendo l'intromissione di scritture effettuate
-da altri processi.
-
-
-\subsection{Un esempio dell'uso delle pipe}
+comunicazione fra processi attraverso una \textit{pipe}, utilizzando le
+proprietà ordinarie dei file, ma ci mostra anche qual è il principale limite
+nell'uso delle \textit{pipe}.\footnote{Stevens in \cite{APUE} riporta come
+  limite anche il fatto che la comunicazione è unidirezionale, ma in realtà
+  questo è un limite superabile usando una coppia di \textit{pipe}, anche se
+  al costo di una maggiore complessità di gestione.}  È necessario infatti che
+i processi possano condividere i file descriptor della \textit{pipe}, e per
+questo essi devono comunque essere \textsl{parenti} (dall'inglese
+\textit{siblings}), cioè o derivare da uno stesso processo padre in cui è
+avvenuta la creazione della \textit{pipe}, o, più comunemente, essere nella
+relazione padre/figlio.
+
+A differenza di quanto avviene con i file normali, la lettura da una
+\textit{pipe} può essere bloccante (qualora non siano presenti dati), inoltre
+se si legge da una \textit{pipe} il cui capo in scrittura è stato chiuso, si
+avrà la ricezione di un EOF (vale a dire che la funzione \func{read} ritornerà
+restituendo 0).  Se invece si esegue una scrittura su una \textit{pipe} il cui
+capo in lettura non è aperto il processo riceverà il segnale \signal{SIGPIPE},
+e la funzione di scrittura restituirà un errore di \errcode{EPIPE} (al ritorno
+del gestore, o qualora il segnale sia ignorato o bloccato).
+
+La dimensione del buffer della \textit{pipe} (\const{PIPE\_BUF}) ci dà inoltre
+un'altra importante informazione riguardo il comportamento delle operazioni di
+lettura e scrittura su di una \textit{pipe}; esse infatti sono atomiche
+fintanto che la quantità di dati da scrivere non supera questa
+dimensione. Qualora ad esempio si effettui una scrittura di una quantità di
+dati superiore l'operazione verrà effettuata in più riprese, consentendo
+l'intromissione di scritture effettuate da altri processi.
+
+La dimensione originale del buffer era di 4096 byte (uguale ad una pagina di
+memoria) fino al kernel 2.6.11, ed è stata portata in seguito a 64kb; ma a
+partire dal kernel 2.6.35 è stata resa disponibile l'operazione di controllo
+\const{F\_SETPIPE\_SZ} (vedi sez.~\ref{sec:ipc_pipes}) che consente di
+modificarne la dimensione.
+
+
+
+\subsection{Un esempio dell'uso delle \textit{pipe}}
 \label{sec:ipc_pipe_use}
 
-Per capire meglio il funzionamento delle pipe faremo un esempio di quello che
-è il loro uso più comune, analogo a quello effettuato della shell, e che
-consiste nell'inviare l'output di un processo (lo standard output) sull'input
-di un altro. Realizzeremo il programma di esempio nella forma di un
-\textit{CGI}\footnote{un CGI (\textit{Common Gateway Interface}) è un
-  programma che permette la creazione dinamica di un oggetto da inserire
-  all'interno di una pagina HTML.}  per Apache, che genera una immagine JPEG
-di un codice a barre, specificato come argomento in ingresso.
+Per capire meglio il funzionamento delle \textit{pipe} faremo un esempio di
+quello che è il loro uso più comune, analogo a quello effettuato della shell,
+e che consiste nell'inviare l'output di un processo (lo standard output)
+sull'input di un altro. Realizzeremo il programma di esempio nella forma di un
+\textit{CGI}\footnote{quella dei CGI (\textit{Common Gateway Interface}) è una
+  interfaccia che consente ad un server web di eseguire un programma il cui
+  output (che deve essere opportunamente formattato seguendo le specifiche
+  dell'interfaccia) può essere presentato come risposta ad una richiesta HTTP
+  al posto del contenuto di un file, e che ha costituito probabilmente la
+  prima modalità con cui sono state create pagine HTML dinamiche.}  che genera
+una immagine JPEG di un codice a barre, specificato come argomento in
+ingresso.
 
 Un programma che deve essere eseguito come \textit{CGI} deve rispondere a
 delle caratteristiche specifiche, esso infatti non viene lanciato da una
 shell, ma dallo stesso web server, alla richiesta di una specifica URL, che di
 solito ha la forma:
-\begin{verbatim}
-    http://www.sito.it/cgi-bin/programma?argomento
-\end{verbatim}
+\begin{Verbatim}
+http://www.sito.it/cgi-bin/programma?argomento
+\end{Verbatim}
 ed il risultato dell'elaborazione deve essere presentato (con una intestazione
-che ne descrive il mime-type) sullo standard output, in modo che il web-server
-possa reinviarlo al browser che ha effettuato la richiesta, che in questo modo
-è in grado di visualizzarlo opportunamente.
-
-Per realizzare quanto voluto useremo in sequenza i programmi \cmd{barcode} e
-\cmd{gs}, il primo infatti è in grado di generare immagini PostScript di
-codici a barre corrispondenti ad una qualunque stringa, mentre il secondo
-serve per poter effettuare la conversione della stessa immagine in formato
-JPEG. Usando una pipe potremo inviare l'output del primo sull'input del
-secondo, secondo lo schema mostrato in fig.~\ref{fig:ipc_pipe_use}, in cui la
-direzione del flusso dei dati è data dalle frecce continue.
+che ne descrive il \textit{mime-type}) sullo \textit{standard output}, in modo
+che il server web possa reinviarlo al browser che ha effettuato la richiesta,
+che in questo modo è in grado di visualizzarlo opportunamente.
 
 \begin{figure}[!htb]
   \centering
   \includegraphics[height=5cm]{img/pipeuse}
-  \caption{Schema dell'uso di una pipe come mezzo di comunicazione fra
+  \caption{Schema dell'uso di una \textit{pipe} come mezzo di comunicazione fra
     due processi attraverso l'esecuzione una \func{fork} e la chiusura dei
     capi non utilizzati.}
   \label{fig:ipc_pipe_use}
 \end{figure}
 
+Per realizzare quanto voluto useremo in sequenza i programmi \cmd{barcode} e
+\cmd{gs}, il primo infatti è in grado di generare immagini PostScript di
+codici a barre corrispondenti ad una qualunque stringa, mentre il secondo
+serve per poter effettuare la conversione della stessa immagine in formato
+JPEG. Usando una \textit{pipe} potremo inviare l'output del primo sull'input del
+secondo, secondo lo schema mostrato in fig.~\ref{fig:ipc_pipe_use}, in cui la
+direzione del flusso dei dati è data dalle frecce continue.
+
 Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato
 intermedio su un file temporaneo. Questo però non tiene conto del fatto che un
-\textit{CGI} deve poter gestire più richieste in concorrenza, e si avrebbe una
+\textit{CGI} può essere eseguito più volte in contemporanea, e si avrebbe una
 evidente \itindex{race~condition} \textit{race condition} in caso di accesso
-simultaneo a detto file.\footnote{il problema potrebbe essere superato
-  determinando in anticipo un nome appropriato per il file temporaneo, che
-  verrebbe utilizzato dai vari sotto-processi, e cancellato alla fine della
-  loro esecuzione; ma a questo punto le cose non sarebbero più tanto
-  semplici.}  L'uso di una pipe invece permette di risolvere il problema in
-maniera semplice ed elegante, oltre ad essere molto più efficiente, dato che
-non si deve scrivere su disco.
+simultaneo a detto file da istanze diverse. Il problema potrebbe essere
+superato utilizzando un sempre diverso per il file temporaneo, che verrebbe
+creato all'avvio di ogni istanza, utilizzato dai sottoprocessi, e cancellato
+alla fine della sua esecuzione; ma a questo punto le cose non sarebbero più
+tanto semplici.  L'uso di una \textit{pipe} invece permette di risolvere il
+problema in maniera semplice ed elegante, oltre ad essere molto più
+efficiente, dato che non si deve scrivere su disco.
 
 Il programma ci servirà anche come esempio dell'uso delle funzioni di
 duplicazione dei file descriptor che abbiamo trattato in
 sez.~\ref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
 funzioni infatti che è possibile dirottare gli stream standard dei processi
 (che abbiamo visto in tab.~\ref{tab:file_std_files} e
-sez.~\ref{sec:file_stream}) sulla pipe. In fig.~\ref{fig:ipc_barcodepage_code}
-abbiamo riportato il corpo del programma, il cui codice completo è disponibile
-nel file \file{BarCodePage.c} che si trova nella directory dei sorgenti.
+sez.~\ref{sec:file_stream}) sulla \textit{pipe}. In
+fig.~\ref{fig:ipc_barcodepage_code} abbiamo riportato il corpo del programma,
+il cui codice completo è disponibile nel file \file{BarCodePage.c} che si
+trova nella directory dei sorgenti.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/BarCodePage.c}
@@ -204,180 +259,200 @@ nel file \file{BarCodePage.c} che si trova nella directory dei sorgenti.
 \end{figure}
 
 La prima operazione del programma (\texttt{\small 4--12}) è quella di creare
-le due pipe che serviranno per la comunicazione fra i due comandi utilizzati
-per produrre il codice a barre; si ha cura di controllare la riuscita della
-chiamata, inviando in caso di errore un messaggio invece dell'immagine
-richiesta.\footnote{la funzione \func{WriteMess} non è riportata in
-  fig.~\ref{fig:ipc_barcodepage_code}; essa si incarica semplicemente di
-  formattare l'uscita alla maniera dei CGI, aggiungendo l'opportuno
-  \textit{mime type}, e formattando il messaggio in HTML, in modo che
-  quest'ultimo possa essere visualizzato correttamente da un browser.}
-
-Una volta create le pipe, il programma può creare (\texttt{\small 13-17}) il
-primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
-\cmd{barcode}. Quest'ultimo legge dallo standard input una stringa di
-caratteri, la converte nell'immagine PostScript del codice a barre ad essa
-corrispondente, e poi scrive il risultato direttamente sullo standard output.
+le due \textit{pipe} che serviranno per la comunicazione fra i due comandi
+utilizzati per produrre il codice a barre; si ha cura di controllare la
+riuscita della chiamata, inviando in caso di errore un messaggio invece
+dell'immagine richiesta. La funzione \func{WriteMess} non è riportata in
+fig.~\ref{fig:ipc_barcodepage_code}; essa si incarica semplicemente di
+formattare l'uscita alla maniera dei CGI, aggiungendo l'opportuno
+\textit{mime-type}, e formattando il messaggio in HTML, in modo che
+quest'ultimo possa essere visualizzato correttamente da un browser.
+
+Una volta create le \textit{pipe}, il programma può creare (\texttt{\small
+  13-17}) il primo processo figlio, che si incaricherà (\texttt{\small
+  19--25}) di eseguire \cmd{barcode}. Quest'ultimo legge dallo standard input
+una stringa di caratteri, la converte nell'immagine PostScript del codice a
+barre ad essa corrispondente, e poi scrive il risultato direttamente sullo
+standard output.
 
 Per poter utilizzare queste caratteristiche prima di eseguire \cmd{barcode} si
-chiude (\texttt{\small 20}) il capo aperto in scrittura della prima pipe, e se
-ne collega (\texttt{\small 21}) il capo in lettura allo standard input, usando
-\func{dup2}. Si ricordi che invocando \func{dup2} il secondo file, qualora
-risulti aperto, viene, come nel caso corrente, chiuso prima di effettuare la
-duplicazione. Allo stesso modo, dato che \cmd{barcode} scrive l'immagine
-PostScript del codice a barre sullo standard output, per poter effettuare una
-ulteriore redirezione il capo in lettura della seconda pipe viene chiuso
-(\texttt{\small 22}) mentre il capo in scrittura viene collegato allo standard
-output (\texttt{\small 23}).
+chiude (\texttt{\small 20}) il capo aperto in scrittura della prima
+\textit{pipe}, e se ne collega (\texttt{\small 21}) il capo in lettura allo
+\textit{standard input} usando \func{dup2}. Si ricordi che invocando
+\func{dup2} il secondo file, qualora risulti aperto, viene, come nel caso
+corrente, chiuso prima di effettuare la duplicazione. Allo stesso modo, dato
+che \cmd{barcode} scrive l'immagine PostScript del codice a barre sullo
+standard output, per poter effettuare una ulteriore redirezione il capo in
+lettura della seconda \textit{pipe} viene chiuso (\texttt{\small 22}) mentre
+il capo in scrittura viene collegato allo standard output (\texttt{\small
+  23}).
 
 In questo modo all'esecuzione (\texttt{\small 25}) di \cmd{barcode} (cui si
 passa in \var{size} la dimensione della pagina per l'immagine) quest'ultimo
-leggerà dalla prima pipe la stringa da codificare che gli sarà inviata dal
-padre, e scriverà l'immagine PostScript del codice a barre sulla seconda.
+leggerà dalla prima \textit{pipe} la stringa da codificare che gli sarà
+inviata dal padre, e scriverà l'immagine PostScript del codice a barre sulla
+seconda.
 
 Al contempo una volta lanciato il primo figlio, il processo padre prima chiude
-(\texttt{\small 26}) il capo inutilizzato della prima pipe (quello in input) e
-poi scrive (\texttt{\small 27}) la stringa da convertire sul capo in output,
-così che \cmd{barcode} possa riceverla dallo standard input. A questo punto
-l'uso della prima pipe da parte del padre è finito ed essa può essere
-definitivamente chiusa (\texttt{\small 28}), si attende poi (\texttt{\small
-  29}) che l'esecuzione di \cmd{barcode} sia completata.
+(\texttt{\small 26}) il capo inutilizzato della prima \textit{pipe} (quello in
+ingresso) e poi scrive (\texttt{\small 27}) la stringa da convertire sul capo
+in uscita, così che \cmd{barcode} possa riceverla dallo \textit{standard
+  input}. A questo punto l'uso della prima \textit{pipe} da parte del padre è
+finito ed essa può essere definitivamente chiusa (\texttt{\small 28}), si
+attende poi (\texttt{\small 29}) che l'esecuzione di \cmd{barcode} sia
+completata.
 
 Alla conclusione della sua esecuzione \cmd{barcode} avrà inviato l'immagine
-PostScript del codice a barre sul capo in scrittura della seconda pipe; a
-questo punto si può eseguire la seconda conversione, da PS a JPEG, usando il
-programma \cmd{gs}. Per questo si crea (\texttt{\small 30--34}) un secondo
-processo figlio, che poi (\texttt{\small 35--42}) eseguirà questo programma
-leggendo l'immagine PostScript creata da \cmd{barcode} dallo standard input,
-per convertirla in JPEG.
+PostScript del codice a barre sul capo in scrittura della seconda
+\textit{pipe}; a questo punto si può eseguire la seconda conversione, da PS a
+JPEG, usando il programma \cmd{gs}. Per questo si crea (\texttt{\small
+  30--34}) un secondo processo figlio, che poi (\texttt{\small 35--42})
+eseguirà questo programma leggendo l'immagine PostScript creata da
+\cmd{barcode} dallo \textit{standard input}, per convertirla in JPEG.
 
 Per fare tutto ciò anzitutto si chiude (\texttt{\small 37}) il capo in
-scrittura della seconda pipe, e se ne collega (\texttt{\small 38}) il capo in
-lettura allo standard input. Per poter formattare l'output del programma in
-maniera utilizzabile da un browser, si provvede anche \texttt{\small 40}) alla
-scrittura dell'apposita stringa di identificazione del mime-type in testa allo
-standard output. A questo punto si può invocare \texttt{\small 41}) \cmd{gs},
-provvedendo gli appositi switch che consentono di leggere il file da
-convertire dallo standard input e di inviare la conversione sullo standard
-output.
+scrittura della seconda \textit{pipe}, e se ne collega (\texttt{\small 38}) il
+capo in lettura allo \textit{standard input}. Per poter formattare l'output
+del programma in maniera utilizzabile da un browser, si provvede anche
+\texttt{\small 40}) alla scrittura dell'apposita stringa di identificazione
+del \textit{mime-type} in testa allo \textit{standard output}. A questo punto
+si può invocare \texttt{\small 41}) \cmd{gs}, provvedendo le opportune opzioni
+del comando che consentono di leggere il file da convertire dallo
+\textit{standard input} e di inviare la conversione sullo \textit{standard
+  output}.
 
 Per completare le operazioni il processo padre chiude (\texttt{\small 44}) il
-capo in scrittura della seconda pipe, e attende la conclusione del figlio
-(\texttt{\small 45}); a questo punto può (\texttt{\small 46}) uscire. Si tenga
-conto che l'operazione di chiudere il capo in scrittura della seconda pipe è
-necessaria, infatti, se non venisse chiusa, \cmd{gs}, che legge il suo
-standard input da detta pipe, resterebbe bloccato in attesa di ulteriori dati
-in ingresso (l'unico modo che un programma ha per sapere che l'input è
-terminato è rilevare che lo standard input è stato chiuso), e la \func{wait}
-non ritornerebbe.
+capo in scrittura della seconda \textit{pipe}, e attende la conclusione del
+figlio (\texttt{\small 45}); a questo punto può (\texttt{\small 46})
+uscire. Si tenga conto che l'operazione di chiudere il capo in scrittura della
+seconda \textit{pipe} è necessaria, infatti, se non venisse chiusa, \cmd{gs},
+che legge il suo \textit{standard input} da detta \textit{pipe}, resterebbe
+bloccato in attesa di ulteriori dati in ingresso (l'unico modo che un
+programma ha per sapere che i dati in ingresso sono terminati è rilevare che
+lo \textit{standard input} è stato chiuso), e la \func{wait} non ritornerebbe.
 
 
 \subsection{Le funzioni \func{popen} e \func{pclose}}
 \label{sec:ipc_popen}
 
-Come si è visto la modalità più comune di utilizzo di una pipe è quella di
-utilizzarla per fare da tramite fra output ed input di due programmi invocati
-in sequenza; per questo motivo lo standard POSIX.2 ha introdotto due funzioni
-che permettono di sintetizzare queste operazioni. La prima di esse si chiama
-\funcd{popen} ed il suo prototipo è:
-\begin{prototype}{stdio.h}
-{FILE *popen(const char *command, const char *type)}
-
-Esegue il programma \param{command}, di cui, a seconda di \param{type},
-restituisce, lo standard input o lo standard output nella pipe collegata allo
-stream restituito come valore di ritorno.
-  
-\bodydesc{La funzione restituisce l'indirizzo dello stream associato alla pipe
-  in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno}
-  potrà assumere i valori relativi alle sottostanti invocazioni di \func{pipe}
-  e \func{fork} o \errcode{EINVAL} se \param{type} non è valido.}
-\end{prototype}
+Come si è visto la modalità più comune di utilizzo di una \textit{pipe} è
+quella di utilizzarla per fare da tramite fra output ed input di due programmi
+invocati in sequenza; per questo motivo lo standard POSIX.2 ha introdotto due
+funzioni che permettono di sintetizzare queste operazioni. La prima di esse si
+chiama \funcd{popen} ed il suo prototipo è:
+
 
-La funzione crea una pipe, esegue una \func{fork}, ed invoca il programma
-\param{command} attraverso la shell (in sostanza esegue \file{/bin/sh} con il
-flag \code{-c}); l'argomento \param{type} deve essere una delle due stringhe
-\verb|"w"| o \verb|"r"|, per indicare se la pipe sarà collegata allo standard
-input o allo standard output del comando invocato.
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{FILE *popen(const char *command, const char *type)}
+\fdesc{Esegue un programma dirottando l'uscita su una \textit{pipe}.} 
+}
 
-La funzione restituisce il puntatore allo stream associato alla pipe creata,
-che sarà aperto in sola lettura (e quindi associato allo standard output del
-programma indicato) in caso si sia indicato \code{"r"}, o in sola scrittura (e
-quindi associato allo standard input) in caso di \code{"w"}.
+{La funzione ritorna l'indirizzo dello stream associato alla \textit{pipe} in
+  caso di successo e \val{NULL} per un errore, nel qual caso \var{errno} potrà
+  assumere i valori relativi alle sottostanti invocazioni di \func{pipe} e
+  \func{fork} o \errcode{EINVAL} se \param{type} non è valido.}
+\end{funcproto}
+
+La funzione crea una \textit{pipe}, esegue una \func{fork} creando un nuovo
+processe nel quale invoca il programma \param{command} attraverso la shell (in
+sostanza esegue \file{/bin/sh} con il flag \code{-c}).
+L'argomento \param{type} deve essere una delle due stringhe \verb|"w"| o
+\verb|"r"|, per richiedere che la \textit{pipe} restituita come valore di
+ritorno sia collegata allo \textit{standard input} o allo \textit{standard
+  output} del comando invocato.
+
+La funzione restituisce il puntatore ad uno stream associato alla
+\textit{pipe} creata, che sarà aperto in sola lettura (e quindi associato allo
+\textit{standard output} del programma indicato) in caso si sia indicato
+\code{r}, o in sola scrittura (e quindi associato allo \textit{standard
+  input}) in caso di \code{w}. A partire dalla versione 2.9 delle \acr{glibc}
+(questa è una estensione specifica di Linux) all'argomento \param{type} può
+essere aggiunta la lettera ``\texttt{e}'' per impostare automaticamente il
+flag di \textit{close-on-exec} \itindex{close-on-exec} sul file descriptor
+sottostante (si ricordi quanto spiegato in sez.~\ref{sec:file_open_close}).
 
 Lo \textit{stream} restituito da \func{popen} è identico a tutti gli effetti
 ai \textit{file stream} visti in sez.~\ref{sec:files_std_interface}, anche se
-è collegato ad una pipe e non ad un file, e viene sempre aperto in modalità
-\textit{fully-buffered} (vedi sez.~\ref{sec:file_buffering}); l'unica
+è collegato ad una \textit{pipe} e non ad un file, e viene sempre aperto in
+modalità \textit{fully-buffered} (vedi sez.~\ref{sec:file_buffering}); l'unica
 differenza con gli usuali stream è che dovrà essere chiuso dalla seconda delle
 due nuove funzioni, \funcd{pclose}, il cui prototipo è:
-\begin{prototype}{stdio.h}
-{int pclose(FILE *stream)}
 
-Chiude il file \param{stream}, restituito da una precedente \func{popen}
-attendendo la terminazione del processo ad essa associato.
-  
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso il valore di \var{errno} deriva dalle sottostanti
-  chiamate.}
-\end{prototype}
-\noindent che oltre alla chiusura dello stream si incarica anche di attendere
-(tramite \func{wait4}) la conclusione del processo creato dalla precedente
-\func{popen}.
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int pclose(FILE *stream)}
+\fdesc{Chiude una \textit{pipe} creata con \func{popen}.} 
+}
+
+{La funzione ritorna lo stato del processo creato da \func{popen} in caso di
+  successo e $-1$ per un errore, nel qual caso \var{errno} assumerà i valori
+  derivanti dalle sottostanti funzioni \func{fclose} e \func{wait4}.}
+\end{funcproto}
+
+La funzione chiude il file \param{stream} associato ad una \textit{pipe}
+creato da una precedente \func{popen}, ed oltre alla chiusura dello stream si
+incarica anche di attendere (tramite \func{wait4}) la conclusione del processo
+creato dalla precedente \func{popen}. Se lo stato di uscita non può essere
+letto la funzione restituirà per \var{errno} un errore di \errval{ECHILD}.
 
 Per illustrare l'uso di queste due funzioni riprendiamo il problema
 precedente: il programma mostrato in fig.~\ref{fig:ipc_barcodepage_code} per
-quanto funzionante, è (volutamente) codificato in maniera piuttosto complessa,
-inoltre nella pratica sconta un problema di \cmd{gs} che non è in
-grado\footnote{nella versione GNU Ghostscript 6.53 (2002-02-13).} di
-riconoscere correttamente l'Encapsulated PostScript, per cui deve essere usato
-il PostScript e tutte le volte viene generata una pagina intera, invece che
-una immagine delle dimensioni corrispondenti al codice a barre.
+quanto funzionante, è volutamente codificato in maniera piuttosto complessa,
+inoltre doveva scontare un problema di \cmd{gs} che non era in grado di
+riconoscere correttamente l'Encapsulated PostScript,\footnote{si fa
+  riferimento alla versione di GNU Ghostscript 6.53 del 2002-02-13, quando
+  l'esempio venne scritto per la prima volta.} per cui si era utilizzato il
+PostScript semplice, generando una pagina intera invece che una immagine delle
+dimensioni corrispondenti al codice a barre.
 
 Se si vuole generare una immagine di dimensioni appropriate si deve usare un
 approccio diverso. Una possibilità sarebbe quella di ricorrere ad ulteriore
 programma, \cmd{epstopsf}, per convertire in PDF un file EPS (che può essere
-generato da \cmd{barcode} utilizzando lo switch \cmd{-E}).  Utilizzando un PDF
+generato da \cmd{barcode} utilizzando l'opzione \cmd{-E}).  Utilizzando un PDF
 al posto di un EPS \cmd{gs} esegue la conversione rispettando le dimensioni
 originarie del codice a barre e produce un JPEG di dimensioni corrette.
 
-Questo approccio però non funziona, per via di una delle caratteristiche
-principali delle pipe. Per poter effettuare la conversione di un PDF infatti è
-necessario, per la struttura del formato, potersi spostare (con \func{lseek})
-all'interno del file da convertire; se si esegue la conversione con \cmd{gs}
-su un file regolare non ci sono problemi, una pipe però è rigidamente
-sequenziale, e l'uso di \func{lseek} su di essa fallisce sempre con un errore
-di \errcode{ESPIPE}, rendendo impossibile la conversione.  Questo ci dice che
-in generale la concatenazione di vari programmi funzionerà soltanto quando
-tutti prevedono una lettura sequenziale del loro input.
+Questo approccio però non può funzionare per via di una delle caratteristiche
+principali delle \textit{pipe}. Per poter effettuare la conversione di un PDF
+infatti è necessario, per la struttura del formato, potersi spostare (con
+\func{lseek}) all'interno del file da convertire. Se si esegue la conversione
+con \cmd{gs} su un file regolare non ci sono problemi, una \textit{pipe} però
+è rigidamente sequenziale, e l'uso di \func{lseek} su di essa fallisce sempre
+con un errore di \errcode{ESPIPE}, rendendo impossibile la conversione.
+Questo ci dice che in generale la concatenazione di vari programmi funzionerà
+soltanto quando tutti prevedono una lettura sequenziale del loro input.
 
 Per questo motivo si è dovuto utilizzare un procedimento diverso, eseguendo
 prima la conversione (sempre con \cmd{gs}) del PS in un altro formato
 intermedio, il PPM,\footnote{il \textit{Portable PixMap file format} è un
   formato usato spesso come formato intermedio per effettuare conversioni, è
   infatti molto facile da manipolare, dato che usa caratteri ASCII per
-  memorizzare le immagini, anche se per questo è estremamente inefficiente.}
-dal quale poi si può ottenere un'immagine di dimensioni corrette attraverso
-vari programmi di manipolazione (\cmd{pnmcrop}, \cmd{pnmmargin}) che può
-essere infine trasformata in PNG (con \cmd{pnm2png}).
+  memorizzare le immagini, anche se per questo è estremamente inefficiente
+  come formato di archiviazione.}  dal quale poi si può ottenere un'immagine
+di dimensioni corrette attraverso vari programmi di manipolazione
+(\cmd{pnmcrop}, \cmd{pnmmargin}) che può essere infine trasformata in PNG (con
+\cmd{pnm2png}).
 
 In questo caso però occorre eseguire in sequenza ben quattro comandi diversi,
-inviando l'output di ciascuno all'input del successivo, per poi ottenere il
-risultato finale sullo standard output: un caso classico di utilizzazione
-delle pipe, in cui l'uso di \func{popen} e \func{pclose} permette di
-semplificare notevolmente la stesura del codice.
-
-Nel nostro caso, dato che ciascun processo deve scrivere il suo output sullo
-standard input del successivo, occorrerà usare \func{popen} aprendo la pipe in
-scrittura. Il codice del nuovo programma è riportato in
+inviando l'uscita di ciascuno all'ingresso del successivo, per poi ottenere il
+risultato finale sullo \textit{standard output}: un caso classico di
+utilizzazione delle pipe, in cui l'uso di \func{popen} e \func{pclose}
+permette di semplificare notevolmente la stesura del codice.
+
+Nel nostro caso, dato che ciascun processo deve scrivere la sua uscita sullo
+\textit{standard input} del successivo, occorrerà usare \func{popen} aprendo
+la \textit{pipe} in scrittura. Il codice del nuovo programma è riportato in
 fig.~\ref{fig:ipc_barcode_code}.  Come si può notare l'ordine di invocazione
 dei programmi è l'inverso di quello in cui ci si aspetta che vengano
 effettivamente eseguiti. Questo non comporta nessun problema dato che la
-lettura su una pipe è bloccante, per cui ciascun processo, per quanto lanciato
-per primo, si bloccherà in attesa di ricevere sullo standard input il
-risultato dell'elaborazione del precedente, benché quest'ultimo venga invocato
-dopo.
+lettura su una \textit{pipe} è bloccante, per cui un processo, anche se
+lanciato per primo, se non ottiene i dati che gli servono si bloccherà in
+attesa sullo \textit{standard input} finché non otterrà il risultato
+dell'elaborazione del processo che li deve creare, che pur essendo logicamente
+precedente, viene lanciato dopo di lui.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/BarCode.c}
@@ -387,28 +462,31 @@ dopo.
   \label{fig:ipc_barcode_code}
 \end{figure}
 
-Nel nostro caso il primo passo (\texttt{\small 14}) è scrivere il mime-type
-sullo standard output; a questo punto il processo padre non necessita più di
-eseguire ulteriori operazioni sullo standard output e può tranquillamente
-provvedere alla redirezione.
+Nel nostro caso il primo passo (\texttt{\small 14}) è scrivere il
+\textit{mime-type} sullo \textit{standard output}; a questo punto il processo
+padre non necessita più di eseguire ulteriori operazioni sullo
+\textit{standard output} e può tranquillamente provvedere alla redirezione.
 
 Dato che i vari programmi devono essere lanciati in successione, si è
 approntato un ciclo (\texttt{\small 15--19}) che esegue le operazioni in
-sequenza: prima crea una pipe (\texttt{\small 17}) per la scrittura eseguendo
-il programma con \func{popen}, in modo che essa sia collegata allo standard
-input, e poi redirige (\texttt{\small 18}) lo standard output su detta pipe.
+sequenza: prima crea una \textit{pipe} (\texttt{\small 17}) per la scrittura
+eseguendo il programma con \func{popen}, in modo che essa sia collegata allo
+\textit{standard input}, e poi redirige (\texttt{\small 18}) lo
+\textit{standard output} su detta \textit{pipe}.
 
 In questo modo il primo processo ad essere invocato (che è l'ultimo della
-catena) scriverà ancora sullo standard output del processo padre, ma i
-successivi, a causa di questa redirezione, scriveranno sulla pipe associata
-allo standard input del processo invocato nel ciclo precedente.
+catena) scriverà ancora sullo \textit{standard output} del processo padre, ma
+i successivi, a causa di questa redirezione, scriveranno sulla \textit{pipe}
+associata allo \textit{standard input} del processo invocato nel ciclo
+precedente.
 
 Alla fine tutto quello che resta da fare è lanciare (\texttt{\small 21}) il
 primo processo della catena, che nel caso è \cmd{barcode}, e scrivere
-(\texttt{\small 23}) la stringa del codice a barre sulla pipe, che è collegata
-al suo standard input, infine si può eseguire (\texttt{\small 24--27}) un
-ciclo che chiuda, nell'ordine inverso rispetto a quello in cui le si sono
-create, tutte le pipe create con \func{pclose}.
+(\texttt{\small 23}) la stringa del codice a barre sulla \textit{pipe}, che è
+collegata al suo \textit{standard input}, infine si può eseguire
+(\texttt{\small 24--27}) un ciclo che chiuda con \func{pclose}, nell'ordine
+inverso rispetto a quello in cui le si sono create, tutte le \textit{pipe}
+create in precedenza.
 
 
 \subsection{Le \textit{pipe} con nome, o \textit{fifo}}
@@ -416,49 +494,52 @@ create, tutte le pipe create con \func{pclose}.
 
 Come accennato in sez.~\ref{sec:ipc_pipes} il problema delle \textit{pipe} è
 che esse possono essere utilizzate solo da processi con un progenitore comune
-o nella relazione padre/figlio; per superare questo problema lo standard
+o nella relazione padre/figlio. Per superare questo problema lo standard
 POSIX.1 ha definito dei nuovi oggetti, le \textit{fifo}, che hanno le stesse
-caratteristiche delle pipe, ma che invece di essere strutture interne del
-kernel, visibili solo attraverso un file descriptor, sono accessibili
-attraverso un \itindex{inode} inode che risiede sul filesystem, così che i
-processi le possono usare senza dovere per forza essere in una relazione di
-\textsl{parentela}.
-
-Utilizzando una \textit{fifo} tutti i dati passeranno, come per le pipe,
-attraverso un apposito buffer nel kernel, senza transitare dal filesystem;
-\itindex{inode} l'inode allocato sul filesystem serve infatti solo a fornire un
-punto di riferimento per i processi, che permetta loro di accedere alla stessa
-fifo; il comportamento delle funzioni di lettura e scrittura è identico a
-quello illustrato per le pipe in sez.~\ref{sec:ipc_pipes}.
+caratteristiche delle \textit{pipe}, ma che invece di essere strutture interne
+del kernel, visibili solo attraverso un file descriptor, sono accessibili
+attraverso un \itindex{inode} \textit{inode} che risiede sul filesystem, così
+che i processi le possono usare senza dovere per forza essere in una relazione
+di \textsl{parentela}.
+
+Utilizzando una \textit{fifo} tutti i dati passeranno, come per le
+\textit{pipe}, attraverso un apposito buffer nel kernel, senza transitare dal
+filesystem; \itindex{inode} l'\textit{inode} allocato sul filesystem serve
+infatti solo a fornire un punto di riferimento per i processi, che permetta
+loro di accedere alla stessa fifo; il comportamento delle funzioni di lettura
+e scrittura è identico a quello illustrato per le \textit{pipe} in
+sez.~\ref{sec:ipc_pipes}.
 
 Abbiamo già visto in sez.~\ref{sec:file_mknod} le funzioni \func{mknod} e
-\func{mkfifo} che permettono di creare una fifo; per utilizzarne una un
-processo non avrà che da aprire il relativo \index{file!speciali} file
+\func{mkfifo} che permettono di creare una \textit{fifo}; per utilizzarne una
+un processo non avrà che da aprire il relativo \index{file!speciali} file
 speciale o in lettura o scrittura; nel primo caso sarà collegato al capo di
-uscita della fifo, e dovrà leggere, nel secondo al capo di ingresso, e dovrà
-scrivere.
-
-Il kernel crea una singola pipe per ciascuna fifo che sia stata aperta, che può
-essere acceduta contemporaneamente da più processi, sia in lettura che in
-scrittura. Dato che per funzionare deve essere aperta in entrambe le
-direzioni, per una fifo di norma la funzione \func{open} si blocca se viene
-eseguita quando l'altro capo non è aperto.
-
-Le fifo però possono essere anche aperte in modalità \textsl{non-bloccante},
-nel qual caso l'apertura del capo in lettura avrà successo solo quando anche
-l'altro capo è aperto, mentre l'apertura del capo in scrittura restituirà
-l'errore di \errcode{ENXIO} fintanto che non verrà aperto il capo in lettura.
-
-In Linux è possibile aprire le fifo anche in lettura/scrittura,\footnote{lo
-  standard POSIX lascia indefinito il comportamento in questo caso.}
-operazione che avrà sempre successo immediato qualunque sia la modalità di
-apertura (bloccante e non bloccante); questo può essere utilizzato per aprire
-comunque una fifo in scrittura anche se non ci sono ancora processi il
-lettura; è possibile anche usare la fifo all'interno di un solo processo, nel
-qual caso però occorre stare molto attenti alla possibili situazioni di
-stallo.\footnote{se si cerca di leggere da una fifo che non contiene dati si
-  avrà un \itindex{deadlock} deadlock immediato, dato che il processo si
-  blocca e non potrà quindi mai eseguire le funzioni di scrittura.}
+uscita della \textit{fifo}, e dovrà leggere, nel secondo al capo di ingresso,
+e dovrà scrivere.
+
+Il kernel crea una singola \textit{pipe} per ciascuna \textit{fifo} che sia
+stata aperta, che può essere acceduta contemporaneamente da più processi, sia
+in lettura che in scrittura. Dato che per funzionare deve essere aperta in
+entrambe le direzioni, per una \textit{fifo} di norma la funzione \func{open}
+si blocca se viene eseguita quando l'altro capo non è aperto.
+
+Le \textit{fifo} però possono essere anche aperte in modalità
+\textsl{non-bloccante}, nel qual caso l'apertura del capo in lettura avrà
+successo solo quando anche l'altro capo è aperto, mentre l'apertura del capo
+in scrittura restituirà l'errore di \errcode{ENXIO} fintanto che non verrà
+aperto il capo in lettura.
+
+In Linux è possibile aprire le \textit{fifo} anche in
+lettura/scrittura,\footnote{lo standard POSIX lascia indefinito il
+  comportamento in questo caso.}  operazione che avrà sempre successo
+immediato qualunque sia la modalità di apertura (bloccante e non bloccante);
+questo può essere utilizzato per aprire comunque una fifo in scrittura anche
+se non ci sono ancora processi il lettura; è possibile anche usare la fifo
+all'interno di un solo processo, nel qual caso però occorre stare molto
+attenti alla possibili situazioni di stallo.\footnote{se si cerca di leggere
+  da una fifo che non contiene dati si avrà un \itindex{deadlock}
+  \textit{deadlock} immediato, dato che il processo si blocca e non potrà
+  quindi mai eseguire le funzioni di scrittura.}
 
 Per la loro caratteristica di essere accessibili attraverso il filesystem, è
 piuttosto frequente l'utilizzo di una fifo come canale di comunicazione nelle
@@ -470,14 +551,14 @@ sez.~\ref{sec:ipc_pipes}).
 
 A parte il caso precedente, che resta probabilmente il più comune, Stevens
 riporta in \cite{APUE} altre due casistiche principali per l'uso delle fifo:
-\begin{itemize}
+\begin{itemize*}
 \item Da parte dei comandi di shell, per evitare la creazione di file
   temporanei quando si devono inviare i dati di uscita di un processo
   sull'input di parecchi altri (attraverso l'uso del comando \cmd{tee}).
   
 \item Come canale di comunicazione fra client ed server (il modello
   \textit{client-server} è illustrato in sez.~\ref{sec:net_cliserv}).
-\end{itemize}
+\end{itemize*}
 
 Nel primo caso quello che si fa è creare tante fifo, da usare come standard
 input, quanti sono i processi a cui i vogliono inviare i dati, questi ultimi
@@ -513,7 +594,7 @@ un detto a caso estratto da un insieme di frasi; sia il numero delle frasi
 dell'insieme, che i file da cui esse vengono lette all'avvio, sono importabili
 da riga di comando. Il corpo principale del server è riportato in
 fig.~\ref{fig:ipc_fifo_server}, dove si è tralasciata la parte che tratta la
-gestione delle opzioni a riga di comando, che effettua il settaggio delle
+gestione delle opzioni a riga di comando, che effettua l'impostazione delle
 variabili \var{fortunefilename}, che indica il file da cui leggere le frasi,
 ed \var{n}, che indica il numero di frasi tenute in memoria, ad un valore
 diverso da quelli preimpostati. Il codice completo è nel file