Correzione ai limiti, aggiustate referenze e iniziato le funzioni per
[gapil.git] / system.tex
index ca1fa7a98222e207f129532eb54e5b278b3f5974..40ec611f1ab333141f99d5893149cba116a13fee 100644 (file)
@@ -1,11 +1,12 @@
-\chapter{La gestione del sistema, delle risorse, e degli errori}
+fo \chapter{La gestione del sistema, delle risorse, e degli errori}
 \label{cha:system}
 
 In questo capitolo tratteremo varie interfacce che attengono agli aspetti più
-generali del sistema, come quelle per la gestione di parametri e
-configurazione, quelle per la lettura dei limiti e delle caratteristiche dello
-stesso, quelle per il controllo dell'uso delle risorse da parte dei processi,
-quelle per la gestione dei tempi e degli errori.
+generali del sistema, come quelle per la gestione dei parametri e della
+configurazione dello stesso, quelle per la lettura dei limiti e delle
+caratteristiche, quelle per il controllo dell'uso delle risorse dei processi,
+quelle per la gestione ed il controllo dei filesystem, degli utenti, dei tempi
+e degli errori.
 
 
 
@@ -13,19 +14,19 @@ quelle per la gestione dei tempi e degli errori.
 \label{sec:sys_characteristics}
 
 In questa sezione tratteremo le varie modalità con cui un programma può
-ottenere informazioni riguardo alle capacità del sistema. Ogni sistema infatti
-è contraddistinto da un gran numero di limiti e costanti che lo
-caratterizzano, e che possono dipendere da fattori molteplici, come
+ottenere informazioni riguardo alle capacità del sistema. Ogni sistema
+unix-like infatti è contraddistinto da un gran numero di limiti e costanti che
+lo caratterizzano, e che possono dipendere da fattori molteplici, come
 l'architettura hardware, l'implementazione del kernel e delle librerie, le
 opzioni di configurazione.
 
 La definizione di queste caratteristiche ed il tentativo di provvedere dei
 meccanismi generali che i programmi potessero usare per ricavarle è uno degli
-aspetti più complessi e controversi coi cui i vari standard si sono dovuti
-confrontare, spesso con risultati spesso tutt'altro che chiari. Proveremo
-comunque a dare una descrizione dei principali metodi previsti dai vari
-standard per ricavare sia le caratteristiche specifiche del sistema, che
-quelle dei file.
+aspetti più complessi e controversi con cui le diverse standardizzazioni si
+sono dovute confrontare, spesso con risultati spesso tutt'altro che chiari.
+Proveremo comunque a dare una descrizione dei principali metodi previsti dai
+vari standard per ricavare sia le caratteristiche specifiche del sistema, che
+quelle della gestione dei file.
 
 
 \subsection{Limiti e parametri di sistema}
@@ -58,7 +59,7 @@ tramite la funzione \func{sysconf} (che esamineremo in
 \secref{sec:sys_sysconf}).
 
 Lo standard ANSI C definisce dei limiti che sono tutti fissi, pertanto questo
-saranno sempre disponibili al momento della compilazione; un elenco, ripreso
+saranno sempre disponibili al momento della compilazione. Un elenco, ripreso
 da \file{limits.h}, è riportato in \tabref{tab:sys_ansic_macro}. Come si può
 vedere per la maggior parte questi limiti attengono alle dimensioni dei dati
 interi, che sono in genere fissati dall'architettura hardware (le analoghe
@@ -78,21 +79,21 @@ avere un valore minimo di 8.
     \hline
     \macro{MB\_LEN\_MAX}&       16  & massima dimensione di un 
                                       carattere esteso\\
-    \macro{CHAR\_BIT} &          8  & bit di \type{char}\\
-    \macro{UCHAR\_MAX}&        255  & massimo di \type{unsigned char}\\
-    \macro{SCHAR\_MIN}&       -128  & minimo di \type{signed char}\\
-    \macro{SCHAR\_MAX}&        127  & massimo di \type{signed char}\\
-    \macro{CHAR\_MIN} &\footnotemark& minimo di \type{char}\\
-    \macro{CHAR\_MAX} &\footnotemark& massimo di \type{char}\\
-    \macro{SHRT\_MIN} &     -32768  & minimo di \type{short}\\
-    \macro{SHRT\_MAX} &      32767  & massimo di \type{short}\\
-    \macro{USHRT\_MAX}&      65535  & massimo di \type{unsigned short}\\
-    \macro{INT\_MAX}  & 2147483647  & minimo di \type{int}\\
-    \macro{INT\_MIN}  &-2147483648  & minimo di \type{int}\\
-    \macro{UINT\_MAX} & 4294967295  & massimo di \type{unsigned int}\\
-    \macro{LONG\_MAX} & 2147483647  & massimo di \type{long}\\
-    \macro{LONG\_MIN} &-2147483648  & minimo di \type{long}\\
-    \macro{ULONG\_MAX}& 4294967295  & massimo di \type{unsigned long}\\
+    \macro{CHAR\_BIT} &          8  & bit di \ctyp{char}\\
+    \macro{UCHAR\_MAX}&        255  & massimo di \ctyp{unsigned char}\\
+    \macro{SCHAR\_MIN}&       -128  & minimo di \ctyp{signed char}\\
+    \macro{SCHAR\_MAX}&        127  & massimo di \ctyp{signed char}\\
+    \macro{CHAR\_MIN} &\footnotemark& minimo di \ctyp{char}\\
+    \macro{CHAR\_MAX} &\footnotemark& massimo di \ctyp{char}\\
+    \macro{SHRT\_MIN} &     -32768  & minimo di \ctyp{short}\\
+    \macro{SHRT\_MAX} &      32767  & massimo di \ctyp{short}\\
+    \macro{USHRT\_MAX}&      65535  & massimo di \ctyp{unsigned short}\\
+    \macro{INT\_MAX}  & 2147483647  & minimo di \ctyp{int}\\
+    \macro{INT\_MIN}  &-2147483648  & minimo di \ctyp{int}\\
+    \macro{UINT\_MAX} & 4294967295  & massimo di \ctyp{unsigned int}\\
+    \macro{LONG\_MAX} & 2147483647  & massimo di \ctyp{long}\\
+    \macro{LONG\_MIN} &-2147483648  & minimo di \ctyp{long}\\
+    \macro{ULONG\_MAX}& 4294967295  & massimo di \ctyp{unsigned long}\\
     \hline                
   \end{tabular}
   \caption{Costanti definite in \file{limits.h} in conformità allo standard
@@ -107,7 +108,7 @@ avere un valore minimo di 8.
   a seconda che il sistema usi caratteri con segno o meno.}
 
 A questi valori lo standard ISO C90 ne aggiunge altri tre, relativi al tipo
-\type{long long} introdotto con il nuovo standard, i relativi valori sono in
+\ctyp{long long} introdotto con il nuovo standard, i relativi valori sono in
 \tabref{tab:sys_isoc90_macro}.
 
 \begin{table}[htb]
@@ -118,10 +119,10 @@ A questi valori lo standard ISO C90 ne aggiunge altri tre, relativi al tipo
     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
     \hline
     \hline
-    \macro{LLONG\_MAX}& 9223372036854775807& massimo di \type{long long}\\
-    \macro{LLONG\_MIN}&-9223372036854775808& minimo di \type{long long}\\
+    \macro{LLONG\_MAX}& 9223372036854775807& massimo di \ctyp{long long}\\
+    \macro{LLONG\_MIN}&-9223372036854775808& minimo di \ctyp{long long}\\
     \macro{ULLONG\_MAX}&18446744073709551615&
