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
-  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
@@ -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
-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
@@ -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
-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
-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
@@ -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
-(\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
@@ -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
-  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
@@ -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
-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}.
 
@@ -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
-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
@@ -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
-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
-prossime sezioni. 
+prossime sezioni.
 
 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
-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}
@@ -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
-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{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.90\textwidth}
     \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
-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.
@@ -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 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}).
-\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
@@ -1417,16 +1426,16 @@ file; il suo prototipo è:
   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
-  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
@@ -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
-  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}
 
+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
-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.
-  \item[\errcode{EIDRM}] la coda è stata cancellata.
   \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}
-  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
@@ -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}.
 
+\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
@@ -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}).
 
-\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
@@ -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
-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
-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}).
@@ -1551,41 +1568,39 @@ vengono modificati:
 \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)}
-  
-  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}
-  \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{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}
-  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
@@ -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:
-\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
@@ -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}.
-\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ù
@@ -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
-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
@@ -1638,15 +1653,15 @@ vengono modificati:
 \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}).
 
-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
@@ -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
-\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
-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
@@ -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
-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
@@ -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. 
 
-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
-\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:
-\begin{verbatim}
-[piccardi@gont sources]$ ipcs
+\begin{Console}
+[piccardi@gont sources]$ \textbf{ipcs}
 
 ------ 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           
-\end{verbatim}
+\end{Console}
+%$
 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
-[piccardi@gont sources]$ ./mqfortune
+[piccardi@gont sources]$ \textbf{./mqfortune}
 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
-  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
@@ -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
-\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}
 
-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
-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
-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,
@@ -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.
 
-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 è
@@ -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
-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
-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
-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{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \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},
-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}.
-\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*}
 
-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{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/sem.h}
   \end{minipage} 
   \normalsize 
@@ -1978,16 +1986,33 @@ funzioni di controllo.
   \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.
-\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
@@ -2015,51 +2040,49 @@ indicano rispettivamente:
   \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}
-      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}.
-  \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}. 
 
+
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \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
-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
-\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
-  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
-  \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.
@@ -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
-  \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
-  \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}
-  (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
-  \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
-  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
-  \struct{semid\_ds}.  Si devono avere i privilegi di scrittura sul semaforo.
+  \struct{semid\_ds}.  Si devono avere i privilegi di scrittura.
 \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
@@ -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})
-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{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{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}
-  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
-\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
-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{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \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}
 
-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
-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
-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
-\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}}
-\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
-    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}
-    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 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
-  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}
-  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
@@ -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}
-    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}
-    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}
 
-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
-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ù
-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
-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}
@@ -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
-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
@@ -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.
 
-%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 è
@@ -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
-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
@@ -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.
-    \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
@@ -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
-\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
@@ -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:  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
@@ -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:  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
@@ -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:  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:  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: 
+% LocalWords:  SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop
+% LocalWords:  scan