Altre correzioni, con esempi sul server fortunes e relativa "demonizzazzione"
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 12 Jan 2003 16:10:07 +0000 (16:10 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 12 Jan 2003 16:10:07 +0000 (16:10 +0000)
ipc.tex
sources/FortuneParse.c
sources/MQFortuneServer.c

diff --git a/ipc.tex b/ipc.tex
index 6f69e46..951d424 100644 (file)
--- 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
index 24dabd1..c81c7e8 100644 (file)
@@ -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;
index cae21ea..0f56bde 100644 (file)
@@ -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);