Finita revisione semafori SysV IPC
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index cd29ca77fa3f099f5147bff32c890d35bfd6f10f..1f9226dbf186c1ab592b5ba296fa917ff462d094 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -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
@@ -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
@@ -1326,7 +1326,7 @@ Una coda di messaggi è costituita da una \itindex{linked~list} \textit{linked
   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. Lo schema
   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. Lo schema
-illustrato in realta è una semplificazione di quello usato fino ai kernel
+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
 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
@@ -1458,7 +1458,7 @@ per \param{cmd} sono:
 
 A questi tre valori, che sono quelli previsti dallo standard, su Linux se ne
 affiancano altri tre (\const{IPC\_INFO}, \const{MSG\_STAT} e
 
 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{icps} per ottenere le
+\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.
 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.
@@ -2059,8 +2059,9 @@ anche la loro inizializzazione, è \funcd{semctl}; il suo prototipo è:
   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}
   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 richiesta.
+  \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 è né il creatore né il proprietario del semaforo e
     \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 è né il creatore né il proprietario del semaforo e
@@ -2106,9 +2107,9 @@ 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:
+\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
 \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
@@ -2135,30 +2136,29 @@ 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}
 
 Come per \func{msgctl} esistono tre ulteriori valori, \const{IPC\_INFO},
 \end{basedescript}
 
 Come per \func{msgctl} esistono tre ulteriori valori, \const{IPC\_INFO},
@@ -2200,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 
@@ -2254,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
@@ -2320,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}
@@ -2364,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
@@ -2389,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 è
@@ -2499,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
@@ -2522,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
@@ -4766,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
@@ -4788,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
@@ -4801,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