\label{fig:proc_task_struct}
\end{figure}
-Come accennato in sez.~\ref{sec:intro_unix_struct} è lo
-\textit{scheduler}\itindex{scheduler} che decide quale processo mettere in
-esecuzione; esso viene eseguito ad ogni system call ed ad ogni
-interrupt,\footnote{più in una serie di altre occasioni.}
+Come accennato in sez.~\ref{sec:intro_unix_struct} è lo \textit{scheduler}
+\itindex{scheduler} che decide quale processo mettere in esecuzione; esso
+viene eseguito ad ogni system call ed ad ogni interrupt,\footnote{più in una
+ serie di altre occasioni.}
% TODO completare questa parte.
(ma può essere anche attivato esplicitamente). Il timer di sistema provvede
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}).}
% TODO verificare gli ultimi cambiamenti del 2.6
% Si ha cioè un interrupt dal timer ogni centesimo di secondo.
-Ogni volta che viene eseguito, lo \textit{scheduler}\itindex{scheduler}
+Ogni volta che viene eseguito, lo \textit{scheduler} \itindex{scheduler}
effettua il calcolo delle priorità dei vari processi attivi (torneremo su
questo in sez.~\ref{sec:proc_priority}) e stabilisce quale di essi debba
essere posto in esecuzione fino alla successiva invocazione.
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
del programma per caricare le librerie necessarie ed effettuare il link
dell'eseguibile. Se il programma è in formato ELF per caricare le librerie
dinamiche viene usato l'interprete indicato nel segmento \const{PT\_INTERP},
-in genere questo è \file{/lib/ld-linux.so.1} per programmi linkati con le
-\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi linkati con le
+in genere questo è \file{/lib/ld-linux.so.1} per programmi collegati con le
+\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi collegati con le
\acr{glibc}.
Infine nel caso il file sia uno script esso deve iniziare con una linea nella
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 \itindex{append~mode}
+ \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.
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
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
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{}.
+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
delle funzioni all'interno dei gestori dei segnali.
Fintanto che una funzione opera soltanto con le variabili locali è rientrante;
-queste infatti vengono allocate nello \itindex{stack} stack, e un'altra
+queste infatti vengono allocate nello \itindex{stack} stack, ed un'altra
invocazione non fa altro che allocarne un'altra copia. Una funzione può non
essere rientrante quando opera su memoria che non è nello \itindex{stack}
stack. Ad esempio una funzione non è mai rientrante se usa una variabile
\code{\_r} al nome della versione normale.
-
%%% Local Variables:
%%% 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 LD
+% 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 PF
+% 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 PT
+% LocalWords: pag ssize length proc capgetp prehemptive cache runnable Stopped
+% LocalWords: Uninterrutible SIGSTOP soft slice nice niceness counter which SC
+% LocalWords: getpriority who setpriority RTLinux RTAI Adeos fault FIFO First
+% LocalWords: yield Robin setscheduler policy param OTHER priority setparam to
+% LocalWords: min getparam getscheduler interval robin ENOSYS fifo ping long
+% LocalWords: affinity setaffinity unsigned mask cpu NUMA CLR ISSET SETSIZE RR
+% LocalWords: getaffinity assembler deadlock REENTRANT SAFE tgz MYPGRP l'OR rr
+% LocalWords: WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WCOREDUMP WIFSTOPPED
+% LocalWords: WSTOPSIG opt char INTERP arg SIG IGN DFL mascheck grp FOWNER RAW
+% LocalWords: FSETID SETPCAP BIND SERVICE ADMIN PACKET IPC OWNER MODULE RAWIO
+% LocalWords: PACCT RESOURCE TTY CONFIG SETFCAP hdrp datap libcap lcap text tp
+% LocalWords: get ncap caps CapInh CapPrm fffffeff CapEff getcap STAT dall'I
+% LocalWords: inc PRIO SUSv PRGR prio SysV SunOS Ultrix sched timespec len sig
+% LocalWords: cpusetsize cpuset atomic