+\item se il permesso per gli altri è appropriato l'accesso è consentito.
+\end{itemize}
+solo se tutti i controlli elencati falliscono l'accesso è negato. Si noti che
+a differenza di quanto avviene per i permessi dei file, fallire in uno dei
+passi elencati non comporta il fallimento dell'accesso. Un'altra differenza è
+che per gli oggetti di IPC il valore di \var{umask} (si ricordi quanto esposto
+in \secref{sec:file_umask}) non ha alcun effetto.
+
+
+\subsection{Gli identificatori ed il loro utilizzo}
+\label{sec:ipc_sysv_id_use}
+
+L'unico campo di \var{ipc\_perm} del quale non abbiamo ancora parlato è
+\var{seq}, che in \figref{fig:ipc_ipc_perm} è qualificato con un criptico
+``\textit{numero di sequenza}'', ne parliamo adesso dato che esso è
+strettamente attinente alle modalità con cui il kernel assegna gli
+identificatori degli oggetti del sistema di IPC.
+
+Quando il sistema si avvia, alla creazione di ogni nuovo oggetto di IPC viene
+assegnato un numero progressivo, pari al numero di oggetti di quel tipo
+esistenti. Se il comportamente fosse sempre questo sarebbe identico a quello
+usato nell'assegnazione dei file descriptor nei processi, ed i valori degli
+identificatori tenderebbero ad essere riutilizzati spesso e restare di piccole
+dimensioni ed inferiori al numero massimo di oggetti diponibili.
+
+Questo va benissimo nel caso dei file descriptor, che sono locali ad un
+processo, ma qui il comportamento varrebbe per tutto il sistema, e per
+processi del tutto scorrelati fra loro. Così si potrebbero avere situazioni
+come quella in cui un server esce e cancella le sue code di messaggi, ed il
+relativo identificatore viene immediatamente assegnato a quelle di un altro
+server partito subito dopo, con la possibilità che i client del primo non
+facciano in tempo ad accorgersi dell'avvenuto, e finiscano con l'interagire
+con gli oggetti del secondo, con conseguenze imprevedibili.
+
+Proprio per evitare questo tipo di situazioni il sistema usa il valore di
+\var{req} per provvedere un meccanismo che porti gli identificatori ad
+assumere tutti i valori possibili, rendendo molto più lungo il periodo in cui
+un identificatore può venire riutilizzato.
+
+Il sistema dispone sempre di un numero fisso di oggetti di IPC,\footnote{fino
+ al kernel 2.2.x questi valori, definiti dalle costanti \macro{MSGMNI},
+ \macro{SEMMNI} e \macro{SHMMNI}, potevano essere cambiati (come tutti gli
+ altri limiti relativi al \textit{System V IPC}) solo con una ricompilazione
+ del kernel, andando a modificarne la definizione nei relativi haeder 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 \texttt{syscntl}.} 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
+precedenza per restituire l'identificatore al numero di oggetti presenti viene
+sommato il valore di \var{seq} moltiplicato per il numero massimo di oggetti
+di quel tipo,\footnote{questo vale fino ai kernel della serie 2.2.x, dalla
+ serie 2.4.x viene usato lo stesso fattore per tutti gli oggetti, esso è dato
+ dalla costante \macro{IPCMNI}, definita in \file{include/linux/ipc.h}, che
+ indica il limite massimo per il numero di oggetti di IPC, ed il cui valore è
+ 32768.} si evita così il riutilizzo degli stessi numeri, e si fa sì che
+l'identificatore assuma tutti i valori possibili.
+
+In \figref{fig:ipc_sysv_idtest} è riportato il codice di un semplice programma
+di test che si limita a creare un oggetto (specificato a riga di comando),
+stamparne il numero di identificatore e cancellarlo per un numero specificato
+di volte.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+int main(int argc, char *argv[])
+{
+ ...
+ switch (type) {
+ case 'q': /* Message Queue */
+ debug("Message Queue Try\n");
+ for (i=0; i<n; i++) {
+ id = msgget(IPC_PRIVATE, IPC_CREAT|0666);
+ printf("Identifier Value %d \n", id);
+ msgctl(id, IPC_RMID, NULL);
+ }
+ break;
+ case 's': /* Semaphore */
+ debug("Semaphore\n");
+ for (i=0; i<n; i++) {
+ id = semget(IPC_PRIVATE, 1, IPC_CREAT|0666);
+ printf("Identifier Value %d \n", id);
+ semctl(id, 0, IPC_RMID);
+ }
+ break;
+ case 'm': /* Shared Memory */
+ debug("Shared Memory\n");
+ for (i=0; i<n; i++) {
+ id = shmget(IPC_PRIVATE, 1000, IPC_CREAT|0666);
+ printf("Identifier Value %d \n", id);
+ shmctl(id, IPC_RMID, NULL);
+ }
+ break;
+ default: /* should not reached */
+ return -1;
+ }
+ return 0;
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione principale del programma di test per l'assegnazione degli
+ identificatori degli oggetti di IPC \file{IPCTestId.c}.}
+ \label{fig:ipc_sysv_idtest}
+\end{figure}