Inserita l'indicizzazione delle funzioni. Ricontrollate le chiamate
[gapil.git] / system.tex
1 \chapter{La gestione del sistema}
2 \label{cha:system}
3
4 In questo capitolo si è raccolta le trattazione delle varie funzioni
5 concernenti la gestione generale del sistema che permettono di trattare
6 le varie informazioni ad esso connesse, come i limiti sulle risorse, la
7 gestione dei tempi, degli errori, degli utenti ed in generale dei vari
8 parametri di configurazione del sistema.
9
10
11
12
13 \section{La gestione delle risorse e dei limiti di sistema}
14 \label{sec:sys_limits}
15
16 In questa sezione esamimeremo le funzioni che permettono di gestire le
17 varie risorse associate ad un processo ed i relativi limiti, e quelle
18 relatica al sistema in quanto tale. 
19
20
21 \var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime}
22
23 \section{La gestione dei tempi del sistema}
24 \label{sec:sys_time}
25
26 In questa sezione tratteremo le varie funzioni per la gestione delle
27 date e del tempo in un sistema unix-like, e quelle per convertire i vari
28 tempi nelle differenti rappresentazioni che vengono utilizzate.
29
30
31 \subsection{La misura del tempo in unix}
32 \label{sec:sys_unix_time}
33
34 Storicamente i sistemi unix-like hanno sempre mantenuto due distinti
35 valori per i tempi all'interno del sistema, essi sono rispettivamente
36 chiamati \textit{calendar time} e \textit{process time}, secondo le
37 definizioni:
38 \begin{itemize}
39 \item \textit{calendar time}: è il numero di secondi dalla mezzanotte del
40   primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene
41   usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the
42     Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time)
43   dato che l'UTC corrisponde all'ora locale di Greenwich.  È il tempo su cui
44   viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per
45   indicare le date di modifica dei file o quelle di avvio dei processi. Per
46   memorizzare questo tempo è stato riservato il tipo primitivo \type{time\_t}.
47 \item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato
48   in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate
49   dal timer di sistema, e che per Linux avvengono ogni centesimo di
50   secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni
51     millesimo di secondo}. Il dato primitivo usato per questo tempo è
52   \type{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di
53   operazione del timer, e corrisponde dunque al numero di tick al secondo.  Lo
54   standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK});
55   questo valore può comunque essere ottenuto con \func{sysconf} (vedi
56   \secref{sec:sys_limits}).
57 \end{itemize}
58
59 In genere si usa il \textit{calendar time} per tenere le date dei file e le
60 informazioni analoghe che riguardano i tempi di ``orologio'', usati ad esempio
61 per i demoni che compiono lavori amministrativi ad ore definite, come
62 \cmd{cron}. Di solito questo vene convertito automaticamente dal valore in UTC
63 al tempo locale, utilizzando le opportune informazioni di localizzazione
64 (specificate in \file{/etc/timezone}). E da tenere presente che questo tempo è
65 mantenuto dal sistema e non corrisponde all'orologio hardware del calcolatore.
66
67 Il \textit{process time} di solito si esprime in secondi e viene usato appunto
68 per tenere conto dei tempi di esecuzione dei processi. Per ciascun processo il
69 kernel tiene tre di questi tempi: 
70 \begin{itemize*}
71 \item \textit{clock time}
72 \item \textit{user time}
73 \item \textit{system time}
74 \end{itemize*}
75 il primo è il tempo ``reale'' (viene anche chiamato \textit{wall clock time})
76 dall'avvio del processo, e misura il tempo trascorso fino alla sua
77 conclusione; chiaramente un tale tempo dipende anche dal carico del sistema e
78 da quanti altri processi stavano girando nello stesso periodo. Il secondo
79 tempo è quello che la CPU ha speso nell'esecuzione delle istruzioni del
80 processo in user space. Il terzo è il tempo impiegato dal kernel per eseguire
81 delle system call per conto del processo medesimo (tipo quello usato per
82 eseguire una \func{write} su un file). In genere la somma di user e system
83 time viene chiamato \textit{CPU time}. 
84
85
86
87
88
89 \section{La gestione degli errori}
90 \label{sec:sys_errors}
91
92 La gestione degli errori è in genere una materia complessa. Inoltre il modello
93 utilizzato dai sistema unix-like è basato sull'architettura a processi, e
94 presenta una serie di problemi nel caso lo si debba usare con i thread.
95 Esamineremo in questa sezione le sue caratteristiche principali.
96
97
98 \subsection{La variabile \var{errno}}
99 \label{sec:sys_errno}
100
101 Quasi tutte le funzioni delle librerie del C sono in grado di individuare e
102 riportare condizioni di errore, ed è una buona norma di programmazione
103 controllare sempre che le funzioni chiamate si siano concluse correttamente.
104
105 In genere le funzioni di libreria usano un valore speciale per indicare che
106 c'è stato un errore. Di solito questo valore è -1 o un puntatore nullo o la
107 costante \macro{EOF} (a seconda della funzione); ma questo valore segnala solo
108 che c'è stato un errore, non il tipo di errore. 
109
110 Per riportare il tipo di errore il sistema usa la variabile globale
111 \var{errno}\footnote{L'uso di una variabile globale può comportare alcuni
112   problemi (ad esempio nel caso dei thread) ma lo standard ISO C consente
113   anche di definire \var{errno} come un \textit{modifiable lvalue}, quindi si
114   può anche usare una macro, e questo è infatti il modo usato da Linux per
115   renderla locale ai singoli thread }, definita nell'header \file{errno.h}, la
116 variabile è in genere definita come \type{volatile} dato che può essere
117 cambiata in modo asincrono da un segnale (per una descrizione dei segnali si
118 veda \secref{cha:signals}), ma dato che un manipolatore di segnale scritto
119 bene salva e ripristina il valore della variabile, di questo non è necessario
120 preoccuparsi nella programmazione normale.
121
122 I valori che può assumere \var{errno} sono riportati in \capref{cha:errors},
123 nell'header \file{errno.h} sono anche definiti i nomi simbolici per le
124 costanti numeriche che identificano i vari errori; essi iniziano tutti per
125 \macro{E} e si possono considerare come nomi riservati. In seguito faremo
126 sempre rifermento a tali valori, quando descriveremo i possibili errori
127 restituiti dalle funzioni. Il programma di esempio \cmd{errcode} stampa il
128 codice relativo ad un valore numerico con l'opzione \cmd{-l}.
129
130 Il valore di \var{errno} viene sempre settato a zero all'avvio di un
131 programma, gran parte delle funzioni di libreria settano \var{errno} ad un
132 valore diverso da zero in caso di errore. Il valore è invece indefinito in
133 caso di successo, perché anche se una funzione ha successo, può chiamarne
134 altre al suo interno che falliscono, modificando così \var{errno}.
135
136 Pertanto un valore non nullo di \var{errno} non è sintomo di errore (potrebbe
137 essere il risultato di un errore precedente) e non lo si può usare per
138 determinare quando o se una chiamata a funzione è fallita.  La procedura da
139 seguire è sempre quella di controllare \var{errno} immediatamente dopo aver
140 verificato il fallimento della funzione attraverso il suo codice di ritorno.
141
142
143 \subsection{Le funzioni \func{strerror} e \func{perror}}
144 \label{sec:sys_strerror}
145
146 Benché gli errori siano identificati univocamente dal valore numerico di
147 \var{errno} le librerie provvedono alcune funzioni e variabili utili per
148 riportare in opportuni messaggi le condizioni di errore verificatesi.  La
149 prima funzione che si può usare per ricavare i messaggi di errore è
150 \func{strerror}, il cui prototipo è:
151 \begin{prototype}{string.h}{char * strerror(int errnum)} 
152   Ritorna una stringa (statica) che descrive l'errore il cui codice è passato
153   come parametro.
154 \end{prototype}
155
156 In generale \func{strerror} viene usata passando \var{errno} come parametro;
157 nel caso si specifichi un codice sbagliato verrà restituito un messaggio di
158 errore sconosciuto. La funzione utilizza una stringa statica che non deve
159 essere modificata dal programma e che è utilizzabile solo fino ad una chiamata
160 successiva a \func{strerror}; nel caso si usino i thread è
161 provvista\footnote{questa funzione è una estensione GNU, non fa parte dello
162   standard POSIX} una versione apposita:
163 \begin{prototype}{string.h}
164 {char * strerror\_r(int errnum, char * buff, size\_t size)} 
165   Analoga a \func{strerror} ma ritorna il messaggio in un buffer
166   specificato da \param{buff} di lunghezza massima (compreso il terminatore)
167   \param{size}.
168 \end{prototype}
169 \noindent
170 che utilizza un buffer che il singolo thread deve allocare, per evitare i
171 problemi connessi alla condivisione del buffer statico. Infine, per completare
172 la caratterizzazione dell'errore, si può usare anche la variabile
173 globale\footnote{anche questa è una estensione GNU}
174 \var{program\_invocation\_short\_name} che riporta il nome del programma
175 attualmente in esecuzione.
176
177 Una seconda funzione usata per riportare i codici di errore in maniera
178 automatizzata sullo standard error (vedi \secref{sec:file_std_descr}) è
179 \func{perror}, il cui prototipo è:
180 \begin{prototype}{stdio.h}{void perror (const char *message)} 
181   Stampa il messaggio di errore relativo al valore corrente di \var{errno}
182   sullo standard error; preceduto dalla stringa \var{message}.
183 \end{prototype}
184 i messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati
185 in \capref{cha:errors}), e, usando il valore corrente di \var{errno}, si
186 riferiscono all'ultimo errore avvenuto. La stringa specificata con
187 \var{message} viene stampato prime del messaggio d'errore, seguita dai due
188 punti e da uno spazio, il messaggio è terminato con un a capo.
189
190 Il messaggio può essere riportato anche usando altre variabili globali
191 dichiarate in \file{errno.h}:
192 \begin{verbatim}
193    const char *sys_errlist[];
194    int sys_nerr;
195 \end{verbatim}
196 la prima contiene i puntatori alle stringhe di errore indicizzati da
197 \var{errno}; la seconda esprime il valore più alto per un codice di errore,
198 l'utilizzo di questa stringa è sostanzialmente equivalente a quello di
199 \func{strerror}.
200
201 In \nfig\ è riportata la sezione attinente del codice del programma
202 \cmd{errcode}, che può essere usato per stampare i messaggi di errore e le
203 costanti usate per identificare i singoli errori; il sorgente completo del
204 programma è allegato nel file \file{ErrCode.c} e contiene pure la gestione
205 delle opzioni e tutte le definizioni necessarie ad associare il valore
206 numerico alla costante simbolica. In particolare si è riportata la sezione che
207 converte la stringa passata come parametro in un intero (\texttt{\small
208   1--2}), controllando con i valori di ritorno di \func{strtol} che la
209 conversione sia avvenuta correttamente (\texttt{\small 4--10}), e poi stampa,
210 a seconda dell'opzione scelta il messaggio di errore (\texttt{\small 11--14})
211 o la macro (\texttt{\small 15--17}) associate a quel codice.
212
213 \begin{figure}[!htb]
214   \footnotesize
215   \begin{lstlisting}{}
216     /* convert string to number */
217     err = strtol(argv[optind], NULL, 10);
218     /* testing error condition on conversion */
219     if (err==LONG_MIN) {
220         perror("Underflow on error code");
221         return 1;
222     } else if (err==LONG_MIN) {
223         perror("Overflow on error code");
224         return 1;
225     }
226     /* conversion is fine */
227     if (message) {
228         printf("Error message for %d is %s\n", err, strerror(err));
229     }
230     if (label) {
231         printf("Error label for %d is %s\n", err, err_code[err]);
232     }
233   \end{lstlisting}
234   \caption{Codice per la stampa del messaggio di errore standard.}
235   \label{fig:sys_err_mess}
236 \end{figure}