+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.
+
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+int main(int argc, char *argv[], char *envp[])
+{
+ ...
+ /* create two pipes to handle process communication */
+ if ( (retval = pipe(pipein)) ) {
+ WriteMess("input pipe creation error");
+ exit(0);
+ }
+ if ( (retval = pipe(pipeout)) ) {
+ WriteMess("output pipe creation error");
+ exit(0);
+ }
+ /* fork child to run barcode program */
+ pid = fork();
+ if (pid == -1) {
+ WriteMess("child creation error");
+ exit(0);
+ }
+ /* if child */
+ if (pid == 0) {
+ close(pipein[1]); /* close output side of input pipe */
+ dup2(0, pipein[0]); /* remap stdin in pipe input */
+ close(pipeout[0]); /* close input side of output pipe */
+ dup2(1, pipeout[1]); /* remap stdout in pipe output */
+ execlp("barcode", "barcode", "-E", NULL);
+ } else {
+ /* first set the pipe */
+ close(pipein[0]); /* close input side of input pipe */
+ close(pipeout[1]); /* close output side of output pipe */
+ write(pipein[1], argv[1], strlen(argv[1]));
+ close(pipein[1]);
+ waitpid(pid, NULL, 0);
+ pid = fork();
+ if (pid == -1) {
+ WriteMess("child creation error")
+ exit(0);
+ }
+ if (pid == 0) {
+ /* send mime type */
+ write(0,content, strlen(content));
+ dup2(0, pipeout[0]);
+ execlp("gs", "gs", "-sDEVICE=jpeg", "-sOutputFile=-", "-", NULL);
+ } else {
+ close(pipeout[0]);
+ waitpid(pid, NULL, 0);
+ }
+ }
+ exit(0);
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Codice del \textit{cgi-bin} \cmd{BarCode}.}
+ \label{fig:ipc_barcode_code}
+\end{figure}
+
+
+Il primo passo (\texttt{\small 4-12}) è quello di creare le due pipe, una per
+l'input e l'altra per l'output, che servono per la comunicazione con i due
+programmi che verranno utilizzati, inviando in caso di errore (attraverso una
+apposita funzione \func{WriteMess}, non riportata in
+\ref{fig:ipc_barcode_code}, che si incarica di formattare l'output in HTML
+perché sia interpretabile da un browser) un messaggio invece dell'immagine
+richiesta.
+
+Una volta create le pipe il programma può creare (\texttt{\small 13-18}) il
+primo processo figlio, che si incaricherà (\texttt{\small 19-25}) di eseguire
+\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 questo il processo figlio prima chiude (\texttt{\small 21}) il capo aperto
+in scrittura della prima pipe (che sarà usato dal padre per trasmettergli la
+stringa da codificare), e poi collega (\texttt{\small 22}) il capo il lettura
+allo standard input usando \func{dup2}. Analogamente il capo in lettura della
+seconda pipe sarà chiuso mentre il capo in scrittura viene collegato allo
+standard output (\texttt{\small 23-24}. In questo modo all'esecuzione
+(\texttt{\small 25}) di \cmd{barcode} quest'ultimo leggerà la stringa da
+codificare dalla prima pipe e scriverà l'immagine postscript nella seconda.
+
+Dall'altra parte il processo padre prima chiude (\texttt{\small 28-29}) i due
+capi inutilizzati delle pipe (input della prima ed output della seconda), poi
+scrive (\texttt{\small 30}) la stringa da convertire sull'output della prima
+pipe 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 31}), si attenderà poi (\texttt{\small 32}) che pure
+l'esecuzione di \cmd{barcode} venga 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;
+
+
+
+
+\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 comuni in una sola
+chiamata. La prima di esse si chiama \func{popen} ed il suo prototipo è:
+
+
+L'esempio in \figref{fig:ipc_barcode_code} per quanto perfettamente
+funzionante, è piuttosto complesso; 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 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}, che invece viene trattato correttamente.
+
+
+