+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 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}.