comunque a che esso sia invocato periodicamente, generando un interrupt
periodico secondo la frequenza specificata dalla costante \const{HZ}, definita
in \file{asm/param.h}, ed il cui valore è espresso in Hertz.\footnote{Fino al
- kernel 2.4 l valore usuale di questa costante era 100, per tutte le
+ kernel 2.4 il valore usuale di questa costante era 100, per tutte le
architetture eccetto l'alpha, per la quale era 1000. Occorre fare attenzione
a non confondere questo valore con quello dei clock tick (vedi
sez.~\ref{sec:sys_unix_time}).}
Per quanto riguarda la gestione della memoria, in generale
il\index{segmento!testo} segmento di testo, che è identico per i due processi,
è condiviso e tenuto in read-only per il padre e per i figli. Per gli altri
-segmenti Linux utilizza la tecnica del \textit{copy on
- write}\itindex{copy~on~write}; questa tecnica comporta che una pagina di
-memoria viene effettivamente copiata per il nuovo processo solo quando ci
-viene effettuata sopra una scrittura (e si ha quindi una reale differenza fra
-padre e figlio). In questo modo si rende molto più efficiente il meccanismo
-della creazione di un nuovo processo, non essendo più necessaria la copia di
-tutto lo spazio degli indirizzi virtuali del padre, ma solo delle pagine di
-memoria che sono state modificate, e solo al momento della modifica stessa.
+segmenti Linux utilizza la tecnica del \textit{copy on write}
+\itindex{copy~on~write}; questa tecnica comporta che una pagina di memoria
+viene effettivamente copiata per il nuovo processo solo quando ci viene
+effettuata sopra una scrittura (e si ha quindi una reale differenza fra padre
+e figlio). In questo modo si rende molto più efficiente il meccanismo della
+creazione di un nuovo processo, non essendo più necessaria la copia di tutto
+lo spazio degli indirizzi virtuali del padre, ma solo delle pagine di memoria
+che sono state modificate, e solo al momento della modifica stessa.
La differenza che si ha nei due processi è che nel processo padre il valore di
ritorno della funzione \func{fork} è il \acr{pid} del processo figlio, mentre
(fino alla conclusione) e poi il padre.
In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di
-scheduling usato dal kernel, dalla particolare situazione in cui si trova la
-macchina al momento della chiamata, risultando del tutto impredicibile.
-Eseguendo più volte il programma di prova e producendo un numero diverso di
-figli, si sono ottenute situazioni completamente diverse, compreso il caso in
-cui il processo padre ha eseguito più di una \func{fork} prima che uno dei
-figli venisse messo in esecuzione.
+\itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione
+in cui si trova la macchina al momento della chiamata, risultando del tutto
+impredicibile. Eseguendo più volte il programma di prova e producendo un
+numero diverso di figli, si sono ottenute situazioni completamente diverse,
+compreso il caso in cui il processo padre ha eseguito più di una \func{fork}
+prima che uno dei figli venisse messo in esecuzione.
Pertanto non si può fare nessuna assunzione sulla sequenza di esecuzione delle
istruzioni del codice fra padre e figli, né sull'ordine in cui questi potranno
essere messi in esecuzione. Se è necessaria una qualche forma di precedenza
occorrerà provvedere ad espliciti meccanismi di sincronizzazione, pena il
-rischio di incorrere nelle cosiddette \textit{race
- condition}\itindex{race~condition} (vedi sez.~\ref{sec:proc_race_cond}).
+rischio di incorrere nelle cosiddette \textit{race condition}
+\itindex{race~condition} (vedi sez.~\ref{sec:proc_race_cond}).
Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli
processi completamente separati, le modifiche delle variabili nei processi
\func{fork} veniva fatta solo per poi eseguire una \func{exec}. La funzione
venne introdotta in BSD per migliorare le prestazioni.
-Dato che Linux supporta il \textit{copy on write}\itindex{copy~on~write} la
+Dato che Linux supporta il \textit{copy on write} \itindex{copy~on~write} la
perdita di prestazioni è assolutamente trascurabile, e l'uso di questa
funzione (che resta un caso speciale della system call \func{\_\_clone}) è
deprecato; per questo eviteremo di trattarla ulteriormente.
\end{verbatim} %$
\normalsize e come si vede, dato che non si è fatto nulla per riceverne lo
stato di terminazione, i tre processi figli sono ancora presenti pur essendosi
-conclusi, con lo stato di zombie\index{zombie} e l'indicazione che sono stati
+conclusi, con lo stato di zombie \index{zombie} e l'indicazione che sono stati
terminati.
-La possibilità di avere degli zombie\index{zombie} deve essere tenuta sempre
+La possibilità di avere degli zombie \index{zombie} deve essere tenuta sempre
presente quando si scrive un programma che deve essere mantenuto in esecuzione
a lungo e creare molti figli. In questo caso si deve sempre avere cura di far
leggere l'eventuale stato di uscita di tutti i figli (in genere questo si fa
attraverso un apposito \textit{signal handler}, che chiama la funzione
\func{wait}, vedi sez.~\ref{sec:sig_sigchld} e sez.~\ref{sec:proc_wait}).
-Questa operazione è necessaria perché anche se gli
-\textit{zombie}\index{zombie} non consumano risorse di memoria o processore,
-occupano comunque una voce nella tabella dei processi, che a lungo andare
-potrebbe esaurirsi.
+Questa operazione è necessaria perché anche se gli \textit{zombie}
+\index{zombie} non consumano risorse di memoria o processore, occupano
+comunque una voce nella tabella dei processi, che a lungo andare potrebbe
+esaurirsi.
Si noti che quando un processo adottato da \cmd{init} termina, esso non
diviene uno \textit{zombie}\index{zombie}; questo perché una delle funzioni di
provvedere a concluderne la terminazione.
-\subsection{Le funzioni \func{wait} e \func{waitpid}}
+\subsection{Le funzioni \func{wait} e \func{waitpid}}
\label{sec:proc_wait}
Uno degli usi più comuni delle capacità multitasking di un sistema unix-like
deve essere un programma valido (binario, non un altro script) che verrà
chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti]
filename}.\footnote{si tenga presente che con Linux quanto viene scritto
- come \texttt{argomenti} viene passato all'inteprete come un unico argomento
+ come \texttt{argomenti} viene passato all'interprete come un unico argomento
con una unica stringa di lunghezza massima di 127 caratteri e se questa
dimensione viene ecceduta la stringa viene troncata; altri Unix hanno
dimensioni massime diverse, e diversi comportamenti, ad esempio FreeBSD
esegue la scansione della riga e la divide nei vari argomenti e se è troppo
- lunga restitituisce un errore di \const{ENAMETOOLONG}, una comparazione dei
+ lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei
vari comportamenti si trova su
\href{http://www.in-ulm.de/~mascheck/various/shebang/}
{\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.}
ricorrere ad altre funzioni.
Le due funzioni \funcd{setreuid} e \funcd{setregid} derivano da BSD che, non
-supportando\footnote{almeno fino alla versione 4.3+BSD TODO, FIXME verificare
- e aggiornare la nota.} gli identificatori del gruppo \textit{saved}, le usa
-per poter scambiare fra di loro \textit{effective} e \textit{real}. I
-rispettivi prototipi sono:
+supportando\footnote{almeno fino alla versione 4.3+BSD.} gli identificatori
+del gruppo \textit{saved}, le usa per poter scambiare fra di loro
+\textit{effective} e \textit{real}. I rispettivi prototipi sono:
\begin{functions}
\headdecl{unistd.h}
\headdecl{sys/types.h}
\textbf{Capacità}&\textbf{Descrizione}\\
\hline
\hline
+%
+% POSIX-draft defined capabilities.
+%
\const{CAP\_CHOWN} & la capacità di cambiare proprietario e gruppo
proprietario di un file (vedi
sez.~\ref{sec:file_chown}).\\
di impostare il bit \acr{sgid} su un file anche
quando questo è relativo ad un gruppo cui non si
appartiene (vedi sez.~\ref{sec:file_chmod}).\\
- \const{CAP\_IPC\_LOCK} & la capacità di effettuare il \textit{memory
- locking} \itindex{memory~locking} con le
- funzioni \func{mlock}, \func{mlockall},
- \func{shmctl}, \func{mmap} (vedi
- sez.~\ref{sec:proc_mem_lock} e
- sez.~\ref{sec:file_memory_map}). \\
- \const{CAP\_IPC\_OWNER} & la capacità di evitare il controllo dei permessi
- per le operazioni sugli oggetti di
- intercomunicazione fra processi (vedi
- sez.~\ref{sec:ipc_sysv}).\\
\const{CAP\_KILL} & la capacità di mandare segnali a qualunque
processo (vedi sez.~\ref{sec:sig_kill_raise}).\\
- \const{CAP\_LEASE} & la capacità di creare dei \textit{file lease}
- \index{file!lease} su di un file (vedi
- sez.~\ref{sec:file_asyncronous_lease})
- indipendentemente dalla proprietà dello
- stesso.\footnotemark\\
- \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi
- \textit{immutable} e \textit{append only} per i
- file su un filesystem che supporta questi
- attributi estesi.\\
- \const{CAP\_MKNOD} & la capacità di creare file di dispositivo con la
- funzione \func{mknod} (vedi
- sez.~\ref{sec:file_mknod}).\footnotemark\\
- \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni
- privilegiate sulla rete (impostare le opzioni
- privilegiate dei socket, abilitare il
- multicasting, impostare interfacce di rete e
- tabella di instradamento).\\
- \const{CAP\_NET\_BIND\_SERVICE}& la capacità di porre in ascolto server
- su porte riservate (vedi
- sez.~\ref{sec:TCP_func_bind}).\\
- \const{CAP\_NET\_BROADCAST}& la capacità di consentire l'uso di socket in
- broadcast e multicast.\\
- \const{CAP\_NET\_RAW} & la capacità di usare socket \texttt{RAW} e
- \texttt{PACKET} (quelli che permettono di creare
- pacchetti nei protocolli di basso livello).\\
\const{CAP\_SETGID} & la capacità di manipolare i group ID dei
processi, sia il principale che i supplementari,
(vedi sez.~\ref{sec:proc_setgroups} che quelli
trasmessi tramite i \index{socket} socket
\textit{unix domain} (vedi
sez.~\ref{sec:unix_socket}).\\
- \const{CAP\_SETPCAP} & la capacità di impostare o rimuovere una capacità
- (limitatamente a quelle che il processo
- chiamante ha nel suo insieme di capacità
- permesse) da qualunque processo.\\
\const{CAP\_SETUID} & la capacità di manipolare gli user ID del
processo (con \func{setuid}, \func{setreuid},
\func{setresuid}, \func{setfsuid}) e di
trasmettere un valore arbitrario
dell'\textsl{uid} nel passaggio delle
credenziali coi socket unix domain (vedi
- sez.~\ref{sec:unix_socket_xxx}).\\
+ sez.~\ref{sec:unix_socket}).\\
+%
+% Linux specific capabilities
+%
+\hline
+ \const{CAP\_SETPCAP} & la capacità di impostare o rimuovere una capacità
+ (limitatamente a quelle che il processo
+ chiamante ha nel suo insieme di capacità
+ permesse) da qualunque processo.\\
+ \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi
+ \textit{immutable} e \textit{append only} per i
+ file su un filesystem che supporta questi
+ attributi estesi.\\
+ \const{CAP\_NET\_BIND\_SERVICE}& la capacità di porre in ascolto server
+ su porte riservate (vedi
+ sez.~\ref{sec:TCP_func_bind}).\\
+ \const{CAP\_NET\_BROADCAST}& la capacità di consentire l'uso di socket in
+ \itindex{broadcast} \textit{broadcast} e
+ \itindex{multicast} \textit{multicast}.\\
+ \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni
+ privilegiate sulla rete (impostare le opzioni
+ privilegiate dei socket, abilitare il
+ \itindex{multicast} \textit{multicasting},
+ impostare interfacce di rete e
+ tabella di instradamento).\\
+ \const{CAP\_NET\_RAW} & la capacità di usare socket \texttt{RAW} e
+ \texttt{PACKET} (quelli che permettono di creare
+ pacchetti nei protocolli di basso livello).\\
+ \const{CAP\_IPC\_LOCK} & la capacità di effettuare il \textit{memory
+ locking} \itindex{memory~locking} con le
+ funzioni \func{mlock}, \func{mlockall},
+ \func{shmctl}, \func{mmap} (vedi
+ sez.~\ref{sec:proc_mem_lock} e
+ sez.~\ref{sec:file_memory_map}). \\
+ \const{CAP\_IPC\_OWNER} & la capacità di evitare il controllo dei permessi
+ per le operazioni sugli oggetti di
+ intercomunicazione fra processi (vedi
+ sez.~\ref{sec:ipc_sysv}).\\
+ \const{CAP\_SYS\_MODULE}& la capacità di caricare e rimuovere moduli del
+ kernel. \\
+ \const{CAP\_SYS\_RAWIO} & la capacità di eseguire operazioni sulle porte
+ di I/O con \func{ioperm} e \func{iopl} (vedi
+ sez.~\ref{sec:file_io_port}).\\
+ \const{CAP\_SYS\_CHROOT}& la capacità di eseguire la funzione
+ \func{chroot} (vedi
+ sez.~\ref{sec:file_chroot}).\\
+ \const{CAP\_SYS\_PTRACE}& consente di tracciare qualunque processo con
+ \func{ptrace} (vedi
+ sez.~\ref{sec:xxx_ptrace}).\\
+% TODO documentatare ptrace
+ \const{CAP\_SYS\_PACCT} & la capacità di usare le funzioni di
+ \textit{accounting} dei processi (vedi
+ sez.~\ref{sec:sys_bsd_accounting}).\\
\const{CAP\_SYS\_ADMIN} & la capacità di eseguire una serie di compiti
amministrativi (come impostare le quote,
attivare e disattivare la swap, montare,
rimontare e smontare filesystem, ecc.). \\
- \const{CAP\_SYS\_BOOT} & la capacità di fare eseguire un reboot del
+ \const{CAP\_SYS\_BOOT} & la capacità di fare eseguire un riavvio del
sistema.\\
- \const{CAP\_SYS\_CHROOT}& la capacità di eseguire la funzione
- \func{chroot} (vedi
- sez.~\ref{sec:file_chroot}).\\
- \const{CAP\_SYS\_MODULE}& la capacità di caricare e rimuovere moduli del
- kernel. \\
\const{CAP\_SYS\_NICE} & la capacità di modificare le priorità dei
processi (vedi sez.~\ref{sec:proc_priority}). \\
- \const{CAP\_SYS\_PACCT} & la capacità di usare le funzioni di
- \textit{accounting} dei processi (vedi
- sez.~\ref{sec:sys_bsd_accounting}).\\
- \const{CAP\_SYS\_RAWIO} & la capacità di eseguire operazioni sulle porte
- di I/O con \func{ioperm} e \func{iopl} (vedi
- sez.~\ref{sec:file_io_port}).\\
\const{CAP\_SYS\_RESOURCE}& la capacità di superare le limitazioni sulle
risorse, aumentare le quote disco, usare lo
spazio disco riservato all'amministratore.\\
\const{CAP\_SYS\_TTY\_CONFIG}& la capacità di simulare un \textit{hangup}
della console, con la funzione
\func{vhangup}.\\
- \const{CAP\_SYS\_PTRACE}& consente di tracciare qualunque processo con
- \func{ptrace} (vedi
- sez.~\ref{sec:xxx_ptrace}).\\
-% TODO documentatare ptrace
+ \const{CAP\_MKNOD} & la capacità di creare file di dispositivo con la
+ funzione \func{mknod} (vedi
+ sez.~\ref{sec:file_mknod}).\footnotemark\\
+ \const{CAP\_LEASE} & la capacità di creare dei \textit{file lease}
+ \index{file!lease} su di un file (vedi
+ sez.~\ref{sec:file_asyncronous_lease})
+ indipendentemente dalla proprietà dello
+ stesso.\footnotemark\\
+ \const{CAP\_SETFCAP} & la capacità di impostare le
+ \textit{capabilities} di un file (non
+ supportata).\\
\hline
\end{tabular}
\caption{Le costanti che identificano le \textit{capabilities} presenti nel
\label{tab:proc_capabilities}
\end{table}
-\footnotetext[21]{questa capacità è presente soltato a partire dai kernel
+\footnotetext[21]{questa capacità è presente soltanto a partire dai kernel
della serie 2.4.x.}
-\footnotetext{questa capacità è presente soltato a partire dai kernel della
+\footnotetext{questa capacità è presente soltanto a partire dai kernel della
serie 2.4.x.}
Per gestire questo nuovo meccanismo ciascun processo porta con sé tre distinti
ciascun bit corrisponde ad una capacità diversa; se ne è riportato
l'elenco,\footnote{si tenga presente che l'elenco delle \textit{capabilities}
presentato questa tabella, ripreso dalla relativa pagina di manuale
- (accessibile con \texttt{man capabilities}), è quello aggiornato al kernel
- 2.6.6.} con una breve descrizione, ed il nome delle costanti che
-identificano i singoli bit, in tab.~\ref{tab:proc_capabilities}.
+ (accessibile con \texttt{man capabilities}) e dalle definizioni in
+ \texttt{sys/capabilities.h}, è quello aggiornato al kernel 2.6.6.} con una
+breve descrizione, ed il nome delle costanti che identificano i singoli bit,
+in tab.~\ref{tab:proc_capabilities}; la tabella è divisa in due parti, la
+prima riporta le \textit{capabilities} previste nella bozza dello standard
+POSIX1.e, la seconda quelle specifiche di Linux.
L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile
per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui
\func{capget} e \func{capset}, sono soggette ad essere modificate con il
cambiamento del kernel (in particolare i tipi di dati delle strutture) ed
anche se finora l'interfaccia è risultata stabile, non c'è nessuna
-assicurazione che questa venga mantenuta. Pertando se si vogliono scrivere
+assicurazione che questa venga mantenuta. Pertanto se si vogliono scrivere
programmi portabili che possano essere eseguiti su qualunque versione del
kernel è opportuno utilizzare le interfacce di alto livello.
programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta
libreria attraverso l'opzione \texttt{-lcap} del compilatore.
-Le funzioni dell'interfaccia POSIX.1e prevedono l'uso di uno tipo di dato
-opaco, \type{cap\_t}, come puntatore ai dati mantenuti nel cosiddetto
-\textit{capability state},\footnote{si tratta in sostanza di un puntatore ad
- una struttura interna utilizzata dalle librerie, i cui campi non devono mai
- essere acceduti direttamente.} in sono memorizzati tutti i dati delle
-\textit{capabilities}. In questo modo è possibile mascherare i dettagli della
-gestione di basso livello, che potranno essere modificati senza dover cambiare
-le funzioni dell'interfaccia, che faranno riferimento soltanto ad oggetti di
-questo tipo. L'interfaccia pertanto non soltanto fornirà le funzioni per
-modificare e leggere le \textit{capabilities}, ma anche quelle per gestire i
-dati attraverso \type{cap\_t}.
-
-La prima funzione dell'interfaccia è allora quella che permette di
-inizializzare un \textit{capability state}, allocando al contempo la memoria
-necessaria per i relativi dati. La funzione è \funcd{cap\_init} ed il suo
-prototipo è:
+Le funzioni dell'interfaccia delle bozze di POSIX.1e prevedono l'uso di uno
+tipo di dato opaco, \type{cap\_t}, come puntatore ai dati mantenuti nel
+cosiddetto \textit{capability state},\footnote{si tratta in sostanza di un
+ puntatore ad una struttura interna utilizzata dalle librerie, i cui campi
+ non devono mai essere acceduti direttamente.} in sono memorizzati tutti i
+dati delle \textit{capabilities}. In questo modo è possibile mascherare i
+dettagli della gestione di basso livello, che potranno essere modificati senza
+dover cambiare le funzioni dell'interfaccia, che faranno riferimento soltanto
+ad oggetti di questo tipo. L'interfaccia pertanto non soltanto fornisce le
+funzioni per modificare e leggere le \textit{capabilities}, ma anche quelle
+per gestire i dati attraverso \type{cap\_t}.
+
+La prima funzione dell'interfaccia è quella che permette di inizializzare un
+\textit{capability state}, allocando al contempo la memoria necessaria per i
+relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è:
\begin{functions}
\headdecl{sys/capability.h}
\bodydesc{La funzione ritorna un valore non nullo in caso di successo e
\macro{NULL} in caso di errore, nel qual caso \var{errno} assumerà il
valore \errval{ENOMEM}.
-}
+ }
\end{functions}
La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato
con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando
-non c'è memoria suffuciente ad allocare i dati) viene restituito \macro{NULL}
+non c'è memoria sufficiente ad allocare i dati) viene restituito \macro{NULL}
ed \var{errno} viene impostata a \errval{ENOMEM}. La memoria necessaria a
mantenere i dati viene automaticamente allocata da \func{cap\_init}, ma dovrà
essere disallocata esplicitamente quando non più necessaria utilizzando la
\bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.
-}
+ }
\end{functions}
La funzione permette di liberare la memoria allocata dalle altre funzioni
\bodydesc{La funzione ritorna un valore non nullo in caso di successo e
\macro{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i
valori \errval{ENOMEM} o \errval{EINVAL}.
-}
+ }
\end{functions}
-La funzione crea una copia del \textit{capability state} \param{cap\_p}
-passato come argomento, restituendo il puntatore alla copia che conterrà gli
-stessi valori delle \textit{capabilities} presenti nell'originale. La memoria
-necessaria viene allocata automaticamente dalla funzione. Una volta effettuata
-la copia i due \textit{capability state} potranno essere modificati in maniera
-completamente indipendente.
+La funzione crea una copia del \textit{capability state} posto all'indirizzo
+\param{cap\_p} che si è passato come argomento, restituendo il puntatore alla
+copia, che conterrà gli stessi valori delle \textit{capabilities} presenti
+nell'originale. La memoria necessaria viene allocata automaticamente dalla
+funzione. Una volta effettuata la copia i due \textit{capability state}
+potranno essere modificati in maniera completamente indipendente.
Una seconda classe di funzioni di servizio sono quelle per la gestione dei
dati contenuti all'interno di un \textit{capability state}; la prima di esse è
\bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.
-}
+ }
\end{functions}
La funzione si limita ad azzerare tutte le \textit{capabilities} presenti nel
-\textit{capability state} \param{cap\_p} passato come argomento restituendo
-uno stato \textsl{vuoto}, analogo a quello che si ottiene nella creazione con
-\func{cap\_init}.
+\textit{capability state} all'indirizzo \param{cap\_p} passato come argomento,
+restituendo uno stato \textsl{vuoto}, analogo a quello che si ottiene nella
+creazione con \func{cap\_init}.
Per la gestione dei valori delle \textit{capabilities} presenti in un
\textit{capability state} l'interfaccia prevede due funzioni,
}
\end{functions}
-In entrambe le funzioni l'argomento \param{cap\_p} indica il
+In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al
\textit{capability state} su cui operare, mentre l'argomento \param{flag}
indica su quale dei tre insiemi illustrati a
-pag.~\pageref{sec:capabilities_set} si intende operare. Questo deve essere
-specificato con una variabile di tipo \type{cap\_flag\_t} e può assumere
+pag.~\pageref{sec:capabilities_set} si intende operare. Questi devono essere
+specificati con una variabile di tipo \type{cap\_flag\_t} che può assumere
esclusivamente\footnote{si tratta in effetti di un tipo enumerato, come si può
verificare dalla sua definizione che si trova in
\texttt{/usr/include/sys/capability.h}.} uno dei valori illustrati in
\label{tab:cap_set_identifier}
\end{table}
-La capacità che si intende controllare o impostare deve essere specificata
-attraverso una variabile di tipo \type{cap\_value\_t}, che può prendere come
-valore uno qualunque di quelli riportati in tab.~\ref{tab:proc_capabilities},
-in questo caso però non è possibile combinare diversi valori in una maschera
-binaria, una variabile di tipo \type{cap\_value\_t} deve indicare una sola
-\textit{capabilities}.\footnote{nel file di header citato nella nota
- precedente il tipo \type{cap\_value\_t} è definito come \ctyp{int}, ma i
- valori validi sono soltanto quelli di tab.~\ref{tab:proc_capabilities}.}
-Infine lo stato di una \textit{capabilities} è descritto ad una variabile di
-tipo \type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto
-uno\footnote{anche questo è un tipo enumerato.} dei valori di
-tab.~\ref{tab:cap_value_type}.
+La capacità che si intende controllare o impostare invece deve essere
+specificata attraverso una variabile di tipo \type{cap\_value\_t}, che può
+prendere come valore uno qualunque di quelli riportati in
+tab.~\ref{tab:proc_capabilities}, in questo caso però non è possibile
+combinare diversi valori in una maschera binaria, una variabile di tipo
+\type{cap\_value\_t} deve indicare una sola capacità.\footnote{nel file di
+ header citato nella nota precedente il tipo \type{cap\_value\_t} è definito
+ come \ctyp{int}, ma i valori validi sono soltanto quelli di
+ tab.~\ref{tab:proc_capabilities}.} Infine lo stato di una capacità è
+descritto ad una variabile di tipo \type{cap\_flag\_value\_t}, che a sua volta
+può assumere soltanto uno\footnote{anche questo è un tipo enumerato.} dei
+valori di tab.~\ref{tab:cap_value_type}.
\begin{table}[htb]
\centering
dall'argomento \param{cap} all'interno dell'insieme indicato dall'argomento
\param{flag} e ne restituisce il valore nella variabile posta all'indirizzo
puntato dall'argomento \param{value\_p}; è possibile cioè leggere soltanto uno
-stato di una \textit{capability} alla volta.
+stato di una capacità alla volta.
La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata
più capacità, anche se solo all'interno dello stesso insieme; per questo essa
tipo di impostazione da eseguire (cancellazione o impostazione) viene indicato
dall'argomento \param{value}.
+Per la visualizzazione dello stato delle \textit{capabilities} l'interfaccia
+prevede una funzione apposita, \funcd{cap\_to\_text}, il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/capability.h}
+
+ \funcdecl{char * cap\_to\_text(cap\_t caps, ssize\_t * length\_p)}
+ Genera una visualizzazione testuale delle \textit{capabilities}.
+
+ \bodydesc{La funzione ritorna un puntatore alla stringa con la descrizione
+ delle \textit{capabilities} in caso di successo e \val{NULL} in caso di
+ errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL} o
+ \errval{ENOMEM}.
+ }
+\end{functions}
+
+La funzione ritorna l'indirizzo di una stringa contente la descrizione
+testuale del contenuto del \textit{capabilities state} \param{caps} passato
+come argomento, e, qualora l'argomento \param{length\_p} sia diverso da
+\val{NULL}, restituisce nella variabile intera da questo puntata la lunghezza
+della stringa. La stringa restituita viene allocata automaticamente dalla
+funzione e deve essere liberata con \func{cap\_free}.
+
+Fin quei abbiamo trattato delle funzioni di manipolazione dei
+\textit{capabilities state}; quando si vuole eseguire la lettura delle
+\textit{capabilities} del processo corrente si deve usare la funzione
+\funcd{cap\_get\_proc}, il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/capability.h}
+ \funcdecl{cap\_t cap\_get\_proc(void)}
+ Legge le \textit{capabilities} del processo corrente.
+
+ \bodydesc{La funzione ritorna un valore diverso da \val{NULL} in caso di
+ successo e \val{NULL} in caso di errore, nel qual caso \var{errno} può
+ assumere i valori \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM}. }
+\end{functions}
+La funzione legge il valore delle \textit{capabilities} del processo corrente
+e restituisce il puntatore ad un \textit{capabilities state} contenente il
+risultato, che provvede ad allocare autonomamente, e che occorrerà liberare
+con \func{cap\_free} quando non sarà più utilizzato.
+
+Se invece si vogliono leggere le \textit{capabilities} di un processo
+specifico occorre usare la funzione \funcd{capgetp}, il cui
+prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un
+ prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t},
+ ma il valore di ritorno è intero, come si può verificare anche dalla
+ dichiarazione della stessa in \texttt{sys/capability.h}.} è:
+\begin{functions}
+ \headdecl{sys/capability.h}
+ \funcdecl{int capgetp(pid\_t pid, cap\_t cap\_d)}
+ Legge le \textit{capabilities} del processo indicato da \param{pid}.
+
+ \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL},
+ \errval{EPERM} o \errval{ENOMEM}.
+ }
+\end{functions}
+
+La funzione legge il valore delle \textit{capabilities} del processo indicato
+con l'argomento \param{pid}, salvando il risultato nel \textit{capabilities
+ state} all'indirizzo \param{cap\_d} che deve essere stato creato in
+precedenza. Qualora il processo non esista si avrà un errore di
+\errval{ESRCH}. Gli stessi valori possono essere letti direttamente nel
+filesystem \textit{proc}, nei file \texttt{/proc/<pid>/status}; ad esempio per
+\texttt{init} si otterrà qualcosa del tipo:
+\begin{Verbatim}
+...
+CapInh: 0000000000000000
+CapPrm: 00000000fffffeff
+CapEff: 00000000fffffeff
+\end{Verbatim}
+
+Infine per impostare le \textit{capabilities} del processo corrente (non
+esiste una funzione che permetta di cambiare le \textit{capabilities} di un
+altro processo) si deve usare la funzione \funcd{cap\_set\_proc}, il cui
+prototipo è:
+\begin{functions}
+ \headdecl{sys/capability.h}
+
+ \funcdecl{int cap\_set\_proc(cap\_t cap\_p)}
+ Imposta le \textit{capabilities} del processo corrente.
+
+ \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL},
+ \errval{EPERM} o \errval{ENOMEM}.
+ }
+\end{functions}
+
+La funzione modifica le \textit{capabilities} del processo corrente secondo
+quanto specificato con l'argomento \param{cap\_p}, posto che questo sia
+possibile nei termini spiegati in precedenza (non sarà ad esempio possibile
+impostare capacità non presenti nell'insieme di quelle permesse). In caso di
+successo i nuovi valori saranno effettivi al ritorno della funzione, in caso
+di fallimento invece lo stato delle capacità resterà invariato. Si tenga
+presente che \textsl{tutte} le capacità specificate tramite \param{cap\_p}
+devono essere permesse; se anche una sola non lo è la funzione fallirà, e per
+quanto appena detto, lo stato delle \textit{capabilities} non verrà modificato
+(neanche per le parti eventualmente permesse).
+
+Come esempio di utilizzo di queste funzioni nei sorgenti allegati alla guida
+si è distribuito il programma \texttt{getcap.c}, che consente di leggere le
+\textit{capabilities} del processo corrente\footnote{vale a dire di sé stesso,
+ quando lo si lancia, il che può sembrare inutile, ma serve a mostrarci quali
+ sono le \textit{capabilities} standard che ottiene un processo lanciato
+ dalla riga di comando.} o tramite l'opzione \texttt{-p}, quelle di un
+processo qualunque il cui pid viene passato come parametro dell'opzione.
+
+\begin{figure}[htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/getcap.c}
+ \end{minipage}
+ \normalsize
+ \caption{Corpo principale del programma \texttt{getcap.c}.}
+ \label{fig:proc_getcap}
+\end{figure}
+
+La sezione principale del programma è riportata in fig.~\ref{fig:proc_getcap},
+e si basa su una condizione sulla variabile \var{pid} che se si è usato
+l'opzione \texttt{-p} è impostata (nella sezione di gestione delle opzioni,
+che si è tralasciata) al valore del \textsl{pid} del processo di cui si vuole
+leggere le \textit{capabilities} e nulla altrimenti. Nel primo caso
+(\texttt{\small 1--6}) si utilizza direttamente (\texttt{\small 2})
+\func{cap\_get\_proc} per ottenere lo stato delle capacità del processo, nel
+secondo (\texttt{\small 7--14}) prima si inizializza (\texttt{\small 8}) uno
+stato vuoto e poi (\texttt{\small 9}) si legge il valore delle capacità del
+processo indicato.
+
+Il passo successivo è utilizzare (\texttt{\small 16}) \func{cap\_to\_text} per
+tradurre in una stringa lo stato, e poi (\texttt{\small 17}) stamparlo; infine
+(\texttt{\small 19--20}) si libera la memoria allocata dalle precedenti
+funzioni con \func{cap\_free} per poi ritornare dal ciclo principale della
+funzione.
\itindend{capabilities}
\texttt{len} è stato eliminato, successivamente si è introdotta la versione
riportata con però un secondo argomento di tipo \texttt{size\_t cpusetsize}
(anche questa citata nella pagina di manuale); la versione citata è quella
- riportata nel manuale delle \textsl{glibc} e corripondente alla definizione
+ riportata nel manuale delle \textsl{glibc} e corrispondente alla definizione
presente in \file{sched.h}.} è:
\begin{prototype}{sched.h}
{int sched\_setaffinity (pid\_t pid, const cpu\_set\_t *cpuset)}
Per facilitare l'uso dell'argomento \param{cpuset} le \acr{glibc} hanno
introdotto un apposito dato di tipo, \ctyp{cpu\_set\_t},\footnote{questa è una
estensione specifica delle \acr{glibc}, da attivare definendo la macro
- \macro{\_GNU\_SOURCE}, non esiste infatti una standardardizzazione per
+ \macro{\_GNU\_SOURCE}, non esiste infatti una standardizzazione per
questo tipo di interfaccia e POSIX al momento non prevede nulla al
riguardo.} che permette di identificare un insieme di processori. Il dato è
una maschera binaria: in generale è un intero a 32 bit in cui ogni bit
La funzione restituirà all'indirizzo specificato da \param{cpuset} il valore
della maschera di affinità del processo, così da poterla riutilizzare per una
successiva reimpostazione. In questo caso non sono necessari privilegi
-paricolari.
+particolari.
È chiaro che queste funzioni per la gestione dell'affinità hanno significato
soltanto su un sistema multiprocessore, esse possono comunque essere
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
+
+% LocalWords: multitasking like VMS child process identifier pid sez shell fig
+% LocalWords: parent kernel init pstree keventd kswapd table struct linux call
+% LocalWords: nell'header scheduler system interrupt timer HZ asm Hertz clock
+% LocalWords: l'alpha tick fork wait waitpid exit exec image glibc int pgid ps
+% LocalWords: sid threads thread Ingo Molnar ppid getpid getppid sys unistd
+% LocalWords: void ForkTest tempnam pathname sibling cap errno EAGAIN ENOMEM
+% LocalWords: stack read only copy write tab client spawn forktest sleep PATH
+% LocalWords: source LIBRARY scheduling race condition printf descriptor dup
+% LocalWords: close group session tms lock vfork execve BSD stream main abort
+% LocalWords: SIGABRT SIGCHLD SIGHUP foreground SIGCONT termination signal ANY
+% LocalWords: handler kill EINTR POSIX options WNOHANG ECHILD option WUNTRACED
+% LocalWords: dump bits rusage getrusage heap const filename argv envp EACCES
+% LocalWords: filesystem noexec EPERM suid sgid root nosuid ENOEXEC ENOENT ELF
+% LocalWords: ETXTBSY EINVAL ELIBBAD BIG EFAULT EIO ENAMETOOLONG ELOOP ENOTDIR
+% LocalWords: ENFILE EMFILE argc execl path execv execle execlp execvp vector
+% LocalWords: list environ NULL umask pending utime cutime ustime fcntl linker
+% LocalWords: opendir libc interpreter FreeBSD capabilities Mandatory Access
+% LocalWords: Control MAC SELinux Security Modules LSM superuser uid gid saved
+% LocalWords: effective euid egid dell' fsuid fsgid getuid geteuid getgid SVr
+% LocalWords: getegid IDS NFS setuid setgid all' logout utmp screen xterm TODO
+% LocalWords: setreuid setregid FIXME ruid rgid seteuid setegid setresuid size
+% LocalWords: setresgid getresuid getresgid value result argument setfsuid DAC
+% LocalWords: setfsgid NGROUPS sysconf getgroups getgrouplist groups ngroups
+% LocalWords: setgroups initgroups patch LIDS CHOWN OVERRIDE Discrectionary
+% LocalWords: SEARCH chattr sticky NOATIME socket domain immutable append mmap
+% LocalWords: broadcast multicast multicasting memory locking mlock mlockall
+% LocalWords: shmctl ioperm iopl chroot ptrace accounting swap reboot hangup
+% LocalWords: vhangup mknod lease permitted inherited inheritable bounding AND
+% LocalWords: capability capget capset header ESRCH undef version obj clear
+% LocalWords: pag ssize length proc capgetp prehemptive cache runnable Stopped
+% LocalWords: Uninterrutible SIGSTOP soft slice nice niceness counter which
+% LocalWords: getpriority who setpriority RTLinux RTAI Adeos fault FIFO First
+% LocalWords: yield Robin setscheduler policy param OTHER priority setparam
+% LocalWords: min getparam getscheduler interval robin ENOSYS fifo ping long
+% LocalWords: affinity setaffinity unsigned mask cpu NUMA CLR ISSET SETSIZE
+% LocalWords: getaffinity assembler deadlock REENTRANT SAFE