aggancia (\texttt{\small 39--41}) al processo all'indirizzo \var{shmptr}; sarà
attraverso questo puntatore che potremo accedere alla memoria condivisa, che
sarà vista nella forma data da \struct{DirProp}. Infine con la stessa chiave
-si crea (\texttt{\small 42--45}) anche un mutex, che utilizzaremo per regolare
-l'accesso alla memoria condivisa.
+si crea (\texttt{\small 42--45}) anche un mutex (utilizzando le funzioni di
+intrfaccia già descritte in \secref{sec:ipc_sysv_sem}) che utilizzaremo per
+regolare l'accesso alla memoria condivisa.
Una volta completata l'inizializzazione e la creazione degli oggetti di
intercomunicazione il programma eseguirà indefinitamente (\texttt{\small
(\texttt{\small 51}), e si attende (\texttt{\small 52}) per il periodo di
tempo specificato a riga di comando con l'opzione \code{-p}.
-
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
\tabref{tab:file_type_macro}, si contano (\texttt{\small 11--17}) quanti ce ne
sono per ciascun tipo.
-In \figref{fig:ipc_dirmonitor_sub} è riportato inoltre (\texttt{\small
- 23--35}) il codice del gestore di segnali usato per terminare il programma,
-che si incarica di cancellare tutti gli oggetti non più necessari.
+In \figref{fig:ipc_dirmonitor_sub} è riportato anche (\texttt{\small 23--35})
+il codice del gestore di segnali di terminazione usato per chiudere il
+programma, che oltre a provocare l'uscita del programma si incarica anche di
+cancellare tutti gli oggetti di intercomunicazione non più necessari. Nel
+caso anzitutto (\texttt{\small 24}) si acquisisce il mutex per evitare di
+operare mentre un client sta ancora leggendo i dati, dopo di che prima si
+distacca (\texttt{\small 25--28}) il segmento e poi lo si cancella
+(\texttt{\small 29--32}). Infine (\texttt{\small 33}) si rimuove il mutex e si
+esce.
+
+Il codice del client che permette di leggere le informazioni mantenute nella
+memoria condivisa è riportato in \figref{fig:ipc_dirmonitor_client}, al solito
+si è omessa la sezione di gestione delle opzioni e la funzione che stampa a
+video le istruzioni; il codice completo è nei sorgenti allegati, nel file
+\file{ReadMonitor.c}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h> /* directory */
+#include <stdlib.h> /* C standard library */
+#include <unistd.h>
+
+#include "Gapil.h"
+#include "macros.h"
+
+int main(int argc, char *argv[])
+{
+ int i;
+ key_t key;
+ ..
+ /* find needed IPC objects */
+ key = ftok("./DirMonitor.c", 1); /* define a key */
+ shmid = shmget(key, 4096, 0); /* get the shared memory ID */
+ if (shmid < 0) {
+ perror("Cannot find shared memory");
+ exit(1);
+ }
+ if ( (shmptr = shmat(shmid, NULL, 0)) == NULL ) { /* attach to process */
+ perror("Cannot attach segment");
+ exit(1);
+ }
+ if ((mutex = MutexFind(key)) == -1) { /* get the Mutex */
+ perror("Cannot find mutex");
+ exit(1);
+ }
+ /* main loop */
+ MutexLock(mutex); /* lock shared memory */
+ printf("File presenti %d file, per un totale di %d byte\n",
+ shmptr->tot_files, shmptr->tot_size);
+ printf("Ci sono %d file dati\n", shmptr->tot_regular);
+ printf("Ci sono %d directory\n", shmptr->tot_dir);
+ printf("Ci sono %d link\n", shmptr->tot_link);
+ printf("Ci sono %d fifo\n", shmptr->tot_fifo);
+ printf("Ci sono %d socket\n", shmptr->tot_sock);
+ printf("Ci sono %d device a carrateri\n", shmptr->tot_char);
+ printf("Ci sono %d device a blocchi\n", shmptr->tot_block);
+ MutexUnlock(mutex); /* unlock shared memory */
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Codice del programma client \file{ReadMonitor.c}.}
+ \label{fig:ipc_dirmonitor_client}
+\end{figure}
-Anzitutto (\texttt{\small 24}) si acquisisce il mutex per evitare di operare
-mentre un client sta ancora leggendo i dati, dopo di che si distacca
-(\texttt{\small 25--28}) il segmento e lo si cancella (\texttt{\small
- 29--32}). Infine (\texttt{\small 33}) si rimuove il mutex e si esce.
+Una volta completata la gestione delle opzioni a riga di comando il programma
+rigenera (\texttt{\small 16}) la chiave usata per identificare memoria
+condivisa e mutex, richiede (\texttt{\small 17}) l'identificatore della
+memoria condivisa (che in questo caso deve già esistere), uscendo in caso di
+errore (\texttt{\small 18--21}). Una volta ottenuto l'identificatore si può
+(\texttt{\small 22--25}) agganciare il segmento al processo (anche in questo
+caso uscendo se qualcosa non funziona). Infine (\texttt{\small 26--29}) si
+richede pure l'identificatore del mutex.
+
+Una volta completata l'inizializzazione ed ottenuti i riferimenti agli oggetti
+di intercomunicazione necessari viene eseguito il corpo principale del
+programma (\texttt{\small 30--41}); si acquisisce (\texttt{\small 31}) il
+mutex (qui avviene il blocco se la memoria condivisa non è disponibile), e poi
+(\texttt{\small 32--40}) si stampano i vari valori in essa contenuti. Infine
+(\texttt{\small 41}) si rilascia il mutex.
%% Per capire meglio il funzionamento delle funzioni facciamo ancora una volta