Ancora pipe e fifo
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 30 Apr 2013 17:43:40 +0000 (17:43 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 30 Apr 2013 17:43:40 +0000 (17:43 +0000)
ipc.tex

diff --git a/ipc.tex b/ipc.tex
index 3ead8bbb4d6144786d80cb7305a7e37ea5422960..550b323eca806729ecb7c4dd869b433afc51fc64 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -53,8 +53,8 @@ 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 pipe non han nulla a che fare con i
-file di dati di cui si è parlato al cap.~\ref{cha:file_IO_interface}.
+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
@@ -83,18 +83,15 @@ 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 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.
-
-% TODO: la dimensione è cambiata a 64k (vedi man 7 pipe) e può essere
-% modificata con F_SETPIPE_SZ dal 2.6.35 (vedi fcntl)
+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}
 
@@ -133,111 +130,124 @@ 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 pipe (secondo la situazione illustrata in
+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 limite nell'uso
-delle 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 pipe, anche se al costo di una maggiore
-  complessità di gestione.}  È 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 \textit{pipe},
-o, più comunemente, essere nella relazione padre/figlio.
+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 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).
+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 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.
+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 pipe}
+\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}
@@ -249,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.
 
-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"}.
+\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 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}
@@ -432,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}}
@@ -461,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
@@ -515,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