+identico è l'uso degli argomenti \param{key} e \param{flag} per cui non
+ripeteremo quanto detto al proposito in \secref{sec:ipc_sysv_mq}. L'argomento
+\param{size} specifica invece la dimensione, in byte, del segmento, che viene
+comunque arrotondata al multiplo superiore di \macro{PAGE\_SIZE}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}[labelstep=0]{}
+struct shmid_ds {
+ struct ipc_perm shm_perm; /* operation perms */
+ int shm_segsz; /* size of segment (bytes) */
+ time_t shm_atime; /* last attach time */
+ time_t shm_dtime; /* last detach time */
+ time_t shm_ctime; /* last change time */
+ unsigned short shm_cpid; /* pid of creator */
+ unsigned short shm_lpid; /* pid of last operator */
+ short shm_nattch; /* no. of current attaches */
+};
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \var{shmid\_ds}, associata a ciascun segmento di
+ memoria condivisa.}
+ \label{fig:ipc_shmid_ds}
+\end{figure}
+
+A ciascun segmento di memoria condivisa è associata una struttura
+\var{shmid\_ds}, riportata in \figref{fig:ipc_shmid_ds}. Come nel caso delle
+code di messaggi quando si crea un nuovo segmento di memoria condivisa con
+\func{shmget} questa struttura viene inizializzata, in particolare il campo
+\var{shm\_perm} viene inizializzato come illustrato in
+\secref{sec:ipc_sysv_access_control}, e valgono le considerazioni ivi fatte
+relativamente ai permessi di accesso; per quanto riguarda gli altri campi
+invece:
+\begin{itemize*}
+\item il campo \var{shm\_segsz}, che esprime la dimensione del segmento, viene
+ inizializzato al valore di \param{size}.
+\item il campo \var{shm\_ctime}, che esprime il tempo di creazione del
+ segmento, viene inizializzato al tempo corrente.
+\item i campi \var{shm\_atime} e \var{shm\_atime}, che esprimno
+ rispettivamente il tempo dell'ultima volta che il segmento è stato
+ agganciato o sganciato da un processo, vengono inizializzati a zero.
+\item il campo \var{shm\_lpid}, che esprime il \acr{pid} del processo che ha
+ eseguito l'ultima operazione, viene inizializzato a zero.
+\item il campo \var{shm\_cpid}, che esprime il \acr{pid} del processo che ha
+ creato il segmento, viene inizializzato al \acr{pid} del processo chiamante.
+\item il campo \var{shm\_nattac}, che esprime il numero di processi agganciati
+ al segmento viene inizializzato a zero.
+\end{itemize*}
+
+Come per le code di messaggi e gli insiemi di semafori, anche per i segmenti
+di memoria condivisa esistono una serie di limiti, i cui valori, riportati in
+\tabref{tab:ipc_shm_limits} sono associati ad altrettante costanti. Alcuni di
+questi limiti sono al solito accessibili e modificabili attraverso
+\func{sysctl} o scrivendo direttamente nei rispettivi file di
+\file{/proc/sys/kernel/}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|c|r|c|p{7cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Valore} & \textbf{File in \texttt{proc}}
+ & \textbf{Significato} \\
+ \hline
+ \hline
+ \macro{SHMALL}&0x200000&\file{shmall}& Numero massimo di pagine che
+ possono essere usate per i segmenti di
+ memoria condivisa. \\
+ \macro{SHMMAX}&0x2000000&\file{shmmax}& Dimensione massima di un segmento
+ di memoria condivisa.\\
+ \macro{SHMMNI}&4096&\file{msgmni}& Numero massimo di segmenti di memoria
+ condivisa presenti nel kernel.\\
+ \macro{SHMMIN}& 1& --- & Dimensione minima di un segmento di
+ memoria condivisa. \\
+ \hline
+ \end{tabular}
+ \caption{Valori delle costanti associate ai limiti dei segmenti di memoria
+ condivisa, insieme al relativo file in \file{/proc/sys/kernel/} ed al
+ valore preimpostato presente nel sistema.}
+ \label{tab:ipc_shm_limits}
+\end{table}
+
+Al solito la funzione che permette di effettuare le operazioni di controllo su
+un segmento di memoria condivisa è \func{shmctl}; il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/ipc.h}
+ \headdecl{sys/shm.h}
+
+ \funcdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)}
+
+ Esegue le operazioni di controllo su un segmento di memoria condivisa.
+
+ \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[\macro{EACCES}] Si è richiesto \macro{IPC\_STAT} ma i permessi non
+ consentono l'accesso in lettura al segmento.
+ \item[\macro{EINVAL}] O \param{shmid} o \param{cmd} hanno valori non
+ validi.
+ \item[\macro{EIDRM}] L'argomento \param{shmid} fa riferimento ad un
+ segmento che è stato cancellato.
+ \item[\macro{EPERM}] Si è specificato un comando con \macro{IPC\_SET} o
+ \macro{IPC\_RMID} senza i permessi necessari.
+ \item[\macro{EOVERFLOW}] L'argomento \param{shmid} fa riferimento ad un
+ segmento che è stato cancellato.
+ \end{errlist}
+ ed inoltre \macro{EFAULT}.}
+\end{functions}
+
+Il comportamento della funzione dipende dal valore del comando passato
+attraverso l'argomento \param{cmd}, i valori possibili sono i seguenti:
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\macro{IPC\_STAT}] Legge le informazioni riguardo il segmento di memoria
+ condivisa nella struttura \var{shmid\_ds} puntata da \param{buf}. Occorre
+ avere il permesso di lettura sulla coda.
+\item[\macro{IPC\_RMID}] Marca il segmento di memoria condivisa per la
+ rimozione, questo verrà cancellato effettivamente solo quando l'ultimo
+ processo ad esso agganciato si sarà staccato. Questo comando può essere
+ eseguito solo da un processo con userid effettivo, corrispondente al
+ creatore o al proprietario della coda, o all'amministratore.
+\item[\macro{IPC\_SET}] Permette di modificare i permessi ed il proprietario
+ del segmento. Per modificare i valori di \var{shm\_perm.mode},
+ \var{shm\_perm.uid} e \var{shm\_perm.gid} occorre essere il proprietario o
+ il creatore della coda, oppure l'amministratore. Compiuta l'operazione
+ aggiorna anche il valore del campo \var{shm\_ctime}.
+\item[\macro{SHM\_LOCK}] Abilita il \textit{memory locking}\index{memory
+ locking} (vedi \secref{sec:proc_mem_lock}) sul segmento di memoria
+ condivisa. Solo l'amministratore può utilizzare questo comando.
+\item[\macro{SHM\_UNLOCK}] Disabilita il \textit{memory locking}. Solo
+ l'amministratore può utilizzare questo comando.
+\end{basedescript}
+i primi tre comandi sono gli stessi già visti anche per le code ed i semafori,
+gli ultimi due sono delle estensioni previste solo in Linux.
+
+Per utilizzare i segmenti di memoria condivisa si usano due funzioni, la prima
+di queste è \func{shmat}, che serve ad agganciare un segmento al processo
+chiamante, in modo che quest'ultimo possa vederlo nel suo spazio di indirizzi;
+il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/shm.h}
+
+ \funcdecl{void *shmat(int shmid, const void *shmaddr, int shmflg)}
+ Aggancia al processo un segmento di memoria condivisa.
+
+ \bodydesc{La funzione restituisce l'indirizzo del segmento in caso di
+ successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i
+ valori:
+ \begin{errlist}
+ \item[\macro{EACCES}] Il processo non ha i privilegi per accedere al
+ segmento nella modalità richiesta.
+ \item[\macro{EINVAL}] Si è specificato un identificatore invalido per
+ \param{shmid}, o un indirizzo non allineato sul confine di una pagina
+ per \param{shmaddr}.
+ \item[\macro{EIDRM}] Si è richiesto un segmento marcato per la
+ cancellazione.
+ \end{errlist}
+ ed inoltre \macro{ENOMEM}.}
+\end{functions}
+
+La funzione inserisce un segmento di memoria condivisa all'interno dello
+spazio di indirizzi del processo, come mostrato in così che questo possa
+accedervi, 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 \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, che
+verrà restituito dalla funzione.
+
+
+La seconda funzione è \func{shmdt}, che consente di sganciare un segmento di
+memoria condivisa dal processo chiamante, , quando questo non è più
+necessario, il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/shm.h}
+
+ \funcdecl{int shmdt(const void *shmaddr)}
+ Sgancia dal processo un segmento di memoria condivisa.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
+ errore, la funzione fallisce solo quando non c'è un segmento agganciato
+ all'indirizzo \func{shmaddr}, con \var{errno} che assume il valore
+ \macro{EINVAL}.}
+\end{functions}
+
+
+
+
+