Aggiornamento anno note di copyright, dimenticato da gennaio...
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index b7ccdd8411a4f68dab756173ccc7f5275d204a60..439d1d15aedea6f96688388f465c703d2aaacf6b 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,6 +1,6 @@
 %% ipc.tex
 %%
-%% Copyright (C) 2000-2007 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2008 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -66,8 +66,9 @@ La funzione restituisce la coppia di file descriptor nel vettore
 accennato concetto di funzionamento di una pipe è semplice: quello che si
 scrive nel file descriptor aperto in scrittura viene ripresentato tale e quale
 nel file descriptor aperto in lettura. I file descriptor infatti non sono
-connessi a nessun file reale, ma ad un buffer nel kernel, la cui dimensione è
-specificata dal parametro di sistema \const{PIPE\_BUF}, (vedi
+connessi a nessun file reale, ma, come accennato in
+sez.~\ref{sec:file_sendfile_splice}, ad un buffer nel kernel, la cui
+dimensione è specificata dal parametro di sistema \const{PIPE\_BUF}, (vedi
 sez.~\ref{sec:sys_file_limits}). Lo schema di funzionamento di una pipe è
 illustrato in fig.~\ref{fig:ipc_pipe_singular}, in cui sono illustrati i due
 capi della pipe, associati a ciascun file descriptor, con le frecce che
@@ -133,7 +134,7 @@ Per capire meglio il funzionamento delle pipe faremo un esempio di quello che
 è il loro uso più comune, analogo a quello effettuato della shell, e che
 consiste nell'inviare l'output di un processo (lo standard output) sull'input
 di un altro. Realizzeremo il programma di esempio nella forma di un
-\textit{CGI}\footnote{Un CGI (\textit{Common Gateway Interface}) è un
+\textit{CGI}\footnote{un CGI (\textit{Common Gateway Interface}) è un
   programma che permette la creazione dinamica di un oggetto da inserire
   all'interno di una pagina HTML.}  per Apache, che genera una immagine JPEG
 di un codice a barre, specificato come argomento in ingresso.
@@ -174,10 +175,10 @@ evidente \itindex{race~condition} \textit{race condition} in caso di accesso
 simultaneo a detto file.\footnote{il problema potrebbe essere superato
   determinando in anticipo un nome appropriato per il file temporaneo, che
   verrebbe utilizzato dai vari sotto-processi, e cancellato alla fine della
-  loro esecuzione; ma a questo le cose non sarebbero più tanto semplici.}
-L'uso di una pipe invece permette di risolvere il problema in maniera semplice
-ed elegante, oltre ad essere molto più efficiente, dato che non si deve
-scrivere su disco.
+  loro esecuzione; ma a questo punto le cose non sarebbero più tanto
+  semplici.}  L'uso di una pipe invece permette di risolvere il problema in
+maniera semplice ed elegante, oltre ad essere molto più efficiente, dato che
+non si deve scrivere su disco.
 
 Il programma ci servirà anche come esempio dell'uso delle funzioni di
 duplicazione dei file descriptor che abbiamo trattato in
@@ -568,7 +569,7 @@ ricevuta la risposta, uscir
 A questo punto il server resta (se non ci sono altri client che stanno
 effettuando richieste) con la fifo chiusa sul lato in lettura, ed in questo
 stato la funzione \func{read} non si bloccherà in attesa di input, ma
-ritornerà in continuazione, restituendo un end-of-file.\footnote{Si è usata
+ritornerà in continuazione, restituendo un end-of-file.\footnote{si è usata
   questa tecnica per compatibilità, Linux infatti supporta l'apertura delle
   fifo in lettura/scrittura, per cui si sarebbe potuto effettuare una singola
   apertura con \const{O\_RDWR}, la doppia apertura comunque ha il vantaggio
@@ -893,8 +894,9 @@ con i 16 bit meno significativi \index{inode} dell'inode del file
 \param{pathname} (che vengono ottenuti attraverso \func{stat}, da cui derivano
 i possibili errori), e gli 8 bit meno significativi del numero del dispositivo
 su cui è il file.  Diventa perciò relativamente facile ottenere delle
-collisioni, specie se i file sono su dispositivi con lo stesso \textit{minor
-  number}, come \file{/dev/hda1} e \file{/dev/sda1}.
+collisioni, specie se i file sono su dispositivi con lo stesso
+\itindex{minor~number} \textit{minor number}, come \file{/dev/hda1} e
+\file{/dev/sda1}.
 
 In genere quello che si fa è utilizzare un file comune usato dai programmi che
 devono comunicare (ad esempio un header comune, o uno dei programmi che devono
@@ -977,7 +979,7 @@ solo se tutti i controlli elencati falliscono l'accesso 
 a differenza di quanto avviene per i permessi dei file, fallire in uno dei
 passi elencati non comporta il fallimento dell'accesso. Un'ulteriore
 differenza rispetto a quanto avviene per i file è che per gli oggetti di IPC
-il valore di \var{umask} (si ricordi quanto esposto in
+il valore di \itindex{umask} \textit{umask} (si ricordi quanto esposto in
 sez.~\ref{sec:file_perm_management}) non ha alcun significato.
 
 
@@ -1017,8 +1019,9 @@ Il sistema dispone sempre di un numero fisso di oggetti di IPC,\footnote{fino
   altri limiti relativi al \textit{SysV IPC}) solo con una ricompilazione del
   kernel, andando a modificarne la definizione nei relativi header file.  A
   partire dal kernel 2.4.x è possibile cambiare questi valori a sistema attivo
-  scrivendo sui file \file{shmmni}, \file{msgmni} e \file{sem} di
-  \file{/proc/sys/kernel} o con l'uso di \func{sysctl}.} e per ciascuno di
+  scrivendo sui file \procrelfile{/proc/sys/kernel}{shmmni},
+  \procrelfile{/proc/sys/kernel}{msgmni} e \procrelfile{/proc/sys/kernel}{sem}
+  di \file{/proc/sys/kernel} o con l'uso di \func{sysctl}.} e per ciascuno di
 essi viene mantenuto in \var{seq} un numero di sequenza progressivo che viene
 incrementato di uno ogni volta che l'oggetto viene cancellato. Quando
 l'oggetto viene creato usando uno spazio che era già stato utilizzato in
@@ -1160,7 +1163,7 @@ coda.
     \hline
     \hline
     \const{MSGMNI}&   16& \file{msgmni} & Numero massimo di code di
-                                          messaggi. \\
+                                          messaggi.\\
     \const{MSGMAX}& 8192& \file{msgmax} & Dimensione massima di un singolo
                                           messaggio.\\
     \const{MSGMNB}&16384& \file{msgmnb} & Dimensione massima del contenuto di 
@@ -1175,7 +1178,9 @@ Le code di messaggi sono caratterizzate da tre limiti fondamentali, definiti
 negli header e corrispondenti alle prime tre costanti riportate in
 tab.~\ref{tab:ipc_msg_limits}, come accennato però in Linux è possibile
 modificare questi limiti attraverso l'uso di \func{sysctl} o scrivendo nei
-file \file{msgmax}, \file{msgmnb} e \file{msgmni} di \file{/proc/sys/kernel/}.
+file \procrelfile{/proc/sys/kernel}{msgmax},
+\procrelfile{/proc/sys/kernel}{msgmnb} e
+\procrelfile{/proc/sys/kernel}{msgmni} di \file{/proc/sys/kernel/}.
 
 
 \begin{figure}[htb]
@@ -1860,16 +1865,16 @@ indicano rispettivamente:
     \textbf{Costante} & \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    \const{SEMMNI}&          128 & Numero massimo di insiemi di semafori. \\
+    \const{SEMMNI}&          128 & Numero massimo di insiemi di semafori.\\
     \const{SEMMSL}&          250 & Numero massimo di semafori per insieme.\\
     \const{SEMMNS}&\const{SEMMNI}*\const{SEMMSL}& Numero massimo di semafori
-                                   nel sistema .\\
+                                   nel sistema.\\
     \const{SEMVMX}&        32767 & Massimo valore per un semaforo.\\
     \const{SEMOPM}&           32 & Massimo numero di operazioni per chiamata a
                                    \func{semop}. \\
     \const{SEMMNU}&\const{SEMMNS}& Massimo numero di strutture di ripristino.\\
     \const{SEMUME}&\const{SEMOPM}& Massimo numero di voci di ripristino.\\
-    \const{SEMAEM}&\const{SEMVMX}& valore massimo per l'aggiustamento
+    \const{SEMAEM}&\const{SEMVMX}& Valore massimo per l'aggiustamento
                                    all'uscita. \\
     \hline
   \end{tabular}
@@ -1882,7 +1887,7 @@ 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 \file{/proc/sys/kernel/sem}.
+direttamente nel file \procfile{/proc/sys/kernel/sem}.
 
 La funzione che permette di effettuare le varie operazioni di controllo sui
 semafori (fra le quali, come accennato, è impropriamente compresa anche la
@@ -2008,10 +2013,10 @@ tutti i semafori il cui valore viene modificato.
     \textbf{Operazione}  & \textbf{Valore restituito} \\
     \hline
     \hline
-    \const{GETNCNT}& valore di \var{semncnt}.\\
-    \const{GETPID} & valore di \var{sempid}.\\
-    \const{GETVAL} & valore di \var{semval}.\\
-    \const{GETZCNT}& valore di \var{semzcnt}.\\
+    \const{GETNCNT}& Valore di \var{semncnt}.\\
+    \const{GETPID} & Valore di \var{sempid}.\\
+    \const{GETVAL} & Valore di \var{semval}.\\
+    \const{GETZCNT}& Valore di \var{semzcnt}.\\
     \hline
   \end{tabular}
   \caption{Valori di ritorno della funzione \func{semctl}.} 
@@ -2428,23 +2433,25 @@ che permettono di cambiarne il valore.
     & \textbf{Significato} \\
     \hline
     \hline
-    \const{SHMALL}& 0x200000&\file{shmall}& Numero massimo di pagine che 
-                                       possono essere usate per i segmenti di
-                                       memoria condivisa. \\
-    \const{SHMMAX}&0x2000000&\file{shmmax}& Dimensione massima di un segmento 
-                                            di memoria condivisa.\\
-    \const{SHMMNI}&     4096&\file{msgmni}& Numero massimo di segmenti di 
-                                            memoria condivisa presenti nel
-                                            kernel.\\ 
+    \const{SHMALL}& 0x200000&\procrelfile{/proc/sys/kernel}{shmall}
+                            & Numero massimo di pagine che 
+                              possono essere usate per i segmenti di
+                              memoria condivisa.\\
+    \const{SHMMAX}&0x2000000&\procrelfile{/proc/sys/kernel}{shmmax} 
+                            & Dimensione massima di un segmento di memoria
+                              condivisa.\\ 
+    \const{SHMMNI}&     4096&\procrelfile{/proc/sys/kernel}{msgmni}
+                            & Numero massimo di segmenti di memoria condivisa
+                              presenti nel kernel.\\ 
     \const{SHMMIN}&        1& ---         & Dimensione minima di un segmento di
-                                            memoria condivisa. \\
+                                            memoria condivisa.\\
     \const{SHMLBA}&\const{PAGE\_SIZE}&--- & Limite inferiore per le dimensioni
                                             minime di un segmento (deve essere
                                             allineato alle dimensioni di una
-                                            pagina di memoria). \\
+                                            pagina di memoria).\\
     \const{SHMSEG}&   ---   &     ---     & Numero massimo di segmenti di
-                                            memoria condivisa 
-                                            per ciascun processo.\\
+                                            memoria condivisa per ciascun
+                                            processo.\\
 
 
     \hline
@@ -2470,7 +2477,7 @@ un segmento di memoria condivisa 
     \begin{errlist}
     \item[\errcode{EACCES}] si è richiesto \const{IPC\_STAT} ma i permessi non
       consentono l'accesso in lettura al segmento.
-    \item[\errcode{EINVAL}] O \param{shmid} non è un identificatore valido o
+    \item[\errcode{EINVAL}] o \param{shmid} non è un identificatore valido o
       \param{cmd} non è un comando valido.
     \item[\errcode{EIDRM}] l'argomento \param{shmid} fa riferimento ad un
       segmento che è stato cancellato.
@@ -2567,9 +2574,9 @@ stato marcato per la cancellazione.
   \label{fig:ipc_shmem_layout}
 \end{figure}
 
-L'argomento \param{shmaddr} specifica a quale indirizzo\footnote{Lo standard
+L'argomento \param{shmaddr} specifica a quale indirizzo\footnote{lo standard
   SVID prevede che l'argomento \param{shmaddr} sia di tipo \ctyp{char *}, così
-  come il valore di ritorno della funzione. In Linux è stato così con le
+  come il valore di ritorno della funzione; in Linux è stato così con le
   \acr{libc4} e le \acr{libc5}, con il passaggio alle \acr{glibc} il tipo di
   \param{shmaddr} è divenuto un \ctyp{const void *} e quello del valore di
   ritorno un \ctyp{void *}.} deve essere associato il segmento, se il valore
@@ -2599,12 +2606,12 @@ indirizzo come arrotondamento, in Linux 
 
 L'uso di \const{SHM\_RDONLY} permette di agganciare il segmento in sola
 lettura (si ricordi che anche le pagine di memoria hanno dei permessi), in tal
-caso un tentativo di scrivere sul segmento comporterà una violazione di
-accesso con l'emissione di un segnale di \const{SIGSEGV}. Il comportamento
-usuale di \func{shmat} è quello di agganciare il segmento con l'accesso in
-lettura e scrittura (ed il processo deve aver questi permessi in
-\var{shm\_perm}), non è prevista la possibilità di agganciare un segmento in
-sola scrittura.
+caso un tentativo di scrivere sul segmento comporterà una
+\itindex{segment~violation} violazione di accesso con l'emissione di un
+segnale di \const{SIGSEGV}. Il comportamento usuale di \func{shmat} è quello
+di agganciare il segmento con l'accesso in lettura e scrittura (ed il processo
+deve aver questi permessi in \var{shm\_perm}), non è prevista la possibilità
+di agganciare un segmento in sola scrittura.
 
 In caso di successo la funzione aggiorna anche i seguenti campi di
 \struct{shmid\_ds}:
@@ -3234,6 +3241,7 @@ pi
 sez.~\ref{sec:ipc_sysv_shm} che possa restituisca i risultati via rete.
 \itindend{memory~mapping}
 
+% TODO fare esempio di mmap anonima
 
 \section{Il sistema di comunicazione fra processi di POSIX}
 \label{sec:ipc_posix}
@@ -3251,8 +3259,9 @@ una interfaccia completamente nuova, che tratteremo in questa sezione.
 Oggi Linux supporta tutti gli oggetti definito nello standard POSIX per l'IPC,
 ma a lungo non è stato così; la memoria condivisa è presente a partire dal
 kernel 2.4.x, i semafori sono forniti dalle \acr{glibc} nella sezione che
-implementa i thread POSIX di nuova generazione che richiedono il kernel 2.6,
-le code di messaggi sono supportate a partire dal kernel 2.6.6.
+implementa i \itindex{thread} \textit{thread} POSIX di nuova generazione che
+richiedono il kernel 2.6, le code di messaggi sono supportate a partire dal
+kernel 2.6.6.
 
 La caratteristica fondamentale dell'interfaccia POSIX è l'abbandono dell'uso
 degli identificatori e delle chiavi visti nel SysV IPC, per passare ai
@@ -3315,7 +3324,7 @@ Le code di messaggi POSIX sono supportate da Linux a partire dalla versione
 2.6.6-rc1 del kernel,\footnote{l'implementazione è dovuta a Michal Wronski e
   Krzysztof Benedyczak, e le relative informazioni si possono trovare su
   \href{http://www.geocities.com/wronski12/posix_ipc/index.html}
-  {\texttt{http://www.geocities.com/wronski12/posix\_ipc/index.html}}.} In
+  {\textsf{http://www.geocities.com/wronski12/posix\_ipc/index.html}}.} In
 generale, come le corrispettive del SysV IPC, le code di messaggi sono poco
 usate, dato che i socket, nei casi in cui sono sufficienti, sono più comodi, e
 che in casi più complessi la comunicazione può essere gestita direttamente con
@@ -3335,7 +3344,7 @@ POSIX.\footnote{in realt
 
 La libreria inoltre richiede la presenza dell'apposito filesystem di tipo
 \texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto
-aggiungendo ad \file{/etc/fstab} una riga come:
+aggiungendo ad \conffile{/etc/fstab} una riga come:
 \begin{verbatim}
 mqueue   /dev/mqueue       mqueue    defaults        0      0
 \end{verbatim}
@@ -3703,15 +3712,15 @@ della stessa struttura per l'invio dei segnali usati per l'I/O asincrono.
 Attraverso questa struttura si possono impostare le modalità con cui viene
 effettuata la notifica; in particolare il campo \var{sigev\_notify} deve
 essere posto a \const{SIGEV\_SIGNAL}\footnote{il meccanismo di notifica basato
-  sui thread, specificato tramite il valore \const{SIGEV\_THREAD}, non è
-  implementato.} ed il campo \var{sigev\_signo} deve indicare il valore del
-segnale che sarà inviato al processo. Inoltre il campo \var{sigev\_value} è il
-puntatore ad una struttura \struct{sigval\_t} (definita in
-fig.~\ref{fig:sig_sigval}) che permette di restituire al gestore del segnale un
-valore numerico o un indirizzo,\footnote{per il suo uso si riveda la
-  trattazione fatta in sez.~\ref{sec:sig_real_time} a proposito dei segnali
-  real-time.} posto che questo sia installato nella forma estesa vista in
-sez.~\ref{sec:sig_sigaction}.
+  sui \itindex{thread} \textit{thread}, specificato tramite il valore
+  \const{SIGEV\_THREAD}, non è implementato.} ed il campo \var{sigev\_signo}
+deve indicare il valore del segnale che sarà inviato al processo. Inoltre il
+campo \var{sigev\_value} è il puntatore ad una struttura \struct{sigval\_t}
+(definita in fig.~\ref{fig:sig_sigval}) che permette di restituire al gestore
+del segnale un valore numerico o un indirizzo,\footnote{per il suo uso si
+  riveda la trattazione fatta in sez.~\ref{sec:sig_real_time} a proposito dei
+  segnali real-time.} posto che questo sia installato nella forma estesa vista
+in sez.~\ref{sec:sig_sigaction}.
 
 La funzione registra il processo chiamante per la notifica se
 \param{notification} punta ad una struttura \struct{sigevent} opportunamente
@@ -3768,20 +3777,20 @@ suoi contenuti in memoria,\footnote{il filesystem \texttt{tmpfs} 
   per la memoria condivisa; esso infatti non ha dimensione fissa, ed usa
   direttamente la cache interna del kernel (che viene usata anche per la
   shared memory in stile SysV). In più i suoi contenuti, essendo trattati
-  direttamente dalla memoria virtuale\index{memoria~virtuale} possono essere
+  direttamente dalla memoria virtuale \index{memoria~virtuale} possono essere
   salvati sullo swap automaticamente.} che viene attivato abilitando l'opzione
 \texttt{CONFIG\_TMPFS} in fase di compilazione del kernel.
 
 
-Per potere utilizzare l'interfaccia POSIX per le code di messaggi le
+Per potere utilizzare l'interfaccia POSIX per la memoria condivisa le
 \acr{glibc}\footnote{le funzioni sono state introdotte con le glibc-2.2.}
 richiedono di compilare i programmi con l'opzione \code{-lrt}; inoltre è
 necessario che in \file{/dev/shm} sia montato un filesystem \texttt{tmpfs};
-questo di norma viene eseguita aggiungendo una riga tipo:
+questo di norma viene fatto aggiungendo una riga del tipo di:
 \begin{verbatim}
 tmpfs   /dev/shm        tmpfs   defaults        0      0
 \end{verbatim}
-ad \file{/etc/fstab}. In realtà si può montare un filesystem \texttt{tmpfs}
+ad \conffile{/etc/fstab}. In realtà si può montare un filesystem \texttt{tmpfs}
 dove si vuole, per usarlo come RAM disk, con un comando del tipo:
 \begin{verbatim}
 mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs
@@ -3845,7 +3854,7 @@ segmento di memoria condiviso con le stesse modalit
 il flag \const{FD\_CLOEXEC}.  Chiamate effettuate da diversi processi usando
 lo stesso nome, restituiranno file descriptor associati allo stesso segmento
 (così come, nel caso di file di dati, essi sono associati allo stesso
-\index{inode}inode).  In questo modo è possibile effettuare una chiamata ad
+\index{inode} inode).  In questo modo è possibile effettuare una chiamata ad
 \func{mmap} sul file descriptor restituito da \func{shm\_open} ed i processi
 vedranno lo stesso segmento di memoria condivisa.
 
@@ -3939,15 +3948,16 @@ restituendo al chiamante il valore di ritorno.
 \label{sec:ipc_posix_sem}
 
 Fino alla serie 2.4.x del kernel esisteva solo una implementazione parziale
-dei semafori POSIX che li realizzava solo a livello di thread e non di
-processi,\footnote{questo significava che i semafori erano visibili solo
-  all'interno dei thread creati da un singolo processo, e non potevano essere
-  usati come meccanismo di sincronizzazione fra processi diversi.} fornita
-attraverso la sezione delle estensioni \textit{real-time} delle
-\acr{glibc}.\footnote{quelle che si accedono collegandosi alla libreria
-  \texttt{librt}.} Esisteva inoltre una libreria che realizzava (parzialmente)
-l'interfaccia POSIX usando le funzioni dei semafori di SysV IPC (mantenendo
-così tutti i problemi sottolineati in sez.~\ref{sec:ipc_sysv_sem}).
+dei semafori POSIX che li realizzava solo a livello di \itindex{thread}
+\textit{thread} e non di processi,\footnote{questo significava che i semafori
+  erano visibili solo all'interno dei \itindex{thread} \textit{thread} creati
+  da un singolo processo, e non potevano essere usati come meccanismo di
+  sincronizzazione fra processi diversi.} fornita attraverso la sezione delle
+estensioni \textit{real-time} delle \acr{glibc}.\footnote{quelle che si
+  accedono collegandosi alla libreria \texttt{librt}.} Esisteva inoltre una
+libreria che realizzava (parzialmente) l'interfaccia POSIX usando le funzioni
+dei semafori di SysV IPC (mantenendo così tutti i problemi sottolineati in
+sez.~\ref{sec:ipc_sysv_sem}).
 
 A partire dal kernel 2.5.7 è stato introdotto un meccanismo di
 sincronizzazione completamente nuovo, basato sui cosiddetti
@@ -3963,8 +3973,6 @@ Anche in questo caso 
 questa interfaccia, oltre ad utilizzare gli opportuni file di definizione,
 occorrerà compilare i programmi con l'opzione \texttt{-lrt}. 
 
-% TODO trattare l'argomento a partire da man sem_overview.
-
 La funzione che permette di creare un nuovo semaforo POSIX, creando il
 relativo file, o di accedere ad uno esistente, è \funcd{sem\_open}, questa
 prevede due forme diverse a seconda che sia utilizzata per aprire un semaforo
@@ -4036,9 +4044,9 @@ accesso.
 
 Questo significa che un nuovo semaforo viene sempre creato con l'user-ID ed il
 group-ID effettivo del processo chiamante, e che i permessi indicati con
-\param{mode} vengono filtrati dal valore della \textit{umask} del processo.
-Inoltre per poter aprire un semaforo è necessario avere su di esso sia il
-permesso di lettura che quello di scrittura.
+\param{mode} vengono filtrati dal valore della \itindex{umask} \textit{umask}
+del processo.  Inoltre per poter aprire un semaforo è necessario avere su di
+esso sia il permesso di lettura che quello di scrittura.
 
 Una volta che si sia ottenuto l'indirizzo di un semaforo, sarà possibile
 utilizzarlo; se si ricorda quanto detto all'inizio di
@@ -4074,13 +4082,14 @@ successo e proseguire.
 
 Si tenga presente che la funzione può sempre essere interrotta da un segnale
 (nel qual caso si avrà un errore di \const{EINTR}) e che questo avverrà
-comunque, anche se si è installato il relativo gestore con \const{SA\_RESTART}
-(vedi sez.~\ref{sec:sig_sigaction}) per riavviare le system call interrotte.
+comunque, anche se si è richiesta la semantica BSD installando il relativo
+gestore con \const{SA\_RESTART} (vedi sez.~\ref{sec:sig_sigaction}) per
+riavviare le system call interrotte.
 
 Della funzione \func{sem\_wait} esistono due varianti che consentono di
 gestire diversamente le modalità di attesa in caso di risorsa occupata, la
-prima di queste è \funcd{sem\_trywait} che serve ad effettuare un tentativo di
-acquisizione senza bloccarsi; il suo prototipo è:
+prima di queste è \funcd{sem\_trywait}, che serve ad effettuare un tentativo
+di acquisizione senza bloccarsi; il suo prototipo è:
 \begin{functions}
   \headdecl{semaphore.h} 
   
@@ -4098,14 +4107,17 @@ acquisizione senza bloccarsi; il suo prototipo 
 }
 \end{functions}
 
-La funzione è identica a \func{sem\_wait} ed ha lo stesso effetto (vale a dire
-che in caso di risorsa disponibile questa viene immediatamente acquisita), la
-differenza è che nel caso in cui il semaforo è occupato essa non si blocca e
-ritorna invece immediatamente, con un errore di \errval{EAGAIN}.
-
-La seconda variante è una estensione che può essere utilizzata soltanto se si
-definisce la macro \macro{\_XOPEN\_SOURCE} ad un valore di 600 prima di
-includere \texttt{semaphore.h}, è \func{sem\_timedwait}, il cui prototipo è:
+La funzione è identica a \func{sem\_wait} ed se la risorsa è libera ha lo
+stesso effetto, vale a dire che in caso di semaforo diverso da zero la
+funzione lo decrementa e ritorna immediatamente; la differenza è che nel caso
+in cui il semaforo è occupato essa non si blocca e di nuovo ritorna
+immediatamente, restituendo però un errore di \errval{EAGAIN}, così che il
+programma possa proseguire.
+
+La seconda variante di \func{sem\_wait} è una estensione specifica che può
+essere utilizzata soltanto se viene definita la macro \macro{\_XOPEN\_SOURCE}
+ad un valore di 600 prima di includere \texttt{semaphore.h}, la funzione è
+\func{sem\_timedwait}, ed il suo prototipo è:
 \begin{functions}
   \headdecl{semaphore.h} 
 
@@ -4119,18 +4131,23 @@ includere \texttt{semaphore.h}, 
     \begin{errlist}
     \item[\errcode{ETIMEDOUT}] è scaduto il tempo massimo di attesa. 
     \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
     \end{errlist}    
 }
 \end{functions}
 
 Anche in questo caso il comportamento della funzione è identico a quello di
-\func{sem\_wait}, solo che in questo caso è possibile impostare, con
-l'argomento \param{abs\_timeout}, un tempo limite scaduto il quale la funzione
-ritorna comunque anche se non è possibile acquisire il semaforo, riportando un
-errore di \errval{ETIMEDOUT}.
-
-La seconda funzione di gestione dei semafori è \funcd{sem\_post}, che viene
-utilizzata per rilasciare un semaforo occupato; il suo prototipo è:
+\func{sem\_wait}, la sola differenza consiste nel fatto che con questa
+funzione è possibile impostare tramite l'argomento \param{abs\_timeout} un
+tempo limite per l'attesa, scaduto il quale la funzione ritorna comunque,
+anche se non è possibile acquisire il semaforo. In tal caso la funzione
+fallirà, riportando un errore di \errval{ETIMEDOUT}.
+
+La seconda funzione principale utilizzata per l'uso dei semafori è
+\funcd{sem\_post}, che viene usata per rilasciare un semaforo occupato o, in
+generale, per aumentare di una unità il valore dello stesso anche qualora non
+fosse occupato;\footnote{si ricordi che in generale un semaforo viene usato
+  come indicatore di un numero di risorse disponibili.} il suo prototipo è:
 \begin{functions}
   \headdecl{semaphore.h} 
   
@@ -4146,26 +4163,195 @@ utilizzata per rilasciare un semaforo occupato; il suo prototipo 
 }
 \end{functions}
 
-La funzione incrementa il valore del semaforo puntato dall'argomento
-\param{sem}, se questo era nullo la relativa risorsa risulterà sbloccata,
-cosicché un altro processo (o thread) bloccato in una \func{sem\_wait} sul
-suddetto semaforo potrà essere svegliato e rimesso in esecuzione. Si tenga
-presente che la funzione è è sicura per l'uso all'interno di un gestore di
-segnali.
+La funzione incrementa di uno il valore corrente del semaforo indicato
+dall'argomento \param{sem}, se questo era nullo la relativa risorsa risulterà
+sbloccata, cosicché un altro processo (o \itindex{thread} \textit{thread})
+eventualmente bloccato in una \func{sem\_wait} sul semaforo potrà essere
+svegliato e rimesso in esecuzione.  Si tenga presente che la funzione è sicura
+\index{funzioni!sicure} per l'uso all'interno di un gestore di segnali (si
+ricordi quanto detto in sez.~\ref{sec:sig_signal_handler}).
+
+Se invece di operare su un semaforo se ne vuole solamente leggere il valore,
+si può usare la funzione \funcd{sem\_getvalue}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_getvalue(sem\_t *sem, int *sval)}
+  
+  Richiede il valore del semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione legge il valore del semaforo indicato dall'argomento \param{sem} e
+lo restituisce nella variabile intera puntata dall'argomento
+\param{sval}. Qualora ci siano uno o più processi bloccati in attesa sul
+semaforo lo standard prevede che la funzione possa restituire un valore nullo
+oppure il numero di processi bloccati in una \func{sem\_wait} sul suddetto
+semaforo; nel caso di Linux vale la prima opzione.
 
+Questa funzione può essere utilizzata per avere un suggerimento sullo stato di
+un semaforo, ovviamente non si può prendere il risultato riportato in
+\param{sval} che come indicazione, il valore del semaforo infatti potrebbe
+essere già stato modificato al ritorno della funzione.
 
+% TODO verificare comportamento sem_getvalue
 
+Una volta che non ci sia più la necessità di operare su un semaforo se ne può
+terminare l'uso con la funzione \funcd{sem\_close}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_close(sem\_t *sem)}
+  
+  Chiude il semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione chiude il semaforo indicato dall'argomento \param{sem}; questo
+comporta che tutte le risorse che il sistema può avere assegnato al processo
+nell'uso dello stesso vengono rilasciate. Questo significa che un altro
+processo bloccato sul semaforo a causa della acquisizione da parte del
+processo che chiama \func{sem\_close} potrà essere riavviato.
+
+Si tenga presente poi che come per i file all'uscita di un processo tutti i
+semafori che questo aveva aperto vengono automaticamente chiusi; questo
+comportamento risolve il problema che si aveva con i semafori del \textit{SysV
+  IPC} (di cui si è parlato in sez.~\ref{sec:ipc_sysv_sem}) per i quali le
+risorse possono restare bloccate. Si tenga poi presente che, a differenza di
+quanto avviene per i file, in caso di una chiamata ad \func{execve} tutti i
+semafori vengono chiusi automaticamente.
+
+Come per i semafori del \textit{SysV IPC} anche quelli POSIX hanno una
+persistenza di sistema; questo significa che una volta che si è creato un
+semaforo con \func{sem\_open} questo continuerà ad esistere fintanto che il
+kernel resta attivo (vale a dire fino ad un successivo riavvio) a meno che non
+lo si cancelli esplicitamente. Per far questo si può utilizzare la funzione
+\funcd{sem\_unlink}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_unlink(const char *name)}
+  
+  Rimuove il semaforo \param{name}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EACCESS}] non si hanno i permessi necessari a cancellare il
+      semaforo.
+    \item[\errcode{ENAMETOOLONG}] il nome indicato è troppo lungo.
+    \item[\errcode{ENOENT}] il semaforo \param{name} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione rimuove il semaforo indicato dall'argomento \param{name}, che
+prende un valore identico a quello usato per creare il semaforo stesso con
+\func{sem\_open}. Il semaforo viene rimosso dal filesystem immediatamente; ma
+il semaforo viene effettivamente cancellato dal sistema soltanto quando tutti
+i processi che lo avevano aperto lo chiudono. Si segue cioè la stessa
+semantica usata con \func{unlink} per i file, trattata in dettaglio in
+sez.~\ref{sec:file_link}.
 
 Una delle caratteristiche peculiari dei semafori POSIX è che questi possono
-anche essere utilizzati in forma anonima. In questo caso si dovrà porre la
-variabile che contiene l'indirizzo del semaforo in un tratto di memoria che
-sia accessibile a tutti i processi in gioco. Questo può essere una variabile
-globale nel caso si usino i thread (nel qual caso si parla di
-\textit{thread-shared semaphore}), o un tratto di memoria condivisa nel caso
-si usino o processo (nel qual caso si parla di \textit{process-shared
-  semaphore}).
+anche essere utilizzati anche in forma anonima, senza necessità di fare
+ricorso ad un nome sul filesystem o ad altri indicativi.  In questo caso si
+dovrà porre la variabile che contiene l'indirizzo del semaforo in un tratto di
+memoria che sia accessibile a tutti i processi in gioco.  La funzione che
+consente di inizializzare un semaforo anonimo è \funcd{sem\_init}, il cui
+prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_init(sem\_t *sem, int pshared, unsigned int value)}
+
+  Inizializza il semaforo anonimo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il valore di \param{value} eccede
+      \const{SEM\_VALUE\_MAX}.
+    \item[\errcode{ENOSYS}] il valore di \param{pshared} non è nullo ed il
+      sistema non supporta i semafori per i processi.
+    \end{errlist}
+}
+\end{functions}
+
+La funzione inizializza un semaforo all'indirizzo puntato dall'argomento
+\param{sem}, e come per \func{sem\_open} consente di impostare un valore
+iniziale con \param{value}. L'argomento \param{pshared} serve ad indicare se
+il semaforo deve essere utilizzato dai \itindex{thread} \textit{thread} di uno
+stesso processo (con un valore nullo) o condiviso fra processi diversi (con un
+valore non nullo).
+
+Qualora il semaforo debba essere condiviso dai \itindex{thread}
+\textit{thread} di uno stesso processo (nel qual caso si parla di
+\textit{thread-shared semaphore}), occorrerà che \param{sem} sia l'indirizzo
+di una variabile visibile da tutti i \itindex{thread} \textit{thread}, si
+dovrà usare cioè una variabile globale o una variabile allocata dinamicamente
+nello \itindex{heap} heap.
+
+Qualora il semaforo debba essere condiviso fra più processi (nel qual caso si
+parla di \textit{process-shared semaphore}) la sola scelta possibile per
+renderlo visibile a tutti è di porlo in un tratto di memoria condivisa. Questo
+potrà essere ottenuto direttamente sia con \func{shmget} (vedi
+sez.~\ref{sec:ipc_sysv_shm}) che con \func{shm\_open} (vedi
+sez.~\ref{sec:ipc_posix_shm}), oppure, nel caso che tutti i processi in gioco
+abbiano un genitore comune, con una mappatura anonima con \func{mmap} (vedi
+sez.~\ref{sec:file_memory_map}),\footnote{si ricordi che i tratti di memoria
+  condivisa vengono mantenuti nei processi figli attraverso la funzione
+  \func{fork}.} a cui essi poi potranno accedere.
+
+Una volta inizializzato il semaforo anonimo con \func{sem\_init} lo si potrà
+utilizzare nello stesso modo dei semafori normali con \func{sem\_wait} e
+\func{sem\_post}. Si tenga presente però che inizializzare due volte lo stesso
+semaforo può dar luogo ad un comportamento indefinito. 
+
+
+Una volta che non si intenda più utilizzare un semaforo anonimo questo può
+essere eliminato da sistema; per far questo di deve utilizzare una apposita
+funzione, \funcd{sem\_destroy}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_destroy(sem\_t *sem)}
+
+  Elimina il semaforo anonimo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il valore di \param{value} eccede
+      \const{SEM\_VALUE\_MAX}.
+    \end{errlist}
+}
+\end{functions}
 
