\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{EAFNOSUPPORT}] I socket locali non sono supportati.
- \item[\errcode{EPROTONOSUPPORT}] Il protocollo specificato non è supportato.
- \item[\errcode{EOPNOTSUPP}] Il protocollo specificato non supporta la
+ \item[\errcode{EAFNOSUPPORT}] i socket locali non sono supportati.
+ \item[\errcode{EPROTONOSUPPORT}] il protocollo specificato non è supportato.
+ \item[\errcode{EOPNOTSUPP}] il protocollo specificato non supporta la
creazione di coppie di socket.
\end{errlist}
ed inoltre \errval{EMFILE}, \errval{EFAULT}.
\bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EACCES}] Il processo chiamante non ha i privilegi per accedere
+ \item[\errcode{EACCES}] il processo chiamante non ha i privilegi per accedere
alla coda richiesta.
- \item[\errcode{EEXIST}] Si è richiesta la creazione di una coda che già
+ \item[\errcode{EEXIST}] si è richiesta la creazione di una coda che già
esiste, ma erano specificati sia \const{IPC\_CREAT} che \const{IPC\_EXCL}.
- \item[\errcode{EIDRM}] La coda richiesta è marcata per essere cancellata.
- \item[\errcode{ENOENT}] Si è cercato di ottenere l'identificatore di una coda
+ \item[\errcode{EIDRM}] la coda richiesta è marcata per essere cancellata.
+ \item[\errcode{ENOENT}] si è cercato di ottenere l'identificatore di una coda
di messaggi specificando una chiave che non esiste e \const{IPC\_CREAT}
non era specificato.
- \item[\errcode{ENOSPC}] Si è cercato di creare una coda di messaggi quando è
+ \item[\errcode{ENOSPC}] si è cercato di creare una coda di messaggi quando è
stato superato il limite massimo di code (\const{MSGMNI}).
\end{errlist}
ed inoltre \errval{ENOMEM}.
\bodydesc{La funzione restituisce 0 in caso di successo o -1 in caso di
errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EACCES}] Si è richiesto \const{IPC\_STAT} ma processo
+ \item[\errcode{EACCES}] si è richiesto \const{IPC\_STAT} ma processo
chiamante non ha i privilegi di lettura sulla coda.
- \item[\errcode{EIDRM}] La coda richiesta è stata cancellata.
- \item[\errcode{EPERM}] Si è richiesto \const{IPC\_SET} o \const{IPC\_RMID} ma
+ \item[\errcode{EIDRM}] la coda richiesta è stata cancellata.
+ \item[\errcode{EPERM}] si è richiesto \const{IPC\_SET} o \const{IPC\_RMID} ma
il processo non ha i privilegi, o si è richiesto di aumentare il valore di
\var{msg\_qbytes} oltre il limite \const{MSGMNB} senza essere
amministratore.
\bodydesc{La funzione restituisce 0, e -1 in caso di 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 è
+ \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}.
- \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
- \item[\errcode{EINVAL}] Si è specificato un \param{msgid} invalido, o un
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \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}
successo, e -1 in caso di 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
+ \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{EINTR}] La funzione è stata interrotta da un segnale mentre
+ \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
+ \item[\errcode{EINVAL}] si è specificato un \param{msgid} invalido o un
valore di \param{msgsz} negativo.
\end{errlist}
ed inoltre \errval{EFAULT}.
demandata al kernel. La forma più semplice di semaforo è quella del
\textsl{semaforo binario}, o \textit{mutex}, in cui un valore diverso da zero
(normalmente 1) indica la libertà di accesso, e un valore nullo l'occupazione
-della risorsa; in generale però si possono usare semafori con valori interi,
+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.
\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
+ \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
+ \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
+ \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},
diventa necessario indicare esplicitamente che si vuole il ripristino del
semaforo all'uscita del processo.
-
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
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
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
+ \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{EPERM}] Si è richiesto \const{IPC\_SET} o \const{IPC\_RMID}
+ \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
+ \item[\errcode{EPERM}] si è richiesto \const{IPC\_SET} o \const{IPC\_RMID}
ma il processo non ha privilegi sufficienti ad eseguire l'operazione.
- \item[\errcode{ERANGE}] Si è richiesto \const{SETALL} \const{SETVAL} ma il
+ \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}
\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
+ \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
+ \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.
- \item[\errcode{EAGAIN}] Un'operazione comporterebbe il blocco del processo,
+ \item[\errcode{EAGAIN}] un'operazione comporterebbe il blocco del processo,
ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg}.
- \item[\errcode{EINTR}] La funzione, bloccata in attesa dell'esecuzione
+ \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
+ \item[\errcode{E2BIG}] l'argomento \param{nsops} è maggiore del numero
massimo di operazioni \const{SEMOPM}.
- \item[\errcode{ERANGE}] Per alcune operazioni il valore risultante del
+ \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}.
\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 è superato il limite (\const{SHMMNI}) sul numero
+ \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
la memoria ad essi riservata.
- \item[\errcode{EINVAL}] Si è richiesta una dimensione per un nuovo segmento
+ \item[\errcode{EINVAL}] si è richiesta una dimensione per un nuovo segmento
maggiore di \const{SHMMAX} o minore di \const{SHMMIN}, o se il segmento
già esiste \param{size} è maggiore delle sue dimensioni.
- \item[\errcode{ENOMEM}] Il sistema non ha abbastanza memoria per poter
+ \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},
\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
errore, nel qual caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\errcode{EACCES}] Si è richiesto \const{IPC\_STAT} ma i permessi non
+ \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
\param{cmd} non è un comando valido.
- \item[\errcode{EIDRM}] L'argomento \param{shmid} fa riferimento ad un
+ \item[\errcode{EIDRM}] l'argomento \param{shmid} fa riferimento ad un
segmento che è stato cancellato.
- \item[\errcode{EPERM}] Si è specificato un comando con \const{IPC\_SET} o
+ \item[\errcode{EPERM}] si è specificato un comando con \const{IPC\_SET} o
\const{IPC\_RMID} senza i permessi necessari.
- \item[\errcode{EOVERFLOW}] Si è tentato il comando \const{IPC\_STAT} ma il
+ \item[\errcode{EOVERFLOW}] si è tentato il comando \const{IPC\_STAT} ma il
valore del group-ID o dell'user-ID è troppo grande per essere
memorizzato nella struttura puntata da \param{buf}.
- \item[\errcode{EFAULT}] L'indirizzo specificato con \param{buf} non è
+ \item[\errcode{EFAULT}] l'indirizzo specificato con \param{buf} non è
valido.
\end{errlist}
}
successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i
valori:
\begin{errlist}
- \item[\errcode{EACCES}] Il processo non ha i privilegi per accedere al
+ \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
segmento nella modalità richiesta.
- \item[\errcode{EINVAL}] Si è specificato un identificatore invalido per
+ \item[\errcode{EINVAL}] si è specificato un identificatore invalido per
\param{shmid}, o un indirizzo non allineato sul confine di una pagina
per \param{shmaddr}.
\end{errlist}
La caratteristica fondamentale dell'interfaccia POSIX è l'abbandono dell'uso
degli identificatori e delle chiavi visti nel SysV IPC, per passare ai
-\textit{POSIX IPC names}\itindex{POSIX~IPC~names}, che sono sostanzialmente
+\itindex{POSIX~IPC~names} \textit{POSIX IPC names}, che sono sostanzialmente
equivalenti ai nomi dei file. Tutte le funzioni che creano un oggetto di IPC
POSIX prendono come primo argomento una stringa che indica uno di questi nomi;
lo standard è molto generico riguardo l'implementazione, ed i nomi stessi
richiesto è che:
\begin{itemize}
\item i nomi devono essere conformi alle regole che caratterizzano i
- \itindex{pathname}\textit{pathname}, in particolare non essere più lunghi di
+ \itindex{pathname} \textit{pathname}, in particolare non essere più lunghi di
\const{PATH\_MAX} byte e terminati da un carattere nullo.
\item se il nome inizia per una \texttt{/} chiamate differenti allo stesso
nome fanno riferimento allo stesso oggetto, altrimenti l'interpretazione del
dettagli si faccia riferimento a sez.~\ref{sec:ipc_posix_shm},
sez.~\ref{sec:ipc_posix_sem} e sez.~\ref{sec:ipc_posix_mq}) ed i nomi
specificati nelle relative funzioni sono considerati come un
-\itindsub{pathname}{assoluto}\textit{pathname} assoluto (comprendente
+\itindsub{pathname}{assoluto} \textit{pathname} assoluto (comprendente
eventuali sottodirectory) rispetto a queste radici.
Il vantaggio degli oggetti di IPC POSIX è comunque che essi vengono inseriti
nell'albero dei file, e possono essere maneggiati con le usuali funzioni e
comandi di accesso ai file,\footnote{questo è vero nel caso di Linux, che usa
una implementazione che lo consente, non è detto che altrettanto valga per
- altri kernel; in particolare sia la memoria condivisa che per le code di
- messaggi, come si può facilmente evincere con uno \cmd{strace}, le system
- call utilizzate sono le stesse, in quanto detti oggetti sono realizzati con
- dei file in speciali filesystem.} che funzionano come su dei file normali.
+ altri kernel; in particolare, come si può facilmente verificare con uno
+ \cmd{strace}, sia per la memoria condivisa che per le code di messaggi le
+ system call utilizzate da Linux sono le stesse di quelle dei file, essendo
+ detti oggetti realizzati come tali in appositi filesystem.} che funzionano
+come su dei file normali.
In particolare i permessi associati agli oggetti di IPC POSIX sono identici ai
-permessi dei file, e il controllo di accesso segue esattamente la stessa
-semantica (quella illustrata in sez.~\ref{sec:file_access_control}), invece di
+permessi dei file, ed il controllo di accesso segue esattamente la stessa
+semantica (quella illustrata in sez.~\ref{sec:file_access_control}), e non
quella particolare (si ricordi quanto visto in
-sez.~\ref{sec:ipc_sysv_access_control}) usata per gli oggetti del SysV IPC.
-Per quanto riguarda l'attribuzione dell'utente e del gruppo proprietari
-dell'oggetto alla creazione di quest'ultimo essa viene effettuata secondo la
-semantica SysV; essi corrispondono cioè a userid e groupid effettivi del
-processo che esegue la creazione.
-
+sez.~\ref{sec:ipc_sysv_access_control}) che viene usata per gli oggetti del
+SysV IPC. Per quanto riguarda l'attribuzione dell'utente e del gruppo
+proprietari dell'oggetto alla creazione di quest'ultimo essa viene effettuata
+secondo la semantica SysV: corrispondono cioè a user-ID e group-ID effettivi
+del processo che esegue la creazione.
\subsection{Code di messaggi}
mutex (o semafori) e memoria condivisa con tutta la flessibilità che occorre.
Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel
-superiore al 2.6.6 (o precedente, purché cui siano stati opportunamente
-applicati i relativi patch) occorre utilizzare la libreria
-\file{libmqueue}\footnote{i programmi che usano le code di messaggi cioè
- devono essere compilati aggiungendo l'opzione \code{-lmqueue} al comando
- \cmd{gcc}, dato che le funzioni non fanno parte della libreria standard, in
- corrispondenza all'inclusione del supporto nel kernel ufficiale, anche le
- relative funzioni sono state inserite nelle \acr{glibc}, e presenti a
- partire dalla versione 2.3.4 delle medesime.} che contiene le funzioni
-dell'interfaccia POSIX.\footnote{in realtà l'implementazione è realizzata
- tramite delle speciali chiamate ad \func{ioctl} sui file del filesystem
- speciale su cui vengono mantenuti questi oggetti di IPC.}
+superiore al 2.6.6 (o precedente, se sono stati opportunamente applicati i
+relativi patch) occorre utilizzare la libreria \file{libmqueue}\footnote{i
+ programmi che usano le code di messaggi cioè devono essere compilati
+ aggiungendo l'opzione \code{-lmqueue} al comando \cmd{gcc}; in
+ corrispondenza all'inclusione del supporto nel kernel ufficiale anche
+ \file{libmqueue} è stata inserita nelle \acr{glibc}, a partire dalla
+ versione 2.3.4 delle medesime.} che contiene le funzioni dell'interfaccia
+POSIX.\footnote{in realtà l'implementazione è realizzata tramite delle
+ opportune chiamate ad \func{ioctl} sui file del filesystem speciale su cui
+ vengono mantenuti questi oggetti di IPC.}
La libreria inoltre richiede la presenza dell'apposito filesystem di tipo
\texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto
di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
valori:
\begin{errlist}
- \item[\errcode{EACCES}] Il processo non ha i privilegi per accedere al
+ \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
alla memoria secondo quanto specificato da \param{oflag}.
- \item[\errcode{EEXIST}] Si è specificato \const{O\_CREAT} e
+ \item[\errcode{EEXIST}] si è specificato \const{O\_CREAT} e
\const{O\_EXCL} ma la coda già esiste.
- \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
- \item[\errcode{EINVAL}] Il file non supporta la funzione, o si è
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] il file non supporta la funzione, o si è
specificato \const{O\_CREAT} con una valore non nullo di \param{attr} e
valori non validi di \var{mq\_maxmsg} e \var{mq\_msgsize}.
- \item[\errcode{ENOENT}] Non si è specificato \const{O\_CREAT} ma la coda
+ \item[\errcode{ENOENT}] non si è specificato \const{O\_CREAT} ma la coda
non esiste.
\end{errlist}
ed inoltre \errval{ENOMEM}, \errval{ENOSPC}, \errval{EFAULT},
\label{fig:ipc_mq_attr}
\end{figure}
-Per ls creazione della coda i campi della struttura che devono essere
+Per la creazione della coda i campi della struttura che devono essere
specificati sono \var{mq\_msgsize} e \var{mq\_maxmsg}, che indicano
rispettivamente la dimensione massima di un messaggio ed il numero massimo di
messaggi che essa può contenere. Il valore dovrà essere positivo e minore dei
\bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di
errore; nel quel caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\errcode{EAGAIN}] Si è aperta la coda con \const{O\_NONBLOCK}, e la
+ \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
coda è piena.
- \item[\errcode{EMSGSIZE}] La lunghezza del messaggio \param{msg\_len}
+ \item[\errcode{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
eccede il limite impostato per la coda.
- \item[\errcode{ENOMEM}] Il kernel non ha memoria sufficiente. Questo
+ \item[\errcode{ENOMEM}] il kernel non ha memoria sufficiente. Questo
errore può avvenire quando l'inserimento del messaggio
- \item[\errcode{EINVAL}] Si è specificato un valore nullo per
+ \item[\errcode{EINVAL}] si è specificato un valore nullo per
\param{msg\_len}, o un valore di \param{msg\_prio} fuori dai limiti, o
un valore non valido per \param{abs\_timeout}.
- \item[\errcode{ETIMEDOUT}] L'inserimento del messaggio non è stato
+ \item[\errcode{ETIMEDOUT}] l'inserimento del messaggio non è stato
effettuato entro il tempo stabilito.
\end{errlist}
ed inoltre \errval{EBADF} ed \errval{EINTR}.}
di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
valori:
\begin{errlist}
- \item[\errcode{EAGAIN}] Si è aperta la coda con \const{O\_NONBLOCK}, e la
+ \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
coda è vuota.
- \item[\errcode{EMSGSIZE}] La lunghezza del messaggio sulla coda eccede il
+ \item[\errcode{EMSGSIZE}] la lunghezza del messaggio sulla coda eccede il
valore \param{msg\_len} specificato per la ricezione.
- \item[\errcode{EINVAL}] Si è specificato un valore nullo per
+ \item[\errcode{EINVAL}] si è specificato un valore nullo per
\param{msg\_ptr}, o un valore non valido per \param{abs\_timeout}.
- \item[\errcode{ETIMEDOUT}] La ricezione del messaggio non è stata
+ \item[\errcode{ETIMEDOUT}] la ricezione del messaggio non è stata
effettuata entro il tempo stabilito.
\end{errlist}
ed inoltre \errval{EBADF}, \errval{EINTR}, \errval{ENOMEM}, o
La funzione estrae dalla coda il messaggio a priorità più alta, o il più
vecchio fra quelli della stessa priorità. Una volta ricevuto il messaggio
viene tolto dalla coda e la sua dimensione viene restituita come valore di
-ritorno.\footnote{si tenga presente che 0 è una dimensione valida la
+ritorno.\footnote{si tenga presente che 0 è una dimensione valida e che la
condizione di errore è restituita dal valore -1; Stevens in \cite{UNP2} fa
notare che questo è uno dei casi in cui vale ciò che lo standard
\textsl{non} dice, una dimensione nulla infatti, pur non essendo citata, non
\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{EBUSY}] C'è già un processo registrato per la notifica.
- \item[\errcode{EBADF}] Il descrittore non fa riferimento ad una coda di
+ \item[\errcode{EBUSY}] c'è già un processo registrato per la notifica.
+ \item[\errcode{EBADF}] il descrittore non fa riferimento ad una coda di
messaggi.
\end{errlist}}
\end{prototype}
-\subsection{Semafori}
-\label{sec:ipc_posix_sem}
-
-Fino alla serie 2.4.x del kernel esistevano due implementazioni dei semafori
-POSIX; una parziale 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.} presente
-nella sezione delle estensioni \textit{real-time} delle
-\acr{glibc},\footnote{quelle che si accedono collegandosi alla libreria
- \texttt{librt}.} ed una che realizzava 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
-\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 delle
-\acr{glibc} che usano questa nuova infrastruttura per quella che viene quella
-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
-\textit{real-time} \texttt{librt}, questo significa che se si vuole utilizzare
-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.
-
-
-
-
-\begin{functions}
- \headdecl{semaphore.h}
-
- \funcdecl{sem\_t *sem_open(const char *name, int oflag)}
-
- \funcdecl{sem\_t *sem_open(const char *name, int oflag,, mode_t mode,
- unsigned int value)}
-
- Crea un semaforo o ne apre uno esistente.
-
- \bodydesc{Le funzioni restituiscono il numero di byte del messaggio in caso
- di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
- valori:
- \begin{errlist}
- \item[\errcode{EAGAIN}] Si è aperta la coda con \const{O\_NONBLOCK}, e la
- coda è vuota.
- \end{errlist}
- ed inoltre \errval{EBADF}, \errval{EINTR}, \errval{ENOMEM}, o
- \errval{EINVAL}.}
-\end{functions}
-
-
\subsection{Memoria condivisa}
\label{sec:ipc_posix_shm}
restituendo al chiamante il valore di ritorno.
+
+
+\subsection{Semafori}
+\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}).
+
+A partire dal kernel 2.5.7 è stato introdotto un meccanismo di
+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 delle
+\acr{glibc} che usano questa nuova infrastruttura per quella che viene quella
+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
+\textit{real-time} \texttt{librt}, questo significa che se si vuole utilizzare
+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
+esistente o per crearne uno nuovi, i relativi prototipi sono:
+\begin{functions}
+ \headdecl{semaphore.h}
+
+ \funcdecl{sem\_t *sem\_open(const char *name, int oflag)}
+
+ \funcdecl{sem\_t *sem\_open(const char *name, int oflag, mode\_t mode,
+ unsigned int value)}
+
+ Crea un semaforo o ne apre uno esistente.
+
+ \bodydesc{La funzione restituisce l'indirizzo del semaforo in caso di
+ successo e \const{SEM\_FAILED} in caso di errore; nel quel caso
+ \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EACCESS}] il semaforo esiste ma non si hanno permessi
+ sufficienti per accedervi.
+ \item[\errcode{EEXIST}] si sono specificati \const{O\_CREAT} e
+ \const{O\_EXCL} ma il semaforo esiste.
+ \item[\errcode{EINVAL}] il valore di \param{value} eccede
+ \const{SEM\_VALUE\_MAX}.
+ \item[\errcode{ENAMETOOLONG}] si è utilizzato un nome troppo lungo.
+ \item[\errcode{ENOENT}] non si è usato \const{O\_CREAT} ed il nome
+ specificato non esiste.
+ \end{errlist}
+ ed inoltre \errval{ENFILE} ed \errval{ENOMEM}.}
+\end{functions}
+
+L'argomento \param{name} definisce il nome del semaforo che si vuole
+utilizzare, ed è quello che permette a processi diversi di accedere allo
+stesso semaforo. Questo deve essere specificato con un pathname nella forma
+\texttt{/qualchenome}, che non ha una corrispondenza diretta con un pathname
+reale; con Linux infatti i file associati ai semafori sono mantenuti nel
+filesystem virtuale \texttt{/dev/shm}, e gli viene assegnato automaticamente
+un nome nella forma \texttt{sem.qualchenome}.\footnote{si ha cioè una
+ corrispondenza per cui \texttt{/qualchenome} viene rimappato, nella
+ creazione tramite \func{sem\_open}, su \texttt{/dev/shm/sem.qualchenome}.}
+
+L'argomento \param{oflag} è quello che controlla le modalità con cui opera la
+funzione, ed è passato come maschera binaria; i bit corrispondono a quelli
+utilizzati per l'analogo argomento di \func{open}, anche se dei possibili
+valori visti in sez.~\ref{sec:file_open} sono utilizzati soltanto
+\const{O\_CREAT} e \const{O\_EXCL}.
+
+Se si usa \const{O\_CREAT} si richiede la creazione del semaforo qualora
+questo non esista, ed in tal caso occorre utilizzare la seconda forma della
+funzione, in cui si devono specificare sia un valore iniziale con l'argomento
+\param{value},\footnote{e si noti come così diventa possibile, differenza di
+ quanto avviene per i semafori del \textit{SysV IPC}, effettuare in maniera
+ atomica creazione ed inizializzazione di un semaforo usando una unica
+ funzione.} che una maschera dei permessi con l'argomento
+\param{mode};\footnote{anche questo argomento prende gli stessi valori
+ utilizzati per l'analogo di \func{open}, che si sono illustrati in dettaglio
+ sez.~\ref{sec:file_perm_overview}.} questi verranno assegnati al semaforo
+appena creato. Se il semaforo esiste già i suddetti valori saranno invece
+ignorati. Usando il flag \const{O\_EXCL} si richiede invece la verifica che il
+semaforo non esiste, usandolo insieme ad \const{O\_CREAT} la funzione fallisce
+qualora un semaforo con lo stesso nome sia già presente.
+
+La funzione restituisce in caso di successo un puntatore all'indirizzo del
+semaforo con un valore di tipo \ctyp{sem\_t *}, è questo valore che dovrà
+essere passato alle altre funzioni per operare sul semaforo stesso. Si tenga
+presente che, come accennato in sez.~\ref{sec:ipc_posix_generic}, i semafori
+usano la semantica standard dei file per quanto riguarda i controlli di
+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.
+
+Una volta che si sia ottenuto l'indirizzo di un semaforo, sarà possibile
+utilizzarlo; se si ricorda quanto detto all'inizio di
+sez.~\ref{sec:ipc_sysv_sem}, dove si sono introdotti i concetti generali
+relativi ai semafori, le operazioni principali sono due, quella che richiede
+l'uso di una risorsa bloccando il semaforo e quella che rilascia la risorsa
+liberando il semaforo. La prima operazione è effettuata dalla funzione
+\funcd{sem\_wait}, il cui prototipo è:
+\begin{functions}
+ \headdecl{semaphore.h}
+
+ \funcdecl{int sem\_wait(sem\_t *sem)}
+
+ Blocca 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{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+ \end{errlist}
+}
+\end{functions}
+
+La funzione cerca di decrementare il valore del semaforo indicato dal
+puntatore \param{sem}, se questo ha un valore positivo, cosa che significa che
+la risorsa è disponibile, la funzione ha successo, il valore del semaforo
+viene diminuito di 1 ed essa ritorna immediatamente; se il valore è nullo la
+funzione si blocca fintanto che il valore del semaforo non torni
+positivo\footnote{ovviamente per opera di altro processo che lo rilascia
+ chiamando \func{sem\_post}.} così che poi essa possa decrementarlo con
+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.
+
+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 è:
+\begin{functions}
+ \headdecl{semaphore.h}
+
+ \funcdecl{int sem\_trywait(sem\_t *sem)}
+
+ Tenta di bloccare 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à gli stessi valori:
+ \begin{errlist}
+ \item[\errcode{EAGAIN}] il semaforo non può essere acquisito senza
+ bloccarsi.
+ \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+ \end{errlist}
+}
+\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 è:
+\begin{functions}
+ \headdecl{semaphore.h}
+
+ \funcdecl{int sem\_timedwait(sem\_t *sem, const struct timespec
+ *abs\_timeout)}
+
+ Blocca 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à gli stessi valori:
+ \begin{errlist}
+ \item[\errcode{ETIMEDOUT}] è scaduto il tempo massimo di attesa.
+ \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+ \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 è:
+\begin{functions}
+ \headdecl{semaphore.h}
+
+ \funcdecl{int sem\_post(sem\_t *sem)}
+
+ Rilascia 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 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.
+
+
+
+
+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}).
+
+
+
+
% LocalWords: like fifo System POSIX RPC Calls Common Object Request Brocker
% LocalWords: Architecture descriptor kernel unistd int filedes errno EMFILE
% LocalWords: ENFILE EFAULT BUF sez fig fork Stevens siblings EOF read SIGPIPE
% 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
+% LocalWords: CreateShm RemoveShm LIBRARY Library libmqueue FAILED EACCESS
+% LocalWords: ENAMETOOLONG qualchenome RESTART trywait XOPEN SOURCE timedwait
+% LocalWords: process
%%% Local Variables: