Aggiunte sulle fifo
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 898305fdd703de19aeb56ca31e5e53d9f23f2bb6..c16d5c32ea8486a3d50d94697642579f590e5190 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -86,8 +86,8 @@ capo della pipe, l'altro pu
 \begin{figure}[htb]
   \centering
   \includegraphics[height=5cm]{img/pipefork}
 \begin{figure}[htb]
   \centering
   \includegraphics[height=5cm]{img/pipefork}
-  \caption{Schema dell'uso di una pipe come mezzo di comunicazione fra
-  processo attraverso una \func{fork}.}
+  \caption{Schema dei collegamenti ad una pipe, condivisi fra processo padre e
+    figlio dopo l'esecuzione \func{fork}.}
   \label{fig:ipc_pipe_fork}
 \end{figure}
 
   \label{fig:ipc_pipe_fork}
 \end{figure}
 
@@ -101,6 +101,22 @@ processi possano condividere i file descriptor della pipe, e per questo essi
 devono comunque derivare da uno stesso processo padre che ha aperto la pipe,
 o, più comunemente, essere nella relazione padre/figlio.
 
 devono comunque derivare da uno stesso processo padre che ha aperto la 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 \macro{EPIPE}, e la funzione di scrittura
+restituirà un errore di \macro{EPIPE} (al ritorno del manipolatore, o qualora
+il segnale sia ignorato o bloccato).
+
+La dimensione del buffer della pipe (\macro{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}
 
 
 \subsection{Un esempio dell'uso delle pipe}
@@ -110,45 +126,58 @@ Per capire meglio il funzionamento di una 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. Realizzaremo il programma nella forma di un
 è 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. Realizzaremo il programma nella forma di un
-\textit{cgi}\footnote{NdA, inserire una breve descrizione di cosa è un cgi.}
-per apache, che genera una immagine JPEG di un codice a barre, specificato
-come parametro di input.
-
-Un programma che deve essere eseguito come \textit{cgi} per apache 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:
+\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 parametro di input.
+
+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}
 \begin{verbatim}
-http://www.sito.it/cgi-bin/programma?parametro
+    http://www.sito.it/cgi-bin/programma?parametro
 \end{verbatim}
 ed il risultato dell'elaborazione deve essere presentato (con una intestazione
 \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 apache possa
-reinviarlo al browser che ha effettuato la richiesta.
-
+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 fare questo 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
 
 Per fare questo 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.
+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 \figref{fig:ipc_pipe_use}, in cui la direzione del flusso
+dei dati è data dalle frecce continue.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[height=5cm]{img/pipeuse}
+  \caption{Schema dell'uso di una pipe come mezzo di comunicazione fra
+    due processi attraverso attraverso l'esecuzione una \func{fork} e la
+    chiusura dei capi non utilizzati.}
+  \label{fig:ipc_pipe_use}
+\end{figure}
 
 Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato
 
 Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato
-intermedio su un file temporaneo. Questo però non tiene conto del fatto che il
-\textit{cgi} deve poter gestire più richieste in concorrenza, e si avrebbe una
+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
 evidente race condition in caso di accesso simultaneo a detto
 evidente race condition in caso di accesso simultaneo a detto
-file.\footnote{la questione potrebbe essere evitata creando prima dei file
-  temporanei, da comunicare poi ai vari sotto-processi, da cancellare alla
-  fine dell'esecuzione; ma a questo punto avremmo perso tutta la semplicità.}
-L'uso di una pipe invece permette di risolvere il problema in maniera semplice
-ed elegante.
-
-Il programma ci servirà anche come esempio dell'uso di alcune delle funzioni
-di manipolazione dei file descriptor, come \func{dup} e \func{dup2}, viste in
-\secref{sec:file_dup}; è attraverso queste funzioni che è possibile dirottare
-gli stream standard dei processi (che abbiamo visto in
-\secref{sec:file_std_descr} e \secref{sec:file_std_stream}) sulla pipe. Le
-sezioni significative del programma è riportato in
-\figref{fig:ipc_barcode_code}, il codice è disponibile nel file
-\file{BarCode.c} nella directory dei sorgenti.
+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 le
+  cose non sarebbero più tanto semplici.}  L'uso di una pipe invece permette
+di risolvere il problema in maniera semplice ed elegante.
+
+Il programma ci servirà anche come esempio dell'uso delle funzioni di
+duplicazione dei file descriptor che abbiamo trattato in
+\secref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
+funzioni infatti che è possibile dirottare gli stream standard dei processi
+(che abbiamo visto in \secref{sec:file_std_descr} e
+\secref{sec:file_std_stream}) sulla pipe. In \figref{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}[!htb]
 
 
 \begin{figure}[!htb]
@@ -205,74 +234,78 @@ int main(int argc, char *argv[], char *envp[])
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
-  \caption{Codice del \textit{cgi-bin} \cmd{BarCode}.}
-  \label{fig:ipc_barcode_code}
+  \caption{Sezione principale del codice del \textit{CGI} 
+    \file{BarCodePage.c}.}
+  \label{fig:ipc_barcodepage_code}
 \end{figure}
 
 \end{figure}
 
-Il primo passo (\texttt{\small 4--12}) è quello di creare le due pipe che
-servono per la comunicazione fra i due programmi che verranno utilizzati per
-produrre il codice a barre; si ha cura di controllare la riuscita della
+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
 chiamata, inviando in caso di errore un messaggio invece dell'immagine
 richiesta.\footnote{la funzione \func{WriteMess}, non è riportata in
-  \ref{fig:ipc_barcode_code}, ma si incarica semplicemente di formattare
-  l'uscita, aggiungendo un \textit{mime type}, in modo che possa essere
-  interpretata direttamente da un browser.}
+  \secref{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
+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
 primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
-il programma \cmd{barcode}: quest'ultimo funziona ricevendo dallo standard
-input la stringa da convertire nell'immagine postscript del codice a barre,
-che sarà scritta sullo standard output.
-
-Per utilizzare queste caratteristiche il primo figlio chiude (\texttt{\small
-  20}) il capo aperto in scrittura della prima pipe, dato che userà il capo
-aperto in lettura per ricevere dal padre la stringa da codificare; per far
-questo collega (\texttt{\small 21}) il capo in lettura della pipe allo
-standard input usando \func{dup2}. Dato che \cmd{barcode} scrive l'immagine
-postscript del codice a barre sullo standard output per poter effettuare una
+\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
 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}).  
+output (\texttt{\small 23}).
 
 In questo modo all'esecuzione (\texttt{\small 25}) di \cmd{barcode} (cui si
 
 In questo modo all'esecuzione (\texttt{\small 25}) di \cmd{barcode} (cui si
-passa in \var{size} la dimensione per l'immagine) quest'ultimo leggerà la
-stringa da codificare che gli viene inviata dal padre dalla prima pipe e
-scriverà l'immagine postscript del codice a barre sulla seconda.
-
-Dall'altra parte il processo padre prima chiude (\texttt{\small 26}) il capo
-inutilizzato della prima pipe (quello in input), 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 è
-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à effettuato 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} sullo
-standard input per convertirla in JPEG.
-
-Per fare tutto ciò il secondo figlio anzitutto chiude (\texttt{\small 37}) il
-capo in scrittura della seconda pipe, e collega (\texttt{\small 38}) il capo
-in lettura allo standard input. Per poter formattare l'output del programma in
+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.
+
+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.
+
+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.
+
+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
 maniera utilizzabile da un browser, si provvede anche \texttt{\small 40}) alla
