Aggiunti TODO
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 87c35f8c0a8c81a1b0bc159862a5e68290fad41f..6bfab48e4e48563d08932b5ea2637f442dbcf754 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -269,7 +269,7 @@ formattare l'uscita alla maniera dei CGI, aggiungendo l'opportuno
 quest'ultimo possa essere visualizzato correttamente da un browser.
 
 Una volta create le \textit{pipe}, il programma può creare (\texttt{\small
 quest'ultimo possa essere visualizzato correttamente da un browser.
 
 Una volta create le \textit{pipe}, il programma può creare (\texttt{\small
-  13-17}) il primo processo figlio, che si incaricherà (\texttt{\small
+  13--17}) il primo processo figlio, che si incaricherà (\texttt{\small
   19--25}) di eseguire \cmd{barcode}. Quest'ultimo legge dallo standard input
 una stringa di caratteri, la converte nell'immagine PostScript del codice a
 barre ad essa corrispondente, e poi scrive il risultato direttamente sullo
   19--25}) di eseguire \cmd{barcode}. Quest'ultimo legge dallo standard input
 una stringa di caratteri, la converte nell'immagine PostScript del codice a
 barre ad essa corrispondente, e poi scrive il risultato direttamente sullo
@@ -355,7 +355,7 @@ chiama \funcd{popen} ed il suo prototipo è:
 \end{funcproto}
 
 La funzione crea una \textit{pipe}, esegue una \func{fork} creando un nuovo
 \end{funcproto}
 
 La funzione crea una \textit{pipe}, esegue una \func{fork} creando un nuovo
-processe nel quale invoca il programma \param{command} attraverso la shell (in
+processo nel quale invoca il programma \param{command} attraverso la shell (in
 sostanza esegue \file{/bin/sh} con il flag \code{-c}).
 L'argomento \param{type} deve essere una delle due stringhe \verb|"w"| o
 \verb|"r"|, per richiedere che la \textit{pipe} restituita come valore di
 sostanza esegue \file{/bin/sh} con il flag \code{-c}).
 L'argomento \param{type} deve essere una delle due stringhe \verb|"w"| o
 \verb|"r"|, per richiedere che la \textit{pipe} restituita come valore di
@@ -641,25 +641,25 @@ ovviamente il caso in cui la funzione \func{mkfifo} fallisce per la precedente
 esistenza della \textit{fifo}).
 
 Una volta che si è certi che la \textit{fifo} di ascolto esiste la procedura
 esistenza della \textit{fifo}).
 
 Una volta che si è certi che la \textit{fifo} di ascolto esiste la procedura
-di inizializzazione è completata. A questo punto si può chiamare
-(\texttt{\small 23}) la funzione \func{daemon} per far proseguire l'esecuzione
-del programma in background come demone.  Si può quindi procedere
-(\texttt{\small 24--33}) alla apertura della \textit{fifo}: si noti che questo
-viene fatto due volte, prima in lettura e poi in scrittura, per evitare di
-dover gestire all'interno del ciclo principale il caso in cui il server è in
-ascolto ma non ci sono client che effettuano richieste.  Si ricordi infatti
-che quando una \textit{fifo} è aperta solo dal capo in lettura, l'esecuzione di
-\func{read} ritorna con zero byte (si ha cioè una condizione di end-of-file).
+di inizializzazione è completata. A questo punto (\texttt{\small 23}) si può
+chiamare la funzione \func{daemon} per far proseguire l'esecuzione del
+programma in background come demone.  Si può quindi procedere (\texttt{\small
+  24--33}) alla apertura della \textit{fifo}: si noti che questo viene fatto
+due volte, prima in lettura e poi in scrittura, per evitare di dover gestire
+all'interno del ciclo principale il caso in cui il server è in ascolto ma non
+ci sono client che effettuano richieste.  Si ricordi infatti che quando una
+\textit{fifo} è aperta solo dal capo in lettura, l'esecuzione di \func{read}
+ritorna con zero byte (si ha cioè una condizione di end-of-file).
 
 Nel nostro caso la prima apertura si bloccherà fintanto che un qualunque
 
 Nel nostro caso la prima apertura si bloccherà fintanto che un qualunque
-client non apre a sua volta la \textit{fifo} nota in scrittura per effettuare la sua
-richiesta. Pertanto all'inizio non ci sono problemi, il client però, una volta
-ricevuta la risposta, uscirà, chiudendo tutti i file aperti, compresa la
-\textit{fifo}.  A questo punto il server resta (se non ci sono altri client
-che stanno effettuando richieste) con la \textit{fifo} chiusa sul lato in
-lettura, ed in questo stato la funzione \func{read} non si bloccherà in attesa
-di dati in ingresso, ma ritornerà in continuazione, restituendo una condizione
-di \textit{end-of-file}.
+client non apre a sua volta la \textit{fifo} nota in scrittura per effettuare
+la sua richiesta. Pertanto all'inizio non ci sono problemi, il client però,
+una volta ricevuta la risposta, uscirà, chiudendo tutti i file aperti,
+compresa la \textit{fifo}.  A questo punto il server resta (se non ci sono
+altri client che stanno effettuando richieste) con la \textit{fifo} chiusa sul
+lato in lettura, ed in questo stato la funzione \func{read} non si bloccherà
+in attesa di dati in ingresso, ma ritornerà in continuazione, restituendo una
+condizione di \textit{end-of-file}.
 
 Si è usata questa tecnica per compatibilità, Linux infatti supporta l'apertura
 delle \textit{fifo} in lettura/scrittura, per cui si sarebbe potuto effettuare
 
 Si è usata questa tecnica per compatibilità, Linux infatti supporta l'apertura
 delle \textit{fifo} in lettura/scrittura, per cui si sarebbe potuto effettuare
@@ -714,7 +714,7 @@ principale del programma e le definizioni delle variabili. Il codice completo
 La prima istruzione (\texttt{\small 12}) compone il nome della \textit{fifo}
 che dovrà essere utilizzata per ricevere la risposta dal server.  Si usa il
 \ids{PID} del processo per essere sicuri di avere un nome univoco; dopo di che
 La prima istruzione (\texttt{\small 12}) compone il nome della \textit{fifo}
 che dovrà essere utilizzata per ricevere la risposta dal server.  Si usa il
 \ids{PID} del processo per essere sicuri di avere un nome univoco; dopo di che
-(\texttt{\small 13-18}) si procede alla creazione del relativo file, uscendo
+(\texttt{\small 13--18}) si procede alla creazione del relativo file, uscendo
 in caso di errore (a meno che il file non sia già presente sul filesystem).
 
 A questo punto il client può effettuare l'interrogazione del server, per
 in caso di errore (a meno che il file non sia già presente sul filesystem).
 
 A questo punto il client può effettuare l'interrogazione del server, per
@@ -722,7 +722,7 @@ questo prima si apre la \textit{fifo} nota (\texttt{\small 19--23}), e poi ci
 si scrive (\texttt{\small 24}) la stringa composta in precedenza, che contiene
 il nome della \textit{fifo} da utilizzare per la risposta. Infine si richiude
 la \textit{fifo} del server che a questo punto non serve più (\texttt{\small
 si scrive (\texttt{\small 24}) la stringa composta in precedenza, che contiene
 il nome della \textit{fifo} da utilizzare per la risposta. Infine si richiude
 la \textit{fifo} del server che a questo punto non serve più (\texttt{\small
-  25}).
+  25}). 
 
 Inoltrata la richiesta si può passare alla lettura della risposta; anzitutto
 si apre (\texttt{\small 26--30}) la \textit{fifo} appena creata, da cui si
 
 Inoltrata la richiesta si può passare alla lettura della risposta; anzitutto
 si apre (\texttt{\small 26--30}) la \textit{fifo} appena creata, da cui si
@@ -1020,7 +1020,7 @@ problema del \textit{SysV-IPC}. Non esiste infatti una modalità chiara per
 identificare un oggetto, come sarebbe stato se lo si fosse associato ad in
 file, e tutta l'interfaccia è inutilmente complessa.  Per questo se ne
 sconsiglia assolutamente l'uso nei nuovi programmi, considerato che è ormai
 identificare un oggetto, come sarebbe stato se lo si fosse associato ad in
 file, e tutta l'interfaccia è inutilmente complessa.  Per questo se ne
 sconsiglia assolutamente l'uso nei nuovi programmi, considerato che è ormai
-disponibile una revisione completa dei meccamismi di IPC fatta secondo quanto
+disponibile una revisione completa dei meccanismi di IPC fatta secondo quanto
 indicato dallo standard POSIX.1b, che presenta una realizzazione più sicura ed
 una interfaccia più semplice, che tratteremo in sez.~\ref{sec:ipc_posix}.
 
 indicato dallo standard POSIX.1b, che presenta una realizzazione più sicura ed
 una interfaccia più semplice, che tratteremo in sez.~\ref{sec:ipc_posix}.
 
@@ -1161,7 +1161,7 @@ numero di tutti gli oggetti presenti nel \textit{SysV-IPC}, ed il cui default
 l'identificatore assuma tutti i valori possibili.
 
 In fig.~\ref{fig:ipc_sysv_idtest} è riportato il codice di un semplice
 l'identificatore assuma tutti i valori possibili.
 
 In fig.~\ref{fig:ipc_sysv_idtest} è riportato il codice di un semplice
-programma di test che si limita a creare un oggetto di ICP (specificato con
+programma di test che si limita a creare un oggetto di IPC (specificato con
 una opzione a riga di comando), stamparne il numero di identificatore, e
 cancellarlo, il tutto un numero di volte specificato tramite una seconda
 opzione.  La figura non riporta il codice di selezione delle opzioni, che
 una opzione a riga di comando), stamparne il numero di identificatore, e
 cancellarlo, il tutto un numero di volte specificato tramite una seconda
 opzione.  La figura non riporta il codice di selezione delle opzioni, che
@@ -1171,11 +1171,11 @@ di creazione, stampa, cancellazione.
 
 I valori di default sono per l'uso delle code di messaggi e per 5 ripetizioni
 del ciclo. Per questo motivo se non si utilizzano opzioni verrà eseguito per
 
 I valori di default sono per l'uso delle code di messaggi e per 5 ripetizioni
 del ciclo. Per questo motivo se non si utilizzano opzioni verrà eseguito per
-cinque volte il ciclo (\texttt{\small 7-11}), in cui si crea una coda di
+cinque volte il ciclo (\texttt{\small 7--11}), in cui si crea una coda di
 messaggi (\texttt{\small 8}), se ne stampa l'identificativo (\texttt{\small
   9}) e la si rimuove (\texttt{\small 10}). Non stiamo ad approfondire adesso
 il significato delle funzioni utilizzate, che verranno esaminate nelle
 messaggi (\texttt{\small 8}), se ne stampa l'identificativo (\texttt{\small
   9}) e la si rimuove (\texttt{\small 10}). Non stiamo ad approfondire adesso
 il significato delle funzioni utilizzate, che verranno esaminate nelle
-prossime sezioni. 
+prossime sezioni.
 
 Quello che ci interessa infatti è verificare l'allocazione degli
 identificativi associati agli oggetti; lanciando il comando si otterrà
 
 Quello che ci interessa infatti è verificare l'allocazione degli
 identificativi associati agli oggetti; lanciando il comando si otterrà
@@ -1325,12 +1325,12 @@ Una coda di messaggi è costituita da una \itindex{linked~list} \textit{linked
   puntatori), è invece relativamente lenta nell'accesso casuale e nella
   ricerca.}  I nuovi messaggi vengono inseriti in coda alla lista e vengono
 letti dalla cima, in fig.~\ref{fig:ipc_mq_schema} si è riportato uno schema
   puntatori), è invece relativamente lenta nell'accesso casuale e nella
   ricerca.}  I nuovi messaggi vengono inseriti in coda alla lista e vengono
 letti dalla cima, in fig.~\ref{fig:ipc_mq_schema} si è riportato uno schema
-semplificato con cui queste strutture vengono mantenute dal
-kernel.\footnote{lo schema illustrato è in realtà una semplificazione di
-  quello usato fino ai kernel della serie 2.2, a partire della serie 2.4 la
-  gestione delle code di messaggi è effettuata in maniera diversa, ma abbiamo
-  mantenuto lo schema precedente dato che illustra in maniera più che adeguata
-  i principi di funzionamento delle code di messaggi.}
+semplificato con cui queste strutture vengono mantenute dal kernel. Lo schema
+illustrato in realtà è una semplificazione di quello usato fino ai kernel
+della serie 2.2. A partire della serie 2.4 la gestione delle code di messaggi
+è effettuata in maniera diversa (e non esiste una struttura \struct{msqid\_ds}
+nel kernel), ma abbiamo mantenuto lo schema precedente dato che illustra in
+maniera più che adeguata i principi di funzionamento delle code di messaggi.
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=13cm]{img/mqstruct}
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=13cm]{img/mqstruct}
@@ -1340,22 +1340,27 @@ kernel.\footnote{lo schema illustrato è in realtà una semplificazione di
 
 
 A ciascuna coda è associata una struttura \struct{msqid\_ds} la cui
 
 
 A ciascuna coda è associata una struttura \struct{msqid\_ds} la cui
-definizione è riportata in fig.~\ref{fig:ipc_msqid_ds}. In questa struttura il
-kernel mantiene le principali informazioni riguardo lo stato corrente della
-coda.\footnote{come accennato questo vale fino ai kernel della serie 2.2, essa
-  viene usata nei kernel della serie 2.4 solo per compatibilità in quanto è
-  quella restituita dalle funzioni dell'interfaccia; si noti come ci sia una
-  differenza con i campi mostrati nello schema di fig.~\ref{fig:ipc_mq_schema}
-  che sono presi dalla definizione di \file{include/linux/msg.h}, e fanno
-  riferimento alla definizione della omonima struttura usata nel kernel.} In
-fig.~\ref{fig:ipc_msqid_ds} sono elencati i campi significativi definiti in
-\headfile{sys/msg.h}, a cui si sono aggiunti gli ultimi tre campi che sono
-previsti dalla implementazione originale di System V, ma non dallo standard
-Unix98.
+definizione è riportata in fig.~\ref{fig:ipc_msqid_ds} ed a cui si accede
+includendo  \headfile{sys/msg.h};
+%
+% INFO: sotto materiale obsoleto e non interessante
+% In questa struttura il
+% kernel mantiene le principali informazioni riguardo lo stato corrente della
+% coda. Come accennato questo vale fino ai kernel della serie 2.2, essa viene
+% usata nei kernel della serie 2.4 solo per compatibilità in quanto è quella
+% restituita dalle funzioni dell'interfaccia; si noti come ci sia una differenza
+% con i campi mostrati nello schema di fig.~\ref{fig:ipc_mq_schema} che sono
+% presi dalla definizione di \file{include/linux/msg.h}, e fanno riferimento
+% alla definizione della omonima struttura usata nel kernel. 
+%In fig.~\ref{fig:ipc_msqid_ds} sono elencati i campi definiti in
+%\headfile{sys/msg.h};  
+si tenga presente che il campo \var{\_\_msg\_cbytes} non è previsto dallo
+standard POSIX.1-2001 e che alcuni campi fino al kernel 2.2 erano definiti
+come \ctyp{short}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.90\textwidth}
     \includestruct{listati/msqid_ds.h}
   \end{minipage} 
   \normalsize 
     \includestruct{listati/msqid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -1365,9 +1370,11 @@ Unix98.
 \end{figure}
 
 Quando si crea una nuova coda con \func{msgget} questa struttura viene
 \end{figure}
 
 Quando si crea una nuova coda con \func{msgget} questa struttura viene
-inizializzata, in particolare il campo \var{msg\_perm} viene inizializzato
-come illustrato in sez.~\ref{sec:ipc_sysv_access_control}, per quanto riguarda
-gli altri campi invece:
+inizializzata,\footnote{in realtà viene inizializzata una struttura interna al
+  kernel, ma i dati citati sono gli stessi.} in particolare il campo
+\var{msg\_perm} che esprime i permessi di accesso viene inizializzato nella
+modalità illustrata in sez.~\ref{sec:ipc_sysv_access_control}. Per quanto
+riguarda gli altri campi invece:
 \begin{itemize*}
 \item il campo \var{msg\_qnum}, che esprime il numero di messaggi presenti
   sulla coda, viene inizializzato a 0.
 \begin{itemize*}
 \item il campo \var{msg\_qnum}, che esprime il numero di messaggi presenti
   sulla coda, viene inizializzato a 0.
@@ -1377,16 +1384,18 @@ gli altri campi invece:
 \item i campi \var{msg\_stime} e \var{msg\_rtime}, che esprimono
   rispettivamente il tempo in cui è stato inviato o ricevuto l'ultimo
   messaggio sulla coda, sono inizializzati a 0.
 \item i campi \var{msg\_stime} e \var{msg\_rtime}, che esprimono
   rispettivamente il tempo in cui è stato inviato o ricevuto l'ultimo
   messaggio sulla coda, sono inizializzati a 0.
-\item il campo \var{msg\_ctime}, che esprime il tempo di creazione della coda,
-  viene inizializzato al tempo corrente.
-\item il campo \var{msg\_qbytes} che esprime la dimensione massima del
+\item il campo \var{msg\_ctime}, che esprime il tempo di ultima modifica della
+  coda, viene inizializzato al tempo corrente.
+\item il campo \var{msg\_qbytes}, che esprime la dimensione massima del
   contenuto della coda (in byte) viene inizializzato al valore preimpostato
   del sistema (\const{MSGMNB}).
   contenuto della coda (in byte) viene inizializzato al valore preimpostato
   del sistema (\const{MSGMNB}).
-\item i campi \var{msg\_first} e \var{msg\_last} che esprimono l'indirizzo del
-  primo e ultimo messaggio sono inizializzati a \val{NULL} e
-  \var{msg\_cbytes}, che esprime la dimensione in byte dei messaggi presenti è
-  inizializzato a zero. Questi campi sono ad uso interno dell'implementazione
-  e non devono essere utilizzati da programmi in user space).
+\item il campo \var{\_\_msg\_cbytes}, che esprime la dimensione in byte dei
+  messaggi presenti sulla coda, viene inizializzato a zero.
+% i campi \var{msg\_first} e \var{msg\_last} che esprimono l'indirizzo del
+%   primo e ultimo messaggio sono inizializzati a \val{NULL} e
+%   \var{msg\_cbytes}, che esprime la dimensione in byte dei messaggi presenti è
+%   inizializzato a zero. Questi campi sono ad uso interno dell'implementazione
+%   e non devono essere utilizzati da programmi in user space).
 \end{itemize*}
 
 Una volta creata una coda di messaggi le operazioni di controllo vengono
 \end{itemize*}
 
 Una volta creata una coda di messaggi le operazioni di controllo vengono
@@ -1417,16 +1426,16 @@ file; il suo prototipo è:
   generico.}
 \end{funcproto}
 
   generico.}
 \end{funcproto}
 
-
-La funzione permette di accedere ai valori della struttura \struct{msqid\_ds},
-mantenuta all'indirizzo \param{buf}, per la coda specificata
-dall'identificatore \param{msqid}. Il comportamento della funzione dipende dal
-valore dell'argomento \param{cmd}, che specifica il tipo di azione da
-eseguire; i valori possibili sono:
-\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+La funzione permette di eseguire una operazione di controllo per la coda
+specificata dall'identificatore \param{msqid}, utilizzando i valori della
+struttura \struct{msqid\_ds}, mantenuta all'indirizzo \param{buf}. Il
+comportamento della funzione dipende dal valore dell'argomento \param{cmd},
+che specifica il tipo di azione da eseguire. I valori possibili
+per \param{cmd} sono:
+\begin{basedescript}{\desclabelwidth{1.6cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{IPC\_STAT}] Legge le informazioni riguardo la coda nella
 \item[\const{IPC\_STAT}] Legge le informazioni riguardo la coda nella
-  struttura indicata da \param{buf}. Occorre avere il permesso di lettura
-  sulla coda.
+  struttura \struct{msqid\_ds} indicata da \param{buf}. Occorre avere il
+  permesso di lettura sulla coda.
 \item[\const{IPC\_RMID}] Rimuove la coda, cancellando tutti i dati, con
   effetto immediato. Tutti i processi che cercheranno di accedere alla coda
   riceveranno un errore di \errcode{EIDRM}, e tutti processi in attesa su
 \item[\const{IPC\_RMID}] Rimuove la coda, cancellando tutti i dati, con
   effetto immediato. Tutti i processi che cercheranno di accedere alla coda
   riceveranno un errore di \errcode{EIDRM}, e tutti processi in attesa su
@@ -1437,41 +1446,50 @@ eseguire; i valori possibili sono:
 \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
   della coda, ed il limite massimo sulle dimensioni del totale dei messaggi in
   essa contenuti (\var{msg\_qbytes}). I valori devono essere passati in una
 \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
   della coda, ed il limite massimo sulle dimensioni del totale dei messaggi in
   essa contenuti (\var{msg\_qbytes}). I valori devono essere passati in una
-  struttura \struct{msqid\_ds} puntata da \param{buf}.  Per modificare i valori
-  di \var{msg\_perm.mode}, \var{msg\_perm.uid} e \var{msg\_perm.gid} occorre
-  essere il proprietario o il creatore della coda, oppure l'amministratore; lo
-  stesso vale per \var{msg\_qbytes}, ma l'amministratore ha la facoltà di
-  incrementarne il valore a limiti superiori a \const{MSGMNB}.
+  struttura \struct{msqid\_ds} puntata da \param{buf}.  Per modificare i
+  valori di \var{msg\_perm.mode}, \var{msg\_perm.uid} e \var{msg\_perm.gid}
+  occorre essere il proprietario o il creatore della coda, oppure
+  l'amministratore e lo stesso vale per \var{msg\_qbytes}. Infine solo
+  l'amministratore (più precisamente un processo con la capacità
+  \itindex{capability} \const{CAP\_IPC\_RESOURCE}) ha la facoltà di
+  incrementarne il valore a limiti superiori a \const{MSGMNB}. Se eseguita con
+  successo la funzione aggiorna anche il campo \var{msg\_ctime}.
 \end{basedescript}
 
 \end{basedescript}
 
+A questi tre valori, che sono quelli previsti dallo standard, su Linux se ne
+affiancano altri tre (\const{IPC\_INFO}, \const{MSG\_STAT} e
+\const{MSG\_INFO}) introdotti ad uso del programma \cmd{ipcs} per ottenere le
+informazioni generali relative alle risorse usate dalle code di
+messaggi. Questi potranno essere modificati o rimossi in favore dell'uso di
+\texttt{/proc}, per cui non devono essere usati e non li tratteremo.
 
 Una volta che si abbia a disposizione l'identificatore, per inviare un
 
 Una volta che si abbia a disposizione l'identificatore, per inviare un
-messaggio su una coda si utilizza la funzione \funcd{msgsnd}; il suo prototipo
-è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/msg.h} 
-  
-  \funcdecl{int msgsnd(int msqid, struct msgbuf *msgp, size\_t msgsz, int
-    msgflg)} 
+messaggio su una coda si utilizza la funzione di sistema \funcd{msgsnd}, il
+cui prototipo è:
 
 
-  Invia un messaggio sulla coda \param{msqid}.
-  
-  \bodydesc{La funzione restituisce 0, e $-1$ in caso di errore, nel qual caso
-    \var{errno} assumerà uno dei valori:
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/msg.h}
+\fdecl{int msgsnd(int msqid, struct msgbuf *msgp, size\_t msgsz, int msgflg)}
+\fdesc{Invia un messaggio su una coda.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
   \begin{errlist}
   \item[\errcode{EACCES}] non si hanno i privilegi di accesso sulla coda.
   \begin{errlist}
   \item[\errcode{EACCES}] non si hanno i privilegi di accesso sulla coda.
-  \item[\errcode{EIDRM}] la coda è stata cancellata.
   \item[\errcode{EAGAIN}] il messaggio non può essere inviato perché si è
   \item[\errcode{EAGAIN}] il messaggio non può essere inviato perché si è
-  superato il limite \var{msg\_qbytes} sul numero massimo di byte presenti
-  sulla coda, e si è richiesto \const{IPC\_NOWAIT} in \param{flag}.
+    superato il limite \var{msg\_qbytes} sul numero massimo di byte presenti
+    sulla coda, e si è richiesto \const{IPC\_NOWAIT} in \param{flag}.
+  \item[\errcode{EIDRM}] la coda è stata cancellata.
   \item[\errcode{EINVAL}] si è specificato un \param{msgid} invalido, o un
     valore non positivo per \param{mtype}, o un valore di \param{msgsz}
     maggiore di \const{MSGMAX}.
   \end{errlist}
   \item[\errcode{EINVAL}] si è specificato un \param{msgid} invalido, o un
     valore non positivo per \param{mtype}, o un valore di \param{msgsz}
     maggiore di \const{MSGMAX}.
   \end{errlist}
-  ed inoltre \errval{EFAULT}, \errval{EINTR} ed \errval{ENOMEM}.  }
-\end{functions}
+  ed inoltre \errval{EFAULT}, \errval{EINTR} e \errval{ENOMEM} nel loro
+  significato generico.}
+\end{funcproto}
 
 La funzione inserisce il messaggio sulla coda specificata da \param{msqid}; il
 messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso il
 
 La funzione inserisce il messaggio sulla coda specificata da \param{msqid}; il
 messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso il
@@ -1481,6 +1499,17 @@ fig.~\ref{fig:ipc_msbuf} che è quella che deve contenere effettivamente il
 messaggio.  La dimensione massima per il testo di un messaggio non può
 comunque superare il limite \const{MSGMAX}.
 
 messaggio.  La dimensione massima per il testo di un messaggio non può
 comunque superare il limite \const{MSGMAX}.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.8\textwidth}
+    \includestruct{listati/msgbuf.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{Schema della struttura \structd{msgbuf}, da utilizzare come
+    argomento per inviare/ricevere messaggi.}
+  \label{fig:ipc_msbuf}
+\end{figure}
+
 La struttura di fig.~\ref{fig:ipc_msbuf} è comunque solo un modello, tanto che
 la definizione contenuta in \headfile{sys/msg.h} usa esplicitamente per il
 secondo campo il valore \code{mtext[1]}, che non è di nessuna utilità ai fini
 La struttura di fig.~\ref{fig:ipc_msbuf} è comunque solo un modello, tanto che
 la definizione contenuta in \headfile{sys/msg.h} usa esplicitamente per il
 secondo campo il valore \code{mtext[1]}, che non è di nessuna utilità ai fini
@@ -1504,17 +1533,6 @@ cioè \var{message} è una propria struttura che si passa alla funzione,
 consideriamo il caso dell'esempio in fig.~\ref{fig:ipc_msbuf}, \param{msgsz}
 dovrà essere pari a \const{LENGTH}).
 
 consideriamo il caso dell'esempio in fig.~\ref{fig:ipc_msbuf}, \param{msgsz}
 dovrà essere pari a \const{LENGTH}).
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
-    \includestruct{listati/msgbuf.h}
-  \end{minipage} 
-  \normalsize 
-  \caption{Schema della struttura \structd{msgbuf}, da utilizzare come
-    argomento per inviare/ricevere messaggi.}
-  \label{fig:ipc_msbuf}
-\end{figure}
-
 Per capire meglio il funzionamento della funzione riprendiamo in
 considerazione la struttura della coda illustrata in
 fig.~\ref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo messaggio
 Per capire meglio il funzionamento della funzione riprendiamo in
 considerazione la struttura della coda illustrata in
 fig.~\ref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo messaggio