-    massimo di \type{unsigned long long}\\
+    massimo di \ctyp{unsigned long long}\\
     \hline                
   \end{tabular}
   \caption{Macro definite in \file{limits.h} in conformità allo standard
@@ -275,10 +276,10 @@ esplicitamente, se ne trova una menzione completa nell'header file
 \label{sec:sys_sysconf}
 
 Come accennato in \secref{sec:sys_limits} quando uno dei limiti o delle
-caratteristiche del sistema può variare, è necessario ottenerne il valore
-attraverso la funzione \func{sysconf}, per non dover essere costretti a
+caratteristiche del sistema può variare, per non dover essere costretti a
 ricompilare un programma tutte le volte che si cambiano le opzioni con cui è
-compilato il kernel, o alcuni dei parametri modificabili a run time. Il
+compilato il kernel, o alcuni dei parametri modificabili a run time, è
+necessario ottenerne il valore attraverso la funzione \func{sysconf}. Il
 prototipo di questa funzione è:
 \begin{prototype}{unistd.h}{long sysconf(int name)}
   Restituisce il valore del parametro di sistema \param{name}.
@@ -350,7 +351,7 @@ sostituendolo a \code{\_POSIX\_} per le macro definite dagli gli altri due.
 
 In generale si dovrebbe fare uso di \func{sysconf} solo quando la relativa
 macro non è definita, quindi con un codice analogo al seguente:
-\footnotesize
+%\footnotesize
 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 get_child_max(void)
 {
@@ -365,10 +366,10 @@ get_child_max(void)
     return val;
 }
 \end{lstlisting}
-\normalsize 
-ma in realtà in Linux queste macro sono comunque definite e indicando un
-limite generico, per cui è sempre meglio usare i valori restituiti da
-quest'ultima.
+%\normalsize 
+ma in realtà in Linux queste macro sono comunque definite, indicando però un
+limite generico. Per questo motivo è sempre meglio usare i valori restituiti
+da \func{sysconf}.
 
 
 \subsection{I limiti dei file}
@@ -402,11 +403,11 @@ riportate in \tabref{tab:sys_file_macro}.
   \label{tab:sys_file_macro}
 \end{table}
 
-Come per i limiti di sistema POSIX.1 detta una serie di valori minimi per
-queste caratteristiche, che ogni sistema che vuole essere conforme deve
-rispettare; le relative macro sono riportate in \tabref{tab:sys_posix1_file},
-e per esse vale lo stesso discorso fatto per le analoghe di
-\tabref{tab:sys_posix1_general}.
+Come per i limiti di sistema, lo standard POSIX.1 detta una serie di valori
+minimi anche per queste caratteristiche, che ogni sistema che vuole essere
+conforme deve rispettare; le relative macro sono riportate in
+\tabref{tab:sys_posix1_file}, e per esse vale lo stesso discorso fatto per le
+analoghe di \tabref{tab:sys_posix1_general}.
 
 \begin{table}[htb]
   \centering
@@ -446,10 +447,10 @@ implementazioni moderne.
 \label{sec:sys_pathconf}
 
 In generale i limiti per i file sono molto più soggetti ad essere variabili
-rispetto ai precedenti limiti generali del sistema; ad esempio parametri come
-la lunghezza del nome del file o il numero di link possono variare da
-filesystem a filesystem; per questo motivo questi limiti devono essere sempre
-controllati con la funzione \func{pathconf}, il cui prototipo è:
+rispetto ai limiti generali del sistema; ad esempio parametri come la
+lunghezza del nome del file o il numero di link possono variare da filesystem
+a filesystem; per questo motivo questi limiti devono essere sempre controllati
+con la funzione \func{pathconf}, il cui prototipo è:
 \begin{prototype}{unistd.h}{long pathconf(char *path, int name)}
   Restituisce il valore del parametro \param{name} per il file \param{path}.
   
@@ -461,7 +462,7 @@ controllati con la funzione \func{pathconf}, il cui prototipo 
 E si noti come la funzione in questo caso richieda un parametro che specifichi
 a quale file si fa riferimento, dato che il valore del limite cercato può
 variare a seconda del filesystem. Una seconda versione della funzione,
-\func{fpathconf}, opera su un file descriptor invece che su un pathname, il
+\func{fpathconf}, opera su un file descriptor invece che su un pathname. Il
 suo prototipo è:
 \begin{prototype}{unistd.h}{long fpathconf(int fd, int name)}
   Restituisce il valore del parametro \param{name} per il file \param{fd}.
@@ -477,7 +478,7 @@ suo prototipo 
 \label{sec:sys_uname}
 
 Un'altra funzione che si può utilizzare per raccogliere informazioni sia
-riguardo al sistema che al computer su cui esso sta girando è \func{uname}, il
+riguardo al sistema che al computer su cui esso sta girando è \func{uname}; il
 suo prototipo è:
 \begin{prototype}{sys/utsname.h}{int uname(struct utsname *info)}
   Restituisce informazioni sul sistema nella struttura \param{info}.
@@ -488,20 +489,9 @@ suo prototipo 
 
 La funzione, che viene usata dal comando \cmd{uname}, restituisce le
 informazioni richieste nella struttura \param{info}; anche questa struttura è
-definita in \file{sys/utsname.h} come:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-struct utsname {
-    char sysname[_UTSNAME_LENGTH];
-    char nodename[_UTSNAME_LENGTH];
-    char release[_UTSNAME_LENGTH];
-    char version[_UTSNAME_LENGTH];
-    char machine[_UTSNAME_LENGTH];
-#ifdef _GNU_SOURCE
-    char domainname[_UTSNAME_DOMAIN_LENGTH];
-#endif
-};
-\end{lstlisting}
-e le informazioni memorizzate nei suoi membri indicano rispettivamente:
+definita in \file{sys/utsname.h}, secondo quanto mostrato in
+\secref{fig:sys_utsname}, e le informazioni memorizzate nei suoi membri
+indicano rispettivamente:
 \begin{itemize*}
 \item il nome del sistema operativo;
 \item il nome della release del kernel;
@@ -510,8 +500,42 @@ e le informazioni memorizzate nei suoi membri indicano rispettivamente:
 \item il nome della stazione;
 \item il nome del domino.
 \end{itemize*}
-(l'ultima informazione è stata aggiunta di recente e non è prevista dallo
-standard POSIX). 
+l'ultima informazione è stata aggiunta di recente e non è prevista dallo
+standard POSIX, essa è accessibile, come mostrato in \figref{fig:sig_stack_t},
+solo definendo \macro{\_GNU\_SOURCE}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+  \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct utsname {
+    char sysname[];
+    char nodename[];
+    char release[];
+    char version[];
+    char machine[];
+#ifdef _GNU_SOURCE
+    char domainname[];
+#endif
+};
+  \end{lstlisting}
+  \end{minipage}
+  \normalsize 
+  \caption{La struttura \var{utsname}.} 
+  \label{fig:sys_utsname}
+\end{figure}
+
+In generale si tenga presente che le dimensioni delle stringe di una
+\var{utsname} non è specificata, e che esse sono sempre terminate con
+\macro{NULL}; il manuale delle \acr{glibc} indica due diverse dimensioni,
+\macro{\_UTSNAME\_LENGTH} per i campi standard e
+\macro{\_UTSNAME\_DOMAIN\_LENGTH} per quello specifico per il nome di dominio;
+altri sistemi usano nomi diversi come \macro{SYS\_NMLN} o \macro{\_SYS\_NMLN}
+or \macro{UTSLEN} che possono avere valori diversi. Nel caso di Linux
+\func{uname} corrisponde in realtà a 3 system call diverse, le prime due usano
+rispettivamente delle lunghezze delle stringhe di 9 e 65 byte; la terza usa
+anch'essa 65 byte, ma restituisce anche l'ultimo campo, \var{domainname}, con
+una lunghezza di 257 byte.
 
 
 \section{Opzioni e configurazione del sistema}
@@ -574,15 +598,15 @@ I parametri a cui la funzione permettere di accedere sono organizzati in
 maniera gerarchica all'interno un albero; per accedere ad uno di essi occorre
 specificare un cammino attraverso i vari nodi dell'albero, in maniera analoga
 a come avviene per la risoluzione di un pathname (da cui l'uso alternativo del
-filesystem \file{/proc} che vedremo dopo).
+filesystem \file{/proc}, che vedremo dopo).
 
 Ciascun nodo dell'albero è identificato da un valore intero, ed il cammino che
 arriva ad identificare un parametro specifico è passato alla funzione
 attraverso l'array \param{name}, di lunghezza \param{nlen}, che contiene la
 sequenza dei vari nodi da attraversare. Ogni parametro ha un valore in un
