+accesso dal punto di vista dei processi; vedremo quali sono gli identificatori
+usati, come questi possono essere modificati nella creazione e nel lancio di
+nuovi processi, le varie funzioni per la loro manipolazione diretta e tutte le
+problematiche connesse ad una gestione accorta dei privilegi.
+
+
+\subsection{Gli identificatori del controllo di accesso}
+\label{sec:proc_access_id}
+
+Come accennato in sez.~\ref{sec:intro_multiuser} il modello base\footnote{in
+ realtà già esistono estensioni di questo modello base, che lo rendono più
+ flessibile e controllabile, come le \textit{capabilities} illustrate in
+ sez.~\ref{sec:proc_capabilities}, le ACL per i file (vedi
+ sez.~\ref{sec:file_ACL}) o il \textit{Mandatory Access Control} di
+ \textit{SELinux}; inoltre basandosi sul lavoro effettuato con
+ \textit{SELinux}, a partire dal kernel 2.5.x, è iniziato lo sviluppo di una
+ infrastruttura di sicurezza, i \textit{Linux Security Modules}, o LSM, in
+ grado di fornire diversi agganci a livello del kernel per modularizzare
+ tutti i possibili controlli di accesso, cosa che ha permesso di realizzare
+ diverse alternative a \textit{SELinux}.}
+di sicurezza di un sistema unix-like è fondato sui concetti di utente e
+gruppo, e sulla separazione fra l'amministratore (\textsl{root}, detto spesso
+anche \textit{superuser}) che non è sottoposto a restrizioni, ed il resto
+degli utenti, per i quali invece vengono effettuati i vari controlli di
+accesso.
+
+Abbiamo già accennato come il sistema associ ad ogni utente e gruppo due
+identificatori univoci, lo \itindex{User~ID~(UID)} \textsl{User-ID}
+(abbreviato in \ids{UID}) ed il \itindex{Group~ID~(GID)} \textsl{Group-ID}
+(abbreviato in \ids{GID}). Questi servono al kernel per identificare uno
+specifico utente o un gruppo di utenti, per poi poter controllare che essi
+siano autorizzati a compiere le operazioni richieste. Ad esempio in
+sez.~\ref{sec:file_access_control} vedremo come ad ogni file vengano associati
+un utente ed un gruppo (i suoi \textsl{proprietari}, indicati appunto tramite
+un \ids{UID} ed un \ids{GID}) che vengono controllati dal kernel nella
+gestione dei permessi di accesso.
+
+Dato che tutte le operazioni del sistema vengono compiute dai processi, è
+evidente che per poter implementare un controllo sulle operazioni occorre
+anche poter identificare chi è che ha lanciato un certo programma, e pertanto
+anche a ciascun processo dovrà essere associato un utente e un gruppo.
+
+Un semplice controllo di una corrispondenza fra identificativi non garantisce
+però sufficiente flessibilità per tutti quei casi in cui è necessario poter
+disporre di privilegi diversi, o dover impersonare un altro utente per un
+limitato insieme di operazioni. Per questo motivo in generale tutti i sistemi
+unix-like prevedono che i processi abbiano almeno due gruppi di
+identificatori, chiamati rispettivamente \textit{real} ed \textit{effective}
+(cioè \textsl{reali} ed \textsl{effettivi}). Nel caso di Linux si aggiungono
+poi altri due gruppi, il \textit{saved} (\textsl{salvati}) ed il
+\textit{filesystem} (\textsl{di filesystem}), secondo la situazione illustrata
+in tab.~\ref{tab:proc_uid_gid}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|c|c|l|p{7cm}|}
+ \hline
+ \textbf{Suffisso} & \textbf{Gruppo} & \textbf{Denominazione}
+ & \textbf{Significato} \\
+ \hline
+ \hline
+ \texttt{uid} & \textit{real} & \textsl{user-ID reale}
+ & Indica l'utente che ha lanciato il programma.\\
+ \texttt{gid} & '' &\textsl{group-ID reale}
+ & Indica il gruppo principale dell'utente che ha lanciato
+ il programma.\\
+ \hline
+ \texttt{euid}& \textit{effective} &\textsl{user-ID effettivo}
+ & Indica l'utente usato nel controllo di accesso.\\
+ \texttt{egid}& '' & \textsl{group-ID effettivo}
+ & Indica il gruppo usato nel controllo di accesso.\\
+ -- & -- & \textsl{group-ID supplementari}
+ & Indicano gli ulteriori gruppi cui l'utente appartiene.\\
+ \hline
+ -- & \textit{saved} & \textsl{user-ID salvato}
+ & Mantiene una copia dell'\acr{euid} iniziale.\\
+ -- & '' & \textsl{group-ID salvato}
+ & Mantiene una copia dell'\acr{egid} iniziale.\\
+ \hline
+ \texttt{fsuid}& \textit{filesystem} &\textsl{user-ID di filesystem}
+ & Indica l'utente effettivo per l'accesso al filesystem. \\
+ \texttt{fsgid}& '' & \textsl{group-ID di filesystem}
+ & Indica il gruppo effettivo per l'accesso al filesystem.\\
+ \hline
+ \end{tabular}
+ \caption{Identificatori di utente e gruppo associati a ciascun processo con
+ indicazione dei suffissi usati dalle varie funzioni di manipolazione.}
+ \label{tab:proc_uid_gid}
+\end{table}
+
+Al primo gruppo appartengono l'\ids{UID} \textsl{reale} ed il \ids{GID}
+\textsl{reale}: questi vengono impostati al login ai valori corrispondenti
+all'utente con cui si accede al sistema (e relativo gruppo principale).
+Servono per l'identificazione dell'utente e normalmente non vengono mai
+cambiati. In realtà vedremo (in sez.~\ref{sec:proc_setuid}) che è possibile
+modificarli, ma solo ad un processo che abbia i privilegi di amministratore;
+questa possibilità è usata proprio dal programma \cmd{login} che, una volta
+completata la procedura di autenticazione, lancia una shell per la quale
+imposta questi identificatori ai valori corrispondenti all'utente che entra
+nel sistema.
+
+Al secondo gruppo appartengono l'\ids{UID} \textsl{effettivo} e il \ids{GID}
+\textsl{effettivo}, a cui si aggiungono gli eventuali \ids{GID}
+\textsl{supplementari} dei gruppi dei quali l'utente fa parte. Questi sono
+invece gli identificatori usati nelle verifiche dei permessi del processo e
+per il controllo di accesso ai file (argomento affrontato in dettaglio in
+sez.~\ref{sec:file_perm_overview}).
+
+Questi identificatori normalmente sono identici ai corrispondenti del gruppo
+\textit{real} tranne nel caso in cui, come accennato in
+sez.~\ref{sec:proc_exec}, il programma che si è posto in esecuzione abbia i
+bit \acr{suid} o \acr{sgid} impostati (il significato di questi bit è
+affrontato in dettaglio in sez.~\ref{sec:file_special_perm}). In questo caso
+essi saranno impostati all'utente e al gruppo proprietari del file. Questo
+consente, per programmi in cui ci sia questa necessità, di dare a qualunque
+utente i privilegi o i permessi di un altro, compreso l'amministratore.
+
+Come nel caso del \ids{PID} e del \ids{PPID}, anche tutti questi
+identificatori possono essere ottenuti da un programma attraverso altrettante
+funzioni di sistema dedicate alla loro lettura, queste sono \funcd{getuid},
+\funcd{geteuid}, \funcd{getgid} e \funcd{getegid}, ed i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/types.h}
+\fdecl{uid\_t getuid(void)}
+\fdesc{Legge l'\ids{UID} reale del processo corrente.}
+\fdecl{uid\_t geteuid(void)}
+\fdesc{Legge l'\ids{UID} effettivo del processo corrente.}
+\fdecl{gid\_t getgid(void)}
+\fdesc{Legge il \ids{GID} reale del processo corrente.}
+\fdecl{gid\_t getegid(void)}
+\fdesc{Legge il \ids{GID} effettivo del processo corrente.}
+}
+{Le funzioni ritornano i rispettivi identificativi del processo corrente, e
+ non sono previste condizioni di errore.}
+\end{funcproto}
+
+In generale l'uso di privilegi superiori, ottenibile con un \ids{UID}
+\textsl{effettivo} diverso da quello reale, deve essere limitato il più
+possibile, per evitare abusi e problemi di sicurezza, per questo occorre anche
+un meccanismo che consenta ad un programma di rilasciare gli eventuali
+maggiori privilegi necessari, una volta che si siano effettuate le operazioni
+per i quali erano richiesti, e a poterli eventualmente recuperare in caso
+servano di nuovo.
+
+Questo in Linux viene fatto usando altri due gruppi di identificatori, il
+\textit{saved} ed il \textit{filesystem}. Il primo gruppo è lo stesso usato in
+SVr4, e previsto dallo standard POSIX quando è definita
+\macro{\_POSIX\_SAVED\_IDS},\footnote{in caso si abbia a cuore la portabilità
+ del programma su altri Unix è buona norma controllare sempre la
+ disponibilità di queste funzioni controllando se questa costante è
+ definita.} il secondo gruppo è specifico di Linux e viene usato per
+migliorare la sicurezza con NFS (il \textit{Network File System}, protocollo
+che consente di accedere ai file via rete).
+
+L'\ids{UID} \textsl{salvato} ed il \ids{GID} \textsl{salvato} sono copie
+dell'\ids{UID} \textsl{effettivo} e del \ids{GID} \textsl{effettivo} del
+processo padre, e vengono impostati dalla funzione \func{exec} all'avvio del
+processo, come copie dell'\ids{UID} \textsl{effettivo} e del \ids{GID}
+\textsl{effettivo} dopo che questi sono stati impostati tenendo conto di
+eventuali permessi \acr{suid} o \acr{sgid} (su cui torneremo in
+sez.~\ref{sec:file_special_perm}). Essi quindi consentono di tenere traccia
+di quale fossero utente e gruppo effettivi all'inizio dell'esecuzione di un
+nuovo programma.
+
+L'\ids{UID} \textsl{di filesystem} e il \ids{GID} \textsl{di filesystem} sono
+un'estensione introdotta in Linux per rendere più sicuro l'uso di NFS
+(torneremo sull'argomento in sez.~\ref{sec:proc_setuid}). Essi sono una
+replica dei corrispondenti identificatori del gruppo \textit{effective}, ai
+quali si sostituiscono per tutte le operazioni di verifica dei permessi
+relativi ai file (trattate in sez.~\ref{sec:file_perm_overview}). Ogni
+cambiamento effettuato sugli identificatori effettivi viene automaticamente
+riportato su di essi, per cui in condizioni normali si può tranquillamente
+ignorarne l'esistenza, in quanto saranno del tutto equivalenti ai precedenti.
+
+
+\subsection{Le funzioni di gestione degli identificatori dei processi}
+\label{sec:proc_setuid}
+
+Le funzioni di sistema più comuni che vengono usate per cambiare identità
+(cioè utente e gruppo di appartenenza) ad un processo, e che come accennato in
+sez.~\ref{sec:proc_access_id} seguono la semantica POSIX che prevede
+l'esistenza dell'\ids{UID} salvato e del \ids{GID} salvato, sono
+rispettivamente \funcd{setuid} e \funcd{setgid}; i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/types.h}
+\fdecl{int setuid(uid\_t uid)}
+\fdesc{Imposta l'\ids{UID} del processo corrente.}
+\fdecl{int setgid(gid\_t gid)}
+\fdesc{Imposta il \ids{GID} del processo corrente.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+}
+\end{funcproto}
+
+Il funzionamento di queste due funzioni è analogo, per cui considereremo solo
+la prima, la seconda si comporta esattamente allo stesso modo facendo
+riferimento al \ids{GID} invece che all'\ids{UID}. Gli eventuali \ids{GID}
+supplementari non vengono modificati.
+
+L'effetto della chiamata è diverso a seconda dei privilegi del processo; se
+l'\ids{UID} effettivo è zero (cioè è quello dell'amministratore di sistema)
+allora tutti gli identificatori (\textit{real}, \textit{effective} e
+\textit{saved}) vengono impostati al valore specificato da \param{uid},
+altrimenti viene impostato solo l'\ids{UID} effettivo, e soltanto se il valore
+specificato corrisponde o all'\ids{UID} reale o all'\ids{UID} salvato. Negli
+altri casi viene segnalato un errore con \errcode{EPERM}.
+
+Come accennato l'uso principale di queste funzioni è quello di poter
+consentire ad un programma con i bit \acr{suid} o \acr{sgid} impostati (vedi
+sez.~\ref{sec:file_special_perm}) di riportare l'\ids{UID} effettivo a quello
+dell'utente che ha lanciato il programma, effettuare il lavoro che non
+necessita di privilegi aggiuntivi, ed eventualmente tornare indietro.
+
+Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui
+viene gestito l'accesso al file \sysfiled{/var/run/utmp}. In questo file viene
+registrato chi sta usando il sistema al momento corrente; chiaramente non può
+essere lasciato aperto in scrittura a qualunque utente, che potrebbe
+falsificare la registrazione. Per questo motivo questo file (e l'analogo
+\sysfiled{/var/log/wtmp} su cui vengono registrati login e logout) appartengono
+ad un gruppo dedicato (in genere \acr{utmp}) ed i programmi che devono
+accedervi (ad esempio tutti i programmi di terminale in X, o il programma
+\cmd{screen} che crea terminali multipli su una console) appartengono a questo
+gruppo ed hanno il bit \acr{sgid} impostato.
+
+Quando uno di questi programmi (ad esempio \cmd{xterm}) viene lanciato, la
+situazione degli identificatori è la seguente:
+\begin{eqnarray*}
+ \label{eq:1}
+ \textsl{group-ID reale} &=& \textrm{\ids{GID} (del chiamante)} \\
+ \textsl{group-ID effettivo} &=& \textrm{\acr{utmp}} \\
+ \textsl{group-ID salvato} &=& \textrm{\acr{utmp}}
+\end{eqnarray*}
+in questo modo, dato che il \textsl{group-ID effettivo} è quello giusto, il
+programma può accedere a \sysfile{/var/run/utmp} in scrittura ed aggiornarlo.
+A questo punto il programma può eseguire una \code{setgid(getgid())} per
+impostare il \textsl{group-ID effettivo} a quello dell'utente (e dato che il
+\textsl{group-ID reale} corrisponde la funzione avrà successo), in questo modo
+non sarà possibile lanciare dal terminale programmi che modificano detto file,
+in tal caso infatti la situazione degli identificatori sarebbe:
+\begin{eqnarray*}
+ \label{eq:2}
+ \textsl{group-ID reale} &=& \textrm{\ids{GID} (invariato)} \\
+ \textsl{group-ID effettivo} &=& \textrm{\ids{GID}} \\
+ \textsl{group-ID salvato} &=& \textrm{\acr{utmp} (invariato)}
+\end{eqnarray*}
+e ogni processo lanciato dal terminale avrebbe comunque \ids{GID} come
+\textsl{group-ID effettivo}. All'uscita dal terminale, per poter di nuovo
+aggiornare lo stato di \sysfile{/var/run/utmp} il programma eseguirà una
+\code{setgid(utmp)} (dove \var{utmp} è il valore numerico associato al gruppo
+\acr{utmp}, ottenuto ad esempio con una precedente \func{getegid}), dato che
+in questo caso il valore richiesto corrisponde al \textsl{group-ID salvato} la
+funzione avrà successo e riporterà la situazione a:
+\begin{eqnarray*}
+ \label{eq:3}
+ \textsl{group-ID reale} &=& \textrm{\ids{GID} (invariato)} \\
+ \textsl{group-ID effettivo} &=& \textrm{\acr{utmp}} \\
+ \textsl{group-ID salvato} &=& \textrm{\acr{utmp} (invariato)}
+\end{eqnarray*}
+consentendo l'accesso a \sysfile{/var/run/utmp}.
+
+Occorre però tenere conto che tutto questo non è possibile con un processo con
+i privilegi di amministratore, in tal caso infatti l'esecuzione di una
+\func{setuid} comporta il cambiamento di tutti gli identificatori associati al
+processo, rendendo impossibile riguadagnare i privilegi di amministratore.
+Questo comportamento è corretto per l'uso che ne fa \cmd{login} una volta che
+crea una nuova shell per l'utente, ma quando si vuole cambiare soltanto
+l'\ids{UID} effettivo del processo per cedere i privilegi occorre
+ricorrere ad altre funzioni.
+
+Le due funzioni di sistema \funcd{setreuid} e \funcd{setregid} derivano da BSD
+che, non supportando (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{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/types.h}
+\fdecl{int setreuid(uid\_t ruid, uid\_t euid)}
+\fdesc{Imposta \ids{UID} reale e \ids{UID} effettivo del processo corrente.}
+\fdecl{int setregid(gid\_t rgid, gid\_t egid)}
+\fdesc{Imposta \ids{GID} reale e \ids{GID} effettivo del processo corrente.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+}
+\end{funcproto}
+
+Le due funzioni sono identiche, quanto diremo per la prima riguardo gli
+\ids{UID} si applica alla seconda per i \ids{GID}. La funzione
+\func{setreuid} imposta rispettivamente l'\ids{UID} reale e l'\ids{UID}
+effettivo del processo corrente ai valori specificati da \param{ruid}
+e \param{euid}. I processi non privilegiati possono impostare solo valori che
+corrispondano o al loro \ids{UID} effettivo o a quello reale o a quello
+salvato, valori diversi comportano il fallimento della chiamata.
+L'amministratore invece può specificare un valore qualunque. Specificando un
+argomento di valore $-1$ l'identificatore corrispondente verrà lasciato
+inalterato.
+
+Con queste funzioni si possono scambiare fra loro gli \ids{UID} reale ed
+effettivo, e pertanto è possibile implementare un comportamento simile a
+quello visto in precedenza per \func{setgid}, cedendo i privilegi con un primo
+scambio, e recuperandoli, una volta eseguito il lavoro non privilegiato, con
+un secondo scambio.
+
+In questo caso però occorre porre molta attenzione quando si creano nuovi
+processi nella fase intermedia in cui si sono scambiati gli identificatori, in
+questo caso infatti essi avranno un \ids{UID} reale privilegiato, che dovrà
+essere esplicitamente eliminato prima di porre in esecuzione un nuovo
+programma, occorrerà cioè eseguire un'altra chiamata dopo la \func{fork} e
+prima della \func{exec} per uniformare l'\ids{UID} reale a quello effettivo,
+perché in caso contrario il nuovo programma potrebbe a sua volta effettuare
+uno scambio e riottenere dei privilegi non previsti.
+
+Lo stesso problema di propagazione dei privilegi ad eventuali processi figli
+si pone anche per l'\ids{UID} salvato. Ma la funzione \func{setreuid} deriva
+da un'implementazione di sistema che non ne prevede la presenza, e quindi non
+è possibile usarla per correggere la situazione come nel caso precedente. Per
+questo motivo in Linux tutte le volte che si imposta un qualunque valore
+diverso da quello dall'\ids{UID} reale corrente, l'\ids{UID} salvato viene
+automaticamente uniformato al valore dell'\ids{UID} effettivo.
+
+Altre due funzioni di sistema, \funcd{seteuid} e \funcd{setegid}, sono
+un'estensione dello standard POSIX.1, ma sono comunque supportate dalla
+maggior parte degli Unix, esse vengono usate per cambiare gli identificatori
+del gruppo \textit{effective} ed i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/types.h}
+\fdecl{int seteuid(uid\_t uid)}
+\fdesc{Imposta l'\ids{UID} effettivo del processo corrente.}
+\fdecl{int setegid(gid\_t gid)}
+\fdesc{Imposta il \ids{GID} effettivo del processo corrente.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+}
+\end{funcproto}
+
+Ancora una volta le due funzioni sono identiche, e quanto diremo per la prima
+riguardo gli \ids{UID} si applica allo stesso modo alla seconda per i
+\ids{GID}. Con \func{seteuid} gli utenti normali possono impostare l'\ids{UID}
+effettivo solo al valore dell'\ids{UID} reale o dell'\ids{UID} salvato,
+l'amministratore può specificare qualunque valore. Queste funzioni sono usate
+per permettere all'amministratore di impostare solo l'\ids{UID} effettivo,
+dato che l'uso normale di \func{setuid} comporta l'impostazione di tutti gli
+identificatori.
+
+Le due funzioni di sistema \funcd{setresuid} e \funcd{setresgid} sono invece
+un'estensione introdotta in Linux (a partire dal kernel 2.1.44) e permettono
+un completo controllo su tutti e tre i gruppi di identificatori
+(\textit{real}, \textit{effective} e \textit{saved}), i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/types.h}
+\fdecl{int setresuid(uid\_t ruid, uid\_t euid, uid\_t suid)}
+\fdesc{Imposta l'\ids{UID} reale, effettivo e salvato del processo corrente.}
+\fdecl{int setresgid(gid\_t rgid, gid\_t egid, gid\_t sgid)}
+\fdesc{Imposta il \ids{GID} reale, effettivo e salvato del processo corrente.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+}
+\end{funcproto}
+
+Di nuovo le due funzioni sono identiche e quanto detto per la prima riguardo
+gli \ids{UID} si applica alla seconda per i \ids{GID}. La funzione
+\func{setresuid} imposta l'\ids{UID} reale, l'\ids{UID} effettivo e
+l'\ids{UID} salvato del processo corrente ai valori specificati
+rispettivamente dagli argomenti \param{ruid}, \param{euid} e \param{suid}. I
+processi non privilegiati possono cambiare uno qualunque degli\ids{UID} solo
+ad un valore corrispondente o all'\ids{UID} reale, o a quello effettivo o a
+quello salvato, l'amministratore può specificare i valori che vuole. Un valore
+di $-1$ per un qualunque argomento lascia inalterato l'identificatore
+corrispondente.
+
+Per queste funzioni di sistema esistono anche due controparti,
+\funcd{getresuid} e \funcd{getresgid},\footnote{le funzioni non sono standard,
+ anche se appaiono in altri kernel, su Linux sono presenti dal kernel 2.1.44
+ e con le versioni della \acr{glibc} a partire dalla 2.3.2, definendo la
+ macro \macro{\_GNU\_SOURCE}.} che permettono di leggere in blocco i vari
+identificatori; i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/types.h}
+\fdecl{int getresuid(uid\_t *ruid, uid\_t *euid, uid\_t *suid)}
+\fdesc{Legge l'\ids{UID} reale, effettivo e salvato del processo corrente.}
+\fdecl{int getresgid(gid\_t *rgid, gid\_t *egid, gid\_t *sgid)}
+\fdesc{Legge il \ids{GID} reale, effettivo e salvato del processo corrente.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} può assumere solo il valore \errcode{EFAULT} se gli
+ indirizzi delle variabili di ritorno non sono validi. }
+\end{funcproto}
+
+Anche queste funzioni sono un'estensione specifica di Linux, e non richiedono
+nessun privilegio. I valori sono restituiti negli argomenti, che vanno
+specificati come puntatori (è un altro esempio di \textit{value result
+ argument}). Si noti che queste funzioni sono le uniche in grado di leggere
+gli identificatori del gruppo \textit{saved}.
+
+Infine le funzioni \func{setfsuid} e \func{setfsgid} servono per impostare gli
+identificatori del gruppo \textit{filesystem} che sono usati da Linux per il
+controllo dell'accesso ai file. Come già accennato in
+sez.~\ref{sec:proc_access_id} Linux definisce questo ulteriore gruppo di
+identificatori, che in circostanze normali sono assolutamente equivalenti a
+quelli del gruppo \textit{effective}, dato che ogni cambiamento di questi
+ultimi viene immediatamente riportato su di essi.
+
+C'è un solo caso in cui si ha necessità di introdurre una differenza fra gli
+identificatori dei gruppi \textit{effective} e \textit{filesystem}, ed è per
+ovviare ad un problema di sicurezza che si presenta quando si deve
+implementare un server NFS.
+
+Il server NFS infatti deve poter cambiare l'identificatore con cui accede ai
+file per assumere l'identità del singolo utente remoto, ma se questo viene
+fatto cambiando l'\ids{UID} effettivo o l'\ids{UID} reale il server si espone
+alla ricezione di eventuali segnali ostili da parte dell'utente di cui ha
+temporaneamente assunto l'identità. Cambiando solo l'\ids{UID} di filesystem
+si ottengono i privilegi necessari per accedere ai file, mantenendo quelli
+originari per quanto riguarda tutti gli altri controlli di accesso, così che
+l'utente non possa inviare segnali al server NFS.
+
+Le due funzioni di sistema usate per cambiare questi identificatori sono
+\funcd{setfsuid} e \funcd{setfsgid}, ed ovviamente sono specifiche di Linux e
+non devono essere usate se si intendono scrivere programmi portabili; i loro
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/fsuid.h}
+\fdecl{int setfsuid(uid\_t fsuid)}
+\fdesc{Imposta l'\ids{UID} di filesystem del processo corrente.}
+\fdecl{int setfsgid(gid\_t fsgid)}
+\fdesc{Legge il \ids{GID} di filesystem del processo corrente.}
+}
+{Le funzioni restituiscono il nuovo valore dell'identificativo in caso di
+ successo e quello corrente per un errore, in questo caso non viene però
+ impostato nessun codice di errore in \var{errno}.}
+\end{funcproto}
+
+Le due funzioni sono analoghe ed usano il valore passato come argomento per
+effettuare l'impostazione dell'identificativo. Le funzioni hanno successo
+solo se il processo chiamante ha i privilegi di amministratore o, per gli
+altri utenti, se il valore specificato coincide con uno dei di quelli del
+gruppo \textit{real}, \textit{effective} o \textit{saved}.
+
+
+\subsection{Le funzioni per la gestione dei gruppi associati a un processo}
+\label{sec:proc_setgroups}
+
+Le ultime funzioni che esamineremo sono quelle che permettono di operare sui
+gruppi supplementari cui un utente può appartenere. Ogni processo può avere
+almeno \const{NGROUPS\_MAX} gruppi supplementari\footnote{il numero massimo di
+ gruppi secondari può essere ottenuto con \func{sysconf} (vedi
+ sez.~\ref{sec:sys_limits}), leggendo il parametro
+ \const{\_SC\_NGROUPS\_MAX}.} in aggiunta al gruppo primario; questi vengono
+ereditati dal processo padre e possono essere cambiati con queste funzioni.
+
+La funzione di sistema che permette di leggere i gruppi supplementari
+associati ad un processo è \funcd{getgroups}; questa funzione è definita nello
+standard POSIX.1, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{unistd.h}
+\fdecl{int getgroups(int size, gid\_t list[])}
+\fdesc{Legge gli identificatori dei gruppi supplementari.}
+}
+{La funzione ritorna il numero di gruppi letti in caso di successo e $-1$ per
+ un errore, nel qual caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{EFAULT}] \param{list} non ha un indirizzo valido.
+\item[\errcode{EINVAL}] il valore di \param{size} è diverso da zero ma
+ minore del numero di gruppi supplementari del processo.
+\end{errlist}}
+\end{funcproto}
+
+La funzione legge gli identificatori dei gruppi supplementari del processo sul
+vettore \param{list} che deve essere di dimensione pari a \param{size}. Non è
+specificato se la funzione inserisca o meno nella lista il \ids{GID} effettivo
+del processo. Se si specifica un valore di \param{size} uguale a $0$ allora
+l'argomento \param{list} non viene modificato, ma si ottiene il numero di
+gruppi supplementari.
+
+Una seconda funzione, \funcd{getgrouplist}, può invece essere usata per
+ottenere tutti i gruppi a cui appartiene utente identificato per nome; il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{grp.h}
+\fdecl{int getgrouplist(const char *user, gid\_t group, gid\_t *groups, int
+ *ngroups)}
+\fdesc{Legge i gruppi cui appartiene un utente.}
+}
+{La funzione ritorna il numero di gruppi ottenuto in caso di successo e $-1$
+ per un errore, che avviene solo quando il numero di gruppi è maggiore di
+ quelli specificati con \param{ngroups}.}
+\end{funcproto}
+
+La funzione esegue una scansione del database dei gruppi (si veda
+sez.~\ref{sec:sys_user_group}) per leggere i gruppi supplementari dell'utente
+specificato per nome (e non con un \ids{UID}) nella stringa passata con
+l'argomento \param{user}. Ritorna poi nel vettore \param{groups} la lista dei
+\ids{GID} dei gruppi a cui l'utente appartiene. Si noti che \param{ngroups},
+che in ingresso deve indicare la dimensione di \param{group}, è passato come
+\textit{value result argument} perché, qualora il valore specificato sia
+troppo piccolo, la funzione ritorna $-1$, passando comunque indietro il numero
+dei gruppi trovati, in modo da poter ripetere la chiamata con un vettore di
+dimensioni adeguate.
+
+Infine per impostare i gruppi supplementari di un processo ci sono due
+funzioni, che possono essere usate solo se si hanno i privilegi di
+amministratore.\footnote{e più precisamente se si ha la \textit{capability}
+ \const{CAP\_SETGID}.} La prima delle due è la funzione di sistema
+\funcd{setgroups},\footnote{la funzione è definita in BSD e SRv4, ma a
+ differenza di \func{getgroups} non è stata inclusa in POSIX.1-2001, per
+ poterla utilizzare deve essere definita la macro \macro{\_BSD\_SOURCE}.} ed
+il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{grp.h}
+\fdecl{int setgroups(size\_t size, gid\_t *list)}
+\fdesc{Imposta i gruppi supplementari del processo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{EFAULT}] \param{list} non ha un indirizzo valido.
+\item[\errcode{EINVAL}] il valore di \param{size} è maggiore del valore
+ massimo consentito di gruppi supplementari.
+\item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
+\end{errlist}}
+\end{funcproto}
+
+La funzione imposta i gruppi supplementari del processo corrente ai valori
+specificati nel vettore passato con l'argomento \param{list}, di dimensioni
+date dall'argomento \param{size}. Il numero massimo di gruppi supplementari
+che si possono impostare è un parametro di sistema, che può essere ricavato
+con le modalità spiegate in sez.~\ref{sec:sys_characteristics}.
+
+Se invece si vogliono impostare i gruppi supplementari del processo a quelli
+di un utente specifico, si può usare la funzione \funcd{initgroups} il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{grp.h}
+\fdecl{int initgroups(const char *user, gid\_t group)}
+\fdesc{Inizializza la lista dei gruppi supplementari.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare lo spazio per
+ informazioni dei gruppi.
+\item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
+\end{errlist}}
+\end{funcproto}
+
+La funzione esegue la scansione del database dei gruppi (usualmente
+\conffile{/etc/group}) cercando i gruppi di cui è membro l'utente \param{user}
+(di nuovo specificato per nome e non per \ids{UID}) con cui costruisce una
+lista di gruppi supplementari, a cui aggiunge anche \param{group}, infine
+imposta questa lista per il processo corrente usando \func{setgroups}. Si
+tenga presente che sia \func{setgroups} che \func{initgroups} non sono
+definite nello standard POSIX.1 e che pertanto non è possibile utilizzarle
+quando si definisce \macro{\_POSIX\_SOURCE} o si compila con il flag
+\cmd{-ansi}, è pertanto meglio evitarle se si vuole scrivere codice portabile.
+
+
+\section{La gestione della priorità dei processi}
+\label{sec:proc_priority}
+
+In questa sezione tratteremo più approfonditamente i meccanismi con il quale
+lo \textit{scheduler} assegna la CPU ai vari processi attivi. In particolare
+prenderemo in esame i vari meccanismi con cui viene gestita l'assegnazione del
+tempo di CPU, ed illustreremo le varie funzioni di gestione. Tratteremo infine
+anche le altre priorità dei processi (come quelle per l'accesso a disco)
+divenute disponibili con i kernel più recenti.
+
+
+\subsection{I meccanismi di \textit{scheduling}}
+\label{sec:proc_sched}
+
+\itindbeg{scheduler}
+
+La scelta di un meccanismo che sia in grado di distribuire in maniera efficace
+il tempo di CPU per l'esecuzione dei processi è sempre una questione delicata,
+ed oggetto di numerose ricerche; in generale essa dipende in maniera
+essenziale anche dal tipo di utilizzo che deve essere fatto del sistema, per
+cui non esiste un meccanismo che sia valido per tutti gli usi.
+
+La caratteristica specifica di un sistema multitasking come Linux è quella del
+cosiddetto \itindex{preemptive~multitasking} \textit{preemptive
+ multitasking}: questo significa che al contrario di altri sistemi (che usano
+invece il cosiddetto \itindex{cooperative~multitasking} \textit{cooperative
+ multitasking}) non sono i singoli processi, ma il kernel stesso a decidere
+quando la CPU deve essere passata ad un altro processo. Come accennato in
+sez.~\ref{sec:proc_hierarchy} questa scelta viene eseguita da una sezione
+apposita del kernel, lo \textit{scheduler}, il cui scopo è quello di
+distribuire al meglio il tempo di CPU fra i vari processi.
+
+La cosa è resa ancora più complicata dal fatto che con le architetture
+multi-processore si deve anche scegliere quale sia la CPU più opportuna da
+utilizzare.\footnote{nei processori moderni la presenza di ampie cache può
+ rendere poco efficiente trasferire l'esecuzione di un processo da una CPU ad
+ un'altra, per cui effettuare la migliore scelta fra le diverse CPU non è
+ banale.} Tutto questo comunque appartiene alle sottigliezze
+dell'implementazione del kernel; dal punto di vista dei programmi che girano
+in \textit{user space}, anche quando si hanno più processori (e dei processi
+che sono eseguiti davvero in contemporanea), le politiche di
+\textit{scheduling} riguardano semplicemente l'allocazione della risorsa
+\textsl{tempo di esecuzione}, la cui assegnazione sarà governata dai
+meccanismi di scelta delle priorità che restano gli stessi indipendentemente
+dal numero di processori.
+
+Si tenga conto poi che i processi non devono solo eseguire del codice: ad
+esempio molto spesso saranno impegnati in operazioni di I/O, o potranno
+venire bloccati da un comando dal terminale, o sospesi per un certo periodo di
+tempo. In tutti questi casi la CPU diventa disponibile ed è compito dello
+kernel provvedere a mettere in esecuzione un altro processo.
+
+Tutte queste possibilità sono caratterizzate da un diverso \textsl{stato} del
+processo, in Linux un processo può trovarsi in uno degli stati riportati in
+tab.~\ref{tab:proc_proc_states}; ma soltanto i processi che sono nello stato
+\textit{runnable} concorrono per l'esecuzione. Questo vuol dire che, qualunque
+sia la sua priorità, un processo non potrà mai essere messo in esecuzione
+fintanto che esso si trova in uno qualunque degli altri stati.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|p{2.4cm}|c|p{9cm}|}
+ \hline
+ \textbf{Stato} & \texttt{STAT} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \textit{runnable}& \texttt{R} & Il processo è in esecuzione o è pronto ad
+ essere eseguito (cioè è in attesa che gli
+ venga assegnata la CPU).\\
+ \textit{sleep} & \texttt{S} & Il processo è in attesa di un
+ risposta dal sistema, ma può essere
+ interrotto da un segnale.\\
+ \textit{uninterrutible sleep}& \texttt{D} & Il processo è in
+ attesa di un risposta dal sistema (in
+ genere per I/O), e non può essere
+ interrotto in nessuna circostanza.\\
+ \textit{stopped} & \texttt{T} & Il processo è stato fermato con un
+ \signal{SIGSTOP}, o è tracciato.\\
+ \textit{zombie} & \texttt{Z} & Il processo è terminato ma il
+ suo stato di terminazione non è ancora
+ stato letto dal padre.\\
+ \textit{killable}& \texttt{D} & Un nuovo stato introdotto con il kernel
+ 2.6.25, sostanzialmente identico
+ all'\textit{uninterrutible sleep} con la
+ sola differenza che il processo può
+ terminato con \signal{SIGKILL} (usato per
+ lo più per NFS).\\
+ \hline
+ \end{tabular}
+ \caption{Elenco dei possibili stati di un processo in Linux, nella colonna
+ \texttt{STAT} si è riportata la corrispondente lettera usata dal comando
+ \cmd{ps} nell'omonimo campo.}
+ \label{tab:proc_proc_states}
+\end{table}
+
+Si deve quindi tenere presente che l'utilizzo della CPU è soltanto una delle
+risorse che sono necessarie per l'esecuzione di un programma, e a seconda
+dello scopo del programma non è detto neanche che sia la più importante, dato
+che molti programmi dipendono in maniera molto più critica dall'I/O. Per
+questo motivo non è affatto detto che dare ad un programma la massima priorità
+di esecuzione abbia risultati significativi in termini di prestazioni.
+
+Il meccanismo tradizionale di \textit{scheduling} di Unix (che tratteremo in
+sez.~\ref{sec:proc_sched_stand}) è sempre stato basato su delle
+\textsl{priorità dinamiche}, in modo da assicurare che tutti i processi, anche
+i meno importanti, potessero ricevere un po' di tempo di CPU. In sostanza
+quando un processo ottiene la CPU la sua priorità viene diminuita. In questo
+modo alla fine, anche un processo con priorità iniziale molto bassa, finisce
+per avere una priorità sufficiente per essere eseguito.
+
+Lo standard POSIX.1b però ha introdotto il concetto di \textsl{priorità
+ assoluta}, (chiamata anche \textsl{priorità statica}, in contrapposizione
+alla normale priorità dinamica), per tenere conto dei sistemi
+\textit{real-time},\footnote{per sistema \textit{real-time} si intende un
+ sistema in grado di eseguire operazioni in un tempo ben determinato; in
+ genere si tende a distinguere fra l'\textit{hard real-time} in cui è
+ necessario che i tempi di esecuzione di un programma siano determinabili con
+ certezza assoluta (come nel caso di meccanismi di controllo di macchine,
+ dove uno sforamento dei tempi avrebbe conseguenze disastrose), e
+ \textit{soft-real-time} in cui un occasionale sforamento è ritenuto
+ accettabile.} in cui è vitale che i processi che devono essere eseguiti in
+un determinato momento non debbano aspettare la conclusione di altri che non
+hanno questa necessità.
+
+Il concetto di priorità assoluta dice che quando due processi si contendono
+l'esecuzione, vince sempre quello con la priorità assoluta più alta.
+Ovviamente questo avviene solo per i processi che sono pronti per essere
+eseguiti (cioè nello stato \textit{runnable}). La priorità assoluta viene in
+genere indicata con un numero intero, ed un valore più alto comporta una
+priorità maggiore. Su questa politica di \textit{scheduling} torneremo in
+sez.~\ref{sec:proc_real_time}.
+
+In generale quello che succede in tutti gli Unix moderni è che ai processi
+normali viene sempre data una priorità assoluta pari a zero, e la decisione di
+assegnazione della CPU è fatta solo con il meccanismo tradizionale della
+priorità dinamica. In Linux tuttavia è possibile assegnare anche una priorità
+assoluta, nel qual caso un processo avrà la precedenza su tutti gli altri di
+priorità inferiore, che saranno eseguiti solo quando quest'ultimo non avrà
+bisogno della CPU.
+
+
+\subsection{Il meccanismo di \textit{scheduling} standard}
+\label{sec:proc_sched_stand}
+
+A meno che non si abbiano esigenze specifiche,\footnote{per alcune delle quali
+ sono state introdotte delle varianti specifiche.} l'unico meccanismo di
+\textit{scheduling} con il quale si avrà a che fare è quello tradizionale, che
+prevede solo priorità dinamiche. È di questo che, di norma, ci si dovrà
+preoccupare nella programmazione. Come accennato in Linux i processi ordinari
+hanno tutti una priorità assoluta nulla; quello che determina quale, fra tutti
+i processi in attesa di esecuzione, sarà eseguito per primo, è la cosiddetta
+\textsl{priorità dinamica},\footnote{quella che viene mostrata nella colonna
+ \texttt{PR} del comando \texttt{top}.} che è chiamata così proprio perché
+varia nel corso dell'esecuzione di un processo.
+
+Il meccanismo usato da Linux è in realtà piuttosto complesso,\footnote{e
+ dipende strettamente dalla versione di kernel; in particolare a partire
+ dalla serie 2.6.x lo \textit{scheduler} è stato riscritto completamente, con
+ molte modifiche susseguitesi per migliorarne le prestazioni, per un certo
+ periodo ed è stata anche introdotta la possibilità di usare diversi
+ algoritmi, selezionabili sia in fase di compilazione, che, nelle versioni
+ più recenti, all'avvio (addirittura è stato ideato un sistema modulare che
+ permette di cambiare lo \textit{scheduler} a sistema attivo).} ma a grandi
+linee si può dire che ad ogni processo è assegnata una \textit{time-slice},
+cioè un intervallo di tempo (letteralmente una fetta) per il quale, a meno di
+eventi esterni, esso viene eseguito senza essere interrotto. Inoltre la
+priorità dinamica viene calcolata dallo \textit{scheduler} a partire da un
+valore iniziale che viene \textsl{diminuito} tutte le volte che un processo è
+in stato \textit{runnable} ma non viene posto in esecuzione.\footnote{in
+ realtà il calcolo della priorità dinamica e la conseguente scelta di quale
+ processo mettere in esecuzione avviene con un algoritmo molto più
+ complicato, che tiene conto anche della \textsl{interattività} del processo,
+ utilizzando diversi fattori, questa è una brutale semplificazione per
+ rendere l'idea del funzionamento, per una trattazione più dettagliata, anche
+ se non aggiornatissima, dei meccanismi di funzionamento dello
+ \textit{scheduler} si legga il quarto capitolo di \cite{LinKernDev}.} Lo
+\textit{scheduler} infatti mette sempre in esecuzione, fra tutti i processi in
+stato \textit{runnable}, quello che ha il valore di priorità dinamica più
+basso.\footnote{con le priorità dinamiche il significato del valore numerico
+ ad esse associato è infatti invertito, un valore più basso significa una
+ priorità maggiore.} Il fatto che questo valore venga diminuito quando un
+processo non viene posto in esecuzione pur essendo pronto, significa che la
+priorità dei processi che non ottengono l'uso del processore viene
+progressivamente incrementata, così che anche questi alla fine hanno la
+possibilità di essere eseguiti.
+
+Sia la dimensione della \textit{time-slice} che il valore di partenza della
+priorità dinamica sono determinate dalla cosiddetta \textit{nice} (o
+\textit{niceness}) del processo.\footnote{questa è una delle tante proprietà
+ che ciascun processo si porta dietro, essa viene ereditata dai processi
+ figli e mantenuta attraverso una \func{exec}; fino alla serie 2.4 essa era
+ mantenuta nell'omonimo campo \texttt{nice} della \texttt{task\_struct}, con
+ la riscrittura dello \textit{scheduler} eseguita nel 2.6 viene mantenuta nel
+ campo \texttt{static\_prio} come per le priorità statiche.} L'origine del
+nome di questo parametro sta nel fatto che generalmente questo viene usato per
+\textsl{diminuire} la priorità di un processo, come misura di cortesia nei
+confronti degli altri. I processi infatti vengono creati dal sistema con un
+valore nullo e nessuno è privilegiato rispetto agli altri. Specificando un
+valore di \textit{nice} positivo si avrà una \textit{time-slice} più breve ed
+un valore di priorità dinamica iniziale più alto, mentre un valore negativo
+darà una \textit{time-slice} più lunga ed un valore di priorità dinamica
+iniziale più basso.
+
+Esistono diverse funzioni che consentono di indicare un valore di
+\textit{nice} di un processo; la più semplice è \funcd{nice}, che opera sul
+processo corrente, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int nice(int inc)}
+\fdesc{Aumenta il valore di \textit{nice} del processo corrente.}
+}
+{La funzione ritorna il nuovo valore di \textit{nice} in caso di successo e
+ $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+ \item[\errcode{EPERM}] non si ha il permesso di specificare un valore
+ di \param{inc} negativo.
+\end{errlist}}
+\end{funcproto}
+
+\constbeg{PRIO\_MIN}
+\constbeg{PRIO\_MAX}
+
+L'argomento \param{inc} indica l'incremento da effettuare rispetto al valore
+di \textit{nice} corrente, che può assumere valori compresi fra
+\const{PRIO\_MIN} e \const{PRIO\_MAX}; nel caso di Linux sono fra $-20$ e
+$19$,\footnote{in realtà l'intervallo varia a seconda delle versioni di
+ kernel, ed è questo a partire dal kernel 1.3.43, anche se oggi si può avere
+ anche l'intervallo fra $-20$ e $20$.} ma per \param{inc} si può specificare
+un valore qualunque, positivo o negativo, ed il sistema provvederà a troncare
+il risultato nell'intervallo consentito. Valori positivi comportano maggiore
+\textit{cortesia} e cioè una diminuzione della priorità, valori negativi
+comportano invece un aumento della priorità. Con i kernel precedenti il 2.6.12
+solo l'amministratore\footnote{o un processo con la \textit{capability}
+ \const{CAP\_SYS\_NICE}, vedi sez.~\ref{sec:proc_capabilities}.} può
+specificare valori negativi di \param{inc} che permettono di aumentare la
+priorità di un processo, a partire da questa versione è consentito anche agli
+utenti normali alzare (entro certi limiti, che vedremo in
+sez.~\ref{sec:sys_resource_limit}) la priorità dei propri processi.
+
+\constend{PRIO\_MIN}
+\constend{PRIO\_MAX}
+
+Gli standard SUSv2 e POSIX.1 prevedono che la funzione ritorni il nuovo valore
+di \textit{nice} del processo; tuttavia la \textit{system call} di Linux non
+segue questa convenzione e restituisce sempre $0$ in caso di successo e $-1$
+in caso di errore; questo perché $-1$ è anche un valore di \textit{nice}
+legittimo e questo comporta una confusione con una eventuale condizione di
+errore. La \textit{system call} originaria inoltre non consente, se non dotati
+di adeguati privilegi, di diminuire un valore di \textit{nice} precedentemente
+innalzato.
+
+Fino alla \acr{glibc} 2.2.4 la funzione di libreria riportava direttamente il
+risultato dalla \textit{system call}, violando lo standard, per cui per
+ottenere il nuovo valore occorreva una successiva chiamata alla funzione
+\func{getpriority}. A partire dalla \acr{glibc} 2.2.4 \func{nice} è stata
+reimplementata e non viene più chiamata la omonima \textit{system call}, con
+questa versione viene restituito come valore di ritorno il valore di
+\textit{nice}, come richiesto dallo standard.\footnote{questo viene fatto
+ chiamando al suo interno \func{setpriority}, che tratteremo a breve.} In
+questo caso l'unico modo per rilevare in maniera affidabile una condizione di
+errore è quello di azzerare \var{errno} prima della chiamata della funzione e
+verificarne il valore quando \func{nice} restituisce $-1$.
+
+Per leggere il valore di \textit{nice} di un processo occorre usare la
+funzione di sistema \funcd{getpriority}, derivata da BSD; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/time.h}
+\fhead{sys/resource.h}
+\fdecl{int getpriority(int which, int who)}
+\fdesc{Legge un valore di \textit{nice}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{EINVAL}] il valore di \param{which} non è uno di quelli
+ elencati in tab.~\ref{tab:proc_getpriority}.
+\item[\errcode{ESRCH}] non c'è nessun processo che corrisponda ai valori di
+ \param{which} e \param{who}.
+\end{errlist}}
+\end{funcproto}
+
+La funzione permette, a seconda di quanto specificato
+nell'argomento \param{which}, di leggere il valore di \textit{nice} di un
+processo, di un gruppo di processi (vedi sez.~\ref{sec:sess_proc_group}) o di
+un utente indicato dall'argomento \param{who}. Nelle vecchie versioni può
+essere necessario includere anche \headfiled{sys/time.h}, questo non è più
+necessario con versioni recenti delle librerie, ma è comunque utile per
+portabilità.
+
+I valori possibili per \param{which}, ed il tipo di valore che occorre usare
+in corrispondenza per \param{who} solo elencati nella legenda di
+tab.~\ref{tab:proc_getpriority} insieme ai relativi significati. Usare un
+valore nullo per \param{who} indica, a seconda della corrispondente
+indicazione usata per \param{which} il processo, il gruppo di processi o
+l'utente correnti.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|c|l|}
+ \hline
+ \param{which} & \param{who} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{PRIO\_PROCESS} & \type{pid\_t} & processo \\
+ \constd{PRIO\_PRGR} & \type{pid\_t} & \textit{process group} (vedi
+ sez.~\ref{sec:sess_proc_group})\\
+ \constd{PRIO\_USER} & \type{uid\_t} & utente \\
+ \hline
+ \end{tabular}
+ \caption{Legenda del valore dell'argomento \param{which} e del tipo
+ dell'argomento \param{who} delle funzioni \func{getpriority} e
+ \func{setpriority} per le tre possibili scelte.}
+ \label{tab:proc_getpriority}
+\end{table}