@@ -1529,14 +1547,13 @@ Il valore dell'argomento \param{flag} permette di specificare il comportamento
 della funzione. Di norma, quando si specifica un valore nullo, la funzione
 ritorna immediatamente a meno che si sia ecceduto il valore di
 \var{msg\_qbytes}, o il limite di sistema sul numero di messaggi, nel qual
 della funzione. Di norma, quando si specifica un valore nullo, la funzione
 ritorna immediatamente a meno che si sia ecceduto il valore di
 \var{msg\_qbytes}, o il limite di sistema sul numero di messaggi, nel qual
-caso si blocca mandando il processo in stato di \textit{sleep}.  Se si
-specifica per \param{flag} il valore \const{IPC\_NOWAIT} la funzione opera in
-modalità non bloccante, ed in questi casi ritorna immediatamente con un errore
-di \errcode{EAGAIN}.
+caso si blocca.  Se si specifica per \param{flag} il valore
+\const{IPC\_NOWAIT} la funzione opera in modalità non-bloccante, ed in questi
+casi ritorna immediatamente con un errore di \errcode{EAGAIN}.
 
 Se non si specifica \const{IPC\_NOWAIT} la funzione resterà bloccata fintanto
 che non si liberano risorse sufficienti per poter inserire nella coda il
 
 Se non si specifica \const{IPC\_NOWAIT} la funzione resterà bloccata fintanto
 che non si liberano risorse sufficienti per poter inserire nella coda il
-messaggio, nel qual caso ritornerà normalmente. La funzione può ritornare, con
+messaggio, nel qual caso ritornerà normalmente. La funzione può ritornare con
 una condizione di errore anche in due altri casi: quando la coda viene rimossa
 (nel qual caso si ha un errore di \errcode{EIDRM}) o quando la funzione viene
 interrotta da un segnale (nel qual caso si ha un errore di \errcode{EINTR}).
 una condizione di errore anche in due altri casi: quando la coda viene rimossa
 (nel qual caso si ha un errore di \errcode{EIDRM}) o quando la funzione viene
 interrotta da un segnale (nel qual caso si ha un errore di \errcode{EINTR}).
@@ -1551,41 +1568,39 @@ vengono modificati:
 \item Il valore \var{msg\_stime}, che viene impostato al tempo corrente.
 \end{itemize*}
 
 \item Il valore \var{msg\_stime}, che viene impostato al tempo corrente.
 \end{itemize*}
 
-La funzione che viene utilizzata per estrarre un messaggio da una coda è
-\funcd{msgrcv}; il suo prototipo è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/msg.h} 
+La funzione di sistema che viene utilizzata per estrarre un messaggio da una
+coda è \funcd{msgrcv}, ed il suo prototipo è:
 
 
-  \funcdecl{ssize\_t msgrcv(int msqid, struct msgbuf *msgp, size\_t msgsz,
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h} 
+\fhead{sys/msg.h}
+\fdecl{ssize\_t msgrcv(int msqid, struct msgbuf *msgp, size\_t msgsz,
     long msgtyp, int msgflg)}
     long msgtyp, int msgflg)}
-  
-  Legge un messaggio dalla coda \param{msqid}.
-  
-  \bodydesc{La funzione restituisce il numero di byte letti in caso di
-    successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà uno
-    dei valori:
+\fdesc{Legge un messaggio da una coda.} 
+}
+
+{La funzione ritorna il numero di byte letti in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \begin{errlist}
-  \item[\errcode{EACCES}] non si hanno i privilegi di accesso sulla coda.
-  \item[\errcode{EIDRM}] la coda è stata cancellata.
   \item[\errcode{E2BIG}] il testo del messaggio è più lungo di \param{msgsz} e
     non si è specificato \const{MSG\_NOERROR} in \param{msgflg}.
   \item[\errcode{E2BIG}] il testo del messaggio è più lungo di \param{msgsz} e
     non si è specificato \const{MSG\_NOERROR} in \param{msgflg}.
+  \item[\errcode{EACCES}] non si hanno i privilegi di accesso sulla coda.
+  \item[\errcode{EIDRM}] la coda è stata cancellata.
   \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale mentre
     era in attesa di ricevere un messaggio.
   \item[\errcode{EINVAL}] si è specificato un \param{msgid} invalido o un
     valore di \param{msgsz} negativo.
   \end{errlist}
   \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale mentre
     era in attesa di ricevere un messaggio.
   \item[\errcode{EINVAL}] si è specificato un \param{msgid} invalido o un
     valore di \param{msgsz} negativo.
   \end{errlist}
-  ed inoltre \errval{EFAULT}.
-}
-\end{functions}
+  ed inoltre \errval{EFAULT} nel suo significato generico.}
+\end{funcproto}
 
 
-La funzione legge un messaggio dalla coda specificata, scrivendolo sulla
-struttura puntata da \param{msgp}, che dovrà avere un formato analogo a quello
-di fig.~\ref{fig:ipc_msbuf}.  Una volta estratto, il messaggio sarà rimosso
-dalla coda.  L'argomento \param{msgsz} indica la lunghezza massima del testo
-del messaggio (equivalente al valore del parametro \const{LENGTH} nell'esempio
-di fig.~\ref{fig:ipc_msbuf}).
+La funzione legge un messaggio dalla coda specificata da \param{msqid},
+scrivendolo sulla struttura puntata da \param{msgp}, che dovrà avere un
+formato analogo a quello di fig.~\ref{fig:ipc_msbuf}.  Una volta estratto, il
+messaggio sarà rimosso dalla coda.  L'argomento \param{msgsz} indica la
+lunghezza massima del testo del messaggio (equivalente al valore del parametro
+\const{LENGTH} nell'esempio di fig.~\ref{fig:ipc_msbuf}).
 
 Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene
 rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a
 
 Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene
 rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a
@@ -1599,7 +1614,7 @@ una scansione della struttura mostrata in fig.~\ref{fig:ipc_mq_schema},
 restituendo il primo messaggio incontrato che corrisponde ai criteri
 specificati (che quindi, visto come i messaggi vengono sempre inseriti dalla
 coda, è quello meno recente); in particolare:
 restituendo il primo messaggio incontrato che corrisponde ai criteri
 specificati (che quindi, visto come i messaggi vengono sempre inseriti dalla
 coda, è quello meno recente); in particolare:
-\begin{itemize}
+\begin{itemize*}
 \item se \param{msgtyp} è 0 viene estratto il messaggio in cima alla coda, cioè
   quello fra i presenti che è stato inserito per primo. 
 \item se \param{msgtyp} è positivo viene estratto il primo messaggio il cui
 \item se \param{msgtyp} è 0 viene estratto il messaggio in cima alla coda, cioè
   quello fra i presenti che è stato inserito per primo. 
 \item se \param{msgtyp} è positivo viene estratto il primo messaggio il cui
@@ -1608,7 +1623,7 @@ coda, è quello meno recente); in particolare:
 \item se \param{msgtyp} è negativo viene estratto il primo fra i messaggi con
   il valore più basso del tipo, fra tutti quelli il cui tipo ha un valore
   inferiore al valore assoluto di \param{msgtyp}.
 \item se \param{msgtyp} è negativo viene estratto il primo fra i messaggi con
   il valore più basso del tipo, fra tutti quelli il cui tipo ha un valore
   inferiore al valore assoluto di \param{msgtyp}.
-\end{itemize}
+\end{itemize*}
 
 Il valore di \param{msgflg} permette di controllare il comportamento della
 funzione, esso può essere nullo o una maschera binaria composta da uno o più
 
 Il valore di \param{msgflg} permette di controllare il comportamento della
 funzione, esso può essere nullo o una maschera binaria composta da uno o più
@@ -1619,13 +1634,13 @@ di leggere il primo messaggio nella coda con tipo diverso da \param{msgtyp}, e
 ci sono messaggi sulla coda.
 
 Il comportamento usuale della funzione infatti, se non ci sono messaggi
 ci sono messaggi sulla coda.
 
 Il comportamento usuale della funzione infatti, se non ci sono messaggi
-disponibili per la lettura, è di bloccare il processo in stato di
-\textit{sleep}. Nel caso però si sia specificato \const{IPC\_NOWAIT} la
-funzione ritorna immediatamente con un errore \errcode{ENOMSG}. Altrimenti la
-funzione ritorna normalmente non appena viene inserito un messaggio del tipo
-desiderato, oppure ritorna con errore qualora la coda sia rimossa (con
-\var{errno} impostata a \errcode{EIDRM}) o se il processo viene interrotto da
-un segnale (con \var{errno} impostata a \errcode{EINTR}).
+disponibili per la lettura, è di bloccare il processo. Nel caso però si sia
+specificato \const{IPC\_NOWAIT} la funzione ritorna immediatamente con un
+errore \errcode{ENOMSG}. Altrimenti la funzione ritorna normalmente non appena
+viene inserito un messaggio del tipo desiderato, oppure ritorna con errore
+qualora la coda sia rimossa (con \var{errno} impostata a \errcode{EIDRM}) o se
+il processo viene interrotto da un segnale (con \var{errno} impostata a
+\errcode{EINTR}).
 
 Una volta completata con successo l'estrazione del messaggio dalla coda, la
 funzione aggiorna i dati mantenuti in \struct{msqid\_ds}, in particolare
 
 Una volta completata con successo l'estrazione del messaggio dalla coda, la
 funzione aggiorna i dati mantenuti in \struct{msqid\_ds}, in particolare
@@ -1638,15 +1653,15 @@ vengono modificati:
 \end{itemize*}
 
 Le code di messaggi presentano il solito problema di tutti gli oggetti del
 \end{itemize*}
 
 Le code di messaggi presentano il solito problema di tutti gli oggetti del
-SysV-IPC; essendo questi permanenti restano nel sistema occupando risorse
-anche quando un processo è terminato, al contrario delle \textit{pipe} per le
-quali tutte le risorse occupate vengono rilasciate quanto l'ultimo processo
-che le utilizzava termina. Questo comporta che in caso di errori si può
-saturare il sistema, e che devono comunque essere esplicitamente previste
+\textit{SysV-IPC} che essendo questi permanenti restano nel sistema occupando
+risorse anche quando un processo è terminato, al contrario delle \textit{pipe}
+per le quali tutte le risorse occupate vengono rilasciate quanto l'ultimo
+processo che le utilizzava termina. Questo comporta che in caso di errori si
+può saturare il sistema, e che devono comunque essere esplicitamente previste
 delle funzioni di rimozione in caso di interruzioni o uscite dal programma
 (come vedremo in fig.~\ref{fig:ipc_mq_fortune_server}).
 
 delle funzioni di rimozione in caso di interruzioni o uscite dal programma
 (come vedremo in fig.~\ref{fig:ipc_mq_fortune_server}).
 
-L'altro problema è non facendo uso di file descriptor le tecniche di
+L'altro problema è che non facendo uso di file descriptor le tecniche di
 \textit{I/O multiplexing} descritte in sez.~\ref{sec:file_multiplexing} non
 possono essere utilizzate, e non si ha a disposizione niente di analogo alle
 funzioni \func{select} e \func{poll}. Questo rende molto scomodo usare più di
 \textit{I/O multiplexing} descritte in sez.~\ref{sec:file_multiplexing} non
 possono essere utilizzate, e non si ha a disposizione niente di analogo alle
 funzioni \func{select} e \func{poll}. Questo rende molto scomodo usare più di
@@ -1684,18 +1699,17 @@ messaggi sulla base del loro tipo.
 Il programma, oltre alle solite variabili per il nome del file da cui leggere
 le \textit{fortunes} e per il vettore di stringhe che contiene le frasi,
 definisce due strutture appositamente per la comunicazione; con
 Il programma, oltre alle solite variabili per il nome del file da cui leggere
 le \textit{fortunes} e per il vettore di stringhe che contiene le frasi,
 definisce due strutture appositamente per la comunicazione; con
-\var{msgbuf\_read} (\texttt{\small 8--11}) vengono passate le richieste mentre
-con \var{msgbuf\_write} (\texttt{\small 12--15}) vengono restituite le frasi.
+\var{msgbuf\_read} vengono passate (\texttt{\small 8--11}) le richieste mentre
+con \var{msgbuf\_write} vengono restituite (\texttt{\small 12--15}) le frasi.
 
 La gestione delle opzioni si è al solito omessa, essa si curerà di impostare
 
 La gestione delle opzioni si è al solito omessa, essa si curerà di impostare