-formato specifico chee può essere un intero, una stringa o anche una struttura
+formato specifico che può essere un intero, una stringa o anche una struttura
 complessa, per questo motivo il valori vengono passati come puntatori
-\type{void}.
+\ctyp{void}.
 
 L'indirizzo a cui il valore corrente del parametro deve essere letto è
 specificato da \param{oldvalue}, e lo spazio ivi disponibile è specificato da
@@ -623,10 +647,20 @@ nomi dei file corrispondenti, e questo ha il grande vantaggio di rendere
 accessibili i vari parametri a qualunque comando di shell e di permettere la
 navigazione dell'albero dei valori.
 
-Alcune delle corrispondenze con i valori di \func{sysctl} sono riportate nei
-commenti in \file{linux/sysctl.h}, la informazione disponibile in
-\file{/proc/sys} è riportata inoltre nella documentazione inclusa nei sorgenti
-del kernel, nella directory \file{Documentation/sysctl}.
+Alcune delle corrispondenze dei file presenti in \file{/proc/sys} con i valori
+di \func{sysctl} sono riportate nei commenti del codice che può essere trovato
+in \file{linux/sysctl.h},\footnote{indicando un file di definizioni si fa
+  riferimento alla directory standard dei file di include, che in ogni
+  distribuzione che si rispetti è \file{/usr/include}.} la informazione
+disponibile in \file{/proc/sys} è riportata inoltre nella documentazione
+inclusa nei sorgenti del kernel, nella directory \file{Documentation/sysctl}.
+
+Ma oltre alle informazioni ottenibili da \func{sysctl} dentro \file{proc} 
+sono disponibili moltissime altre informazioni, fra cui ad esempio anche
+quelle fornite da \func{uname} (vedi \secref{sec:sys_config}) che sono
+mantenute nei file \file{ostype}, \file{hostname}, \file{osrelease},
+\file{version} e \file{domainname} di \file{/proc/kernel/}.
+
 
 
 \subsection{La gestione delle proprietà dei filesystem}
@@ -660,8 +694,8 @@ sulla directory \param{target}.
   \item[\macro{EINVAL}] il device \param{source} presenta un
     \textit{superblock} non valido, o si è cercato di rimontare un filesystem
     non ancora montato, o di montarlo senza che \param{target} sia un
-    \type{mount point} o di spostarlo quando \param{target} non è un
-    \type{mount point} o è \file{/}.
+    \textit{mount point} o di spostarlo quando \param{target} non è un
+    \textit{mount point} o è \file{/}.
   \item[\macro{EACCES}] non si ha il permesso di accesso su uno dei componenti
   del pathname, o si è cercato di montare un filesystem disponibile in sola
   lettura senza averlo specificato o il device \param{source} è su un
@@ -689,7 +723,7 @@ loro dati sono generati al volo ad ogni lettura, e passati al kernel ad ogni
 scrittura. 
 
 Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere
-una delle stringhe riportate in \file{/proc/filesystems}, che contiene
+una delle stringhe riportate nel file \file{/proc/filesystems}, che contiene
 l'elenco dei filesystem supportati dal kernel; nel caso si sia indicato uno
 dei filesystem virtuali, il contenuto di \param{source} viene ignorato.
 
@@ -699,8 +733,8 @@ precedente contenuto di detta directory viene mascherato dal contenuto della
 directory radice del filesystem montato.
 
 Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un
-\textit{mount point} da una directory ad un'altra, che montare in diversi
-\textit{mount point} lo stesso filesystem, che montare più filesystem sullo
+\textit{mount point} da una directory ad un'altra, sia montare in diversi
+\textit{mount point} lo stesso filesystem, sia montare più filesystem sullo
 stesso \textit{mount point} (nel qual caso vale quanto appena detto, e solo il
 contenuto dell'ultimo filesystem montato sarà visibile).
 
@@ -719,6 +753,7 @@ vanno settati con un OR aritmetico della costante \macro{MS\_MGC\_VAL} con i
 valori riportati in \ntab.
 
 \begin{table}[htb]
+  \footnotesize
   \centering
   \begin{tabular}[c]{|l|r|l|}
     \hline
@@ -762,7 +797,6 @@ deve essere effettuato il rimontaggio del filesystem (con le opzioni
 specificate dagli altri bit), anche in questo caso il valore di \param{source}
 viene ignorato.
 
-
 Una volta che non si voglia più utilizzare un certo filesystem è possibile
 \textsl{smontarlo} usando la funzione \func{umount}, il cui prototipo è:
 \begin{prototype}{sys/mount.h}{umount(const char *target)}
@@ -816,12 +850,15 @@ Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
 informazioni riguardo al filesystem su cui si trova un certo file, sono
 \func{statfs} e \func{fstatfs}, i cui prototipi sono:
 \begin{functions}
-  \headdecl{sys/vfs.h} \funcdecl{int statfs(const char *path, struct statfs
-    *buf)} \funcdecl{int fstatfs(int fd, struct statfs *buf)} Restituisce in
-  \param{buf} le informazioni relative al filesystem su cui è posto il file
-  specificato.
+  \headdecl{sys/vfs.h} 
+  \funcdecl{int statfs(const char *path, struct statfs *buf)} 
+
+  \funcdecl{int fstatfs(int fd, struct statfs *buf)} 
+  
+  Restituisce in \param{buf} le informazioni relative al filesystem su cui è
+  posto il file specificato.
   
-  \bodydesc{Li funzioni restituiscono 0 in caso di successo e -1 in caso di
+  \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
     errore, nel qual caso \var{errno} viene settato ai valori:
   \begin{errlist}
   \item[\macro{ENOSYS}] il filesystem su cui si trova il file specificato non
@@ -834,8 +871,17 @@ informazioni riguardo al filesystem su cui si trova un certo file, sono
 
 Queste funzioni permettono di ottenere una serie di informazioni generali
 riguardo al filesystem su cui si trova il file specificato; queste vengono
-restituite una struttura \param{buf} definita come:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+restituite una struttura \param{buf} di tipo \type{statfs} definita come in
+\ref{fig:sys_statfs}, ed i campi che sono indefiniti per il filesystem in
+esame sono settati a zero.  I valori del campo \var{f\_type} sono definiti per
+i vari filesystem nei relativi file di header dei sorgenti del kernel da
+costanti del tipo \macro{XXX\_SUPER\_MAGIC}, dove \macro{XXX} in genere è il
+nome del filesystem stesso.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+  \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
     struct statfs {
        long    f_type;     /* tipo di filesystem */
        long    f_bsize;    /* dimensione ottimale dei blocchi di I/O */
@@ -849,15 +895,16 @@ restituite una struttura \param{buf} definita come:
        long    f_spare[6]; /* riservati per uso futuro */
     };
 \end{lstlisting}
-ed i campi che sono indefiniti per il filesystem in esame sono settati a zero.
-I valori del campo \var{f\_type} sono definiti per i vari filesystem nei
-relativi file di header dei sorgenti del kernel da costanti del tipo
-\macro{XXX\_SUPER\_MAGIC}, dove \macro{XXX} in genere è il nome del filesystem
-stesso.
+  \end{minipage}
+  \normalsize 
+  \caption{La struttura \var{statfs}.} 
+  \label{fig:sys_statfs}
+\end{figure}
+
 
 Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due
 file standard \file{/etc/fstab} e \file{/etc/mtab}, che convenzionalmente sono
-usati in quasi tutti i sistemi unix per mantenere rispettivamente le
+usati in quasi tutti i sistemi unix-like per mantenere rispettivamente le
 informazioni riguardo ai filesystem da montare e a quelli correntemente
 montati. Le funzioni servono a leggere il contenuto di questi file in
 opportune strutture \var{struct fstab} e \var{struct mntent}, e, per
@@ -874,72 +921,463 @@ tralasceremo la trattazione, rimandando al manuale delle \acr{glibc}
 \subsection{La gestione di utenti e gruppi}
 \label{sec:sys_user_group}
 
-L'ultimo argomento di questa sezione è quello che riguarda le funzioni
-utilizzate per gestire utenti e gruppi all'interno del sistema.
 Tradizionalmente l'informazione per la gestione di utenti e gruppi veniva
-tenuta tutta nei due file di testo \file{/etc/passwd} ed \file{/etc/group};
-oggi la maggior parte delle distribuzioni di Linux usa la libreria PAM (sigla
-che sta \textit{Pluggable Authentication Method}) che permette di separare
-completamente i meccanismi di gestione degli utenti (autenticazione,
-riconoscimeto, ecc.) dal
+tenuta tutta nei due file di testo \file{/etc/passwd} ed \file{/etc/group}, e
+tutte le funzioni facevano riferimento ad essi.  Oggi la maggior parte delle
+distribuzioni di Linux usa la libreria PAM (sigla che sta \textit{Pluggable
+  Authentication Method}) che permette di separare completamente i meccanismi
+di gestione degli utenti (autenticazione, riconoscimento, ecc.) dalle modalità
+in cui i relativi dati vengono mantenuti, per cui pur restando in gran parte
+le stesse\footnote{in genere quello che viene cambiato è l'informazione usata
+  per l'autenticazione, che non è più necessariamente una password criptata da
+  verificare, ma può assumere le forme più diverse, come impronte digitali,
+  chiavi elettroniche, ecc.}, le informazioni non sono più necessariamente
+mantenute in quei file.
+
+In questo paragrafo ci limiteremo comunque alle funzioni classiche per la
+lettura delle informazioni relative a utenti e gruppi previste dallo standard
+POSIX.1, che fanno riferimento a quanto memorizzato nei due file appena
+citati, il cui formato è descritto dalle relative pagine del manuale (cioè
+\cmd{man 5 passwd} e \cmd{man 5 group}).
+
+Per leggere le informazioni relative ad un utente si possono usare due
+funzioni, \func{getpwuid} e \func{getpwnam}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{pwd.h} 
+  \headdecl{sys/types.h} 
+  \funcdecl{struct passwd *getpwuid(uid\_t uid)} 
+  
+  \funcdecl{struct passwd *getpwnam(const char *name)} 
 
+  Restituiscono le informazioni relative all'utente specificato.
+  
+  \bodydesc{Le funzioni ritornano il puntatore alla struttura contenente le
+    informazioni in caso di successo e \macro{NULL} nel caso non sia stato
+    trovato nessun utente corrispondente a quanto specificato.}
+\end{functions}
 
+Le due funzioni forniscono le informazioni memorizzate nel database degli
+utenti (che nelle versioni più recenti possono essere ottenute attraverso PAM)
+relative all'utente specificato attraverso il suo \acr{uid} o il nome di
+login. Entrambe le funzioni restituiscono un puntatore ad una struttura di
+tipo \type{passwd} la cui definizione (anch'essa eseguita in \file{pwd.h}) è
+riportata in \figref{fig:sys_passwd_struct}, dove è pure brevemente illustrato
+il significato dei vari campi. 
 
-Lo standard POSIX.1 definisce una serie di funzioni
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct passwd {
+    char    *pw_name;       /* user name */
+    char    *pw_passwd;     /* user password */
+    uid_t   pw_uid;         /* user id */
+    gid_t   pw_gid;         /* group id */
+    char    *pw_gecos;      /* real name */
+    char    *pw_dir;        /* home directory */
+    char    *pw_shell;      /* shell program */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{passwd} contenente le informazioni relative ad un
+    utente del sistema.}
+  \label{fig:sys_passwd_struct}
+\end{figure}
 
+La struttura usata da entrambe le funzioni è allocata staticamente, per questo
+motivo viene sovrascritta ad ogni nuova invocazione, lo stesso dicasi per la
+memoria dove sono scritte le stringhe a cui i puntatori in essa contenuti
+fanno riferimento. Ovviamente questo implica che dette funzioni non posono
+essere rientranti, per cui ne esistono anche due versioni alternative
+(denotate dalla solita estensione \code{\_r}), i cui prototipi sono:
+\begin{functions}
+  \headdecl{pwd.h} 
+  
+  \headdecl{sys/types.h} 
+  
+  \funcdecl{struct passwd *getpwuid\_r(uid\_t uid, struct passwd *password,
+    char *buffer, size\_t buflen, struct passwd **result)}
+  
+  \funcdecl{struct passwd *getpwnam\_r(const char *name, struct passwd
+    *password, char *buffer, size\_t buflen, struct passwd **result)}
 
+  Restituiscono le informazioni relative all'utente specificato.
+  
+  \bodydesc{Le funzioni ritornano 0 in caso di successo e un codice d'errore
+    altrimenti, nel qual caso \var{errno} sarà settato opportunamente.}
+\end{functions}
 
-\section{Limitazione ed uso delle risorse}
-\label{sec:sys_res_limits}
+In questo caso l'uso è molto più complesso, in quanto bisogna prima allocare
+la memoria necessaria a contenere le informazioni. In particolare i valori
+della struttura \var{passwd} saranno restituiti all'indirizzo \param{password}
+mentre la memoria allocata all'indirizzo \param{buffer}, per un massimo di
+\param{buflen} byte, sarà utilizzata per contenere le stringhe puntate dai
+campi di \param{password}. Infine all'indirizzo puntato da \param{result}
+viene restituito il puntatore ai dati ottenuti, cioè \param{buffer} nel caso
+l'utente esista, o \macro{NULL} altrimenti.  Qualora i dati non possano essere
+contenuti nei byte specificati da \param{buflen}, la funzione fallirà
+restituendo \macro{ERANGE} (e \param{result} sarà comunque settato a
+\macro{NULL}).
+
+Del tutto analoghe alle precedenti sono le funzioni \func{getgrnam} e
+\func{getgrgid} (e le relative analoghe rientranti con la stessa estensione
+\code{\_r}) che permettono di leggere le informazioni relative ai gruppi, i
+loro prototipi sono:
+\begin{functions}
+  \headdecl{grp.h} 
+  \headdecl{sys/types.h} 
 
-In questa sezione esamineremo le funzioni che permettono di esaminare e
-controllare come le varie risorse del sistema (CPU, memoria, ecc.) vengono
-utilizzate dai processi, e le modalità con cui è possibile imporre dei limiti
-sul loro utilizzo.
+  \funcdecl{struct group *getgrgid(gid\_t gid)} 
+  
+  \funcdecl{struct group *getgrnam(const char *name)} 
+  
+  \funcdecl{struct group *getpwuid\_r(gid\_t gid, struct group *password,
+    char *buffer, size\_t buflen, struct group **result)}
+  
+  \funcdecl{struct group *getpwnam\_r(const char *name, struct group
+    *password, char *buffer, size\_t buflen, struct group **result)}
 
+  Restituiscono le informazioni relative al gruppo specificato.
+  
+  \bodydesc{Le funzioni ritornano 0 in caso di successo e un codice d'errore
+    altrimenti, nel qual caso \var{errno} sarà settato opportunamente.}
+\end{functions}
 
+Il comportamento di tutte queste funzioni è assolutamente identico alle
+precedenti che leggono le informazioni sugli utenti, l'unica differenza è che
+in questo caso le informazioni vengono restituite in una struttura di tipo
+\type{group}, la cui definizione è riportata in \figref{fig:sys_group_struct}.
 
-\subsection{L'uso delle risorse}
-\label{sec:sys_resource_use}
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct group {
+    char    *gr_name;        /* group name */
+    char    *gr_passwd;      /* group password */
+    gid_t   gr_gid;          /* group id */
+    char    **gr_mem;        /* group members */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{group} contenente le informazioni relative ad un
+    gruppo del sistema.}
+  \label{fig:sys_group_struct}
+\end{figure}
+
+Le funzioni viste finora sono in grado di leggere le informazioni sia dal file
+delle password in \file{/etc/passwd} che con qualunque altro metodo sia stato
+utilizzato per mantenere il database degli utenti. Non permettono però di
+settare direttamente le password; questo è possibile con un'altra interfaccia
+al database degli utenti, derivata da SVID, che però funziona soltanto con un
+database che sia tenuto su un file che abbia il formato classico di
+\file{/etc/passwd}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Funzione} & \textbf{Significato}\\
+    \hline
+    \hline
+    \func{fgetpwent}   & Legge una voce dal database utenti da un file 
+                         specificato aprendolo la prima volta.\\
+    \func{fgetpwent\_r}& Come la precedente, ma rientrante.\\
+    \func{getpwent}    & Legge una voce dal database utenti (da 
+                         \file{/etc/passwd}) aprendolo la prima volta.\\
+    \func{getpwent\_r} & Come la precedente, ma rientrante.\\
+    \func{setpwent}    & Ritorna all'inizio del database.\\
+    \func{putpwent}    & Immette una voce nel database utenti.\\
+    \func{endpwent}    & Chiude il database degli utenti.\\
+    \func{fgetgrent}   & Legge una voce dal database dei gruppi da un file 
+                         specificato aprendolo la prima volta.\\
+    \func{fgetgrent\_r}& Come la precedente, ma rientrante.\\
+    \func{getgrent}    & Legge una voce dal database dei gruppi (da 
+                         \file{/etc/passwd}) aprendolo la prima volta.\\
+    \func{getgrent\_r} & Come la precedente, ma rientrante.\\
+    \func{setgrent}    & Immette una voce nel database dei gruppi.\\
+    \func{putgrent}    & Immette una voce nel database dei gruppi.\\
+    \func{endgrent}    & Chiude il database dei gruppi.\\
+    \hline
+  \end{tabular}
+  \caption{Funzioni per la manipolazione dei campi di un file usato come
+    database di utenti e gruppi nel formato di \file{/etc/passwd} e
+    \file{/etc/groups}.} 
+  \label{tab:sys_passwd_func}
+\end{table}
 
+Dato che ormai la gran parte delle distribuzioni di Linux utilizzano PAM, che
+come minimo usa almeno le \textit{shadow password} (quindi con delle modifiche
+rispetto al formato classico di \file{/etc/passwd}), le funzioni che danno la
+capacità scrivere delle voci nel database (cioè \func{putpwent} e
+\func{putgrent}) non permettono di effettuarne una specificazione in maniera
+completa. Per questo motivo l'uso di queste funzioni è deprecato in favore
+dell'uso di PAM, ci limiteremo pertanto ad elencarle in
+\tabref{tab:sys_passwd_func}, rimandando chi fosse interessato alle rispettive
+man page e al manuale delle \acr{glibc} per i dettagli del loro funzionamento.
+
+
+
+\subsection{Il database di accounting}
+\label{sec:sys_accounting}
+
+L'ultimo insieme di funzioni relative alla gestione del sistema che
+esamineremo è quello che permette di accedere ai dati del database di
+\textit{accounting}.  In esso vengono mantenute una serie di informazioni
+storiche relative sia agli utenti che si sono collegati al sistema, (tanto per
+quelli correntemente collegati, che per la registrazione degli accessi
+precedenti), sia relative all'intero sistema, come il momento di lancio di
+processi da parte di \cmd{init}, il cambiamento dell'orologio di sistema, il
+cambiamento di runlevel o il riavvio della macchina.
+
+I dati vengono usualmente\footnote{questa è la locazione specificata dal
+  \textit{Linux Filesystem Hierarchy Standard}, adottato dalla gran parte
+  delle distribuzioni.} memorizzati nei due file \file{/var/run/utmp} e
+\file{/var/log/wtmp}. Quando un utente si collega viene aggiunta una voce a
+\file{/var/run/utmp} in cui viene memorizzato il nome di login, il terminale
+da cui ci si collega, l'\acr{uid} della shell di login, l'orario della
+connessione ed altre informazioni.  La voce resta nel file fino al logout,
+quando viene cancellata e spostata in \file{/var/log/wtmp}.
+
+In questo modo il primo file viene utilizzato per registrare sta utilizzando
+il sistema al momento corrente, mentre il secondo mantiene la registrazione
+delle attività degli utenti. A quest'ultimo vengono anche aggiunte delle voci
+speciali per tenere conto dei cambiamenti del sistema, come la modifica del
+runlevel, il riavvio della macchina, ecc. Tutte queste informazioni sono
+descritte in dettaglio nel manuale delle \acr{glibc}.
+
+Questi file non devono mai essere letti direttamente, ma le informazioni che
+contengono possono essere ricavate attraverso le opportune funzioni di
+libreria. Queste sono analoghe alle precedenti (vedi
+\tabref{tab:sys_passwd_func}) usate per accedere al database degli utenti,
+solo che in questo caso la struttura del database di accounting è molto più
+complessa, dato che contiene diversi tipi di informazione.
+
+Le prime tre funzioni, \func{setutent}, \func{endutent} e \func{utmpname}
+servono rispettivamente a aprire e a chiudere il file che contiene il
+database, e a specificare su quale file esso viene mantenuto. I loro prototipi
+sono:
+\begin{functions}
+  \headdecl{utmp.h} 
+  
+  \funcdecl{void utmpname(const char *file)} Specifica il file da usare come
+  database di \textit{accounting}.
+  
+  \funcdecl{void setutent(void)} Apre il file del database di
+  \textit{accounting}, posizionandosi al suo inizio.
+  
+  \funcdecl{void endutent(void)} Chiude il file del database di
+  \textit{accounting}.
+  
+  \bodydesc{Le funzioni non ritornano codici di errore.}
+\end{functions}
 
+In caso questo non venga specificato nessun file viene usato il valore
+standard \macro{\_PATH\_UTMP} (che è definito in \file{paths.h}); in genere
+\func{utmpname} prevede due possibili valori:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{\_PATH\_UTMP}] Specifica il database di accounting per gli utenti
+  correntemente collegati.
+\item[\macro{\_PATH\_WTMP}] Specifica il database di accounting per l'archivio
+  storico degli utenti collegati.
+\end{basedescript}
+corrispondenti ai file \file{/var/run/utmp} e \file{/var/log/wtmp} visti in
+precedenza.
+
+Una volta aperto il file si può eseguire una scansione leggendo o scrivendo
+una voce con le funzioni \func{getutent}, \func{getutid}, \func{getutline} e 
+\func{pututline}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{utmp.h} 
 
+  \funcdecl{struct utmp *getutent(void)} 
+  Legge una voce dal dalla posizione corrente nel database.
+  
+  \funcdecl{struct utmp *getutid(struct utmp *ut)} 
+  Ricerca una voce sul database in base al contenuto di \param{ut}.
 
-\subsection{Limiti sulle risorse}
-\label{sec:sys_resource_limit}
+  \funcdecl{struct utmp *getutline(struct utmp *ut)} 
+  Ricerca nel database la prima voce corrispondente ad un processo sulla linea
+  di terminale specificata tramite \param{ut}.
 
+  \funcdecl{struct utmp *pututline(struct utmp *ut)} 
+  Scrive una voce nel database.
 
-\subsection{Le risorse di memoria}
-\label{sec:sys_memory_res}
+  \bodydesc{Le funzioni ritornano il puntatore ad una struttura \var{utmp} in
+    caso di successo e \macro{NULL} in caso di errore.}
+\end{functions}
 
+Tutte queste funzioni fanno riferimento ad una struttura di tipo \var{utmp},
+la cui definizione in Linux è riportata in \secref{fig:sys_utmp_struct}. Le
+prime tre funzioni servono per leggere una voce dal database; \func{getutent}
+legge semplicemente la prima voce disponibile; le altre due permettono di
+eseguire una ricerca.
 
-\subsection{Le risorse di processore}
-\label{sec:sys_cpu_load}
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct utmp
+{
+    short int ut_type;            /* Type of login.  */
+    pid_t ut_pid;                 /* Process ID of login process.  */
+    char ut_line[UT_LINESIZE];    /* Devicename.  */
+    char ut_id[4];                /* Inittab ID.  */
+    char ut_user[UT_NAMESIZE];    /* Username.  */
+    char ut_host[UT_HOSTSIZE];    /* Hostname for remote login.  */
+    struct exit_status ut_exit;   /* Exit status of a process marked
+                                     as DEAD_PROCESS.  */
+    long int ut_session;          /* Session ID, used for windowing.  */
+    struct timeval ut_tv;         /* Time entry was made.  */
+    int32_t ut_addr_v6[4];        /* Internet address of remote host.  */
+    char __unused[20];            /* Reserved for future use.  */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{utmp} contenente le informazioni di una voce del
+    database di \textit{accounting}.}
+  \label{fig:sys_utmp_struct}
+\end{figure}
+
+Con \func{getutid} si può cercare una voce specifica, a seconda del valore del
+campo \var{ut\_type} dell'argomento \param{ut}.  Questo può assumere i valori
+riportati in \tabref{tab:sys_ut_type}, quando assume i valori
+\macro{RUN\_LVL}, \macro{BOOT\_TIME}, \macro{OLD\_TIME}, \macro{NEW\_TIME},
+verrà restituito la prima voce che corrisponde al tipo determinato; quando
+invece assume i valori \macro{INIT\_PROCESS}, \macro{LOGIN\_PROCESS},
+\macro{USER\_PROCESS} o \macro{DEAD\_PROCESS} verrà restiuita la prima voce
+corripondente al valore del campo \var{ut\_id} specificato in \param{ut}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Funzione} & \textbf{Significato}\\
+    \hline
+    \hline
+    \macro{EMPTY}         & Non contiene informazioni valide. \\
+    \macro{RUN\_LVL}      & Identica il runlevel del sistema. \\
+    \macro{BOOT\_TIME}    & Identifica il tempo di avvio del sistema \\
+    \macro{OLD\_TIME}     & Identifica quando è stato modificato l'orologio di
+                            sistema. \\
+    \macro{NEW\_TIME}     & Identifica da quanto è stato modificato il 
+                            sistema. \\
+    \macro{INIT\_PROCESS} & Identifica un processo lanciato da \cmd{init}. \\
+    \macro{LOGIN\_PROCESS}& Identifica un processo di login. \\
+    \macro{USER\_PROCESS} & Identifica un processo utente. \\
+    \macro{DEAD\_PROCESS} & Identifica un processo terminato. \\
+    \macro{ACCOUNTING}    & ??? \\
+    \hline
+  \end{tabular}
+  \caption{Classificazione delle voci del database di accounting a seconda dei
+    possibili valori del campo \var{ut\_type}.} 
+  \label{tab:sys_ut_type}
+\end{table}
+
+La funzione \func{getutline} esegue la ricerca sulle voci che hanno
+\var{ut\_type} uguale a \macro{LOGIN\_PROCESS} o \macro{USER\_PROCESS},
+restituendo la prima che corrisponde al valore di \var{ut\_line}, che
+specifica il device\footnote{espresso senza il \file{/dev/} iniziale.} di
+terminale che interessa. Lo stesso criterio di ricerca è usato da
+\func{pututline} per trovare uno spazio dove inserire la voce specificata,
+qualora non sia trovata la voce viene aggiunta in coda al database.
+
+In generale occorre però tenere conto che queste funzioni non sono
+completamente standardizzate, e che in sistemi diversi possono esserci
+differenze; ad esempio \func{pututline} restituisce \code{void} in vari
+sistemi (compreso Linux, fino alle \acr{libc5}). Qui seguiremo la sintassi
+fornita dalle \acr{glibc}, ma gli standard POSIX 1003.1-2001 e XPG4.2 hanno
+introdotto delle nuove strutture (e relativi file) di tipo \code{utmpx}, che
+sono un sovrainsieme di \code{utmp}. 
+
+Le \acr{glibc} utilizzano già una versione estesa di \code{utmp}, che rende
+inutili queste nuove strutture; pertanto esse e le relative funzioni di
+gestione (\func{getutxent}, \func{getutxid}, \func{getutxline},
+\func{pututxline}, \func{setutxent} e \func{endutxent}) sono ridefinite come
+sinonimi delle funzioni appena viste.
+
+Come visto in \secref{sec:sys_user_group}, l'uso di strutture allocate
+staticamente rende le funzioni di lettura non rientranti; per questo motivo le
+\acr{glibc} forniscono anche delle versioni rientranti: \func{getutent\_r},
+\func{getutid\_r}, \func{getutline\_r}, che invece di restituire un puntatore
+restituiscono un intero e prendono due argomenti aggiuntivi. Le funzioni si
+comportano esattamente come le analoge non rientranti, solo che restituiscono
+il risultato all'indirizzo specificato dal primo argomento aggiuntivo (di tipo
+\code{struct utmp *buffer}) mentre il secondo (di tipo \code{struct utmp
+  **result)} viene usato per restituire il puntatore allo stesso buffer.
+
+Infine le \acr{glibc} forniscono come estensione per la scrittura delle voci
+in \file{wmtp} altre due funzioni, \func{updwtmp} e \func{logwtmp}, i cui
+prototipi sono:
+\begin{functions}
+  \headdecl{utmp.h} 
+  
+  \funcdecl{void updwtmp(const char *wtmp\_file, const struct utmp *ut)}
+  Aggiunge la voce \param{ut} nel database di accounting \file{wmtp}.
+  
+  \funcdecl{void logwtmp(const char *line, const char *name, const char
+    *host)} Aggiunge nel database di accounting una voce con i valori
+  specificati.
+
+  \bodydesc{Le funzioni ritornano il puntatore ad una struttura \var{utmp} in
+    caso di successo e \macro{NULL} in caso di errore.}
+\end{functions}
+
+La prima funzione permette l'aggiunta di una voce a \file{wmtp} specificando
+direttamente una struttura \type{utmp}, mentre la seconda utilizza gli
+argomenti \param{line}, \param{name} e \param{host} per costruire la voce che
+poi aggiunge chiamando \func{updwtmp}.
+
+
+\section{Limitazione ed uso delle risorse}
+\label{sec:sys_res_limits}
 
 
+Dopo aver esaminato le funzioni che permettono di controllare le varie
+caratteristiche, capacità e limiti del sistema a livello globale, in questa
+sezione tratteremo le varie funzioni che vengono usate per quantificare le
+risorse (CPU, memoria, ecc.)  utilizzate da ogni singolo processo e quelle che
+permettono di imporre a ciascuno di essi vincoli e limiti di utilizzo.
+
+
+\subsection{L'uso delle risorse}
+\label{sec:sys_resource_use}
+
+Come abbiamo accennato in \secref{sec:proc_wait4} le informazioni riguardo
+l'utilizzo delle risorse da parte di un processo è mantenuto in una struttura
+di tipo \code{struct }\type{rusage}, la cui definizione (che si trova in
+\file{sys/resource.h}) è riportata in \figref{fig:sys_rusage_struct}.
 
 \begin{figure}[!htb]
   \footnotesize
   \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 struct rusage {
-     struct timeval ru_utime; /* user time used */
-     struct timeval ru_stime; /* system time used */
-     long ru_maxrss;          /* maximum resident set size */
-     long ru_ixrss;           /* integral shared memory size */
-     long ru_idrss;           /* integral unshared data size */
-     long ru_isrss;           /* integral unshared stack size */
-     long ru_minflt;          /* page reclaims */
-     long ru_majflt;          /* page faults */
-     long ru_nswap;           /* swaps */
-     long ru_inblock;         /* block input operations */
-     long ru_oublock;         /* block output operations */
-     long ru_msgsnd;          /* messages sent */
-     long ru_msgrcv;          /* messages received */
-     long ru_nsignals;   ;    /* signals received */
-     long ru_nvcsw;           /* voluntary context switches */
-     long ru_nivcsw;          /* involuntary context switches */
+    struct timeval ru_utime; /* user time used */
+    struct timeval ru_stime; /* system time used */
+    long ru_maxrss;          /* maximum resident set size */
+    long ru_ixrss;           /* integral shared memory size */
+    long ru_idrss;           /* integral unshared data size */
+    long ru_isrss;           /* integral unshared stack size */
+    long ru_minflt;          /* page reclaims */
+    long ru_majflt;          /* page faults */
+    long ru_nswap;           /* swaps */
+    long ru_inblock;         /* block input operations */
+    long ru_oublock;         /* block output operations */
+    long ru_msgsnd;          /* messages sent */
+    long ru_msgrcv;          /* messages received */
+    long ru_nsignals;   ;    /* signals received */
+    long ru_nvcsw;           /* voluntary context switches */
+    long ru_nivcsw;          /* involuntary context switches */
 };
     \end{lstlisting}
   \end{minipage} 
@@ -949,19 +1387,256 @@ struct rusage {
   \label{fig:sys_rusage_struct}
 \end{figure}
 
+La struttura è ripresa da BSD 4.3, ma attualmente (con i kernel della serie
+2.4.x) i soli campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime},
+\var{ru\_minflt}, \var{ru\_majflt}, e \var{ru\_nswap}. I primi due indicano
+rispettivamente il tempo impiegato dal processo nell'eseguire le istruzioni in
+user space, e quello impiegato dal kernel nelle system call eseguite per conto
+del processo.
+
+Gli altri tre campi servono a quantificare l'uso della memoria virtuale e
+corrispondono rispettivamente al numero di \textit{page fault}\index{page
+  fault} (vedi \secref{sec:proc_mem_gen}) avvenuti senza richiedere I/O (i
+cosiddetti \textit{minor page fault}), a quelli che invece han richiesto I/O
+(detti invece \textit{major page fault}) ed al numero di volte che il processo
+è stato completamente tolto dalla memoria per essere inserito nello swap.
+
+In genere includere esplicitamente \file{<sys/time.h>} non è più necessario,
+ma aumenta la portabilità, e serve comunque quando, come nella maggior parte
+dei casi, si debba accedere ai campi di \var{rusage} relativi ai tempi di
+utilizzo del processore, che sono definiti come \code{struct }\type{timeval}.
+
+
+Questa è la stessa struttura utilizzata da \func{wait4}  per ricavare la
+quantità di risorse impiegato dal processo di cui si è letto lo stato di
+terminazione, ma essa può anche essere letta direttamente utilizzando la
+funzione \func{getrusage}, il cui prototipo è:
+\begin{functions}
+  \headdecl{sys/time.h} 
+  \headdecl{sys/resource.h} 
+  \headdecl{unistd.h} 
+  
+  \funcdecl{int getrusage(int who, struct rusage *usage)} 
+  Legge la quantità di risorse usate da un processo.
+
+
+  \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore,
+  nel qual caso \var{errno} può essere \macro{EINVAL} o \macro{EFAULT}.}
+\end{functions}
+
+L'argomento \param{who} permette di specificare il processo di cui si vuole
+leggere l'uso delle risorse; esso può assumere solo i due valori
+\macro{RUSAGE\_SELF} per indicare il processo corrente e
+\macro{RUSAGE\_CHILDREN} per indicare l'insieme dei processi figli di cui si è
+ricevuto lo stato di terminazione. 
+
+
+\subsection{Limiti sulle risorse}
+\label{sec:sys_resource_limit}
+
+Come accennato nell'introduzione oltre a leggere l'uso delle risorse da parte
+di un processo si possono anche imporre dei limiti sulle sue capacità. Ogni
+processo ha in generale due limiti associati ad ogni risorsa; questi sono
+detti il \textsl{limite corrente} (o \textit{current limit}) che esprime il
+valore che attualmente il processo non può superare, ed il \textsl{limite
+  massimo} (o \textit{maximum limit}) che esprime il valore massimo che può
+assumere il \textsl{limite corrente}.
+
+In generale il primo viene chiamato un limite \textsl{soffice} (o \textit{soft
+  limit}) dato che il suo valore può essere aumentato, mentre il secondo è
+detto \textsl{duro} (o \textit{hard limit}), in quanto un processo normale non
+può modificarne il valore. Il valore di questi limiti è mantenuto in una
+struttura \var{rlimit}, la cui definizione è riportata in
+\figref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a limite
+corrente e massimo.
+
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+    struct rlimit {
+         rlim_t    rlim_cur;
+         rlim_t    rlim_max;
+    };
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{rlimit} per impostare i limiti di utilizzo 
+    delle risorse usate da un processo.}
+  \label{fig:sys_rlimit_struct}
+\end{figure}
+
+In genere il superamento di un limite comporta o l'emissione di un segnale o
+il fallimento della system call che lo ha provocato; per far leggere o settare
+i limiti di utilizzo delle risorse da parte di un processo le \acr{glibc}
+prevedono due funzioni, \func{getrlimit} e \func{setrlimit}, i cui prototipi
+sono:
+\begin{functions}
+  \headdecl{sys/time.h} 
+  \headdecl{sys/resource.h} 
+  \headdecl{unistd.h} 
+  
+  \funcdecl{int getrlimit(int resource, struct rlimit *rlim)} 
+
+  Legge il limite corrente per la risorsa \param{resource}.
+  
+  \funcdecl{int setrlimit(int resource, const struct rlimit *rlim)} 
+  
+  Setta il limite per la risorsa \param{resource}.
+  
+  \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} viene settata ai valori:
+    \begin{errlist}
+    \item[\macro{INVAL}] I valori per \param{resource} non sono validi.
+    \item[\macro{EPERM}] Un processo senza i privilegi di amministratore ha
+    cercato di innalzare i propri limiti.
+    \end{errlist}
+  ed \macro{EFAULT}.}
+\end{functions}
+
+Entrambe le funzioni permettono di specificare su quale risorsa si vuole
+operare attraverso \param{resource}, i cui possibili valori sono elencati in
+\secref{tab:sys_rlimit_values}, e utilizzano una struttura \var{rlimit} per
+specificarne i valori.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{12cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato}\\
+    \hline
+    \hline
+    \macro{RLIMIT\_CPU}    &  Il massimo tempo di CPU che il processo può
+                              usare. Il superamento del limite comporta
+                              l'emissione di un segnale di \macro{SIGXCPU}.\\
+    \macro{RLIMIT\_FSIZE}  &  La massima dimensione di un file che un processo
+                              può usare. Se il processo cerca di scrivere
+                              oltre questa dimensione riceverà un segnale di
+                              \macro{SIGXFSZ}.\\
+    \macro{RLIMIT\_DATA}   &  La massima dimensione della memoria dati di un
+                              processo. Il tentatico di allocare più memoria
+                              causa il fallimento della funzione di
+                              allocazione. \\
+    \macro{RLIMIT\_STACK}  &  La massima dimensione dello stack del
+                              processo. Se il processo esegue operazioni che
+                              estendano lo stack oltre questa dimensione
+                              riceverà un segnale di \macro{SIGSEGV}.\\
+    \macro{RLIMIT\_CORE}   &  La massima dimensione di un file di \textit{core
+                              dump} creato da un processo. Nel caso le 
+                              dimensioni dovessero essere maggiori il file non
+                              verrebbe generato.\footnotemark\\
+    \macro{RLIMIT\_RSS}    &  L'ammontare massimo di memoria fisica dato al
+                              processo. Il limite è solo una indicazione per
+                              il kernel, qualora ci fosse un surplus di
+                              memoria questa verrebbe assegnata.\\
+    \macro{RLIMIT\_NPROC}  &  Il numero massimo di processi che possono essere
+                              creati sullo stesso user id. Se il limite viene
+                              raggiunto \func{fork} fallirà con un
+                              \macro{EAGAIN}.\\
+    \macro{RLIMIT\_NOFILE} &  Il numero massimo di file che il processo può
+                              aprire. L'apertura di un ulteriore file fallirà
+                              con un errore \macro{EMFILE}.\\
+    \macro{RLIMIT\_MEMLOCK}&  L'ammontare massimo di memoria che può essere
+                              bloccata (vedi \secref{sec:proc_mem_lock}).\\
+    \macro{RLIMIT\_AS}     &  La dimensione massima di tutta la memoria che il
+                              processo può ottenere. Se il processo tenta di
+                              allocarne di più  funzioni come \func{brk},
+                              \func{malloc} o \func{mmap} falliranno. \\
+    \hline
+  \end{tabular}
+  \caption{Valori possibili dell'argomento \param{resource} delle funzioni
+    \func{getrlimit} e \func{setrlimit}.} 
+  \label{tab:sys_rlimit_values}
+\end{table}
+
+\footnotetext{Settare questo limite a zero è la maniera più semplice per
+  evitare la creazione di \file{core} file.}
+
+È inoltre definita la costante \macro{RLIM\_INFINITY} che permette di
+sbloccare l'uso di una risorsa, ma solo un processo con i privilegi di
+amministratore può innalzare un limite al di sopra del valore corrente del
+limite massimo. Si tenga conto infine che tutti i limiti vengono ereditati dal
+processo padre attraverso una \func{fork} (vedi \secref{sec:proc_fork}) e
+mantenuti attraverso una \func{exec} (vedi \secref{sec:proc_exec}).
+
+
+\subsection{Le risorse relative alla memoria}
+\label{sec:sys_memory_res}
+
+La gestione della memoria è già stata affrontata in dettaglio in
+\secref{sec:proc_memory}; abbiamo visto allora che il kernel provvede il
+meccanismo della memoria virtuale attraverso la divisione della memoria fisica
+in pagine.
+
+In genere questo è del tutto trasparente al singolo processo, ma in certi
+casi, come per l'I/O mappato in memoria (vedi \ref{sec:file_memory_map}) che
+usa lo stesso meccanismo per accedere ai file, è necessario conoscere le
+dimensioni delle pagine usate dal kernel. Lo stesso vale quando si vuole
+gestire in maniera ottimale l'interazione della memoria allocata con il
+meccanismo della paginazione.
+
+Di solito la dimensione delle pagine di memoria è fissata dall'architettura
+hardware, per cui in genere la dimensione delle pagine di memoria era una
+costante definita in fase di compilazione, ma oggi alcune architetture (ad
+esempio su Sun Sparc) permettono di variare questa dimensione, e non volendo
+dover fornire binari diversi per ogni possibile modello, è necessario poter
+utilizzare una funzione. 
+
+In genere questa dimensione può essere ottenuta attraverso una chiamata a
+\func{sysconf} come \func{sysconf(\_SC\_PAGESIZE)}, ma in BSD 4.2 è stata
+introdotta una apposita funzione, \func{getpagesize}, che restituisce la
+dimensione delle pagine di memoria; il suo prototipo è:
+\begin{prototype}{unistd.h}{int getpagesize(void)}
+  Legge le dimensioni delle pagine di memoria.
+  
+  \bodydesc{La funzione ritorna la dimensione di una pagina in byte, e non
+    sono previsti errori.}
+\end{prototype}
+
+La funzione è prevista in SVr4, 4.4BSD e SUSv2, anche se questo ultimo
+standard la etichetta come obsoleta, mentre lo standard POSIX 1003.1-2001 la
+ha eliminata. In Linux è implementata come una system call nelle architetture
+in cui essa serve, in genere restituisce il valore del simbolo
+\macro{PAGE\_SIZE} del kernel, anche se le versioni delle librerie del C
+precedenti le \acr{glibc} 2.1 implementavano questa funzione restituendo un
+valore statico.
+
+Le \acr{glibc} forniscono, come specifica estensione GNU, altre due funzioni,
+\func{get\_phys\_pages} e \func{get\_avphys\_pages} che permettono di ottenere
+informazioni riguardo la memoria; i loro prototipi sono:
+\begin{functions}
+  \headdecl{sys/sysinfo.h} 
+  
+  \funcdecl{long int get\_phys\_pages(void)} 
+
+  Legge il numero totale di pagine di memorie disponibili per il sistema.
+  
+  \funcdecl{long int get\_avphys\_pages(void)} 
+  
+  Legge il numero.
+  
+  \bodydesc{}
+\end{functions}
+
+
+
+\subsection{Le risorse di processore}
+\label{sec:sys_cpu_load}
+
 
 
 