+La funzione prende come unico argomento l'indirizzo di un semaforo che deve
+essere stato inizializzato con \func{sem\_init}; non deve quindi essere
+applicata a semafori creati con \func{sem\_open}. Inoltre si deve essere
+sicuri che il semaforo sia effettivamente inutilizzato, la distruzione di un
+semaforo su cui sono presenti processi (o \itindex{thread} \textit{thread}) in
+attesa (cioè bloccati in una \func{sem\_wait}) provoca un comportamento
+indefinito.
 
+Si tenga presente infine che utilizzare un semaforo che è stato distrutto con
+\func{sem\_destroy} di nuovo può dare esito a comportamenti indefiniti.  Nel
+caso ci si trovi in una tale evenienza occorre reinizializzare il semaforo una
+seconda volta con \func{sem\_init}.
 
 
 % LocalWords:  like fifo System POSIX RPC Calls Common Object Request Brocker
@@ -4218,7 +4404,7 @@ si usino o processo (nel qual caso si parla di \textit{process-shared
 % LocalWords:  lrt blocks PAGECACHE TRUNC CLOEXEC mmap ftruncate munmap FindShm
 % LocalWords:  CreateShm RemoveShm LIBRARY Library libmqueue FAILED EACCESS
 % LocalWords:  ENAMETOOLONG qualchenome RESTART trywait XOPEN SOURCE timedwait
-% LocalWords:  process
+% LocalWords:  process getvalue sval execve pshared ENOSYS heap PAGE destroy
 
 
 %%% Local Variables: