+illustrata in \figref{fig:ipc_fifo_server_arch} in cui i client inviano le
+richieste al server su una fifo nota mentre le risposte vengono reinviate dal
+server a ciascuno di essi su una fifo temporanea creata per l'occazione.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[height=9cm]{img/fifoserver}
+ \caption{Schema dell'utilizzo delle fifo nella realizzazione di una
+ architettura di comunicazione client/server.}
+ \label{fig:ipc_fifo_server_arch}
+\end{figure}
+
+Come esempio di uso questa architettura e dell'uso delle fifo, abbiamo scritto
+un server di \textit{fortunes}, che restituisce, alle richieste di un client,
+un detto a caso estratto da un insieme di frasi; sia il numero delle frasi
+dell'insieme, che i file da cui esse vengono lette all'avvio, sono importabili
+da riga di comando. Il corpo principale del server è riportato in
+\figref{fig:ipc_fifo_server}, dove si è tralasciata la parte che tratta la
+gestione delle opzioni a riga di comando, che effettua il settaggio delle
+variabili \var{fortunefilename}, che indica il file da cui leggere le frasi,
+ed \var{n}, che indica il numero di frasi tenute in memoria, ad un valore
+diverso da quelli preimpostati. Il codice completo è nel file
+\file{FortuneServer.c}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+int main(int argc, char *argv[])
+{
+ int i, n = 10;
+ char *fortunefilename = "/usr/share/games/fortunes/kids";
+ char *fifoname = "/tmp/fortune.fifo";
+ char **fortune;
+ char line[80];
+ int fifo_server, fifo_client;
+ int nread;
+ ...
+ if (n==0) usage(); /* if no pool depth exit printing usage info */
+ i = FortuneParse(fortunefilename, fortune, n); /* parse phrases */
+ /*
+ * Comunication section
+ */
+ if (mkfifo(fifoname, 0622)) { /* create well known fifo if does't exist */
+ if (errno!=EEXIST) {
+ perror("Cannot create well known fifo");
+ exit(-1);
+ }
+ }
+ while (1) {
+ fifo_server = open(fifoname, O_RDONLY); /* open well known fifo */
+ if (fifo_server < 0) {
+ perror("Cannot open well known fifo");
+ exit(-1);
+ }
+ nread = read(fifo_server, line, 79); /* read request */
+ line[nread] = 0;
+ n = random() % i; /* select random value */
+ fifo_client = open(line, O_WRONLY); /* open client fifo */
+ nread = write(fifo_client, /* write phrase */
+ fortune[n], strlen(fortune[n])+1);
+ close(fifo_client); /* close well known fifo */
+ close(fifo_server); /* close client fifo */
+ }
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione principale del codice del server di \textit{fortunes}
+ basato sulle fifo.}
+ \label{fig:ipc_fifo_server}
+\end{figure}
+
+Il server richiede (\texttt{\small 11}) che sia stata impostata una dimensione
+dell'insieme delle frasi non nulla, stampando, nel caso ciò non avvenga, un
+messaggio apposito ed uscendo. Poi (\texttt{\small 12}) effettua la chiamata
+alla funzione \code{FortuneParse} che legge dal file specificato in
+\var{fortunefilename} le prime \var{n} frasi e le memorizza nel vettore di
+puntatori \var{fortune}. Il codice della funzione non è riportato, in quanto
+non direttamente attinente allo scopo dell'esempio, lo si può trovare nel file
+\file{FortuneParse.c} allegato coi sorgenti degli esempi.
+
+Il passo successivo \texttt{\small 16--21}) è quello di creare, se non esiste
+già, la fifo nota sulla quale il server ascolterà le richieste, qualora si
+riscontri un errore il server uscirà (escludendo ovviamente il caso in cui la
+funzione \func{mkfifo} fallisce per la precedente esistenza della fifo.
+
+Fatto questo si entra nel ciclo principale del programma \texttt{\small
+ 22--36}), che viene eseguito indefinitamente (l'uscita del server deve
+essere effettuata tramite segnale), e che provvede a fornire le risposte ai
+client. Il server è progettato per accettare le richieste dai client che
+devono scrivere il nome della fifo sulla quale vogliono ricevere la risposta
+sulla fifo su cui il server è in ascolto.
+
+Il primo passo è aprire in lettura la fifo (\texttt{\small 23}), se nessun
+client ha effettuato una richiesta la fifo non ha capi aperti in scrittura, e
+pertanto il server si bloccherà. Una volta che un client ha aperto la fifo in
+scrittura il server si sbloccherà ed effetturà la lettura (\texttt{\small 28})
+della richiesta del client (nel caso limitata a 79 byte).
+
+Dopo di che verrà calcolato (\texttt{\small 30}) un numero casuale nel range
+delle frasi disponibili nella nostra lista, e verrà aperta (\texttt{\small
+ 31}) la fifo sulla quale il client vuole ricevere la risposta, che sarà poi
+scritta (\texttt{\small 32}). Dopo di che \texttt{\small 34--35}) entrambe le
+fifo verranno chiuse.
+
+
+Benché il nostro sistema client-server funzioni, la sua struttura è piuttosto
+complessa e continua ad avere vari inconvenienti\footnote{lo stesso Stevens,
+ che esamina questa architettura in \cite{APUE}, nota come sia impossibile
+ per il server sapere se un client è andato in crash, con la possibilità di
+ far restare le fifo temporanee sul filesystem, come sia necessario
+ intercettare \macro{SIGPIPE} dato che un client può terminare dopo aver
+ fatto una richiesta, ma prima che la risposta sia inviata, e come occorra
+ gestire il caso in cui non ci sono client attivi (e la lettura dalla fifo
+ nota restituisca al serve un end-of-file.}; in generale infatti
+l'interfaccia delle fifo non è adatta a risolvere questo tipo di problemi, che
+possono essere affrontati in maniera più semplice ed efficace o usando i
+\textit{socket}\index{socket} (che tratteremo in dettaglio a partire da
+\capref{cha:socket_intro}) o ricorrendo a meccanismi di comunicazione diversi,
+come quelli che esamineremo in seguito.