-in \var{n} il numero di frasi da leggere specificato a linea di comando ed in
-\var{fortunefilename} il file da cui leggerle; dopo aver installato
-(\texttt{\small 19--21}) i gestori dei segnali per trattare l'uscita dal
-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
-\textit{fifo}.
+nella variabile \var{n} il numero di frasi da leggere specificato a linea di
+comando ed in \var{fortunefilename} il file da cui leggerle. Dopo aver
+installato (\texttt{\small 19--21}) i gestori dei segnali per trattare
+l'uscita dal server, viene prima controllato (\texttt{\small 22}) il numero di
+frasi richieste abbia senso (cioè sia maggiore di zero), le quali poi vengono
+lette (\texttt{\small 23}) nel vettore in memoria con la stessa funzione
+\code{FortuneParse} usata anche per il server basato sulle \textit{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
 
 Una volta inizializzato il vettore di stringhe coi messaggi presi dal file
 delle \textit{fortune} si procede (\texttt{\small 25}) con la generazione di
@@ -1709,8 +1723,8 @@ 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
 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
+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 \ids{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 \ids{PID} del
 corrisponde al \ids{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 \ids{PID} del
@@ -1761,31 +1775,32 @@ non viene chiamata con il flag di creazione in quanto la coda deve essere
 preesistente. In caso di errore (ad esempio se il server non è stato avviato)
 il programma termina immediatamente. 
 
 preesistente. In caso di errore (ad esempio se il server non è stato avviato)
 il programma termina immediatamente. 
 
-Una volta acquisito l'identificatore della coda il client compone il
-messaggio di richiesta (\texttt{\small 12--13}) in \var{msg\_read}, usando 1
-per il tipo ed inserendo il proprio \ids{PID} come dato da passare al server.
-Calcolata (\texttt{\small 14}) la dimensione, provvede (\texttt{\small 15}) ad
-immettere la richiesta sulla coda. 
-
-A questo punto non resta che (\texttt{\small 16}) rileggere dalla coda la
-risposta del server richiedendo a \func{msgrcv} di selezionare i messaggi di
-tipo corrispondente al valore del \ids{PID} inviato nella richiesta. L'ultimo
-passo (\texttt{\small 17}) prima di uscire è quello di stampare a video il
-messaggio ricevuto.
+Una volta acquisito l'identificatore della coda il client compone
+(\texttt{\small 12--13}) il messaggio di richiesta in \var{msg\_read}, usando
+1 per il tipo ed inserendo il proprio \ids{PID} come dato da passare al
+server.  Calcolata (\texttt{\small 14}) la dimensione, provvede
+(\texttt{\small 15}) ad immettere la richiesta sulla coda.
+
+A questo punto non resta che rileggere la risposta (\texttt{\small 16}) dalla
+coda del server richiedendo a \func{msgrcv} di selezionare i messaggi di tipo
+corrispondente al valore del \ids{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
  
 Proviamo allora il nostro nuovo sistema, al solito occorre definire
-\code{LD\_LIBRARY\_PATH} per accedere alla libreria \file{libgapil.so}, 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}%$
+\code{LD\_LIBRARY\_PATH} per accedere alla libreria \file{libgapil.so}, dopo
+di che, in maniera del tutto analoga a quanto fatto con il programma che usa
+le \textit{fifo}, potremo far partire il server con:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./mqfortuned -n10}
+\end{Console}
+%$
 come nel caso precedente, avendo eseguito il server in background, il comando
 ritornerà immediatamente; potremo però verificare con \cmd{ps} che il
 programma è effettivamente in esecuzione, e che ha creato una coda di
 messaggi:
 come nel caso precedente, avendo eseguito il server in background, il comando
 ritornerà immediatamente; potremo però verificare con \cmd{ps} che il
 programma è effettivamente in esecuzione, e che ha creato una coda di
 messaggi:
-\begin{verbatim}
-[piccardi@gont sources]$ ipcs
+\begin{Console}
+[piccardi@gont sources]$ \textbf{ipcs}
 
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
 
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
@@ -1796,19 +1811,21 @@ key        semid      owner      perms      nsems
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
 0x0102dc6a 0          piccardi   666        0            0           
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
 0x0102dc6a 0          piccardi   666        0            0           
-\end{verbatim}
+\end{Console}
+%$
 a questo punto potremo usare il client per ottenere le nostre frasi:
 a questo punto potremo usare il client per ottenere le nostre frasi:
-\begin{verbatim}
-[piccardi@gont sources]$ ./mqfortune
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./mqfortune}
 Linux ext2fs has been stable for a long time, now it's time to break it
         -- Linuxkongreß '95 in Berlin
 Linux ext2fs has been stable for a long time, now it's time to break it
         -- Linuxkongreß '95 in Berlin
-[piccardi@gont sources]$ ./mqfortune
+[piccardi@gont sources]$ \textbf{./mqfortune}
 Let's call it an accidental feature.
         --Larry Wall
 Let's call it an accidental feature.
         --Larry Wall
-\end{verbatim}
+\end{Console} 
 con un risultato del tutto equivalente al precedente. Infine potremo chiudere
 il server inviando il segnale di terminazione con il comando \code{killall
 con un risultato del tutto equivalente al precedente. Infine potremo chiudere
 il server inviando il segnale di terminazione con il comando \code{killall
-  mqfortuned} verificando che effettivamente la coda di messaggi viene rimossa.
+  mqfortuned}, verificando che effettivamente la coda di messaggi venga
+rimossa.
 
 Benché funzionante questa architettura risente dello stesso inconveniente
 visto anche nel caso del precedente server basato sulle \textit{fifo}; se il
 
 Benché funzionante questa architettura risente dello stesso inconveniente
 visto anche nel caso del precedente server basato sulle \textit{fifo}; se il
@@ -1817,43 +1834,43 @@ lettura della risposta, quest'ultima resta nella coda (così come per le
 \textit{fifo} si aveva il problema delle \textit{fifo} che restavano nel
 filesystem). In questo caso però il problemi sono maggiori, sia perché è molto
 più facile esaurire la memoria dedicata ad una coda di messaggi che gli
 \textit{fifo} si aveva il problema delle \textit{fifo} che restavano nel
 filesystem). In questo caso però il problemi sono maggiori, sia perché è molto
 più facile esaurire la memoria dedicata ad una coda di messaggi che gli
-\itindex{inode} inode di un filesystem, sia perché, con il riutilizzo dei
-\ids{PID} da parte dei processi, un client eseguito in un momento successivo
-potrebbe ricevere un messaggio non indirizzato a lui.
+\itindex{inode} \textit{inode} di un filesystem, sia perché, con il riutilizzo
+dei \ids{PID} da parte dei processi, un client eseguito in un momento
+successivo potrebbe ricevere un messaggio non indirizzato a lui.
 
 
 
 
 
 
-\subsection{Semafori}
+\subsection{I semafori}
 \label{sec:ipc_sysv_sem}
 
 \label{sec:ipc_sysv_sem}
 
-I semafori non sono meccanismi di intercomunicazione diretta come quelli
-(\textit{pipe}, \textit{fifo} e code di messaggi) visti finora, e non
-consentono di scambiare dati fra processi, ma servono piuttosto come
-meccanismi di sincronizzazione o di protezione per le \index{sezione~critica}
+I semafori non sono propriamente meccanismi di intercomunicazione come
+\textit{pipe}, \textit{fifo} e code di messaggi, poiché non consentono di
+scambiare dati fra processi, ma servono piuttosto come meccanismi di
+sincronizzazione o di protezione per le \index{sezione~critica}
 \textsl{sezioni critiche} del codice (si ricordi quanto detto in
 \textsl{sezioni critiche} del codice (si ricordi quanto detto in
-sez.~\ref{sec:proc_race_cond}).
-
-Un semaforo è uno speciale contatore, mantenuto nel kernel, che permette, a
-seconda del suo valore, di consentire o meno la prosecuzione dell'esecuzione
-di un programma. In questo modo l'accesso ad una risorsa condivisa da più
-processi può essere controllato, associando ad essa un semaforo che consente
-di assicurare che non più di un processo alla volta possa usarla.
+sez.~\ref{sec:proc_race_cond}).  Un semaforo infatti non è altro che un
+contatore mantenuto nel kernel che determina se consentire o meno la
+prosecuzione dell'esecuzione di un programma. In questo modo si può
+controllare l'accesso ad una risorsa condivisa da più processi, associandovi
+un semaforo che assicuri che non possa essere usata da più di un processo alla
+volta.
 
 Il concetto di semaforo è uno dei concetti base nella programmazione ed è
 assolutamente generico, così come del tutto generali sono modalità con cui lo
 
 Il concetto di semaforo è uno dei concetti base nella programmazione ed è
 assolutamente generico, così come del tutto generali sono modalità con cui lo
-si utilizza. Un processo che deve accedere ad una risorsa eseguirà un
-controllo del semaforo: se questo è positivo il suo valore sarà decrementato,
-indicando che si è consumato una unità della risorsa, ed il processo potrà
-proseguire nell'utilizzo di quest'ultima, provvedendo a rilasciarla, una volta
-completate le operazioni volute, reincrementando il semaforo.
-
-Se al momento del controllo il valore del semaforo è nullo, siamo invece in
-una situazione in cui la risorsa non è disponibile, ed il processo si
-bloccherà in stato di \textit{sleep} fin quando chi la sta utilizzando non la
-rilascerà, incrementando il valore del semaforo. Non appena il semaforo torna
-positivo, indicando che la risorsa è disponibile, il processo sarà svegliato,
-e si potrà operare come nel caso precedente (decremento del semaforo, accesso
-alla risorsa, incremento del semaforo).
+si utilizza. Un processo che deve accedere ad una risorsa condivisa eseguirà
+un controllo del semaforo: se questo è positivo il suo valore sarà
+decrementato, indicando che si è consumato una unità della risorsa, ed il
+processo potrà proseguire nell'utilizzo di quest'ultima, provvedendo a
+rilasciarla, una volta completate le operazioni volute, reincrementando il
+semaforo.
+
+Se al momento del controllo il valore del semaforo è nullo la risorsa viene
+considerata non disponibile, ed il processo si bloccherà fin quando chi la sta
+utilizzando non la rilascerà, incrementando il valore del semaforo. Non appena
+il semaforo diventa positivo, indicando che la risorsa è tornata disponibile,
+il processo bloccato in attesa riprenderà l'esecuzione, e potrà operare come
+nel caso precedente (decremento del semaforo, accesso alla risorsa, incremento
+del semaforo).
 
 Per poter implementare questo tipo di logica le operazioni di controllo e
 decremento del contatore associato al semaforo devono essere atomiche,
 
 Per poter implementare questo tipo di logica le operazioni di controllo e
 decremento del contatore associato al semaforo devono essere atomiche,
@@ -1865,37 +1882,35 @@ della risorsa. In generale però si possono usare semafori con valori interi,
 utilizzando il valore del contatore come indicatore del ``numero di risorse''
 ancora disponibili.
 
 utilizzando il valore del contatore come indicatore del ``numero di risorse''
 ancora disponibili.
 
-Il sistema di comunicazione inter-processo di \textit{SysV-IPC} prevede anche i
-semafori, ma gli oggetti utilizzati non sono semafori singoli, ma gruppi di
-semafori detti \textsl{insiemi} (o \textit{semaphore set}); la funzione che
-permette di creare o ottenere l'identificatore di un insieme di semafori è
-\funcd{semget}, ed il suo prototipo è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/sem.h} 
-  
-  \funcdecl{int semget(key\_t key, int nsems, int flag)}
-  
-  Restituisce l'identificatore di un insieme di semafori.
-  
-  \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
-    in caso di errore, nel qual caso \var{errno} assumerà i valori:
-    \begin{errlist}
-    \item[\errcode{ENOSPC}] si è cercato di creare una insieme di semafori
-      quando è stato superato o il limite per il numero totale di semafori
-      (\const{SEMMNS}) o quello per il numero totale degli insiemi
-      (\const{SEMMNI}) nel sistema.
-    \item[\errcode{EINVAL}] l'argomento \param{nsems} è minore di zero o
-      maggiore del limite sul numero di semafori per ciascun insieme
-      (\const{SEMMSL}), o se l'insieme già esiste, maggiore del numero di
-      semafori che contiene.
-    \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter
-      contenere le strutture per un nuovo insieme di semafori.
-    \end{errlist}
-    ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST},
-    \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.}
-\end{functions}
+Il sistema di intercomunicazione di \textit{SysV-IPC} prevede anche una
+implementazione dei semafori, ma gli oggetti utilizzati sono tuttavia non
+semafori singoli, ma gruppi (più propriamente \textsl{insiemi}) di semafori
+detti ``\textit{semaphore set}''. La funzione di sistema che permette di
+creare o ottenere l'identificatore di un insieme di semafori è \funcd{semget},
+ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semget(key\_t key, int nsems, int flag)}
+\fdesc{Restituisce l'identificatore di un insieme di semafori.} 
+}
+
+{La funzione ritorna l'identificatore (un intero positivo) in caso di successo
+  e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{ENOSPC}] si è superato il limite di sistema per il numero
+    totale di semafori (\const{SEMMNS}) o di insiemi (\const{SEMMNI}).
+  \item[\errcode{EINVAL}] \param{nsems} è minore di zero o maggiore del limite
+    sul numero di semafori di un insieme (\const{SEMMSL}), o se l'insieme già
+    esiste, maggiore del numero di semafori che contiene.
+  \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter
+    contenere le strutture per un nuovo insieme di semafori.
+  \end{errlist}
+  ed inoltre \errval{EACCES}, \errval{EEXIST}, \errval{EIDRM} e
+  \errval{ENOENT} con lo stesso significato che hanno per \func{msgget}.}
+\end{funcproto}
 
 La funzione è del tutto analoga a \func{msgget}, solo che in questo caso
 restituisce l'identificatore di un insieme di semafori, in particolare è
 
 La funzione è del tutto analoga a \func{msgget}, solo che in questo caso
 restituisce l'identificatore di un insieme di semafori, in particolare è
@@ -1908,26 +1923,30 @@ richiesta dell'identificatore di un insieme già esistente.
 Purtroppo questa implementazione complica inutilmente lo schema elementare che
 abbiamo descritto, dato che non è possibile definire un singolo semaforo, ma
 se ne deve creare per forza un insieme.  Ma questa in definitiva è solo una
 Purtroppo questa implementazione complica inutilmente lo schema elementare che
 abbiamo descritto, dato che non è possibile definire un singolo semaforo, ma
 se ne deve creare per forza un insieme.  Ma questa in definitiva è solo una
-complicazione inutile, il problema è che i semafori del \textit{SysV-IPC}
-soffrono di altri due, ben più gravi, difetti.
+complicazione inutile dell'interfaccia, il problema è che i semafori forniti
+dal \textit{SysV-IPC} soffrono di altri due difetti progettuali molto più
+gravi.
 
 Il primo difetto è che non esiste una funzione che permetta di creare ed
 inizializzare un semaforo in un'unica chiamata; occorre prima creare l'insieme
 dei semafori con \func{semget} e poi inizializzarlo con \func{semctl}, si
 
 Il primo difetto è che non esiste una funzione che permetta di creare ed
 inizializzare un semaforo in un'unica chiamata; occorre prima creare l'insieme
 dei semafori con \func{semget} e poi inizializzarlo con \func{semctl}, si