-scrittura dell'apposita stringa di mime-type in testa allo standard output. A
-questo punto si può invocare \texttt{\small 41}) il programma \cmd{gs},
+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
 provvedendo gli appositi switch che consentono di leggere il file da
-convertire dallo standard input, ed inviare la conversione sullo standard
+convertire dallo standard input e di inviare la conversione sullo standard
 output.
 
 output.
 
-Per concludere le operazioni il processo padre chiude \texttt{\small 44}) il
+Per completare le operazioni il processo padre chiude (\texttt{\small 44}) il
 capo in scrittura della seconda pipe, e attende la conclusione del figlio
 capo in scrittura della seconda pipe, e attende la conclusione del figlio
-\texttt{\small 45}), per poi uscire \texttt{\small 46}). Si tenga conto che,
-l'operazione di chiudere il capo in scrittura della seconda pipe è necessaria,
-infatti non chiudendola \cmd{gs}, che legge il suo stardard input da detta
-pipe, resterebbe bloccato in attesa di ulteriore input (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. 
+(\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.
 
 
 \subsection{Le funzioni \func{popen} e \func{pclose}}
 
 
 \subsection{Le funzioni \func{popen} e \func{pclose}}
@@ -295,13 +328,12 @@ stream restituito come valore di ritorno.
   potrà assumere i valori relativi alle sottostanti invocazioni di \func{pipe}
   e \func{fork} o \macro{EINVAL} se \param{type} non è valido.}
 \end{prototype}
   potrà assumere i valori relativi alle sottostanti invocazioni di \func{pipe}
   e \func{fork} o \macro{EINVAL} se \param{type} non è valido.}
 \end{prototype}
-\noindent e serve per semplificare l'uso di \func{pipe}. 
 
 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
 
 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 stringa \verb|"w"| o
-\verb|"r"|, per indicare se la pipe sarà collegata allo standard input o allo
-standard output del comando invocato.
+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
 
 La funzione restituisce il puntatore allo stream associato alla pipe creata,
 che sarà aperto in sola lettura (e quindi associato allo standard output del
@@ -309,36 +341,139 @@ programma indicato) in caso si sia indicato \code{"r"}, o in sola scrittura (e
 quindi associato allo standard input) in caso di \code{"w"}.
 
 Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
 quindi associato allo standard input) in caso di \code{"w"}.
 
 Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
-standard visti in \secref{cha:files_std_interface}, e viene sempre aperto in
-modalità \textit{fully-buffered} (vedi \secref{sec:file_buffering}); l'unica
-differenza è che deve essere chiuso dalla seconda delle due funzioni,
-\func{pclose}, il cui prototipo è:
+stream visti in \secref{cha:files_std_interface}, anche se è collegato ad una
+pipe e non ad un inode, e viene sempre aperto in modalità
+\textit{fully-buffered} (vedi \secref{sec:file_buffering}); l'unica differenza
+con gli usuali stream è che dovrà essere chiuso dalla seconda delle due nuove
+funzioni, \func{pclose}, il cui prototipo è:
 \begin{prototype}{stdio.h}
 {int pclose(FILE *stream)}
 
 \begin{prototype}{stdio.h}
 {int pclose(FILE *stream)}
 
-Chiude il file \param{stream}, restituito da una prededente \func{popen}
+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 \func{errno} deriva dalle sottostanti
   chiamate.}
 \end{prototype}
 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 \func{errno} deriva dalle sottostanti
   chiamate.}
 \end{prototype}
-\noindent che si incarica anche di attendere la conclusione del processo
-creato dalla precedente \func{popen}.
-
-Per illustrare l'uso di queste due funzioni riprendiamo l'esempio in
-\figref{fig:ipc_barcode_code}: esso per quanto funzionante, è piuttosto
-complesso; inoltre nella pratica sconta un problema di \cmd{gs} che non è in
+\noindent che oltre alla chiusura dello stream si incarica anche di attendere
+(tramite \func{wait4}) la conclusione del processo creato dalla precedente
+\func{popen}.
+
+Per illustrare l'uso di queste due funzioni riprendiamo il problema
+precedente: il programma mostrato in \figref{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
 grado\footnote{nella versione GNU Ghostscript 6.53 (2002-02-13).} di
-riconoscere correttamente l'encapsulated postscript, per cui tutte le volte
-generata una pagina intera, invece che una semplice figura.  Se si vuole
-generare una immagine di dimensioni corrette si deve allora ricorrere ad
-ulteriore programma, \cmd{epstopsf}, per convertire in PDF il file EPS
-generato da \cmd{barcode}. Utilizzando un file in PDF invece, \cmd{gs} esegue
-la conversione rispettando le dimensioni originarie del codice a barre.
+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.
+
+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
+al posto di un EPS \cmd{gs} esegue la conversione rispettando le dimensioni
+originarie del codice a barre e produce un JPEG delle dimensioni adeguate.
+
+Questo però ci porta a scontrarci con una caratteristica peculiare delle pipe,
+che a prima vista non è evidente. Per poter effettuare la conversione di un
+PDF infatti è necessario, per la struttura del formato, dover eseguire delle
+\func{lseek} sul file da convertire; se si esegue \cmd{gs} su un file normale
+non ci sono problemi, ma una pipe però è rigidamente sequenziale, ed il
+tentativo di eseguire detta operazione su una pipe comporta l'immediato
+fallimento con un errore di \macro{ESPIPE}.  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 una strada diversa, che prevede la
+conversione attraverso \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, è estremamente
+  inefficiente, ma molto facile da manipolare dato che usa caratteri ASCII per
+  memorizzare le immagini.} 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
+\figref{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.
 
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+int main(int argc, char *argv[], char *envp[])
+{
+    FILE *pipe[4];
+    FILE *pipein;
+    char *cmd_string[4]={
+        "pnmtopng",
+        "pnmmargin -white 10",
+        "pnmcrop",
+        "gs -sDEVICE=ppmraw -sOutputFile=- -sNOPAUSE -q - -c showpage -c quit"
+    };  
+    char content[]="Content-type: image/png\n\n";
+    int i;
+    /* write mime-type to stout */ 
+    write(STDOUT_FILENO, content, strlen(content));
+    /* execute chain of command */
+    for (i=0; i<4; i++) {
+        pipe[i] = popen(cmd_string[i], "w");
+        dup2(fileno(pipe[i]), STDOUT_FILENO); 
+    }
+    /* create barcode (in PS) */
+    pipein = popen("barcode", "w");
+    /* send barcode string to barcode program */
+    write(fileno(pipein), argv[1], strlen(argv[1]));
+    /* close all pipes (in reverse order) */
+    for (i=4; i==0; i--) {
+        pclose((pipe[i]));
+    }
+    exit(0);
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Codice completo del \textit{CGI} \file{BarCode.c}.}
+  \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.
 
 
+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.
+
+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.
+
+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}.
 
 
 \subsection{Le \textit{pipe} con nome, o \textit{fifo}}
 
 
 \subsection{Le \textit{pipe} con nome, o \textit{fifo}}