-\var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime}
 
 
 
 \section{La gestione dei tempi del sistema}
 \label{sec:sys_time}
 
-In questa sezione tratteremo le varie funzioni per la gestione delle
-date e del tempo in un sistema unix-like, e quelle per convertire i vari
-tempi nelle differenti rappresentazioni che vengono utilizzate.
+In questa sezione tratteremo le varie funzioni per la gestione delle date e
+del tempo in un sistema unix-like, e quelle per convertire i vari tempi nelle
+differenti rappresentazioni che vengono utilizzate.
 
 
 \subsection{La misura del tempo in Unix}
@@ -1024,6 +1699,14 @@ nell'eseguire un certo processo e viene chiamato \textit{CPU time}.
 
 
 
+\subsection{I tempi di processore}
+\label{sec:sys_cpu_times}
+
+
+\var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime}
+
+
+
 
 \section{La gestione degli errori}
 \label{sec:sys_errors}
@@ -1052,11 +1735,12 @@ Per riportare il tipo di errore il sistema usa la variabile globale
   anche di definire \var{errno} come un \textit{modifiable lvalue}, quindi si
   può anche usare una macro, e questo è infatti il modo usato da Linux per
   renderla locale ai singoli thread.} definita nell'header \file{errno.h}; la
-variabile è in genere definita come \type{volatile} dato che può essere
-cambiata in modo asincrono da un segnale (per una descrizione dei segnali si
-veda \secref{cha:signals}), ma dato che un manipolatore di segnale scritto
-bene salva e ripristina il valore della variabile, di questo non è necessario
-preoccuparsi nella programmazione normale.
+variabile è in genere definita come \ctyp{volatile} dato che può essere
+cambiata in modo asincrono da un segnale (si veda \ref{sec:sig_sigchld} per un
+esempio, ricordando quanto trattato in \ref{sec:proc_race_cond}), ma dato che
+un manipolatore di segnale scritto bene salva e ripristina il valore della
+variabile, di questo non è necessario preoccuparsi nella programmazione
+normale.
 
 I valori che può assumere \var{errno} sono riportati in \capref{cha:errors},
 nell'header \file{errno.h} sono anche definiti i nomi simbolici per le