-perde così ogni possibilità di eseguire l'operazione atomicamente.
+perde così ogni possibilità di eseguire l'operazione atomicamente. Eventuali
+accessi che possono avvenire fra la creazione e l'inizializzazione potranno
+avere effetti imprevisti.
 
 Il secondo difetto deriva dalla caratteristica generale degli oggetti del
 \textit{SysV-IPC} di essere risorse globali di sistema, che non vengono
 
 Il secondo difetto deriva dalla caratteristica generale degli oggetti del
 \textit{SysV-IPC} di essere risorse globali di sistema, che non vengono
-cancellate quando nessuno le usa più; ci si così a trova a dover affrontare
-esplicitamente il caso in cui un processo termina per un qualche errore,
-lasciando un semaforo occupato, che resterà tale fino al successivo riavvio
-del sistema. Come vedremo esistono delle modalità per evitare tutto ciò, ma
-diventa necessario indicare esplicitamente che si vuole il ripristino del
-semaforo all'uscita del processo.
+cancellate quando nessuno le usa più. In questo caso il problema è più grave
+perché ci si a trova a dover affrontare esplicitamente il caso in cui un
+processo termina per un qualche errore lasciando un semaforo occupato, che
+resterà tale fino al successivo riavvio del sistema. Come vedremo esistono
+delle modalità per evitare tutto ciò, ma diventa necessario indicare
+esplicitamente che si vuole il ripristino del semaforo all'uscita del
+processo, e la gestione diventa più complicata.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/semid_ds.h}
   \end{minipage} 
   \normalsize 
     \includestruct{listati/semid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -1937,39 +1956,28 @@ semaforo all'uscita del processo.
 \end{figure}
 
 A ciascun insieme di semafori è associata una struttura \struct{semid\_ds},
 \end{figure}
 
 A ciascun insieme di semafori è associata una struttura \struct{semid\_ds},
-riportata in fig.~\ref{fig:ipc_semid_ds}.\footnote{non si sono riportati i
-  campi ad uso interno del kernel, che vedremo in
-  fig.~\ref{fig:ipc_sem_schema}, che dipendono dall'implementazione.} Come nel
-caso delle code di messaggi quando si crea un nuovo insieme di semafori con
-\func{semget} questa struttura viene inizializzata, in particolare il campo
-\var{sem\_perm} viene inizializzato come illustrato in
+riportata in fig.~\ref{fig:ipc_semid_ds}.\footnote{anche in questo caso in
+  realtà il kernel usa una sua specifica struttura interna, ma i dati
+  significativi sono sempre quelli citati.}  Come nel caso delle code di
+messaggi quando si crea un nuovo insieme di semafori con \func{semget} questa
+struttura viene inizializzata. In particolare il campo \var{sem\_perm}, che
+esprime i permessi di accesso, viene inizializzato come illustrato in
 sez.~\ref{sec:ipc_sysv_access_control} (si ricordi che in questo caso il
 permesso di scrittura è in realtà permesso di alterare il semaforo), per
 quanto riguarda gli altri campi invece:
 \begin{itemize*}
 \item il campo \var{sem\_nsems}, che esprime il numero di semafori
   nell'insieme, viene inizializzato al valore di \param{nsems}.
 sez.~\ref{sec:ipc_sysv_access_control} (si ricordi che in questo caso il
 permesso di scrittura è in realtà permesso di alterare il semaforo), per
 quanto riguarda gli altri campi invece:
 \begin{itemize*}
 \item il campo \var{sem\_nsems}, che esprime il numero di semafori
   nell'insieme, viene inizializzato al valore di \param{nsems}.
-\item il campo \var{sem\_ctime}, che esprime il tempo di creazione
+\item il campo \var{sem\_ctime}, che esprime il tempo di ultimo cambiamento
   dell'insieme, viene inizializzato al tempo corrente.
 \item il campo \var{sem\_otime}, che esprime il tempo dell'ultima operazione
   effettuata, viene inizializzato a zero.
 \end{itemize*}
 
   dell'insieme, viene inizializzato al tempo corrente.
 \item il campo \var{sem\_otime}, che esprime il tempo dell'ultima operazione
   effettuata, viene inizializzato a zero.
 \end{itemize*}
 
-Ciascun semaforo dell'insieme è realizzato come una struttura di tipo
-\struct{sem} che ne contiene i dati essenziali, la sua definizione\footnote{si
-  è riportata la definizione originaria del kernel 1.0, che contiene la prima
-  realizzazione del \textit{SysV-IPC} in Linux. In realtà questa struttura
-  ormai è ridotta ai soli due primi membri, e gli altri vengono calcolati
-  dinamicamente. La si è utilizzata a scopo di esempio, perché indica tutti i
-  valori associati ad un semaforo, restituiti dalle funzioni di controllo, e
-  citati dalle pagine di manuale.} è riportata in fig.~\ref{fig:ipc_sem}.
-Questa struttura, non è accessibile in user space, ma i valori in essa
-specificati possono essere letti in maniera indiretta, attraverso l'uso delle
-funzioni di controllo.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/sem.h}
   \end{minipage} 
   \normalsize 
     \includestruct{listati/sem.h}
   \end{minipage} 
   \normalsize 
@@ -1978,16 +1986,33 @@ funzioni di controllo.
   \label{fig:ipc_sem}
 \end{figure}
 
   \label{fig:ipc_sem}
 \end{figure}
 
-I dati mantenuti nella struttura, ed elencati in fig.~\ref{fig:ipc_sem},
-indicano rispettivamente:
-\begin{description*}
+Ciascun semaforo dell'insieme è realizzato come una struttura di tipo
+\struct{sem} che ne contiene i dati essenziali, la cui definizione è riportata
+in fig.~\ref{fig:ipc_sem}.\footnote{in realtà in fig~\ref{fig:ipc_sem} si è
+  riportata la definizione originaria del kernel 1.0, che contiene la prima
+  realizzazione del \textit{SysV-IPC} in Linux; ormai questa struttura è
+  ridotta ai soli due primi membri, e gli altri vengono calcolati
+  dinamicamente, la si è usata solo a scopo di esempio, perché indica tutti i
+  valori associati ad un semaforo, restituiti dalle funzioni di controllo, e
+  citati dalle pagine di manuale.}  Questa struttura non è accessibile
+direttamente dallo \textit{user space}, ma i valori in essa specificati
+possono essere letti in maniera indiretta, attraverso l'uso delle opportune
+funzioni di controllo.  I dati mantenuti nella struttura, ed elencati in
+fig.~\ref{fig:ipc_sem}, indicano rispettivamente:
+\begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}}
 \item[\var{semval}] il valore numerico del semaforo.
 \item[\var{sempid}] il \ids{PID} dell'ultimo processo che ha eseguito una
   operazione sul semaforo.
 \item[\var{semncnt}] il numero di processi in attesa che esso venga
   incrementato.
 \item[\var{semzcnt}] il numero di processi in attesa che esso si annulli.
 \item[\var{semval}] il valore numerico del semaforo.
 \item[\var{sempid}] il \ids{PID} dell'ultimo processo che ha eseguito una
   operazione sul semaforo.
 \item[\var{semncnt}] il numero di processi in attesa che esso venga
   incrementato.
 \item[\var{semzcnt}] il numero di processi in attesa che esso si annulli.
-\end{description*}
+\end{basedescript}
+
+Come per le code di messaggi anche per gli insiemi di semafori esistono una
+serie di limiti, i cui valori sono associati ad altrettante costanti, che si
+sono riportate in tab.~\ref{tab:ipc_sem_limits}. Alcuni di questi limiti sono
+al solito accessibili e modificabili attraverso \func{sysctl} o scrivendo
+direttamente nel file \sysctlfile{kernel/sem}.
 
 \begin{table}[htb]
   \footnotesize
 
 \begin{table}[htb]
   \footnotesize
@@ -2015,51 +2040,49 @@ indicano rispettivamente:
   \label{tab:ipc_sem_limits}
 \end{table}
 
   \label{tab:ipc_sem_limits}
 \end{table}
 
-Come per le code di messaggi anche per gli insiemi di semafori esistono una
-serie di limiti, i cui valori sono associati ad altrettante costanti, che si
-sono riportate in tab.~\ref{tab:ipc_sem_limits}. Alcuni di questi limiti sono
-al solito accessibili e modificabili attraverso \func{sysctl} o scrivendo
-direttamente nel file \sysctlfile{kernel/sem}.
 
 
-La funzione che permette di effettuare le varie operazioni di controllo sui
-semafori (fra le quali, come accennato, è impropriamente compresa anche la
-loro inizializzazione) è \funcd{semctl}; il suo prototipo è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/sem.h} 
-  
-  \funcdecl{int semctl(int semid, int semnum, int cmd)}
-  \funcdecl{int semctl(int semid, int semnum, int cmd, union semun arg)}
-  
-  Esegue le operazioni di controllo su un semaforo o un insieme di semafori.
-  
-  \bodydesc{La funzione restituisce in caso di successo un valore positivo
-    quanto usata con tre argomenti ed un valore nullo quando usata con
-    quattro. In caso di errore restituisce -1, ed \var{errno} assumerà uno dei
-    valori:
-    \begin{errlist}
-    \item[\errcode{EACCES}] il processo non ha i privilegi per eseguire
-      l'operazione richiesta.
+La funzione di sistema che permette di effettuare le varie operazioni di
+controllo sui semafori fra le quali, come accennato, è impropriamente compresa
+anche la loro inizializzazione, è \funcd{semctl}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semctl(int semid, int semnum, int cmd)}
+\fdecl{int semctl(int semid, int semnum, int cmd, union semun arg)}
+\fdesc{Esegue le operazioni di controllo su un semaforo o un insieme di
+  semafori.}
+}
+
+{La funzione ritorna in caso di successo un valore positivo quanto usata con
+  tre argomenti ed un valore nullo quando usata con quattro e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EACCES}] i permessi assegnati al semaforo non consentono
+    l'operazione di lettura o scrittura richiesta e non si hanno i privilegi
+    di amministratore.
     \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
     \item[\errcode{EPERM}] si è richiesto \const{IPC\_SET} o \const{IPC\_RMID}
     \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
     \item[\errcode{EPERM}] si è richiesto \const{IPC\_SET} o \const{IPC\_RMID}
-      ma il processo non ha privilegi sufficienti ad eseguire l'operazione.
+      ma il processo non è né il creatore né il proprietario del semaforo e
+      non ha i privilegi di amministratore.
     \item[\errcode{ERANGE}] si è richiesto \const{SETALL} \const{SETVAL} ma il
       valore a cui si vuole impostare il semaforo è minore di zero o maggiore
       di \const{SEMVMX}.
     \item[\errcode{ERANGE}] si è richiesto \const{SETALL} \const{SETVAL} ma il
       valore a cui si vuole impostare il semaforo è minore di zero o maggiore
       di \const{SEMVMX}.
-  \end{errlist}
-  ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
-}
-\end{functions}
+   \end{errlist}
+   ed inoltre \errval{EFAULT} ed \errval{EINVAL} nel loro significato
+   generico.}
+\end{funcproto}
 
 La funzione può avere tre o quattro argomenti, a seconda dell'operazione
 specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 \param{semid} o sul singolo semaforo di un insieme, specificato da
 \param{semnum}. 
 
 
 La funzione può avere tre o quattro argomenti, a seconda dell'operazione
 specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 \param{semid} o sul singolo semaforo di un insieme, specificato da
 \param{semnum}. 
 
+
 \begin{figure}[!htb]
   \footnotesize \centering
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
     \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
@@ -2071,33 +2094,41 @@ specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 
 Qualora la funzione operi con quattro argomenti \param{arg} è un argomento
 generico, che conterrà un dato diverso a seconda dell'azione richiesta; per
 
 Qualora la funzione operi con quattro argomenti \param{arg} è un argomento
 generico, che conterrà un dato diverso a seconda dell'azione richiesta; per
-unificare l'argomento esso deve essere passato come una \struct{semun}, la cui
-definizione, con i possibili valori che può assumere, è riportata in
-fig.~\ref{fig:ipc_semun}.
+unificare detto argomento esso deve essere passato come una unione
+\struct{semun}, la cui definizione, con i possibili valori che può assumere, è
+riportata in fig.~\ref{fig:ipc_semun}.
+
+Nelle versioni più vecchie delle \acr{glibc} questa unione veniva definita in
+\file{sys/sem.h}, ma nelle versioni più recenti questo non avviene più in
+quanto lo standard POSIX.1-2001 richiede che sia sempre definita a cura del
+chiamante. In questa seconda evenienza le \acr{glibc} definiscono però la
+macro \macro{\_SEM\_SEMUN\_UNDEFINED} che può essere usata per controllare la
+situazione.
 
 Come già accennato sia il comportamento della funzione che il numero di
 argomenti con cui deve essere invocata dipendono dal valore dell'argomento
 
 Come già accennato sia il comportamento della funzione che il numero di
 argomenti con cui deve essere invocata dipendono dal valore dell'argomento
