From: Simone Piccardi Date: Sun, 12 Jan 2003 16:10:07 +0000 (+0000) Subject: Altre correzioni, con esempi sul server fortunes e relativa "demonizzazzione" X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=72b2686a82a62331891ca894a6c3b476365363fc Altre correzioni, con esempi sul server fortunes e relativa "demonizzazzione" --- diff --git a/ipc.tex b/ipc.tex index 6f69e46..951d424 100644 --- a/ipc.tex +++ b/ipc.tex @@ -1763,7 +1763,7 @@ int main(int argc, char *argv[]) /* Variables definition */ int i, n = 0; char **fortune; /* array of fortune message string */ - char *fortunefilename; /* fortune file name */ + char *fortunefilename = "/usr/share/games/fortunes/linux"; /* file name */ struct msgbuf_read { /* message struct to read request from clients */ long mtype; /* message type, must be 1 */ long pid; /* message data, must be the pid of the client */ @@ -1788,6 +1788,7 @@ int main(int argc, char *argv[]) exit(1); } /* Main body: loop over requests */ + daemon(0, 0); while (1) { msgrcv(msgid, &msg_read, sizeof(int), 1, MSG_NOERROR); n = random() % i; /* select random value */ @@ -1835,7 +1836,7 @@ in \var{n} il numero di frasi da leggere specificato a linea di comando ed in server, viene prima controllato (\texttt{\small 22}) il numero di frasi richieste abbia senso (cioè sia maggiore di zero), le quali poi (\texttt{\small 23}) vengono lette nel vettore in memoria con la stessa -funzione \code{FortuneParse()} usata anche per il server basato sulle fifo. +funzione \code{FortuneParse} usata anche per il server basato sulle fifo. Una volta inizializzato il vettore di stringhe coi messaggi presi dal file delle \textit{fortune} si procede (\texttt{\small 25}) con la generazione di @@ -1845,33 +1846,35 @@ creazione della stessa (si noti come si sia chiamata \func{msgget} con un valore opportuno per l'argomento \param{flag}), avendo cura di abortire il programma (\texttt{\small 27--29}) in caso di errore. -Finita la fase di inizializzazione il server esegue in permanenza il ciclo -principale (\texttt{\small 32--41}). Questo inizia (\texttt{\small 33}) con il -porsi in attesa di un messaggio di richiesta da parte di un client; si noti -infatti come \func{msgrcv} richieda un messaggio con \var{mtype} uguale a 1: -questo è il valore usato per le richieste dato che corrisponde al \acr{pid} di -\cmd{init}, che non può essere un client. L'uso del flag \const{MSG\_NOERROR} -è solo per sicurezza, dato che i messaggi di richiesta sono di dimensione -fissa (e contengono solo il \acr{pid} del client). +Finita la fase di inizializzazione il server prima (\texttt{\small 32}) chiama +la funzione \func{daemon} per andare in background e poi esegue in permanenza +il ciclo principale (\texttt{\small 33--40}). Questo inizia (\texttt{\small + 34}) con il porsi in attesa di un messaggio di richiesta da parte di un +client; si noti infatti come \func{msgrcv} richieda un messaggio con +\var{mtype} uguale a 1: questo è il valore usato per le richieste dato che +corrisponde al \acr{pid} di \cmd{init}, che non può essere un client. L'uso +del flag \const{MSG\_NOERROR} è solo per sicurezza, dato che i messaggi di +richiesta sono di dimensione fissa (e contengono solo il \acr{pid} del +client). Se non sono presenti messaggi di richiesta \func{msgrcv} si bloccherà, ritornando soltanto in corrispondenza dell'arrivo sulla coda di un messaggio di richiesta da parte di un client, in tal caso il ciclo prosegue -(\texttt{\small 34}) selezionando una frase a caso, copiandola (\texttt{\small - 35}) nella struttura \var{msgbuf\_write} usata per la risposta e -calcolandone (\texttt{\small 36}) la dimensione. +(\texttt{\small 35}) selezionando una frase a caso, copiandola (\texttt{\small + 36}) nella struttura \var{msgbuf\_write} usata per la risposta e +calcolandone (\texttt{\small 37}) la dimensione. Per poter permettere a ciascun client di ricevere solo la risposta indirizzata -a lui il tipo del messaggio in uscita viene inizializzato (\texttt{\small 37}) +a lui il tipo del messaggio in uscita viene inizializzato (\texttt{\small 38}) al valore del \acr{pid} del client ricevuto nel messaggio di richiesta. -L'ultimo passo del ciclo (\texttt{\small 38}) è inviare sulla coda il +L'ultimo passo del ciclo (\texttt{\small 39}) è inviare sulla coda il messaggio di risposta. Si tenga conto che se la coda è piena anche questa funzione potrà bloccarsi fintanto che non venga liberato dello spazio. Si noti che il programma può terminare solo grazie ad una interruzione da -parte di un segnale; in tal caso verrà eseguito il gestore -\code{HandSIGTERM}, che semplicemente si limita a cancellare la coda -(\texttt{\small 44}) ed ad uscire (\texttt{\small 45}). +parte di un segnale; in tal caso verrà eseguito (\texttt{\small 45--48}) il +gestore \code{HandSIGTERM}, che semplicemente si limita a cancellare la coda +(\texttt{\small 46}) ed ad uscire (\texttt{\small 47}). \begin{figure}[!bht] \footnotesize \centering @@ -1929,6 +1932,36 @@ tipo corrispondente al valore del \acr{pid} inviato nella richiesta. L'ultimo passo (\texttt{\small 17}) prima di uscire è quello di stampare a video il messaggio ricevuto. +Proviamo allora il nostro nuovo sistema, al solito occorre definire +\code{LD\_LIBRAY\_PATH}, dopo di che, in maniera del tutto analoga a quanto +fatto con il programma che usa le fifo, potremo far partire il server con: +\begin{verbatim} +[piccardi@gont sources]$ ./mqfortuned -n10 +\end{verbatim}%$ +come prima, essendo eseguito in background, il comando ritornerà +immediatamente, ma potremo verificare con \cmd{ps} che il programma è +effettivamente in esecuzione, e che ha creato una coda di messaggi: +\begin{verbatim} +[piccardi@gont sources]$ ipcs + +------ Shared Memory Segments -------- +key shmid owner perms bytes nattch status + +------ Semaphore Arrays -------- +key semid owner perms nsems + +------ Message Queues -------- +key msqid owner perms used-bytes messages +0x0102dc6a 0 piccardi 666 0 0 +\end{verbatim} + + + + + + + + Benché funzionante questa architettura risente dello stesso inconveniente visto anche nel caso del precedente server basato sulle fifo; se il client viene interrotto dopo l'invio del messaggio di richiesta e prima della lettura diff --git a/sources/FortuneParse.c b/sources/FortuneParse.c index 24dabd1..c81c7e8 100644 --- a/sources/FortuneParse.c +++ b/sources/FortuneParse.c @@ -28,7 +28,7 @@ * Read n fortunes from fortune file file, and put it into the * string array fortune * - * $Id: FortuneParse.c,v 1.2 2002/08/18 14:38:04 piccardi Exp $ + * $Id: FortuneParse.c,v 1.3 2003/01/12 16:10:07 piccardi Exp $ * ****************************************************************/ /* @@ -59,7 +59,8 @@ int FortuneParse(char *file, char **fortune, int n) */ fortunefile = fopen(file,"r"); if (fortunefile == NULL) { /* on open error exit */ - perror("Opening fortune file"); + printf("On file %s\n", file); + perror("Cannot open file"); exit(-1); } i = 0; diff --git a/sources/MQFortuneServer.c b/sources/MQFortuneServer.c index cae21ea..0f56bde 100644 --- a/sources/MQFortuneServer.c +++ b/sources/MQFortuneServer.c @@ -26,7 +26,7 @@ * * Usage: fortuned -h give all info * - * $Id: MQFortuneServer.c,v 1.3 2002/12/03 11:06:05 piccardi Exp $ + * $Id: MQFortuneServer.c,v 1.4 2003/01/12 16:10:07 piccardi Exp $ * ****************************************************************/ /* @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) /* Variables definition */ int i, n = 0; char **fortune; /* array of fortune message string */ - char *fortunefilename; /* fortune file name */ + char *fortunefilename = "/usr/share/games/fortunes/linux"; /* file name */ struct msgbuf_read { /* message struct to read request from clients */ long mtype; /* message type, must be 1 */ long pid; /* message data, must be the pid of the client */ @@ -123,6 +123,7 @@ int main(int argc, char *argv[]) } /* Main body: loop over requests */ + daemon(0, 0); while (1) { msgrcv(msgid, &msg_read, sizeof(int), 1, MSG_NOERROR); debug("received request from %d\n", msg_read.pid);