+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 ad un buffer nel kernel, la cui dimensione è
+specificata dalla costante \macro{PIPE\_BUF}, (vedi
+\secref{sec:sys_file_limits}). Lo schema di funzionamento di una pipe è
+illustrato in \figref{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.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[height=5cm]{img/pipe}
+ \caption{Schema della struttura di una 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 \secref{sec:file_sharing}
+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
+\figref{fig:ipc_pipe_fork}). In questo modo se uno dei processi scrive su un
+capo della 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}.}
+ \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 \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}
+\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 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}
+ http://www.sito.it/cgi-bin/programma?parametro
+\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 \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
+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
+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, 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
+\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]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+int main(int argc, char *argv[], char *envp[])
+{
+ ...
+ /* create two pipes, pipein and pipeout, to handle communication */
+ if ( (retval = pipe(pipein)) ) {
+ WriteMess("input pipe creation error");
+ exit(0);
+ }
+ if ( (retval = pipe(pipeout)) ) {
+ WriteMess("output pipe creation error");
+ exit(0);
+ }
+ /* First fork: use child to run barcode program */
+ if ( (pid = fork()) == -1) { /* on error exit */
+ WriteMess("child creation error");
+ exit(0);
+ }
+ /* if child */
+ if (pid == 0) {
+ close(pipein[1]); /* close pipe write end */
+ dup2(pipein[0], STDIN_FILENO); /* remap stdin to pipe read end */
+ close(pipeout[0]);
+ dup2(pipeout[1], STDOUT_FILENO); /* remap stdout in pipe output */
+ execlp("barcode", "barcode", size, NULL);
+ }
+ close(pipein[0]); /* close input side of input pipe */
+ write(pipein[1], argv[1], strlen(argv[1])); /* write parameter to pipe */
+ close(pipein[1]); /* closing write end */
+ waitpid(pid, NULL, 0); /* wait child completion */
+ /* Second fork: use child to run ghostscript */
+ if ( (pid = fork()) == -1) {
+ WriteMess("child creation error");
+ exit(0);
+ }
+ /* second child, convert PS to JPEG */
+ if (pid == 0) {
+ close(pipeout[1]); /* close write end */
+ dup2(pipeout[0], STDIN_FILENO); /* remap read end to stdin */
+ /* send mime type */
+ write(STDOUT_FILENO, content, strlen(content));
+ execlp("gs", "gs", "-q", "-sDEVICE=jpeg", "-sOutputFile=-", "-", NULL);
+ }
+ /* still parent */
+ close(pipeout[1]);
+ waitpid(pid, NULL, 0);
+ exit(0);
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione principale del codice del \textit{CGI}
+ \file{BarCodePage.c}.}
+ \label{fig:ipc_barcodepage_code}
+\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
+ \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
+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}).
+
+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.
+
+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
+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.
+
+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.
+
+
+\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
+\func{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 \macro{NULL} per un errore, nel qual caso \var{errno}
+ potrà assumere i valori relativi alle sottostanti invocazioni di \func{pipe}
+ e \func{fork} o \macro{EINVAL} se \param{type} non è valido.}
+\end{prototype}
+
+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"}.
+
+Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
+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)}
+
+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}
+\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
+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 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 \macro{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}).
+
+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.