@@ -348,51 +483,82 @@ Come accennato in \secref{sec:ipc_pipes} il problema delle \textit{pipe} 
 esse possono essere utilizzate solo da processi con un progenitore comune 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
 esse possono essere utilizzate solo da processi con un progenitore comune 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 invece che essere struttura interne del kernel
-visibili solo attraverso un file descriptor comune, possono essere viste
-attraverso un inode che risiede sul filesystem.
-
-
-Abbiamo già accennato in \secref{sec:file_mknod}
+caratteristiche delle pipe, ma che invece di essere strutture interne del
+kernel, visibili solo attraverso un file descriptor, sono accessibili
+attraverso un 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;
+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 \secref{sec:ipc_pipes}.
+
+Abbiamo già visto in \secref{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 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 \macro{ENXIO} fintanto che non verrà aperto il capo in lettura.
+
+In Linux\footnote{lo standard POSIX lascia indefinito questo comportamento.} è
+possibile aprire le fifo anche in lettura/scrittura, 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 deadlock.\footnote{se si cerca di leggere
+  da una fifo che non contiene dati si avrà un deadlock immediato, dato che il
+  processo si blocca e non potrà quindi mai eseguire le funzioni di
+  scrittura.}
+
+L'impiego più comune per le fifo è quello che le vede impegnate con un
+processo in 
 
 
-che invece possono risiedere
-sul filesystem, e che i processi possono usare per le comunicazioni senza
-dovere per forza essere in relazione diretta.
 
 
-
-
-
-Per poter superare il problema delle \textit{pipe}, illustrato in
-\secref{sec:ipc_pipes}, che ne consente l'uso solo fra processi con un
-progenitore comune o nella relazione padre/figlio,
-  
 \section{La comunicazione fra processi di System V}
 \label{sec:ipc_sysv}
 
 \section{La comunicazione fra processi di System V}
 \label{sec:ipc_sysv}
 
-Per ovviare ai vari limiti dei meccanismo tradizionale di comunicazione fra
-processi visto in \secref{sec:ipc_unix}, nello sviluppo di System V vennero
-introdotti una serie di nuovi oggetti e relative interfacce che garantissero
-una maggiore flessibilità; in questa sezione esamineremo quello che viene
-ormai chiamato il \textit{System V Inter-Process Comunication System}, più
-comunemente noto come \textit{SystemV IPC}.
+Benché le pipe (e le fifo) siano ancora ampiamente usate, esse presentano
+numerosi limiti, il principale dei quali è che il meccanismo di comunicazione
+è rigidamente sequenziale; una situazione in cui un processo scrive qualcosa
+che molti altri devono poter leggere non può essere implementata con una pipe.
+
+Per superarne i vari limiti, nello sviluppo di System V vennero introdotti una
+serie di nuovi oggetti di comunicazione e relative interfacce id
+programmazione che garantissero una maggiore flessibilità; in questa sezione
+esamineremo quello che viene ormai chiamato il \textsl{Sistema di
+  comunicazione inter-processo} di System V , più comunemente noto come
+\textit{System V IPC (Inter-Process Comunication)}.
  
 
 \subsection{Code di messaggi}
 \label{sec:ipc_messque}
 
  
 
 \subsection{Code di messaggi}
 \label{sec:ipc_messque}
 
-Il primo oggetto introdotto dal \textit{SystemV IPC} è quello delle code di
+Il primo oggetto introdotto dal \textit{System V IPC} è quello delle code di
 messaggi.
 
 \subsection{Semafori}
 \label{sec:ipc_semaph}
 
 messaggi.
 
 \subsection{Semafori}
 \label{sec:ipc_semaph}
 
-Il secondo oggetto introdotto dal \textit{SystemV IPC} è quello dei semafori.
+Il secondo oggetto introdotto dal \textit{System V IPC} è quello dei semafori.
 
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_shar_mem}
 
 
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_shar_mem}
 
-Il terzo oggetto introdotto dal \textit{SystemV IPC} è quello della memoria
+Il terzo oggetto introdotto dal \textit{System V IPC} è quello della memoria
 condivisa.
 
 %%% Local Variables: 
 condivisa.
 
 %%% Local Variables: