%% prochand.tex
%%
-%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2006 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
\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\_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 socket \textit{unix domain}
+ (vedi sez.~\ref{sec:unix_socket}).\\
+ \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 \textit{unix domain} (vedi
+ 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
+ \textit{immutable} e \itindex{append~mode}
+ \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.\\
+ \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\_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}).\\
+ \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
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