-\param{cmd}, che specifica l'azione da intraprendere; i valori validi (che
-cioè non causano un errore di \errcode{EINVAL}) per questo argomento sono i
-seguenti:
-\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiando il
-  contenuto della relativa struttura \struct{semid\_ds} all'indirizzo
-  specificato con \var{arg.buf}. Occorre avere il permesso di lettura.
+\param{cmd}, che specifica l'azione da intraprendere. Per questo argomento i
+valori validi, quelli cioè che non causano un errore di \errcode{EINVAL}, sono
+seguenti:
+\begin{basedescript}{\desclabelwidth{1.6cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiandone i
+  valori nella struttura \struct{semid\_ds} posta all'indirizzo specificato
+  con \var{arg.buf}. Occorre avere il permesso di lettura.
   L'argomento \param{semnum} viene ignorato.
 \item[\const{IPC\_RMID}] Rimuove l'insieme di semafori e le relative strutture
   L'argomento \param{semnum} viene ignorato.
 \item[\const{IPC\_RMID}] Rimuove l'insieme di semafori e le relative strutture
-  dati, con effetto immediato. Tutti i processi che erano stato di
-  \textit{sleep} vengono svegliati, ritornando con un errore di
-  \errcode{EIDRM}.  L'\ids{UID} effettivo del processo deve corrispondere o al
-  creatore o al proprietario dell'insieme, o all'amministratore. L'argomento
+  dati, con effetto immediato. Tutti i processi che erano bloccati in attesa
+  vengono svegliati, ritornando con un errore di \errcode{EIDRM}.  L'\ids{UID}
+  effettivo del processo deve corrispondere o al creatore o al proprietario
+  dell'insieme, o all'amministratore. L'argomento
   \param{semnum} viene ignorato.
 \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
   dell'insieme. I valori devono essere passati in una struttura
   \param{semnum} viene ignorato.
 \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
   dell'insieme. I valori devono essere passati in una struttura
-  \struct{semid\_ds} puntata da \param{arg.buf} di cui saranno usati soltanto i
-  campi \var{sem\_perm.uid}, \var{sem\_perm.gid} e i nove bit meno
-  significativi di \var{sem\_perm.mode}. L'\ids{UID} effettivo del processo deve
-  corrispondere o al creatore o al proprietario dell'insieme, o
-  all'amministratore.  L'argomento \param{semnum} viene ignorato.
+  \struct{semid\_ds} puntata da \param{arg.buf} di cui saranno usati soltanto
+  i campi \var{sem\_perm.uid}, \var{sem\_perm.gid} e i nove bit meno
+  significativi di \var{sem\_perm.mode}. La funziona aggiorna anche il campo
+  \var{sem\_ctime}.  L'\ids{UID} effettivo del processo deve corrispondere o
+  al creatore o al proprietario dell'insieme, o all'amministratore.
+  L'argomento \param{semnum} viene ignorato.
 \item[\const{GETALL}] Restituisce il valore corrente di ciascun semaforo
   dell'insieme (corrispondente al campo \var{semval} di \struct{sem}) nel
   vettore indicato da \param{arg.array}. Occorre avere il permesso di lettura.
 \item[\const{GETALL}] Restituisce il valore corrente di ciascun semaforo
   dell'insieme (corrispondente al campo \var{semval} di \struct{sem}) nel
   vettore indicato da \param{arg.array}. Occorre avere il permesso di lettura.
@@ -2105,32 +2136,37 @@ seguenti:
 \item[\const{GETNCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il semaforo \param{semnum} dell'insieme
   \param{semid} venga incrementato (corrispondente al campo \var{semncnt} di
 \item[\const{GETNCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il semaforo \param{semnum} dell'insieme
   \param{semid} venga incrementato (corrispondente al campo \var{semncnt} di
-  \struct{sem}); va invocata con tre argomenti.  Occorre avere il permesso di
+  \struct{sem}). Va invocata con tre argomenti.  Occorre avere il permesso di
   lettura.
 \item[\const{GETPID}] Restituisce come valore di ritorno della funzione il
   \ids{PID} dell'ultimo processo che ha compiuto una operazione sul semaforo
   \param{semnum} dell'insieme \param{semid} (corrispondente al campo
   lettura.
 \item[\const{GETPID}] Restituisce come valore di ritorno della funzione il
   \ids{PID} dell'ultimo processo che ha compiuto una operazione sul semaforo
   \param{semnum} dell'insieme \param{semid} (corrispondente al campo
-  \var{sempid} di \struct{sem}); va invocata con tre argomenti.  Occorre avere
+  \var{sempid} di \struct{sem}). Va invocata con tre argomenti.  Occorre avere
   il permesso di lettura.
 \item[\const{GETVAL}] Restituisce come valore di ritorno della funzione il il
   valore corrente del semaforo \param{semnum} dell'insieme \param{semid}
   il permesso di lettura.
 \item[\const{GETVAL}] Restituisce come valore di ritorno della funzione il il
   valore corrente del semaforo \param{semnum} dell'insieme \param{semid}
-  (corrispondente al campo \var{semval} di \struct{sem}); va invocata con tre
+  (corrispondente al campo \var{semval} di \struct{sem}). Va invocata con tre
   argomenti.  Occorre avere il permesso di lettura.
 \item[\const{GETZCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il valore del semaforo \param{semnum}
   dell'insieme \param{semid} diventi nullo (corrispondente al campo
   argomenti.  Occorre avere il permesso di lettura.
 \item[\const{GETZCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il valore del semaforo \param{semnum}
   dell'insieme \param{semid} diventi nullo (corrispondente al campo
-  \var{semncnt} di \struct{sem}); va invocata con tre argomenti.  Occorre avere
-  il permesso di lettura.
+  \var{semncnt} di \struct{sem}). Va invocata con tre argomenti.  Occorre
+  avere il permesso di lettura.
 \item[\const{SETALL}] Inizializza il valore di tutti i semafori dell'insieme,
   aggiornando il campo \var{sem\_ctime} di \struct{semid\_ds}. I valori devono
   essere passati nel vettore indicato da \param{arg.array}.  Si devono avere i
 \item[\const{SETALL}] Inizializza il valore di tutti i semafori dell'insieme,
   aggiornando il campo \var{sem\_ctime} di \struct{semid\_ds}. I valori devono
   essere passati nel vettore indicato da \param{arg.array}.  Si devono avere i
-  privilegi di scrittura sul semaforo.  L'argomento \param{semnum} viene
-  ignorato.
+  privilegi di scrittura.  L'argomento \param{semnum} viene ignorato.
 \item[\const{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato
   dall'argomento \param{arg.val}, aggiornando il campo \var{sem\_ctime} di
 \item[\const{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato
   dall'argomento \param{arg.val}, aggiornando il campo \var{sem\_ctime} di
-  \struct{semid\_ds}.  Si devono avere i privilegi di scrittura sul semaforo.
+  \struct{semid\_ds}.  Si devono avere i privilegi di scrittura.
 \end{basedescript}
 
 \end{basedescript}
 
+Come per \func{msgctl} esistono tre ulteriori valori, \const{IPC\_INFO},
+\const{SEM\_STAT} e \const{SEM\_INFO}, specifici di Linux e fuori da ogni
+standard, creati specificamente ad uso del comando \cmd{ipcs}. Dato che anche
+questi potranno essere modificati o rimossi, non devono essere utilizzati e
+pertanto non li tratteremo.
+
 Quando si imposta il valore di un semaforo (sia che lo si faccia per tutto
 l'insieme con \const{SETALL}, che per un solo semaforo con \const{SETVAL}), i
 processi in attesa su di esso reagiscono di conseguenza al cambiamento di
 Quando si imposta il valore di un semaforo (sia che lo si faccia per tutto
 l'insieme con \const{SETALL}, che per un solo semaforo con \const{SETVAL}), i
 processi in attesa su di esso reagiscono di conseguenza al cambiamento di
@@ -2164,52 +2200,92 @@ colonna della tabella.
 
 Le operazioni ordinarie sui semafori, come l'acquisizione o il rilascio degli
 stessi (in sostanza tutte quelle non comprese nell'uso di \func{semctl})
 
 Le operazioni ordinarie sui semafori, come l'acquisizione o il rilascio degli
 stessi (in sostanza tutte quelle non comprese nell'uso di \func{semctl})
-vengono effettuate con la funzione \funcd{semop}, il cui prototipo è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/sem.h} 
-  
-  \funcdecl{int semop(int semid, struct sembuf *sops, unsigned nsops)}
-  
-  Esegue le operazioni ordinarie su un semaforo o un insieme di semafori.
-  
-  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore, nel qual caso \var{errno} assumerà uno dei valori:
-    \begin{errlist}
-    \item[\errcode{EACCES}] il processo non ha i privilegi per eseguire
-      l'operazione richiesta.
-    \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
-    \item[\errcode{ENOMEM}] si è richiesto un \const{SEM\_UNDO} ma il sistema
-      non ha le risorse per allocare la struttura di ripristino.
+vengono effettuate con la funzione di sistema \funcd{semop}, il cui prototipo
+è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semop(int semid, struct sembuf *sops, unsigned nsops)}
+\fdesc{Esegue operazioni ordinarie su un semaforo o un insieme di semafori.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+    \item[\errcode{E2BIG}] l'argomento \param{nsops} è maggiore del numero
+      massimo di operazioni \const{SEMOPM}.
+    \item[\errcode{EACCES}] il processo non ha i permessi per eseguire
+      l'operazione richiesta e non ha i privilegi di amministratore.
     \item[\errcode{EAGAIN}] un'operazione comporterebbe il blocco del processo,
       ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg}.
     \item[\errcode{EAGAIN}] un'operazione comporterebbe il blocco del processo,
       ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg}.
+    \item[\errcode{EFBIG}] il valore del campo \var{sem\_num} è negativo o
+      maggiore o uguale al numero di semafori dell'insieme.
+    \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
     \item[\errcode{EINTR}] la funzione, bloccata in attesa dell'esecuzione
       dell'operazione, viene interrotta da un segnale.
     \item[\errcode{EINTR}] la funzione, bloccata in attesa dell'esecuzione
       dell'operazione, viene interrotta da un segnale.
-    \item[\errcode{E2BIG}] l'argomento \param{nsops} è maggiore del numero
-      massimo di operazioni \const{SEMOPM}.
+    \item[\errcode{ENOMEM}] si è richiesto un \const{SEM\_UNDO} ma il sistema
+      non ha le risorse per allocare la struttura di ripristino.
     \item[\errcode{ERANGE}] per alcune operazioni il valore risultante del
       semaforo viene a superare il limite massimo \const{SEMVMX}.
   \end{errlist}
     \item[\errcode{ERANGE}] per alcune operazioni il valore risultante del
       semaforo viene a superare il limite massimo \const{SEMVMX}.
   \end{errlist}
-  ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
-}
-\end{functions}
-
-
-%TODO manca semtimedop, trattare qui, referenziata in
-%sez.~\ref{sec:sig_gen_beha}.
+  ed inoltre \errval{EFAULT} ed \errval{EINVAL} nel loro significato
+  generico.}
+\end{funcproto}
 
 La funzione permette di eseguire operazioni multiple sui singoli semafori di
 un insieme. La funzione richiede come primo argomento l'identificatore
 
 La funzione permette di eseguire operazioni multiple sui singoli semafori di
 un insieme. La funzione richiede come primo argomento l'identificatore
-\param{semid} dell'insieme su cui si vuole operare. Il numero di operazioni da
+\param{semid} dell'insieme su cui si vuole operare, il numero di operazioni da
 effettuare viene specificato con l'argomento \param{nsop}, mentre il loro
 contenuto viene passato con un puntatore ad un vettore di strutture
 \struct{sembuf} nell'argomento \param{sops}. Le operazioni richieste vengono
 effettuare viene specificato con l'argomento \param{nsop}, mentre il loro
 contenuto viene passato con un puntatore ad un vettore di strutture
 \struct{sembuf} nell'argomento \param{sops}. Le operazioni richieste vengono
-effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante.
+effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante,
+ed in tal caso vengono eseguite nella sequenza passata nel
+vettore \param{sops}.
+
+Con lo standard POSIX.1-2001 è stata introdotta una variante di \func{semop}
+che consente di specificare anche un tempo massimo di attesa. La nuova
+funzione di sistema, disponibile a partire dal kernel 2.4.22 e dalle
+\acr{glibc} 2.3.3, ed utilizzabile solo dopo aver definito la macro
+\macro{\_GNU\_SOURCE}, è \funcd{semtimedop}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
+                      struct timespec *timeout)}
+\fdesc{Esegue operazioni ordinarie su un semaforo o un insieme di semafori.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+  \item[\errcode{EAGAIN}] l'operazione comporterebbe il blocco del processo,
+    ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg} oppure si è
+    atteso oltre quanto indicato da \param{timeout}.
+  \end{errlist}
+  e gli altri valori già visti per \func{semop}, con lo stesso significato.}
+\end{funcproto}
+
+Rispetto a \func{semop} la funzione consente di specificare un tempo massimo
+di attesa, indicato con una struttura \struct{timespec} (vedi
+fig.~\ref{fig:sys_timespec_struct}), per le operazioni che verrebbero
+bloccate. Alla scadenza di detto tempo la funzione ritorna comunque con un
+errore di \errval{EAGAIN} senza che nessuna delle operazioni richieste venga
+eseguita. 
+
+Si tenga presente che la precisione della temporizzazione è comunque limitata
+dalla risoluzione dell'orologio di sistema, per cui il tempo di attesa verrà
+arrotondato per eccesso. In caso si passi un valore \val{NULL}
+per \param{timeout} il comportamento di \func{semtimedop} è identico a quello
+di \func{semop}.
+
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/sembuf.h}
   \end{minipage} 
   \normalsize 
     \includestruct{listati/sembuf.h}
   \end{minipage} 
   \normalsize 
@@ -2218,65 +2294,73 @@ effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante.
   \label{fig:ipc_sembuf}
 \end{figure}
 
   \label{fig:ipc_sembuf}
 \end{figure}
 
-Il contenuto di ciascuna operazione deve essere specificato attraverso una
-opportuna struttura \struct{sembuf} (la cui definizione è riportata in
+Come indicato il contenuto di ciascuna operazione deve essere specificato
+attraverso una struttura \struct{sembuf} (la cui definizione è riportata in
 fig.~\ref{fig:ipc_sembuf}) che il programma chiamante deve avere cura di
 allocare in un opportuno vettore. La struttura permette di indicare il
 fig.~\ref{fig:ipc_sembuf}) che il programma chiamante deve avere cura di
 allocare in un opportuno vettore. La struttura permette di indicare il
-semaforo su cui operare, il tipo di operazione, ed un flag di controllo.
+semaforo su cui operare, il tipo di operazione, ed un flag di controllo.  
+
 Il campo \var{sem\_num} serve per indicare a quale semaforo dell'insieme fa
 Il campo \var{sem\_num} serve per indicare a quale semaforo dell'insieme fa
-riferimento l'operazione; si ricordi che i semafori sono numerati come in un
-vettore, per cui il primo semaforo corrisponde ad un valore nullo di
-\var{sem\_num}.
+riferimento l'operazione. Si ricordi che i semafori sono numerati come gli
+elementi di un vettore, per cui il primo semaforo di un insieme corrisponde ad
+un valore nullo di \var{sem\_num}.
 
 Il campo \var{sem\_flg} è un flag, mantenuto come maschera binaria, per il
 quale possono essere impostati i due valori \const{IPC\_NOWAIT} e
 
 Il campo \var{sem\_flg} è un flag, mantenuto come maschera binaria, per il
 quale possono essere impostati i due valori \const{IPC\_NOWAIT} e
-\const{SEM\_UNDO}.  Impostando \const{IPC\_NOWAIT} si fa si che, invece di
-bloccarsi (in tutti quei casi in cui l'esecuzione di una operazione richiede
-che il processo vada in stato di \textit{sleep}), \func{semop} ritorni
-immediatamente con un errore di \errcode{EAGAIN}.  Impostando \const{SEM\_UNDO}
-si richiede invece che l'operazione venga registrata in modo che il valore del
-semaforo possa essere ripristinato all'uscita del processo.
-
-Infine \var{sem\_op} è il campo che controlla l'operazione che viene eseguita
-e determina il comportamento della chiamata a \func{semop}; tre sono i casi
-possibili:
+\const{SEM\_UNDO}.  Impostando \const{IPC\_NOWAIT} si fa si che in tutti quei
+casi in cui l'esecuzione di una operazione richiederebbe di porre il processo
+vada nello stato di \textit{sleep}, invece di bloccarsi \func{semop} ritorni
+immediatamente (abortendo così le eventuali operazioni restanti) con un errore
+di \errcode{EAGAIN}.  Impostando \const{SEM\_UNDO} si richiede invece che
+l'operazione in questione venga registrata, in modo che il valore del semaforo
+possa essere ripristinato all'uscita del processo.
+
+Infine \var{sem\_op} è il campo che controlla qual'è l'operazione che viene
+eseguita e determina in generale il comportamento della chiamata a
+\func{semop}. I casi possibili per il valore di questo campo sono tre:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
 \begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\var{sem\_op}$>0$] In questo caso il valore di \var{sem\_op} viene
-  aggiunto al valore corrente di \var{semval}. La funzione ritorna
-  immediatamente (con un errore di \errcode{ERANGE} qualora si sia superato il
-  limite \const{SEMVMX}) ed il processo non viene bloccato in nessun caso.
-  Specificando \const{SEM\_UNDO} si aggiorna il contatore per il ripristino
-  del valore del semaforo. Al processo chiamante è richiesto il privilegio di
-  alterazione (scrittura) sull'insieme di semafori.
+\item[\var{sem\_op} $>0$] In questo caso il valore viene aggiunto al valore
+  corrente di \var{semval} per il semaforo indicato. Questa operazione non
+  causa mai un blocco del processo, ed eventualmente \func{semop} ritorna
+  immediatamente con un errore di \errcode{ERANGE} qualora si sia superato il
+  limite \const{SEMVMX}. Se l'operazione ha successo si passa immediatamente
+  alla successiva.  Specificando \const{SEM\_UNDO} si aggiorna il contatore
+  per il ripristino del valore del semaforo. Al processo chiamante è richiesto
+  il privilegio di alterazione (scrittura) sull'insieme di semafori.
   
   
-\item[\var{sem\_op}$=0$] Nel caso \var{semval} sia zero l'esecuzione procede
-  immediatamente. Se \var{semval} è diverso da zero il comportamento è
-  controllato da \var{sem\_flg}, se è stato impostato \const{IPC\_NOWAIT} la
-  funzione ritorna con un errore di \errcode{EAGAIN}, altrimenti viene
-  incrementato \var{semzcnt} di uno ed il processo resta in stato di
-  \textit{sleep} fintanto che non si ha una delle condizioni seguenti:
+\item[\var{sem\_op} $=0$] Nel caso \var{semval} sia zero l'operazione ha
+  successo immediato, e o si passa alla successiva o \func{semop} ritorna con
+  successo se questa era l'ultima. Se \var{semval} è diverso da zero il
+  comportamento è controllato da \var{sem\_flg}, se è stato impostato
+  \const{IPC\_NOWAIT} \func{semop} ritorna immediatamente abortendo tutte le
+  operazioni con un errore di \errcode{EAGAIN}, altrimenti viene incrementato
+  \var{semzcnt} di uno ed il processo viene bloccato fintanto che non si
+  verifica una delle condizioni seguenti:
   \begin{itemize*}
   \item \var{semval} diventa zero, nel qual caso \var{semzcnt} viene
   \begin{itemize*}
   \item \var{semval} diventa zero, nel qual caso \var{semzcnt} viene
-    decrementato di uno.
-  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop} ritorna
-    un errore di \errcode{EIDRM}.
+    decrementato di uno, l'operazione ha successo e si passa alla successiva,
+    oppure \func{semop} ritorna con successo se questa era l'ultima.
+  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop}
+    ritorna abortendo tutte le operazioni con un errore di \errcode{EIDRM}.
   \item il processo chiamante riceve un segnale, nel qual caso \var{semzcnt}
   \item il processo chiamante riceve un segnale, nel qual caso \var{semzcnt}
-    viene decrementato di uno e \func{semop} ritorna un errore di
-    \errcode{EINTR}.
+    viene decrementato di uno e \func{semop} ritorna abortendo tutte le
+    operazioni con un errore di \errcode{EINTR}.
   \end{itemize*}
   \end{itemize*}
-  Al processo chiamante è richiesto il privilegio di lettura dell'insieme dei
-  semafori.
+  Al processo chiamante è richiesto soltanto il privilegio di lettura
+  dell'insieme dei semafori.
   
   
-\item[\var{sem\_op}$<0$] Nel caso in cui \var{semval} è maggiore o uguale del
+\item[\var{sem\_op} $<0$] Nel caso in cui \var{semval} è maggiore o uguale del
   valore assoluto di \var{sem\_op} (se cioè la somma dei due valori resta
   valore assoluto di \var{sem\_op} (se cioè la somma dei due valori resta
-  positiva o nulla) i valori vengono sommati e la funzione ritorna
-  immediatamente; qualora si sia impostato \const{SEM\_UNDO} viene anche
+  positiva o nulla) i valori vengono sommati e l'operazione ha successo e si
+  passa alla successiva, oppure \func{semop} ritorna con successo se questa
+  era l'ultima. Qualora si sia impostato \const{SEM\_UNDO} viene anche
   aggiornato il contatore per il ripristino del valore del semaforo. In caso
   contrario (quando cioè la somma darebbe luogo ad un valore di \var{semval}
   aggiornato il contatore per il ripristino del valore del semaforo. In caso
   contrario (quando cioè la somma darebbe luogo ad un valore di \var{semval}
-  negativo) se si è impostato \const{IPC\_NOWAIT} la funzione ritorna con un
-  errore di \errcode{EAGAIN}, altrimenti viene incrementato di uno
-  \var{semncnt} ed il processo resta in stato di \textit{sleep} fintanto che
-  non si ha una delle condizioni seguenti:
+  negativo) se si è impostato \const{IPC\_NOWAIT} \func{semop} ritorna
+  immediatamente abortendo tutte le operazioni con un errore di
+  \errcode{EAGAIN}, altrimenti viene incrementato di uno \var{semncnt} ed il
+  processo resta in stato di \textit{sleep} fintanto che non si ha una delle
+  condizioni seguenti:
   \begin{itemize*}
   \item \var{semval} diventa maggiore o uguale del valore assoluto di
     \var{sem\_op}, nel qual caso \var{semncnt} viene decrementato di uno, il
   \begin{itemize*}
   \item \var{semval} diventa maggiore o uguale del valore assoluto di
     \var{sem\_op}, nel qual caso \var{semncnt} viene decrementato di uno, il
@@ -2284,39 +2368,46 @@ possibili:
     impostato \const{SEM\_UNDO} viene aggiornato il contatore per il
     ripristino del valore del semaforo.
   \item l'insieme di semafori viene rimosso, nel qual caso \func{semop}
     impostato \const{SEM\_UNDO} viene aggiornato il contatore per il
     ripristino del valore del semaforo.
   \item l'insieme di semafori viene rimosso, nel qual caso \func{semop}
-    ritorna un errore di \errcode{EIDRM}.
+    ritorna abortendo tutte le operazioni con un errore di \errcode{EIDRM}.
   \item il processo chiamante riceve un segnale, nel qual caso \var{semncnt}
   \item il processo chiamante riceve un segnale, nel qual caso \var{semncnt}
-    viene decrementato di uno e \func{semop} ritorna un errore di
-    \errcode{EINTR}.
+    viene decrementato di uno e \func{semop} ritorna abortendo tutte le
+    operazioni con un errore di \errcode{EINTR}.
   \end{itemize*}    
   Al processo chiamante è richiesto il privilegio di alterazione (scrittura)
   sull'insieme di semafori.
 \end{basedescript}
 
   \end{itemize*}    
   Al processo chiamante è richiesto il privilegio di alterazione (scrittura)
   sull'insieme di semafori.
 \end{basedescript}
 
-In caso di successo della funzione viene aggiornato il campo \var{sempid} per
-ogni semaforo modificato al valore del \ids{PID} del processo chiamante;
-inoltre vengono pure aggiornati al tempo corrente i campi \var{sem\_otime} e
-\var{sem\_ctime}.
+Qualora si sia usato \func{semtimedop} alle condizioni di errore precedenti si
+aggiunge anche quella di scadenza del tempo di attesa indicato
+con \param{timeout} che farà abortire la funzione, qualora resti bloccata
+troppo a lungo nell'esecuzione delle operazioni richieste, con un errore di
+\errcode{EAGAIN}.
+
+In caso di successo (sia per \func{semop} che per \func{semtimedop}) per ogni
+semaforo modificato verrà aggiornato il campo \var{sempid} al valore del
+\ids{PID} del processo chiamante; inoltre verranno pure aggiornati al tempo
+corrente i campi \var{sem\_otime} e \var{sem\_ctime}.
 
 Dato che, come già accennato in precedenza, in caso di uscita inaspettata i
 
 Dato che, come già accennato in precedenza, in caso di uscita inaspettata i
-semafori possono restare occupati, abbiamo visto come \func{semop} permetta di
-attivare un meccanismo di ripristino attraverso l'uso del flag
-\const{SEM\_UNDO}. Il meccanismo è implementato tramite una apposita struttura
-\kstruct{sem\_undo}, associata ad ogni processo per ciascun semaforo che esso
-ha modificato; all'uscita i semafori modificati vengono ripristinati, e le
-strutture disallocate.  Per mantenere coerente il comportamento queste
-strutture non vengono ereditate attraverso una \func{fork} (altrimenti si
-avrebbe un doppio ripristino), mentre passano inalterate nell'esecuzione di
-una \func{exec} (altrimenti non si avrebbe ripristino).
+semafori possono restare occupati, abbiamo visto come \func{semop} (e
+\func{semtimedop}) permetta di attivare un meccanismo di ripristino attraverso
+l'uso del flag \const{SEM\_UNDO}. Il meccanismo è implementato tramite una
+apposita struttura \kstruct{sem\_undo}, associata ad ogni processo per ciascun
+semaforo che esso ha modificato; all'uscita i semafori modificati vengono
+ripristinati, e le strutture disallocate.  Per mantenere coerente il
+comportamento queste strutture non vengono ereditate attraverso una
+\func{fork} (altrimenti si avrebbe un doppio ripristino), mentre passano
+inalterate nell'esecuzione di una \func{exec} (altrimenti non si avrebbe
+ripristino).
 
 Tutto questo però ha un problema di fondo. Per capire di cosa si tratta
 occorre fare riferimento all'implementazione usata in Linux, che è riportata
 in maniera semplificata nello schema di fig.~\ref{fig:ipc_sem_schema}.  Si è
 presa come riferimento l'architettura usata fino al kernel 2.2.x che è più
 
 Tutto questo però ha un problema di fondo. Per capire di cosa si tratta
 occorre fare riferimento all'implementazione usata in Linux, che è riportata
 in maniera semplificata nello schema di fig.~\ref{fig:ipc_sem_schema}.  Si è
 presa come riferimento l'architettura usata fino al kernel 2.2.x che è più
-semplice (ed illustrata in dettaglio in \cite{tlk}); nel kernel 2.4.x la
+semplice (ed illustrata in dettaglio in \cite{tlk}). Nel kernel 2.4.x la
 struttura del \textit{SysV-IPC} è stata modificata, ma le definizioni relative
 struttura del \textit{SysV-IPC} è stata modificata, ma le definizioni relative
-a queste strutture restano per compatibilità.\footnote{in particolare con le
-  vecchie versioni delle librerie del C, come le libc5.}
+a queste strutture restano per compatibilità (in particolare con le vecchie
+versioni delle librerie del C, come le \acr{libc5}).
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=13cm]{img/semtruct}
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=13cm]{img/semtruct}
@@ -2328,16 +2419,15 @@ Alla creazione di un nuovo insieme viene allocata una nuova strutture
 \struct{semid\_ds} ed il relativo vettore di strutture \struct{sem}. Quando si
 richiede una operazione viene anzitutto verificato che tutte le operazioni
 possono avere successo; se una di esse comporta il blocco del processo il
 \struct{semid\_ds} ed il relativo vettore di strutture \struct{sem}. Quando si
 richiede una operazione viene anzitutto verificato che tutte le operazioni
 possono avere successo; se una di esse comporta il blocco del processo il
-kernel crea una struttura \kstruct{sem\_queue} che viene aggiunta in fondo alla
-coda di attesa associata a ciascun insieme di semafori\footnote{che viene
-  referenziata tramite i campi \var{sem\_pending} e \var{sem\_pending\_last}
-  di \struct{semid\_ds}.}. 
-
-Nella struttura viene memorizzato il riferimento alle operazioni richieste
-(nel campo \var{sops}, che è un puntatore ad una struttura \struct{sembuf}) e
-al processo corrente (nel campo \var{sleeper}) poi quest'ultimo viene messo
-stato di attesa e viene invocato lo \itindex{scheduler} scheduler per passare
-all'esecuzione di un altro processo.
+kernel crea una struttura \kstruct{sem\_queue} che viene aggiunta in fondo
+alla coda di attesa associata a ciascun insieme di semafori, che viene
+referenziata tramite i campi \var{sem\_pending} e \var{sem\_pending\_last} di
+\struct{semid\_ds}.  Nella struttura viene memorizzato il riferimento alle
+operazioni richieste (nel campo \var{sops}, che è un puntatore ad una
+struttura \struct{sembuf}) e al processo corrente (nel campo \var{sleeper})
+poi quest'ultimo viene messo stato di attesa e viene invocato lo
+\itindex{scheduler} \textit{scheduler} per passare all'esecuzione di un altro
+processo.
 
 Se invece tutte le operazioni possono avere successo queste vengono eseguite
 immediatamente, dopo di che il kernel esegue una scansione della coda di
 
 Se invece tutte le operazioni possono avere successo queste vengono eseguite
 immediatamente, dopo di che il kernel esegue una scansione della coda di
@@ -2353,21 +2443,18 @@ contiene (nel vettore puntato dal campo \var{semadj}) un valore di
 aggiustamento per ogni semaforo cui viene sommato l'opposto del valore usato
 per l'operazione.
 
 aggiustamento per ogni semaforo cui viene sommato l'opposto del valore usato
 per l'operazione.
 
-%TODO verificare queste strutture \kstruct{sem\_queue} e \kstruct{sem\_undo}
-
-Queste strutture sono mantenute in due liste,\footnote{rispettivamente
-  attraverso i due campi \var{id\_next} e \var{proc\_next}.} una associata
-all'insieme di cui fa parte il semaforo, che viene usata per invalidare le
-strutture se questo viene cancellato o per azzerarle se si è eseguita una
-operazione con \func{semctl}; l'altra associata al processo che ha eseguito
-l'operazione;\footnote{attraverso il campo \var{semundo} di
-  \kstruct{task\_struct}, come mostrato in \ref{fig:ipc_sem_schema}.} quando un
-processo termina, la lista ad esso associata viene scandita e le operazioni
-applicate al semaforo.  Siccome un processo può accumulare delle richieste di
-ripristino per semafori differenti chiamate attraverso diverse chiamate a
-\func{semop}, si pone il problema di come eseguire il ripristino dei semafori
-all'uscita del processo, ed in particolare se questo può essere fatto
-atomicamente.
+Queste strutture sono mantenute in due liste (rispettivamente attraverso i due
+campi \var{id\_next} e \var{proc\_next}) una associata all'insieme di cui fa
+parte il semaforo, che viene usata per invalidare le strutture se questo viene
+cancellato o per azzerarle se si è eseguita una operazione con \func{semctl},
+l'altra associata al processo che ha eseguito l'operazione, attraverso il
+campo \var{semundo} di \kstruct{task\_struct}, come mostrato in
+\ref{fig:ipc_sem_schema}. Quando un processo termina, la lista ad esso
+associata viene scandita e le operazioni applicate al semaforo.  Siccome un
+processo può accumulare delle richieste di ripristino per semafori differenti
+attraverso diverse chiamate a \func{semop}, si pone il problema di come
+eseguire il ripristino dei semafori all'uscita del processo, ed in particolare
+se questo può essere fatto atomicamente.
 
 Il punto è cosa succede quando una delle operazioni previste per il ripristino
 non può essere eseguita immediatamente perché ad esempio il semaforo è
 
 Il punto è cosa succede quando una delle operazioni previste per il ripristino
 non può essere eseguita immediatamente perché ad esempio il semaforo è
@@ -2463,20 +2550,20 @@ problemi, usando il \itindex{file~locking} \textit{file locking}.
 \label{sec:ipc_sysv_shm}
 
 Il terzo oggetto introdotto dal \textit{SysV-IPC} è quello dei segmenti di
 \label{sec:ipc_sysv_shm}
 
 Il terzo oggetto introdotto dal \textit{SysV-IPC} è quello dei segmenti di
-memoria condivisa. La funzione che permette di ottenerne uno è \funcd{shmget},
-ed il suo prototipo è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/shm.h}
-  
-  \funcdecl{int shmget(key\_t key, int size, int flag)}
-  
-  Restituisce l'identificatore di una memoria condivisa.
-  
-  \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
-    in caso di errore, nel qual caso \var{errno} assumerà i valori:
-    \begin{errlist}
+memoria condivisa. La funzione di sistema che permette di ottenerne uno è
+\funcd{shmget}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/shm.h}
+\fdecl{int shmget(key\_t key, int size, int flag)}
+\fdesc{Ottiene o crea una memoria condivisa.} 
+}
+
+{La funzione ritorna l'identificatore (un intero positivo) in caso di successo
+  e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
     \item[\errcode{ENOSPC}] si è superato il limite (\const{SHMMNI}) sul numero
       di segmenti di memoria nel sistema, o cercato di allocare un segmento le
       cui dimensioni fanno superare il limite di sistema (\const{SHMALL}) per
     \item[\errcode{ENOSPC}] si è superato il limite (\const{SHMMNI}) sul numero
       di segmenti di memoria nel sistema, o cercato di allocare un segmento le
       cui dimensioni fanno superare il limite di sistema (\const{SHMALL}) per
@@ -2486,10 +2573,11 @@ ed il suo prototipo è:
       già esiste \param{size} è maggiore delle sue dimensioni.
     \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter
       contenere le strutture per un nuovo segmento di memoria condivisa.
       già esiste \param{size} è maggiore delle sue dimensioni.
     \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter
       contenere le strutture per un nuovo segmento di memoria condivisa.
-    \end{errlist}
-    ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST},
-    \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.}
-\end{functions}
+   \end{errlist}
+   ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST},
+   \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.}
+\end{funcproto}
+
 
 La funzione, come \func{semget}, è del tutto analoga a \func{msgget}, ed
 identico è l'uso degli argomenti \param{key} e \param{flag} per cui non
 
 La funzione, come \func{semget}, è del tutto analoga a \func{msgget}, ed
 identico è l'uso degli argomenti \param{key} e \param{flag} per cui non
@@ -4121,8 +4209,8 @@ sincronizzazione completamente nuovo, basato sui cosiddetti
 \textit{futex},\footnote{la sigla sta per \textit{fast user mode mutex}.} con
 il quale è stato possibile implementare una versione nativa dei semafori
 POSIX.  Grazie a questo con i kernel della serie 2.6 e le nuove versioni della
 \textit{futex},\footnote{la sigla sta per \textit{fast user mode mutex}.} con
 il quale è stato possibile implementare una versione nativa dei semafori
 POSIX.  Grazie a questo con i kernel della serie 2.6 e le nuove versioni della
-\acr{glibc} che usano questa nuova infrastruttura per quella che viene quella
-che viene chiamata \textit{New Posix Thread Library}, sono state implementate
+\acr{glibc} che usano questa nuova infrastruttura per quella che viene che
+viene chiamata \textit{New Posix Thread Library}, sono state implementate
 anche tutte le funzioni dell'interfaccia dei semafori POSIX.
 
 Anche in questo caso è necessario appoggiarsi alla libreria per le estensioni
 anche tutte le funzioni dell'interfaccia dei semafori POSIX.
 
 Anche in questo caso è necessario appoggiarsi alla libreria per le estensioni
@@ -4730,7 +4818,7 @@ testo alla terminazione di quest'ultimo.
 % LocalWords:  FortuneServer FortuneParse FortuneClient pid libgapil  LD librt
 % LocalWords:  PATH linker pathname ps tmp killall fortuned crash socket domain
 % LocalWords:  socketpair BSD sys protocol sv EAFNOSUPPORT EPROTONOSUPPORT AF
 % LocalWords:  FortuneServer FortuneParse FortuneClient pid libgapil  LD librt
 % LocalWords:  PATH linker pathname ps tmp killall fortuned crash socket domain
 % LocalWords:  socketpair BSD sys protocol sv EAFNOSUPPORT EPROTONOSUPPORT AF
-% LocalWords:  EOPNOTSUPP SOCK Process Comunication ipc perm key exec
+% LocalWords:  EOPNOTSUPP SOCK Process Comunication ipc perm key exec pipefd SZ
 % LocalWords:  header ftok proj stat libc SunOS glibc XPG dell'inode number uid
 % LocalWords:  cuid cgid gid tab MSG shift group umask seq MSGMNI SEMMNI SHMMNI
 % LocalWords:  shmmni msgmni sem sysctl IPCMNI IPCTestId msgget EACCES EEXIST
 % LocalWords:  header ftok proj stat libc SunOS glibc XPG dell'inode number uid
 % LocalWords:  cuid cgid gid tab MSG shift group umask seq MSGMNI SEMMNI SHMMNI
 % LocalWords:  shmmni msgmni sem sysctl IPCMNI IPCTestId msgget EACCES EEXIST
@@ -4752,7 +4840,7 @@ testo alla terminazione di quest'ultimo.
 % LocalWords:  dtime lpid cpid nattac shmall shmmax SHMLBA SHMSEG EOVERFLOW brk
 % LocalWords:  memory shmat shmdt void shmaddr shmflg SVID RND RDONLY rounded
 % LocalWords:  SIGSEGV nattch exit SharedMem ShmCreate memset fill ShmFind home
 % LocalWords:  dtime lpid cpid nattac shmall shmmax SHMLBA SHMSEG EOVERFLOW brk
 % LocalWords:  memory shmat shmdt void shmaddr shmflg SVID RND RDONLY rounded
 % LocalWords:  SIGSEGV nattch exit SharedMem ShmCreate memset fill ShmFind home
-% LocalWords:  ShmRemove DirMonitor DirProp chdir GaPiL shmptr ipcs NFS
+% LocalWords:  ShmRemove DirMonitor DirProp chdir GaPiL shmptr ipcs NFS SETPIPE
 % LocalWords:  ComputeValues ReadMonitor touch SIGTERM dirmonitor unlink fcntl
 % LocalWords:  LockFile UnlockFile CreateMutex FindMutex LockMutex SETLKW GETLK
 % LocalWords:  UnlockMutex RemoveMutex ReadMutex UNLCK WRLCK RDLCK mapping MAP
 % LocalWords:  ComputeValues ReadMonitor touch SIGTERM dirmonitor unlink fcntl
 % LocalWords:  LockFile UnlockFile CreateMutex FindMutex LockMutex SETLKW GETLK
 % LocalWords:  UnlockMutex RemoveMutex ReadMutex UNLCK WRLCK RDLCK mapping MAP
@@ -4765,17 +4853,19 @@ testo alla terminazione di quest'ultimo.
 % LocalWords:  EBUSY sigev SIGNAL signo value sigval siginfo all'userid MESGQ
 % LocalWords:  Konstantin Knizhnik futex tmpfs ramfs cache shared swap CONFIG
 % LocalWords:  lrt blocks PAGECACHE TRUNC CLOEXEC mmap ftruncate munmap FindShm
 % LocalWords:  EBUSY sigev SIGNAL signo value sigval siginfo all'userid MESGQ
 % LocalWords:  Konstantin Knizhnik futex tmpfs ramfs cache shared swap CONFIG
 % LocalWords:  lrt blocks PAGECACHE TRUNC CLOEXEC mmap ftruncate munmap FindShm
-% LocalWords:  CreateShm RemoveShm LIBRARY Library libmqueue FAILED has
+% LocalWords:  CreateShm RemoveShm LIBRARY Library libmqueue FAILED has fclose
 % LocalWords:  ENAMETOOLONG qualchenome RESTART trywait XOPEN SOURCE timedwait
 % LocalWords:  process getvalue sval execve pshared ENOSYS heap PAGE destroy it
 % LocalWords:  xffffffff Arrays owner perms Queues used bytes messages device
 % LocalWords:  Cannot find such Segments getter Signal MSGMAXSIZE been stable
 % LocalWords:  for now it's break Berlin sources Let's an accidental feature
 % LocalWords:  Larry Wall Escape the Hell William ipctestid Identifier segment
 % LocalWords:  ENAMETOOLONG qualchenome RESTART trywait XOPEN SOURCE timedwait
 % LocalWords:  process getvalue sval execve pshared ENOSYS heap PAGE destroy it
 % LocalWords:  xffffffff Arrays owner perms Queues used bytes messages device
 % LocalWords:  Cannot find such Segments getter Signal MSGMAXSIZE been stable
 % LocalWords:  for now it's break Berlin sources Let's an accidental feature
 % LocalWords:  Larry Wall Escape the Hell William ipctestid Identifier segment
-% LocalWords:  violation dell'I SIGINT setter Fri Dec Sleeping seconds
+% LocalWords:  violation dell'I SIGINT setter Fri Dec Sleeping seconds ECHILD
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+% LocalWords:  SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop
+% LocalWords:  scan