R. W. Stevens.
</p>
</td>
+ </tr>
+ <tr>
+ <td width="130" valign="top">
+ <b>
+ <font color="#0000aa">
+ Stato
+ </font>
+ </b>
+ </td>
+ <td bgcolor="lightblue">
+ <p>
+ <b>16 - agosto - 2002</b> <br> Sedici capitoli, 347 pagine.
+ </p>
+ </td>
</tr>
<tr>
<td width="130" valign="top">
<b>
<font color="#0000aa">
- News
+ Notizie
</font>
</b>
</td>
<td bgcolor="lightblue">
+ <p>
+ <b>7 - agosto - 2002</b> <br> Completata la prima stesura delle
+ sezioni relative all'I/O asincrono ed ai segnali real-time,
+ iniziata la stesura della sezione sul memory mapped I/O.
+ </p>
+ <p>
+ <b>22 - luglio - 2002</b> <br> Iniziata la stesura del capitolo
+ sull'I/O avanzato. Completata la sezione su pipe e fifo (in
+ versione preliminare) inziate le sezioni su I/O asincrono ed una
+ sezione aggiuntiva sui segnali real-time nel relativo capitolo.
+ </p>
<p>
<b>3 - luglio - 2002</b> <br> Prima versione del sito, con
rilascio della prima versione di GaPiL in un HTML passabile.
controllo dei parametri del sistema, gestione dei segnali. Sono
da ricontrollare, ma di qualità decente, i capitoli dal
tredicesimo al sedicesimo: reti e socket elementari (il
- sedicesimo capitolo è incopleto). Sono in corso di stesura, e
+ sedicesimo capitolo è incompleto). Sono in corso di stesura, e
pertanto di qualità non classificabile (che può oscillare fra la
bozza non rivista ed il semplice elenco degli argomenti) gli
altri capitoli.
- <br>
- <i> 321 pagine </i>
- </p>
- <p>
- <b>22 - luglio - 2002</b> <br> Aggiornamento: iniziata la
- stesura del capitolo sull'I/O avanzato. Completata la sezione su
- pipe e fifo (in versione preliminare) inziate le sezioni su I/O
- asincrono ed una sezione aggiuntiva sui segnali real-time nel
- relativo capitolo.
- <br>
- <i> 333 pagine </i>
- </p>
- <p>
- <b>22 - agosto - 2002</b> <br> Aggiornamento: completata la
- prima stesura delle sezioni relative all'I/O asincrono ed ai
- segnali real-time, iniziata la stesura della sezione sul memory
- mapped I/O.
- <br>
- <i> 341 pagine </i>
</p>
</td>
</tr>
- </tbody>
+ </tbody>
</table>
<!-- CUT HERE -->
</body>
\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
completare la procedura di terminazione in modo da evitare la formazione di
zombie.
-In \figref{fig:sig_sigchld_handl} è mostrato il codice della nostra
-implementazione del gestore; se aggiungiamo al codice di
-\file{ForkTest.c} l'installazione di questo gestore potremo verificare che
-ripetendo l'esempio visto in \secref{sec:proc_termination} che non si ha più
-la creazione di zombie.
+In \figref{fig:sig_sigchld_handl} è mostrato il codice contenente una
+implementazione generica di una routine di gestione per \macro{SIGCHLD}, (che
+si trova nei sorgenti allegati nel file \file{HandSIGCHLD.c}); se ripetiamo i
+test di \secref{sec:proc_termination}, invocando \cmd{forktest} con l'opzione
+\cmd{-s} (che si limita ad effettuare l'installazione di questa funzione come
+gestore di \macro{SIGCHLD}) potremo verificare che non si ha più la creazione
+di zombie.
% è pertanto
% naturale usare un esempio che ci permette di concludere la trattazione della
#include <sys/wait.h>
#include "macro.h"
-void sigchld_hand(int sig)
+void HandSIGCHLD(int sig)
{
int errno_save;
int status;
\end{lstlisting}
\end{minipage}
\normalsize
- \caption{Un gestore per il segnale \texttt{SIGCHLD}.}
+ \caption{Codice di una funzione generica di gestione per il segnale
+ \texttt{SIGCHLD}.}
\label{fig:sig_sigchld_handl}
\end{figure}
Il codice del gestore è di lettura immediata; come buona norma di
programmazione (si ricordi quanto accennato \secref{sec:sys_errno}) si
comincia (\texttt{\small 12-13}) con il salvare lo stato corrente di
-\var{errno}, in modo da poterlo ripristinare prima del ritorno del
-gestore (\texttt{\small 22-23}). In questo modo si preserva il valore
-della variabile visto dal corso di esecuzione principale del processo, che
-sarebbe altrimenti sarebbe sovrascritto dal valore restituito nella successiva
-chiamata di \func{wait}.
+\var{errno}, in modo da poterlo ripristinare prima del ritorno del gestore
+(\texttt{\small 22-23}). In questo modo si preserva il valore della variabile
+visto dal corso di esecuzione principale del processo, che sarebbe altrimenti
+sarebbe sovrascritto dal valore restituito nella successiva chiamata di
+\func{wait}.
Il compito principale del gestore è quello di ricevere lo stato di
terminazione del processo, cosa che viene eseguita nel ciclo in
*
* Usage: forktest -h give all info's
*
- * $Id: ForkTest.c,v 1.6 2001/09/21 17:10:51 piccardi Exp $
+ * $Id: ForkTest.c,v 1.7 2002/08/18 23:24:44 piccardi Exp $
*
****************************************************************/
/*
#include <stdio.h> /* standard I/O library */
#include <string.h> /* string functions */
+#include "wrappers.h"
+#include "macros.h"
+
/* Help printing routine */
void usage(void);
* Use getopt function
*/
opterr = 0; /* don't want writing to stderr */
- while ( (i = getopt(argc, argv, "hp:c:e:")) != -1) {
+ while ( (i = getopt(argc, argv, "hsp:c:e:")) != -1) {
switch (i) {
/*
* Handling options
case 'e': /* take wait before parent exit */
wait_end = strtol(optarg, NULL, 10); /* convert input */
break;
+ case 's':
+ Signal(SIGCHLD, HandSIGCHLD);
+ break;
case '?': /* unrecognized options */
printf("Unrecognized options -%c\n",optopt);
usage();
printf("Usage:\n");
printf(" forktest [-h] [-p sec] [-c sec] [-e sec] child to fork \n");
printf(" -h print this help\n");
+ printf(" -s install signal handler\n");
printf(" -p sec wait sec seconds before next fork\n");
printf(" -c sec wait sec seconds before child termination\n");
printf(" -e sec wait sec seconds before parent return\n");
*
* Usage: fortuned -h give all info
*
- * $Id: FortuneServer.c,v 1.2 2002/08/18 14:38:04 piccardi Exp $
+ * $Id: FortuneServer.c,v 1.3 2002/08/18 23:24:44 piccardi Exp $
*
****************************************************************/
/*
void usage(void);
int FortuneParse(char *file, char **fortune, int n);
+/* name of well known fifo */
+char *fifoname = "/tmp/fortune.fifo";
int main(int argc, char *argv[])
{
/* Variables definition */
int i, n = 0;
char *fortunefilename = "/usr/share/games/fortunes/kids";
- char *fifoname = "/tmp/fortune.fifo";
char **fortune;
char line[80];
int fifo_server, fifo_client;
* Main code beginning
*
* ***********************************************************/
+ Signal(SIGTERM, HandSIGTERM);
+ Signal(SIGINT, HandSIGTERM);
+ Signal(SIGQUIT, HandSIGTERM);
if (n==0) usage(); /* if no pool depth exit printing usage info */
i = FortuneParse(fortunefilename, fortune, n); /* parse phrases */
for (n=0; n<i; n++) debug("%s\n\n", fortune[n]);
printf(" -n XXX set pool depth\n");
exit(1);
}
+/*
+ * Signal Handler to manage termination
+ */
+void HandSIGTERM(int signo) {
+ unlink(fifoname);
+ exit(0);
+}
--- /dev/null
+#include <errno.h> /* error simbol definitions */
+#include <signal.h> /* signal handling declarations */
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "macros.h"
+
+void HandSIGCHLD(int sig)
+{
+ int errno_save;
+ int status;
+ pid_t pid;
+ /* save errno current value */
+ errno_save = errno;
+ /* loop until no */
+ do {
+ errno = 0;
+ pid = waitpid(WAIT_ANY, &status, WNOHANG);
+ if (pid > 0) {
+ debug("child %d terminated with status %x\n", pid, status);
+ }
+ } while ((pid > 0) && (errno == EINTR));
+ /* restore errno value*/
+ errno = errno_save;
+ /* return */
+ return;
+}
+++ /dev/null
-#include <errno.h> /* error simbol definitions */
-#include <signal.h> /* signal handling declarations */
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "macro.h"
-
-void Hand_CHLD(int sig)
-{
- int errno_save;
- int status;
- pid_t pid;
- /* save errno current value */
- errno_save = errno;
- /* loop until no */
- do {
- errno = 0;
- pid = waitpid(WAIT_ANY, &status, WNOHANG);
- if (pid > 0) {
- debug("child %d terminated with status %x\n", pid, status);
- }
- } while ((pid > 0) && (errno == EINTR));
- /* restore errno value*/
- errno = errno_save;
- /* return */
- return;
-}
testren: TestRen.c
$(CC) $(CFLAGS) $^ -o $@
-forktest: ForkTest.c
+forktest: ForkTest.c HandSIGCHLD.c
$(CC) $(CFLAGS) $^ -o $@
errcode: ErrCode.c
*
* Author: S. Piccardi
*
- * $Id: wrappers.h,v 1.2 2001/06/10 11:47:17 piccardi Exp $
+ * $Id: wrappers.h,v 1.3 2002/08/18 23:24:44 piccardi Exp $
*
***************************************************************/
#include <sys/sem.h> /* IPC semaphore declarations */
ssize_t SockRead(int fd, void *buf, size_t count);
ssize_t SockWrite(int fd, const void *buf, size_t count);
+void HandSIGCHLD(int sig);