Aggiunte varie.
[gapil.git] / system.tex
1 \chapter{La gestione del sistema, delle risorse, e degli errori}
2 \label{cha:system}
3
4 In questo capitolo tratteremo varie interfacce che attengono agli aspetti più
5 generali del sistema, come quelle per la gestione di parametri e
6 configurazione, quelle per la lettura dei limiti e delle carattistiche dello
7 stesso, quelle per il controllo dell'uso delle risorse da parte dei processi,
8 quelle per la gestione dei tempi e degli errori.
9
10
11 \section{La configurazione del sistema}
12 \label{sec:sys_config}
13
14 In questa sezione esamineremo le macro e le funzioni che permettono di
15 conoscere e settare i parametri di configurazione del sistema, di ricavarme
16 limiti e caratteristiche, e di controllare i filesystem disponibili, montarli
17 e rimuoverli da programma.
18
19
20 \subsection{Limiti e parametri di sistema}
21 \label{sec:sys_limits}
22
23 In qualunque sistema sono presenti un gran numero di parametri e costanti il
24 cui valore può essere definito dall'architettura dell'hardware,
25 dall'implementazione del sistema, dalle opzioni con cui si sono compilati il
26 kernel e le librerie o anche configurabili dall'amministratore all'avvio del
27 sistema o durente le sue attività.
28
29 Chiaramente per scrivere programmi portabili occorre poter determinare opzioni
30 disponibili e caratteristiche del sistema (come i valori massimi e minimi dei
31 vari tipi di variabili, o la presenza del supporto del supporto per
32 l'operazione che interessa). Inoltre alcuni di questi limiti devono poter
33 essere determinabili anche in corso di esecuzione del programma, per non dover
34 ricompilare tutti i programmi quando si usa una nuova versione del kernel o si
35 cambia una delle configurazioni del sistema. Per tutto questo sono necessari
36 due tipi di funzionalità:
37 \begin{itemize*}
38 \item la possibilità di determinare limiti ed opzioni al momento della
39   compilazione.
40 \item la possibilità di determinare limiti ed opzioni durante l'esecuzione.
41 \end{itemize*}
42
43 La prima funzionalità si può ottenere includendo gli opportuni header file,
44 mentre per la seconda sono ovviamante necessarie delle funzioni; la situazione
45 è complicata dal fatto che ci sono molti casi in cui alcuni di questi limiti
46 sono fissi in una implementazione mentre possono variare in un altra.
47 Quando i limiti sono fissi vengono definiti come macro nel file
48 \file{limits.h}, se invece possono variare, il loro valore sarà ottenibile
49 tramite la funzione \func{sysconf}. 
50
51 Lo standard ANSI C definisce dei limiti che sono tutti fissi e pertanto
52 disponibili al momanto della compilazione; un elenco è riportato in
53 \tabref{tab:sys_ansic_macro}, come ripreso da \file{limits.h}; come si vede
54 per la maggior parte attengono alle dimensioni dei tipi dei dati interi, le
55 informazioni analoghe per i dati in virgola mobile sono definite a parte e
56 accessibili includendo \file{float.h}. Un'altra costante prevista dallo
57 standard (l'unica che può non essere fissa e che pertanto non è definita in
58 \file{limits.h}) è \macro{FOPEN\_MAX}, essa deve essere definita in
59 \file{stdio.h} ed avere un valore minimo di 8.
60
61 \begin{table}[htb]
62   \centering
63   \footnotesize
64   \begin{tabular}[c]{|l|r|l|}
65     \hline
66     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
67     \hline
68     \hline
69     \macro{MB\_LEN\_MAX}&       16  & massima dimensione di un 
70                                       carattere multibyte\\
71     \macro{CHAR\_BIT} &          8  & bit di \type{char}\\
72     \macro{UCHAR\_MAX}&        255  & massimo di \type{unsigned char}\\
73     \macro{SCHAR\_MIN}&       -128  & minimo di \type{signed char}\\
74     \macro{SCHAR\_MAX}&        127  & massimo di \type{signed char}\\
75     \macro{CHAR\_MIN} &\footnotemark& minimo di \type{char}\\
76     \macro{CHAR\_MAX} &\footnotemark& massimo di \type{char}\\
77     \macro{SHRT\_MIN} &     -32768  & minimo di \type{short}\\
78     \macro{SHRT\_MAX} &      32767  & massimo di \type{short}\\
79     \macro{USHRT\_MAX}&      65535  & massimo di \type{unsigned short}\\
80     \macro{INT\_MAX}  & 2147483647  & minimo di \type{int}\\
81     \macro{INT\_MIN}  &-2147483648  & minimo di \type{int}\\
82     \macro{UINT\_MAX} & 4294967295  & massimo di \type{unsigned int}\\
83     \macro{LONG\_MAX} & 2147483647  & massimo di \type{long}\\
84     \macro{LONG\_MIN} &-2147483648  & minimo di \type{long}\\
85     \macro{ULONG\_MAX}& 4294967295  & massimo di \type{unsigned long}\\
86     \hline                
87   \end{tabular}
88   \caption{Macro definite in \file{limits.h} in conformità allo standard
89     ANSI C.}
90   \label{tab:sys_ansic_macro}
91 \end{table}
92
93 \footnotetext[1]{il valore può essere 0 o \macro{SCHAR\_MIN} a seconda che il
94   sistema usi caratteri con segno o meno.} 
95
96 \footnotetext[2]{il valore può essere \macro{UCHAR\_MAX} o \macro{SCHAR\_MAX}
97   a seconda che il sistema usi caratteri con segno o meno.}
98
99 A questi valori lo standard ISO C90 ne aggiunge altri tre, relativi al tipo
100 \type{long long} introdotto con il nuovo standard, i relativi valori sono in
101 \tabref{tab:sys_isoc90_macro}.
102
103 \begin{table}[htb]
104   \centering
105   \footnotesize
106   \begin{tabular}[c]{|l|r|l|}
107     \hline
108     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
109     \hline
110     \hline
111     \macro{LLONG\_MAX}& 9223372036854775807&massimo di \type{long long}\\
112     \macro{LLONG\_MIN}&-9223372036854775808&minimo di \type{long long}\\
113     \macro{ULLONG\_MAX}&18446744073709551615&
114     massimo di \type{unsigned long long}\\
115     \hline                
116   \end{tabular}
117   \caption{Macro definite in \file{limits.h} in conformità allo standard
118     ISO C90.}
119   \label{tab:sys_isoc90_macro}
120 \end{table}
121
122 Lo standard POSIX.1 definisce 33 diversi limiti o costanti, 15 delle quali,
123 riportate in \secref{tab:sys_posix1_base}, devono essere sempre dichiarate,
124 in quanto definiscono dei valori minimi che qualunque implementazione che sia
125 conforme allo standard deve avere; molti di questi valori sono di scarsa
126 utilità, essendo troppo ristretti ed ampiamente superati in tutte le
127 implementazioni dello standard.
128
129 \begin{table}[htb]
130   \centering
131   \footnotesize
132   \begin{tabular}[c]{|l|r|p{8cm}|}
133     \hline
134     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
135     \hline
136     \hline
137     \macro{\_POSIX\_ARG\_MAX} &4096  & dimensione massima degli argomenti
138                                        passati ad una funzione della famiglia
139                                        \func{exec}.\\ 
140     \macro{\_POSIX\_CHILD\_MAX}  &6  & numero massimo di processi contemporanei
141                                        che un utente può eseguire.\\
142     \macro{\_POSIX\_LINK\_MAX}   &8  & numero massimo di link a un file\\
143     \macro{\_POSIX\_MAX\_CANON}&255  & spazio disponibile nella coda di input
144                                        canonica del terminale\\
145     \macro{\_POSIX\_MAX\_INPUT}&255  & spazio disponibile nella coda di input 
146                                        del terminale\\
147     \macro{\_POSIX\_NGROUPS\_MAX}&0  & numero di gruppi supplementari per
148                                      processo.\\
149     \macro{\_POSIX\_OPEN\_MAX}  &16  & numero massimo di file che un processo
150                                        può mantenere aperti in contemporanea.\\
151     \macro{\_POSIX\_NAME\_MAX}&  14  & lunghezza in byte di un nome di file. \\
152     \macro{\_POSIX\_PATH\_MAX}& 256  & lunghezza in byte di pathname.\\
153     \macro{\_POSIX\_PIPE\_BUF}& 512  & byte scrivibili atomicamente in una
154                                        pipe\\
155     \macro{\_POSIX\_SSIZE\_MAX}&32767& valore massimo del tipo 
156                                        \type{ssize\_t}.\\
157     \macro{\_POSIX\_STREAM\_MAX}&8   & massimo numero di stream aperti per
158                                        processo in contemporanea.\\
159     \macro{\_POSIX\_TZNAME\_MAX}&    & dimensione massima del nome di una
160                                        \texttt{timezone} (vedi ).\\ 
161     \hline                
162   \end{tabular}
163   \caption{Costanti fisse, definite in \file{limits.h}, richieste
164     obbligatoriamente allo standard POSIX.1.}
165   \label{tab:sys_posix1_base}
166 \end{table}
167
168 Oltre a questi valori lo standard ne definisce altri a riguardo
169
170
171 \begin{table}[htb]
172   \centering
173   \footnotesize
174   \begin{tabular}[c]{|l|r|p{8cm}|}
175     \hline
176     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
177     \hline
178     \hline
179     \macro{\_POSIX\_AIO\_LISTIO\_MAX}&  2& \\
180     \macro{\_POSIX\_AIO\_MAX}&  1& \\
181     \macro{\_POSIX\_DELAYTIMER\_MAX}& 32 & \\
182     \macro{\_POSIX\_MQ\_OPEN\_MAX}&  8& \\
183     \macro{\_POSIX\_MQ\_PRIO\_MAX}& 32& \\
184     \macro{\_POSIX\_FD\_SETSIZE}& 16 & \\
185     \macro{\_POSIX\_NAME\_MAX}&  14& \\
186     \macro{\_POSIX\_PATH\_MAX}& 256& \\
187     \macro{\_POSIX\_PIPE\_BUF}& 512& \\
188     \macro{\_POSIX\_SSIZE\_MAX}& 32767& \\
189     \macro{\_POSIX\_STREAM\_MAX}&8 & \\
190     \macro{\_POSIX\_TZNAME\_MAX}& 6& \\
191     \hline                
192   \end{tabular}
193   \caption{Macro definite in \file{limits.h} in conformità allo standard
194     POSIX.1.}
195   \label{tab:sys_posix1_macro}
196 \end{table}
197
198 Lo standard ANSI C definisce dei limiti solo sulle dimensioni dei tipi dei
199 dati, che sono ovviamente fissi, gli standard POSIX.1 e POSIX.2 definiscono
200 molti altri limiti attinenti a varie caratteristiche del sistema (come il
201 numero massimo di figli, la lunghezza di un pathname, ecc.) che possono essere
202 fissi o meno: quando sono fissi vengono definiti come macro nel file
203 \file{limits.h}, se invece possono variare, il loro valore sarà ottenibile
204 tramite la funzione \func{sysconf}.
205
206
207 \subsection{La funzione \func{sysconf}}
208 \label{sec:sys_sysconf}
209
210 Come accennato in \secref{sec:sys_limits} quando uno dei limiti o delle
211 carateristiche del sistema può variare, per evitare di dover ricompilare un
212 programma tutte le volte che si cambiano le opzioni con cui è compilato il
213 kernel, o alcuni dei parametri modificabili a run time, è necessario ottenerne
214 il valore attraverso la funzione \func{sysconf}, il cui prototipo è:
215 \begin{prototype}{unistd.h}{long sysconf(int name)}
216   Restituisce il valore del parametro di sistema \param{name}.
217   
218   \bodydesc{La funzione restituisce indietro il valore del parametro
219     richiesto, o 1 se si tratta di un'opzione disponibile, 0 se l'opzione non
220     è disponibile e -1 in caso di errore (ma \var{errno} non viene settata).}
221 \end{prototype}
222
223 La funzione prende come argomento un intero che specifica quale dei limiti si
224 vuole conoscere; uno specchietto contentente tutti quelli disponibili in
225 Linux, e la corrispondente macro di \func{limits.h}, è riportato in \ntab.
226
227 \begin{table}[htb]
228   \centering
229   \footnotesize
230     \begin{tabular}[c]{|l|l|p{9cm}|}
231       \hline
232       \textbf{Parametro}&\textbf{Macro sostituita} &\textbf{Significato}\\
233       \hline
234       \hline
235       \texttt{\_SC\_ARG\_MAX} &\macro{ARG\_MAX}&
236       La dimensione massima degli argomenti passati ad una funzione
237       della famiglia \func{exec}.\\
238       \texttt{\_SC\_CHILD\_MAX}&\macro{\_CHILD\_MAX}&
239       Il numero massimo di processi contemporanei che un utente può
240       eseguire.\\
241       \texttt{\_SC\_CLK\_TCK}& \macro{CLK\_TCK} &
242       Il numero di \textit{clock tick} al secondo, cioè la frequenza delle
243       interruzioni del timer di sistema (vedi \secref{sec:proc_priority}).\\
244       \texttt{\_SC\_STREAM\_MAX}& \macro{STREAM\_MAX}&
245       Il massimo numero di stream che un processo può mantenere aperti in
246       contemporanea. Questo liminte previsto anche dallo standard ANSI C, che
247       specifica la macro {FOPEN\_MAX}.\\
248       \texttt{\_SC\_TZNAME\_MAX}&\macro{TZNAME\_MAX}&
249       La dimensione massima di un nome di una \texttt{timezone} (vedi ).\\
250       \texttt{\_SC\_OPEN\_MAX}&\macro{\_OPEN\_MAX}&
251       Il numero massimo di file che un processo può mantenere aperti in
252       contemporanea.\\
253       \texttt{\_SC\_JOB\_CONTROL}&\macro{\_POSIX\_JOB\_CONTROL}&
254       Indica se è supportato il \textit{job conotrol} (vedi
255       \secref{sec:sess_xxx}) in stile POSIX.\\
256       \texttt{\_SC\_SAVED\_IDS}&\macro{\_POSIX\_SAVED\_IDS}&
257       Indica se il sistema supporta i \textit{saved id} (vedi
258       \secref{sec:proc_access_id}).\\ 
259       \texttt{\_SC\_VERSION}& \macro{\_POSIX\_VERSION} &
260       Indica il mese e l'anno di approvazione della revisione dello standard
261       POSIX.1 a cui il sistema fa riferimento, nel formato YYYYMML, la
262       revisione più recente è 199009L, che indica il Settembre 1990.\\
263      \hline
264     \end{tabular}
265   \caption{Parametri del sistema leggibili dalla funzione \func{sysconf}.}
266   \label{tab:sys_sysconf_par}
267 \end{table}
268
269
270
271 \subsection{Opzioni e configurazione del sistema}
272 \label{sec:sys_sys_config}
273
274 La funzione \func{sysctl} ...
275
276
277
278 \subsection{La configurazione dei filesystem}
279 \label{sec:sys_file_config}
280
281 La funzione \func{statfs} ...
282
283 La funzione \func{pathconf} ...
284
285
286
287
288 \section{Limitazione ed uso delle risorse}
289 \label{sec:sys_res_limits}
290
291 In questa sezione esamimeremo le funzioni che permettono di esaminare e
292 controllare come le varie risorse del sistema (CPU, memoria, ecc.) vengono
293 utilizzate dai processi, e le modalità con cui è possibile imporre dei limiti
294 sul loro utilizzo.
295
296
297
298 \subsection{L'uso delle risorse}
299 \label{sec:sys_resource_use}
300
301
302 \subsection{Limiti sulle risorse}
303 \label{sec:sys_resource_limit}
304
305
306 \subsection{Le risorse di memoria}
307 \label{sec:sys_memory_res}
308
309
310 \subsection{Le risorse di processore}
311 \label{sec:sys_cpu_load}
312
313
314
315 \begin{figure}[!htb]
316   \footnotesize
317   \centering
318   \begin{minipage}[c]{15cm}
319     \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
320 struct rusage {
321      struct timeval ru_utime; /* user time used */
322      struct timeval ru_stime; /* system time used */
323      long ru_maxrss;          /* maximum resident set size */
324      long ru_ixrss;           /* integral shared memory size */
325      long ru_idrss;           /* integral unshared data size */
326      long ru_isrss;           /* integral unshared stack size */
327      long ru_minflt;          /* page reclaims */
328      long ru_majflt;          /* page faults */
329      long ru_nswap;           /* swaps */
330      long ru_inblock;         /* block input operations */
331      long ru_oublock;         /* block output operations */
332      long ru_msgsnd;          /* messages sent */
333      long ru_msgrcv;          /* messages received */
334      long ru_nsignals;   ;    /* signals received */
335      long ru_nvcsw;           /* voluntary context switches */
336      long ru_nivcsw;          /* involuntary context switches */
337 };
338     \end{lstlisting}
339   \end{minipage} 
340   \normalsize 
341   \caption{La struttura \var{rusage} per la lettura delle informazioni dei 
342     delle risorse usate da un processo.}
343   \label{fig:sys_rusage_struct}
344 \end{figure}
345
346
347
348
349 \var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime}
350
351
352
353 \section{La gestione dei tempi del sistema}
354 \label{sec:sys_time}
355
356 In questa sezione tratteremo le varie funzioni per la gestione delle
357 date e del tempo in un sistema unix-like, e quelle per convertire i vari
358 tempi nelle differenti rappresentazioni che vengono utilizzate.
359
360
361 \subsection{La misura del tempo in unix}
362 \label{sec:sys_unix_time}
363
364 Storicamente i sistemi unix-like hanno sempre mantenuto due distinti
365 valori per i tempi all'interno del sistema, essi sono rispettivamente
366 chiamati \textit{calendar time} e \textit{process time}, secondo le
367 definizioni:
368 \begin{itemize}
369 \item \textit{calendar time}: è il numero di secondi dalla mezzanotte del
370   primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene
371   usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the
372     Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time)
373   dato che l'UTC corrisponde all'ora locale di Greenwich.  È il tempo su cui
374   viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per
375   indicare le date di modifica dei file o quelle di avvio dei processi. Per
376   memorizzare questo tempo è stato riservato il tipo primitivo \type{time\_t}.
377 \item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato
378   in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate
379   dal timer di sistema, e che per Linux avvengono ogni centesimo di
380   secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni
381     millesimo di secondo}. Il dato primitivo usato per questo tempo è
382   \type{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di
383   operazione del timer, e corrisponde dunque al numero di tick al secondo.  Lo
384   standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK});
385   questo valore può comunque essere ottenuto con \func{sysconf} (vedi
386   \secref{sec:sys_limits}).
387 \end{itemize}
388
389 In genere si usa il \textit{calendar time} per tenere le date dei file e le
390 informazioni analoghe che riguardano i tempi di ``orologio'', usati ad esempio
391 per i demoni che compiono lavori amministrativi ad ore definite, come
392 \cmd{cron}. Di solito questo vene convertito automaticamente dal valore in UTC
393 al tempo locale, utilizzando le opportune informazioni di localizzazione
394 (specificate in \file{/etc/timezone}). E da tenere presente che questo tempo è
395 mantenuto dal sistema e non corrisponde all'orologio hardware del calcolatore.
396
397 Il \textit{process time} di solito si esprime in secondi e viene usato appunto
398 per tenere conto dei tempi di esecuzione dei processi. Per ciascun processo il
399 kernel tiene tre di questi tempi: 
400 \begin{itemize*}
401 \item \textit{clock time}
402 \item \textit{user time}
403 \item \textit{system time}
404 \end{itemize*}
405 il primo è il tempo ``reale'' (viene anche chiamato \textit{wall clock time})
406 dall'avvio del processo, e misura il tempo trascorso fino alla sua
407 conclusione; chiaramente un tale tempo dipende anche dal carico del sistema e
408 da quanti altri processi stavano girando nello stesso periodo. Il secondo
409 tempo è quello che la CPU ha speso nell'esecuzione delle istruzioni del
410 processo in user space. Il terzo è il tempo impiegato dal kernel per eseguire
411 delle system call per conto del processo medesimo (tipo quello usato per
412 eseguire una \func{write} su un file). In genere la somma di user e system
413 time viene chiamato \textit{CPU time}. 
414
415
416
417
418
419 \section{La gestione degli errori}
420 \label{sec:sys_errors}
421
422 La gestione degli errori è in genere una materia complessa. Inoltre il modello
423 utilizzato dai sistema unix-like è basato sull'architettura a processi, e
424 presenta una serie di problemi nel caso lo si debba usare con i thread.
425 Esamineremo in questa sezione le sue caratteristiche principali.
426
427
428 \subsection{La variabile \var{errno}}
429 \label{sec:sys_errno}
430
431 Quasi tutte le funzioni delle librerie del C sono in grado di individuare e
432 riportare condizioni di errore, ed è una buona norma di programmazione
433 controllare sempre che le funzioni chiamate si siano concluse correttamente.
434
435 In genere le funzioni di libreria usano un valore speciale per indicare che
436 c'è stato un errore. Di solito questo valore è -1 o un puntatore nullo o la
437 costante \macro{EOF} (a seconda della funzione); ma questo valore segnala solo
438 che c'è stato un errore, non il tipo di errore. 
439
440 Per riportare il tipo di errore il sistema usa la variabile globale
441 \var{errno}\footnote{L'uso di una variabile globale può comportare alcuni
442   problemi (ad esempio nel caso dei thread) ma lo standard ISO C consente
443   anche di definire \var{errno} come un \textit{modifiable lvalue}, quindi si
444   può anche usare una macro, e questo è infatti il modo usato da Linux per
445   renderla locale ai singoli thread.}, definita nell'header \file{errno.h}; la
446 variabile è in genere definita come \type{volatile} dato che può essere
447 cambiata in modo asincrono da un segnale (per una descrizione dei segnali si
448 veda \secref{cha:signals}), ma dato che un manipolatore di segnale scritto
449 bene salva e ripristina il valore della variabile, di questo non è necessario
450 preoccuparsi nella programmazione normale.
451
452 I valori che può assumere \var{errno} sono riportati in \capref{cha:errors},
453 nell'header \file{errno.h} sono anche definiti i nomi simbolici per le
454 costanti numeriche che identificano i vari errori; essi iniziano tutti per
455 \macro{E} e si possono considerare come nomi riservati. In seguito faremo
456 sempre rifermento a tali valori, quando descriveremo i possibili errori
457 restituiti dalle funzioni. Il programma di esempio \cmd{errcode} stampa il
458 codice relativo ad un valore numerico con l'opzione \cmd{-l}.
459
460 Il valore di \var{errno} viene sempre settato a zero all'avvio di un
461 programma, gran parte delle funzioni di libreria settano \var{errno} ad un
462 valore diverso da zero in caso di errore. Il valore è invece indefinito in
463 caso di successo, perché anche se una funzione ha successo, può chiamarne
464 altre al suo interno che falliscono, modificando così \var{errno}.
465
466 Pertanto un valore non nullo di \var{errno} non è sintomo di errore (potrebbe
467 essere il risultato di un errore precedente) e non lo si può usare per
468 determinare quando o se una chiamata a funzione è fallita.  La procedura da
469 seguire è sempre quella di controllare \var{errno} immediatamente dopo aver
470 verificato il fallimento della funzione attraverso il suo codice di ritorno.
471
472
473 \subsection{Le funzioni \func{strerror} e \func{perror}}
474 \label{sec:sys_strerror}
475
476 Benché gli errori siano identificati univocamente dal valore numerico di
477 \var{errno} le librerie provvedono alcune funzioni e variabili utili per
478 riportare in opportuni messaggi le condizioni di errore verificatesi.  La
479 prima funzione che si può usare per ricavare i messaggi di errore è
480 \func{strerror}, il cui prototipo è:
481 \begin{prototype}{string.h}{char * strerror(int errnum)} 
482   Ritorna una stringa (statica) che descrive l'errore il cui codice è passato
483   come parametro.
484 \end{prototype}
485
486 In generale \func{strerror} viene usata passando \var{errno} come parametro;
487 nel caso si specifichi un codice sbagliato verrà restituito un messaggio di
488 errore sconosciuto. La funzione utilizza una stringa statica che non deve
489 essere modificata dal programma e che è utilizzabile solo fino ad una chiamata
490 successiva a \func{strerror}; nel caso si usino i thread è
491 provvista\footnote{questa funzione è una estensione GNU, non fa parte dello
492   standard POSIX} una versione apposita:
493 \begin{prototype}{string.h}
494 {char * strerror\_r(int errnum, char * buff, size\_t size)} 
495   Analoga a \func{strerror} ma ritorna il messaggio in un buffer
496   specificato da \param{buff} di lunghezza massima (compreso il terminatore)
497   \param{size}.
498 \end{prototype}
499 \noindent
500 che utilizza un buffer che il singolo thread deve allocare, per evitare i
501 problemi connessi alla condivisione del buffer statico. Infine, per completare
502 la caratterizzazione dell'errore, si può usare anche la variabile
503 globale\footnote{anche questa è una estensione GNU}
504 \var{program\_invocation\_short\_name} che riporta il nome del programma
505 attualmente in esecuzione.
506
507 Una seconda funzione usata per riportare i codici di errore in maniera
508 automatizzata sullo standard error (vedi \secref{sec:file_std_descr}) è
509 \func{perror}, il cui prototipo è:
510 \begin{prototype}{stdio.h}{void perror (const char *message)} 
511   Stampa il messaggio di errore relativo al valore corrente di \var{errno}
512   sullo standard error; preceduto dalla stringa \var{message}.
513 \end{prototype}
514 i messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati
515 in \capref{cha:errors}), e, usando il valore corrente di \var{errno}, si
516 riferiscono all'ultimo errore avvenuto. La stringa specificata con
517 \var{message} viene stampato prime del messaggio d'errore, seguita dai due
518 punti e da uno spazio, il messaggio è terminato con un a capo.
519
520 Il messaggio può essere riportato anche usando altre variabili globali
521 dichiarate in \file{errno.h}:
522 \begin{verbatim}
523    const char *sys_errlist[];
524    int sys_nerr;
525 \end{verbatim}
526 la prima contiene i puntatori alle stringhe di errore indicizzati da
527 \var{errno}; la seconda esprime il valore più alto per un codice di errore,
528 l'utilizzo di questa stringa è sostanzialmente equivalente a quello di
529 \func{strerror}.
530
531 In \nfig\ è riportata la sezione attinente del codice del programma
532 \cmd{errcode}, che può essere usato per stampare i messaggi di errore e le
533 costanti usate per identificare i singoli errori; il sorgente completo del
534 programma è allegato nel file \file{ErrCode.c} e contiene pure la gestione
535 delle opzioni e tutte le definizioni necessarie ad associare il valore
536 numerico alla costante simbolica. In particolare si è riportata la sezione che
537 converte la stringa passata come parametro in un intero (\texttt{\small
538   1--2}), controllando con i valori di ritorno di \func{strtol} che la
539 conversione sia avvenuta correttamente (\texttt{\small 4--10}), e poi stampa,
540 a seconda dell'opzione scelta il messaggio di errore (\texttt{\small 11--14})
541 o la macro (\texttt{\small 15--17}) associate a quel codice.
542
543 \begin{figure}[!htb]
544   \footnotesize
545   \begin{lstlisting}{}
546     /* convert string to number */
547     err = strtol(argv[optind], NULL, 10);
548     /* testing error condition on conversion */
549     if (err==LONG_MIN) {
550         perror("Underflow on error code");
551         return 1;
552     } else if (err==LONG_MIN) {
553         perror("Overflow on error code");
554         return 1;
555     }
556     /* conversion is fine */
557     if (message) {
558         printf("Error message for %d is %s\n", err, strerror(err));
559     }
560     if (label) {
561         printf("Error label for %d is %s\n", err, err_code[err]);
562     }
563   \end{lstlisting}
564   \caption{Codice per la stampa del messaggio di errore standard.}
565   \label{fig:sys_err_mess}
566 \end{figure}
567
568
569 \section{La gestione di utenti e gruppi}
570 \label{sec:sys_user_group}
571
572
573 %%% Local Variables: 
574 %%% mode: latex
575 %%% TeX-master: "gapil"
576 %%% End: