Proseguito con mount e statfs
[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 caratteristiche 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
12 \section{La lettura delle caratteristiche del sistema}
13 \label{sec:sys_characteristics}
14
15 In questa sezione tratteremo le varie modalità con cui un programma può
16 ottenere informazioni riguardo alle capacità del sistema. Ogni sistema infatti
17 è contraddistinto da un gran numero di limiti e costanti che lo
18 caratterizzano, e che possono dipendere da fattori molteplici, come
19 l'architettura hardware, l'implementazione del kernel e delle librerie, le
20 opzioni di configurazione.
21
22 La definizione di queste caratteristiche ed il tentativo di provvedere dei
23 meccanismi generali che i programmi potessero usare per ricavarle è uno degli
24 aspetti più complessi e controversi coi cui i vari standard si sono dovuti
25 confrontare, spesso con risultati spesso tutt'altro che chiari. Proveremo
26 comunque a dare una descrizione dei principali metodi previsti dai vari
27 standard per ricavare sia le caratteristiche specifiche del sistema, che
28 quelle dei file.
29
30
31 \subsection{Limiti e parametri di sistema}
32 \label{sec:sys_limits}
33
34 Quando si devono determinare le le caratteristiche generali del sistema ci si
35 trova di fronte a diverse possibilità; alcune di queste infatti possono
36 dipendere dall'architettura dell'hardware (come le dimensioni dei tipi
37 interi), o dal sistema operativo (come la presenza o meno dei \textit{saved
38   id}) , altre invece possono dipendere dalle opzioni con cui si è costruito
39 il sistema (ad esempio da come si è compilato il kernel), o dalla
40 configurazione del medesimo; per questo motivo in generale sono necessari due
41 tipi diversi di funzionalità:
42 \begin{itemize*}
43 \item la possibilità di determinare limiti ed opzioni al momento della
44   compilazione.
45 \item la possibilità di determinare limiti ed opzioni durante l'esecuzione.
46 \end{itemize*}
47
48 La prima funzionalità si può ottenere includendo gli opportuni header file,
49 mentre per la seconda sono ovviamente necessarie delle funzioni; la situazione
50 è complicata dal fatto che ci sono molti casi in cui alcuni di questi limiti
51 sono fissi in una implementazione mentre possono variare in un altra. Tutto
52 questo crea una ambiguità che non è sempre possibile risolvere in maniera
53 chiara; in generale quello che succede è che quando i limiti del sistema sono
54 fissi essi vengono definiti come macro nel file \file{limits.h}, se invece
55 possono variare, il loro valore sarà ottenibile tramite la funzione
56 \func{sysconf} (che esamineremo in \secref{sec:sys_sysconf}).
57
58 Lo standard ANSI C definisce dei limiti che sono tutti fissi, pertanto questo
59 saranno sempre disponibili al momento della compilazione; un elenco, ripreso
60 da \file{limits.h}, è riportato in \tabref{tab:sys_ansic_macro}. Come si può
61 vedere per la maggior parte questi limiti attengono alle dimensioni dei dati
62 interi, che sono in genere fissati dall'architettura hardware (le analoghe
63 informazioni per i dati in virgola mobile sono definite a parte, ed
64 accessibili includendo \file{float.h}). Lo standard prevede anche un'altra
65 costante, \macro{FOPEN\_MAX}, che può non essere fissa e che pertanto non è
66 definita in \file{limits.h}; essa deve essere definita in \file{stdio.h} ed
67 avere un valore minimo di 8.
68
69 \begin{table}[htb]
70   \centering
71   \footnotesize
72   \begin{tabular}[c]{|l|r|l|}
73     \hline
74     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
75     \hline
76     \hline
77     \macro{MB\_LEN\_MAX}&       16  & massima dimensione di un 
78                                       carattere multibyte\\
79     \macro{CHAR\_BIT} &          8  & bit di \type{char}\\
80     \macro{UCHAR\_MAX}&        255  & massimo di \type{unsigned char}\\
81     \macro{SCHAR\_MIN}&       -128  & minimo di \type{signed char}\\
82     \macro{SCHAR\_MAX}&        127  & massimo di \type{signed char}\\
83     \macro{CHAR\_MIN} &\footnotemark& minimo di \type{char}\\
84     \macro{CHAR\_MAX} &\footnotemark& massimo di \type{char}\\
85     \macro{SHRT\_MIN} &     -32768  & minimo di \type{short}\\
86     \macro{SHRT\_MAX} &      32767  & massimo di \type{short}\\
87     \macro{USHRT\_MAX}&      65535  & massimo di \type{unsigned short}\\
88     \macro{INT\_MAX}  & 2147483647  & minimo di \type{int}\\
89     \macro{INT\_MIN}  &-2147483648  & minimo di \type{int}\\
90     \macro{UINT\_MAX} & 4294967295  & massimo di \type{unsigned int}\\
91     \macro{LONG\_MAX} & 2147483647  & massimo di \type{long}\\
92     \macro{LONG\_MIN} &-2147483648  & minimo di \type{long}\\
93     \macro{ULONG\_MAX}& 4294967295  & massimo di \type{unsigned long}\\
94     \hline                
95   \end{tabular}
96   \caption{Macro definite in \file{limits.h} in conformità allo standard
97     ANSI C.}
98   \label{tab:sys_ansic_macro}
99 \end{table}
100
101 \footnotetext[1]{il valore può essere 0 o \macro{SCHAR\_MIN} a seconda che il
102   sistema usi caratteri con segno o meno.} 
103
104 \footnotetext[2]{il valore può essere \macro{UCHAR\_MAX} o \macro{SCHAR\_MAX}
105   a seconda che il sistema usi caratteri con segno o meno.}
106
107 A questi valori lo standard ISO C90 ne aggiunge altri tre, relativi al tipo
108 \type{long long} introdotto con il nuovo standard, i relativi valori sono in
109 \tabref{tab:sys_isoc90_macro}.
110
111 \begin{table}[htb]
112   \centering
113   \footnotesize
114   \begin{tabular}[c]{|l|r|l|}
115     \hline
116     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
117     \hline
118     \hline
119     \macro{LLONG\_MAX}& 9223372036854775807& massimo di \type{long long}\\
120     \macro{LLONG\_MIN}&-9223372036854775808& minimo di \type{long long}\\
121     \macro{ULLONG\_MAX}&18446744073709551615&
122     massimo di \type{unsigned long long}\\
123     \hline                
124   \end{tabular}
125   \caption{Macro definite in \file{limits.h} in conformità allo standard
126     ISO C90.}
127   \label{tab:sys_isoc90_macro}
128 \end{table}
129
130 Ovviamente le dimensioni dei vari tipi di dati sono solo una piccola parte
131 delle caratteristiche del sistema; mancano completamente tutte quelle che
132 dipendono dalla implementazione dello stesso; questo per i sistemi unix-like è
133 stato definito in gran parte dallo standard POSIX.1, che tratta anche i limiti
134 delle caratteristiche dei file che vedremo in \secref{sec:sys_file_limits}.
135
136 Purtroppo la sezione dello standard che tratta questi argomenti è una delle
137 meno chiare\footnote{tanto che Stevens, in \cite{APUE}, la porta come esempio
138   di ``standardese''.}, ad esempio lo standard prevede che ci siano 13 macro
139 che descrivono le caratteristiche del sistema (7 per le caratteristiche
140 generiche, riportate in \tabref{tab:sys_generic_macro}, e 6 per le
141 caratteristiche dei file, riportate in \tabref{tab:sys_file_macro}).
142
143 \begin{table}[htb]
144   \centering
145   \footnotesize
146   \begin{tabular}[c]{|l|r|p{8cm}|}
147     \hline
148     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
149     \hline
150     \hline
151     \macro{ARG\_MAX} &131072& dimensione massima degli argomenti
152                               passati ad una funzione della famiglia
153                               \func{exec}.\\ 
154     \macro{CHILD\_MAX} & 999& numero massimo di processi contemporanei
155                               che un utente può eseguire.\\
156     \macro{OPEN\_MAX}  & 256& numero massimo di file che un processo
157                               può mantenere aperti in contemporanea.\\
158     \macro{STREAM\_MAX}&   8& massimo numero di stream aperti per
159                               processo in contemporanea.\\
160     \macro{TZNAME\_MAX}&   6& dimensione massima del nome di una
161                               \texttt{timezone} (vedi ).\\ 
162     \macro{NGROUPS\_MAX}& 32& numero di gruppi supplementari per
163                               processo (vedi \secref{sec:proc_access_id}).\\
164     \macro{SSIZE\_MAX}&32767& valore massimo del tipo \type{ssize\_t}.\\
165     \hline
166     \hline
167   \end{tabular}
168   \caption{Macro .}
169   \label{tab:sys_generic_macro}
170 \end{table}
171
172 Lo standard prevede che queste macro devono essere definite in \file{limits.h}
173 quando i valori a cui fanno riferimento sono fissi, e altrimenti devono essere
174 lasciate indefinite, ed i loro valori dei limiti devono essere accessibili
175 solo attraverso \func{sysconf}.  Si tenga presente poi che alcuni di questi
176 limiti possono assumere valori molto elevati (come \macro{CHILD\_MAX}), e non
177 è pertanto il caso di utilizzarli per allocare staticamente della memoria.
178
179 A complicare la faccenda si aggiunge il fatto che POSIX.1 prevede una serie di
180 altre macro (che iniziano sempre con \code{\_POSIX\_}) che definiscono i
181 valori minimi le stesse caratteristiche devono avere, perché una
182 implementazione possa dichiararsi conforme allo standard; detti valori sono
183 riportati in \tabref{tab:sys_posix1_general}.
184
185 \begin{table}[htb]
186   \centering
187   \footnotesize
188   \begin{tabular}[c]{|l|r|p{8cm}|}
189     \hline
190     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
191     \hline
192     \hline
193     \macro{\_POSIX\_ARG\_MAX}    & 4096& dimensione massima degli argomenti
194                                          passati ad una funzione della famiglia
195                                          \func{exec}.\\ 
196     \macro{\_POSIX\_CHILD\_MAX}  &    6& numero massimo di processi
197                                          contemporanei che un utente può 
198                                          eseguire.\\
199     \macro{\_POSIX\_OPEN\_MAX}   &   16& numero massimo di file che un processo
200                                          può mantenere aperti in 
201                                          contemporanea.\\
202     \macro{\_POSIX\_STREAM\_MAX} &    8& massimo numero di stream aperti per
203                                          processo in contemporanea.\\
204     \macro{\_POSIX\_TZNAME\_MAX} &     & dimensione massima del nome di una
205                                          \texttt{timezone} (vedi ).\\ 
206     \macro{\_POSIX\_NGROUPS\_MAX}&    0& numero di gruppi supplementari per
207                                          processo (vedi 
208                                          \secref{sec:proc_access_id}).\\
209     \macro{\_POSIX\_SSIZE\_MAX}  &32767& valore massimo del tipo 
210                                          \type{ssize\_t}.\\
211     \macro{\_POSIX\_AIO\_LISTIO\_MAX}&2& \\
212     \macro{\_POSIX\_AIO\_MAX}    &    1& \\
213     \hline                
214     \hline                
215   \end{tabular}
216   \caption{Macro dei valori minimi delle caratteristiche generali del sistema
217     per la conformità allo standard POSIX.1.}
218   \label{tab:sys_posix1_general}
219 \end{table}
220
221 In genere questi valori non servono a molto, la loro unica utilità è quella di
222 indicare un limite superiore che assicura la portabilità senza necessità di
223 ulteriori controlli. Tuttavia molti di essi sono ampiamente superati in tutti
224 i sistemi POSIX in uso oggigiorno. Per questo è sempre meglio utilizzare i
225 valori ottenuti da \func{sysconf}.
226
227 \begin{table}[htb]
228   \centering
229   \footnotesize
230   \begin{tabular}[c]{|l|p{8cm}|}
231     \hline
232     \textbf{Macro}&\textbf{Significato}\\
233     \hline
234     \hline
235     \macro{\_POSIX\_JOB\_CONTROL}& il sistema supporta il 
236                                    \textit{job control} (vedi 
237                                    \secref{sec:sess_xxx}).\\
238     \macro{\_POSIX\_SAVED\_IDS}  & il sistema supporta i \textit{saved id} 
239                                    (vedi \secref{sec:proc_access_id}). 
240                                    per il controllo di accesso dei processi\\
241     \macro{\_POSIX\_VERSION}     & fornisce la versione dello standard POSIX.1
242                                    supportata nel formato YYYYMML (ad esempio 
243                                    199009L).\\
244     \hline
245   \end{tabular}
246   \caption{Alcune macro definite in \file{limits.h} in conformità allo standard
247     POSIX.1.}
248   \label{tab:sys_posix1_other}
249 \end{table}
250
251 Oltre ai precedenti valori (e a quelli relativi ai file elencati in
252 \tabref{tab:sys_posix1_file}), che devono essere obbligatoriamente definiti,
253 lo standard POSIX.1 ne prevede parecchi altri.  La lista completa si trova
254 dall'header file \file{bits/posix1\_lim.h} (da non usare mai direttamente, è
255 incluso automaticamente all'interno di \file{limits.h}); di questi vale la
256 pena menzionare quelli di uso più comune, riportati in
257 \tabref{tab:sys_posix1_other}, che permettono di ricavare alcune
258 caratteristiche del sistema (come il supporto del \textit{job control} o dei
259 \textit{saved id}).
260
261 Oltre allo standard POSIX.1, anche lo standard POSIX.2 definisce una serie di
262 altre macro. Siccome queste sono principalmente attinenti a limiti relativi
263 alle applicazioni di sistema presenti (come quelli su alcuni parametri delle
264 espressioni regolari o del comando \cmd{bc}), non li tratteremo
265 esplicitamente, se ne trova una menzione completa nell'header file
266 \file{bits/posix2\_lim.h}, e alcuni di loro sono descritti nella man page di
267 \func{sysconf} e nel manuale delle \acr{glibc}.
268
269
270 \subsection{La funzione \func{sysconf}}
271 \label{sec:sys_sysconf}
272
273 Come accennato in \secref{sec:sys_limits} quando uno dei limiti o delle
274 caratteristiche del sistema può variare, è necessario ottenerne il valore
275 attraverso la funzione \func{sysconf}, per non dover essere costretti a
276 ricompilare un programma tutte le volte che si cambiano le opzioni con cui è
277 compilato il kernel, o alcuni dei parametri modificabili a run time. Il suo
278 prototipo è:
279 \begin{prototype}{unistd.h}{long sysconf(int name)}
280   Restituisce il valore del parametro di sistema \param{name}.
281   
282   \bodydesc{La funzione restituisce indietro il valore del parametro
283     richiesto, o 1 se si tratta di un'opzione disponibile, 0 se l'opzione non
284     è disponibile e -1 in caso di errore (ma \var{errno} non viene settata).}
285 \end{prototype}
286
287 La funzione prende come argomento un intero che specifica quale dei limiti si
288 vuole conoscere; uno specchietto contenente i principali valori disponibili in
289 Linux è riportato in \tabref{tab:sys_sysconf_par}; l'elenco completo è
290 contenuto in \file{bits/confname}, ed una lista più esaustiva, con le relative
291 spiegazioni, si può trovare nel manuale delle \acr{glibc}. 
292
293 \begin{table}[htb]
294   \centering
295   \footnotesize
296     \begin{tabular}[c]{|l|l|p{9cm}|}
297       \hline
298       \textbf{Parametro}&\textbf{Macro sostituita} &\textbf{Significato}\\
299       \hline
300       \hline
301       \texttt{\_SC\_ARG\_MAX} &\macro{ARG\_MAX}&
302       La dimensione massima degli argomenti passati ad una funzione
303       della famiglia \func{exec}.\\
304       \texttt{\_SC\_CHILD\_MAX}&\macro{\_CHILD\_MAX}&
305       Il numero massimo di processi contemporanei che un utente può
306       eseguire.\\
307       \texttt{\_SC\_OPEN\_MAX}&\macro{\_OPEN\_MAX}&
308       Il numero massimo di file che un processo può mantenere aperti in
309       contemporanea.\\
310       \texttt{\_SC\_STREAM\_MAX}& \macro{STREAM\_MAX}&
311       Il massimo numero di stream che un processo può mantenere aperti in
312       contemporanea. Questo limite previsto anche dallo standard ANSI C, che
313       specifica la macro {FOPEN\_MAX}.\\
314       \texttt{\_SC\_TZNAME\_MAX}&\macro{TZNAME\_MAX}&
315       La dimensione massima di un nome di una \texttt{timezone} (vedi ).\\
316       \texttt{\_SC\_NGROUPS\_MAX}&\macro{NGROUP\_MAX}&
317       Massimo numero di gruppi supplementari che può avere un processo (vedi
318       \secref{sec:proc_access_id}).\\ 
319       \texttt{\_SC\_SSIZE\_MAX}&\macro{SSIZE\_MAX}& 
320       valore massimo del tipo di dato \type{ssize\_t}.\\
321       \texttt{\_SC\_CLK\_TCK}& \macro{CLK\_TCK} &
322       Il numero di \textit{clock tick} al secondo, cioè la frequenza delle
323       interruzioni del timer di sistema (vedi \secref{sec:proc_priority}).\\
324       \texttt{\_SC\_JOB\_CONTROL}&\macro{\_POSIX\_JOB\_CONTROL}&
325       Indica se è supportato il \textit{job control} (vedi
326       \secref{sec:sess_xxx}) in stile POSIX.\\
327       \texttt{\_SC\_SAVED\_IDS}&\macro{\_POSIX\_SAVED\_IDS}&
328       Indica se il sistema supporta i \textit{saved id} (vedi
329       \secref{sec:proc_access_id}).\\ 
330       \texttt{\_SC\_VERSION}& \macro{\_POSIX\_VERSION} &
331       Indica il mese e l'anno di approvazione della revisione dello standard
332       POSIX.1 a cui il sistema fa riferimento, nel formato YYYYMML, la
333       revisione più recente è 199009L, che indica il Settembre 1990.\\
334      \hline
335     \end{tabular}
336   \caption{Parametri del sistema leggibili dalla funzione \func{sysconf}.}
337   \label{tab:sys_sysconf_par}
338 \end{table}
339
340 In generale ogni limite o caratteristica del sistema per cui è definita una
341 macro, sia dagli standard ANSI C e ISO C90, che da POSIX.1 e POSIX.2, può
342 essere ottenuto attraverso una chiamata a \func{sysconf}. Il valore si otterrà
343 speficando come valore del parametro \param{name} il nome ottenuto aggiungendo
344 \code{\_SC\_} ai nomi delle macro definite dai primi due, o sostituendolo a
345 \code{\_POSIX\_} per le macro definite dagli gli altri due.
346
347 In generale si dovrebbe fare uso di \func{sysconf} solo quando la relativa
348 macro non è definita, quindi con un codice analogo al seguente:
349 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
350 get_child_max(void)
351 {
352 #ifdef CHILD_MAX
353     return CHILD_MAX;
354 #else
355     int val = sysconf(_SC_CHILD_MAX);
356     if (val < 0) {
357         perror("fatal error");
358         exit(-1);
359     }
360     return val;
361 }
362 \end{lstlisting}
363 ma in realtà in Linux queste macro sono comunque definite e indicando un
364 limite generico, per cui è sempre meglio usare i valori restituiti da
365 quest'ultima.
366
367
368 \subsection{I limiti dei file}
369 \label{sec:sys_file_limits}
370
371 Come per le caratteristiche generali del sistema anche per i file esistono una
372 serie di limiti (come la lunghezza del nome del file o il numero massimo di
373 link) che dipendono sia dall'implementazione che dal filesystem in uso; anche
374 in questo caso lo standard prevede alcune macro che ne specificano il valore,
375 riportate in \tabref{tab:sys_file_macro}.
376
377 \begin{table}[htb]
378   \centering
379   \footnotesize
380   \begin{tabular}[c]{|l|r|p{8cm}|}
381     \hline
382     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
383     \hline
384     \hline                
385     \macro{NAME\_MAX}&  14  & lunghezza in byte di un nome di file. \\
386     \macro{PATH\_MAX}& 256  & lunghezza in byte di pathname.\\
387     \macro{PIPE\_BUF}& 512  & byte scrivibili atomicamente in una pipe\\
388     \macro{LINK\_MAX}   &8  & numero massimo di link a un file\\
389     \macro{MAX\_CANON}&255  & spazio disponibile nella coda di input
390                               canonica del terminale\\
391     \macro{MAX\_INPUT}&255  & spazio disponibile nella coda di input 
392                               del terminale\\
393     \hline                
394   \end{tabular}
395   \caption{Macro per i limiti sulle caratteristiche dei file.}
396   \label{tab:sys_file_macro}
397 \end{table}
398
399 Come per i limiti di sistema POSIX.1 detta una serie di valori minimi per
400 queste caratteristiche, che ogni sistema che vuole essere conforme deve
401 rispettare; le relative macro sono riportate in \tabref{tab:sys_posix1_file},
402 e per esse vale lo stesso discorso fatto per le analoghe di
403 \tabref{tab:sys_posix1_general}.
404
405 \begin{table}[htb]
406   \centering
407   \footnotesize
408   \begin{tabular}[c]{|l|r|p{8cm}|}
409     \hline
410     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
411     \hline
412     \hline
413     \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
414     \macro{\_POSIX\_LINK\_MAX}   &8  & numero massimo di link a un file\\
415     \macro{\_POSIX\_MAX\_CANON}&255  & spazio disponibile nella coda di input
416                                        canonica del terminale\\
417     \macro{\_POSIX\_MAX\_INPUT}&255  & spazio disponibile nella coda di input 
418                                        del terminale\\
419     \macro{\_POSIX\_NAME\_MAX}&  14  & lunghezza in byte di un nome di file. \\
420     \macro{\_POSIX\_PATH\_MAX}& 256  & lunghezza in byte di pathname.\\
421     \macro{\_POSIX\_PIPE\_BUF}& 512  & byte scrivibili atomicamente in una
422                                        pipe\\
423     \macro{\_POSIX\_MQ\_OPEN\_MAX}&  8& \\
424     \macro{\_POSIX\_MQ\_PRIO\_MAX}& 32& \\
425     \macro{\_POSIX\_FD\_SETSIZE}& 16 & \\
426     \macro{\_POSIX\_DELAYTIMER\_MAX}& 32 & \\
427     \hline
428   \end{tabular}
429   \caption{Macro dei valori minimi delle caratteristiche dei file per la
430     conformità allo standard POSIX.1.}
431   \label{tab:sys_posix1_file}
432 \end{table}
433
434 Tutti questi limiti sono definiti in \file{limits.h}; come nel caso precedente
435 il loro uso è di scarsa utilità in quanto ampiamente superati in tutte le
436 implementazioni moderne.
437
438
439 \subsection{La funzione \func{pathconf}}
440 \label{sec:sys_pathconf}
441
442 In generale i limiti per i file sono molto più soggetti ad essere variabili
443 rispetto ai precedenti limiti generali del sistema; ad esempio parametri come
444 la lunghezza del nome del file o il numero di link possono variare da
445 filesystem a filesystem; per questo motivo questi limiti devono essere sempre
446 controllati con la funzione \func{pathconf}, il cui prototipo è:
447 \begin{prototype}{unistd.h}{long pathconf(char *path, int name)}
448   Restituisce il valore del parametro \param{name} per il file \param{path}.
449   
450   \bodydesc{La funzione restituisce indietro il valore del parametro
451     richiesto, o -1 in caso di errore (ed \var{errno} viene settata ad uno
452     degli errori possibili relativi all'accesso a \param{path}).}
453 \end{prototype}
454
455 E si noti come la funzione in questo caso richieda un parametro che specifichi
456 a quale file si fa riferimento, dato che il valore del limite cercato può
457 variare a seconda del filesystem. Una seconda versione della funzione,
458 \func{fpathconf}, opera su un file descriptor invece che su un pathname, il
459 suo prototipo è:
460 \begin{prototype}{unistd.h}{long fpathconf(int fd, int name)}
461   Restituisce il valore del parametro \param{name} per il file \param{fd}.
462   
463   \bodydesc{È identica a \func{pathconf} solo che utilizza un file descriptor
464     invece di un pathname; pertanto gli errori restituiti cambiano di
465     conseguenza.}
466 \end{prototype}
467 \noindent ed il suo comportamento è identico a quello di \func{fpathconf}.
468
469
470 \subsection{La funzione \func{uname}}
471 \label{sec:sys_uname}
472
473 Una altra funzione che si può utilizzare per raccogliere informazioni sia
474 riguardo al sistema che al computer su cui esso sta girando è \func{uname}, il
475 suo prototipo è:
476 \begin{prototype}{sys/utsname.h}{int uname(struct utsname *info)}
477   Restituisce informazioni sul sistema nella struttura \param{info}.
478   
479   \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
480   fallimento, nel qual caso \var{errno} viene settata a \macro{EFAULT}.}
481 \end{prototype}
482
483 La funzione, che viene usata dal comando \cmd{umane}, restituisce le
484 informazioni richieste nella struttura \param{info}, anche questa struttura è
485 definita in \file{sys/utsname.h} come:
486 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
487     struct utsname {
488         char sysname[_UTSNAME_LENGTH];
489         char nodename[_UTSNAME_LENGTH];
490         char release[_UTSNAME_LENGTH];
491         char version[_UTSNAME_LENGTH];
492         char machine[_UTSNAME_LENGTH];
493 #ifdef _GNU_SOURCE
494         char domainname[_UTSNAME_DOMAIN_LENGTH];
495 #endif
496     };
497 \end{lstlisting}
498 e le informazioni memorizzate nei suoi membri indicano rispettivamente:
499 \begin{itemize*}
500 \item il nome del systema operativo;
501 \item il nome della release del kernel;
502 \item il nome della versione del kernel;
503 \item il tipo di macchina in uso;
504 \item il nome della stazione;
505 \item il nome del domino.
506 \end{itemize*}
507 (l'ultima informazione è stata aggiunta di recente e non è prevista dallo
508 standard POSIX). 
509
510
511 \section{Opzioni e configurazione del sistema}
512 \label{sec:sys_config}
513
514 Come abbiamo accennato nella sezione precedente, non tutti i limiti che
515 caratterizzano il sistema sono fissi, o perlomeno non lo sono in tutte le
516 implementazioni. Finora abbiamo visto come si può fare per leggerli, ci manca
517 di esaminare il meccanismo che permette, quando questi possono variare durante
518 l'esecuzione del sistema, di modificarli.
519
520 Inoltre, al di la di quelli che possono essere limiti caratteristici previsti
521 da uno standard, ogni sistema può avere una sua serie di altri parametri di
522 configurazione, che non essendo mai fissi, non sono stati inclusi nella
523 standardizzazione della sezione precedente, e per i quali occorre, oltre al
524 meccanismo di settaggio, pure un meccanismo di lettura.
525
526 Affronteremo questi argomenti in questa sezione, insieme alle funzioni che si
527 usano per la gestione ed il controllo dei filesystem. 
528
529
530 \subsection{La funzione \func{sysctl} ed il filesystem \file{/proc}}
531 \label{sec:sys_sysctl}
532
533 La funzione che permette la lettura ed il settaggio dei parametri del kernel è
534 \func{sysctl}, è una funzione derivata da BSD4.4, ma l'implementazione è
535 specifica di Linux; il suo prototipo è:
536 \begin{functions}
537 \headdecl{unistd.h}
538 \headdecl{linux/unistd.h}
539 \headdecl{linux/sysctl.h}
540 \funcdecl{int sysctl(int *name, int nlen, void *oldval, size\_t *oldlenp, void
541   *newval, size\_t newlen)}
542
543
544 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
545   errore, nel qual caso \var{errno} viene settato ai valori:
546   \begin{errlist}
547   \item[\macro{EPERM}] il processo non ha il permesso di accedere ad uno dei
548     componenti nel cammino specificato per il parametro, o non ha il permesso
549     di accesso al parametro nella modalità scelta.
550   \item[\macro{ENOTDIR}] non esiste un parametro corrispondente al nome
551     \param{name}.
552   \item[\macro{EFAULT}] si è specificato \param{oldlenp} zero quando
553     \param{oldval} è non nullo. 
554   \item[\macro{EINVAL}] o si è specificato un valore non valido per il
555     parametro che si vuole settare o lo spazio provvisto per il ritorno di un
556     valore non è delle giuste dimensioni.
557   \item[\macro{ENOMEM}] talvolta viene usato più correttamente questo errore
558     quando non si è specificato sufficiente spazio per ricevere il valore di un
559     parametro.
560   \end{errlist}
561 }
562 \end{functions}
563
564 I parametri a cui la funzione permettere di accedere sono organizzati in
565 maniera gerarchica ad albero, e per accedere ad uno di essi occorre
566 specificare un cammino attraverso i vari nodi dell'albero, in maniera analoga
567 a come si specifica un pathname (da cui l'uso alternativo del filesystem
568 \file{/proc} che vedremo dopo).
569
570 Ciascun nodo è identificato da un valore intero, ed il cammino che arriva ad
571 identificare un parametro specifico è passato attraverso l'array \param{name},
572 di lunghezza \param{nlen}, che contiene la sequenza dei vari nodi da
573 attraversare. Il formato del valore di un parametro dipende dallo stesso e può
574 essere un intero, una stringa o anche una struttura complessa. 
575
576 L'indirizzo a cui il valore deve essere letto è specificato da
577 \param{oldvalue}, e lo spazio ivi disponibile è specificato da \param{oldlenp}
578 (passato come puntatore per avere indietro la dimensione effettiva di quanto
579 letto); il valore che si vuole scrivere è passato in \param{newval} e la sua
580 dimensione in \param{newlen}.
581
582 Si può effettuare anche una lettura e scrittura simultanea, nel qual caso il
583 valore letto è quello precedente alla scrittura.
584
585 I parametri accessibili attraverso questa funzione sono moltissimi, e possono
586 essere trovati in \file{sysctl.h}, essi inoltre dipendono anche dallo stato
587 corrente del kernel (ad esempio dai moduli che sono stati caricati nel
588 sistema) e in genere i loro nomi possono variare da una versione di kernel
589 all'altra; per questo è sempre il caso di evitare l'uso di \func{sysctl}
590 quando esistono modalità alternative per ottenere le stesse informazioni,
591 alcuni esempi di parametri ottenibili sono:
592 \begin{itemize*}
593 \item il nome di dominio
594 \item i parametri del meccanismo di \textit{paging}.
595 \item il filesystem montato come radice
596 \item la data di compilazione del kernel
597 \item i parametri dello stack TCP
598 \item il numero massimo di file aperti
599 \end{itemize*}
600
601 Come accennato in Linux si ha una modalità alternativa per accedere alle
602 stesse informazioni di \func{sysctl} attaverso l'uso del filesystem
603 \file{/proc}. Questo è un filesystem virtuale, generato direttamente dal
604 kernel, che non fa riferimento a nessun dispositivo fisico, ma presenta in
605 forma di file alcune delle strutture interne del kernel stesso.
606
607 In particolare l'albero dei valori di \func{sysctl} viene presentato in forma
608 di file nella directory \file{/proc/sys}, cosicché è possibile accedervi
609 speficando un pathname e leggendo e scrivendo sul file corrispondente al
610 parametro scelto.  Il kernel si occupa di generare al volo il contenuto ed i
611 nomi dei file corrispondenti, e questo ha il grande vantaggio di rendere
612 accessibili i vari parametri a qualunque comando di shell e di permettere la
613 navigazione dell'albero dei valori.
614
615 Alcune delle corrispondenze con i valori di \func{sysctl} sono riportate nei
616 commenti in \file{linux/sysctl.h}, la informazione disponibile in
617 \file{/proc/sys} è riportata inoltre nella documentazione inclusa nei sorgenti
618 del kernel, nella directory \file{Documentation/sysctl}.
619
620
621 \subsection{La configurazione dei filesystem}
622 \label{sec:sys_file_config}
623
624 Come accennato in \secref{sec:file_organization} per poter accedere ai file
625 occorre prima rendere disponibile al sistema il filesystem su cui essi sono
626 memorizzati; l'operazione di attivazione del filesystem è chiamata
627 \textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica
628   di Linux e non è portabile} si usa la funzione \func{mount} il cui prototipo
629 è:
630 \begin{prototype}{sys/mount.h}
631 {mount(const char *source, const char *target, const char *filesystemtype, 
632   unsigned long mountflags, const void *data)}
633
634 Monta il filesystem di tipo \param{filesystemtype} contenuto in \param{source}
635 sulla directory \param{target}.
636   
637   \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
638   fallimento, nel qual caso \var{errno} viene settata a:
639   \begin{errlist}
640   \item[\macro{EPERM}] il processo non ha i provilegi di amministratore.
641   \item[\macro{ENODEV}] \param{filesystemtype} non esiste o non è configurato
642     nel kernel.
643   \item[\macro{ENOTBLK}] non si è usato un \textit{block device} per
644     \param{source} quando era richiesto.
645   \item[\macro{EBUSY}] \param{source} è già montato, o non può essere
646     rimontato in read-only perché ci sono ancora file aperti in scrittura, o
647     \param{target} è ancora in uso.
648   \item[\macro{EINVAL}] il device \param{source} presenta un
649     \textit{superblock} non valido, o si è cercato di rimontare un filesystem
650     non ancora montato, o di montarlo senza che \param{target} sia un
651     \type{mount point} o di spostarlo quando \param{target} non è un
652     \type{mount point} o è \file{/}.
653   \item[\macro{EACCES}] non si ha il permesso di accesso su uno dei componenti
654   del pathname, o si è cercato di montare un filesystem disponibile in sola
655   lettura senza averlo specificato o il device \param{source} è su un
656   filesystem montato con l'opzione \macro{MS\_NODEV}.
657   \item[\macro{ENXIO}] il \textit{major number} del device \param{source} è
658     sbagliato.
659   \item[\macro{EMFILE}] la tabella dei device \textit{dummy} è piena.
660   \end{errlist}
661   ed inoltre \macro{ENOTDIR}, \macro{EFAULT}, \macro{ENOMEM},
662   \macro{ENAMETOOLONG}, \macro{ENOENT} o \macro{ELOOP}.}
663 \end{prototype}
664
665 La funzione monta sulla directory \param{target} il filesystem contenuto in
666 \param{source}, di norma questo è un file di dispositivo, ma può anche essere
667 un file normale che contiene un filesystem, (che può essere montato \textit{in
668   loopback}).
669
670
671
672 Due funzioni, utili per ottenere in maniera diretta informazioni riguardo al
673 filesystem su cui si trova un certo file, sono \func{statfs} e \func{fstatfs},
674 i cui prototipi sono:
675 \begin{functions}
676   \headdecl{sys/vfs.h} \funcdecl{int statfs(const char *path, struct statfs
677     *buf)} \funcdecl{int fstatfs(int fd, struct statfs *buf)} Restituisce in
678   \param{buf} le informazioni relative al filesystem su cui è posto il file
679   specificato.
680
681 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
682   errore, nel qual caso \var{errno} viene settato ai valori:
683   \begin{errlist}
684   \item[\macro{ENOSYS}] il filesystem su cui si trova il file specificato non
685   supporta la funzione.
686   \end{errlist}
687   e \macro{EFAULT} ed \macro{EIO} per entrambe, \macro{EBADF} per
688   \func{fstatfs}, \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT},
689   \macro{EACCES}, \macro{ELOOP} per \func{statfs}.}
690 \end{functions}
691
692
693
694 \subsection{La gestione di utenti e gruppi}
695 \label{sec:sys_user_group}
696
697
698
699 \section{Limitazione ed uso delle risorse}
700 \label{sec:sys_res_limits}
701
702 In questa sezione esamineremo le funzioni che permettono di esaminare e
703 controllare come le varie risorse del sistema (CPU, memoria, ecc.) vengono
704 utilizzate dai processi, e le modalità con cui è possibile imporre dei limiti
705 sul loro utilizzo.
706
707
708
709 \subsection{L'uso delle risorse}
710 \label{sec:sys_resource_use}
711
712
713
714
715 \subsection{Limiti sulle risorse}
716 \label{sec:sys_resource_limit}
717
718
719 \subsection{Le risorse di memoria}
720 \label{sec:sys_memory_res}
721
722
723 \subsection{Le risorse di processore}
724 \label{sec:sys_cpu_load}
725
726
727
728 \begin{figure}[!htb]
729   \footnotesize
730   \centering
731   \begin{minipage}[c]{15cm}
732     \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
733 struct rusage {
734      struct timeval ru_utime; /* user time used */
735      struct timeval ru_stime; /* system time used */
736      long ru_maxrss;          /* maximum resident set size */
737      long ru_ixrss;           /* integral shared memory size */
738      long ru_idrss;           /* integral unshared data size */
739      long ru_isrss;           /* integral unshared stack size */
740      long ru_minflt;          /* page reclaims */
741      long ru_majflt;          /* page faults */
742      long ru_nswap;           /* swaps */
743      long ru_inblock;         /* block input operations */
744      long ru_oublock;         /* block output operations */
745      long ru_msgsnd;          /* messages sent */
746      long ru_msgrcv;          /* messages received */
747      long ru_nsignals;   ;    /* signals received */
748      long ru_nvcsw;           /* voluntary context switches */
749      long ru_nivcsw;          /* involuntary context switches */
750 };
751     \end{lstlisting}
752   \end{minipage} 
753   \normalsize 
754   \caption{La struttura \var{rusage} per la lettura delle informazioni dei 
755     delle risorse usate da un processo.}
756   \label{fig:sys_rusage_struct}
757 \end{figure}
758
759
760
761
762 \var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime}
763
764
765
766 \section{La gestione dei tempi del sistema}
767 \label{sec:sys_time}
768
769 In questa sezione tratteremo le varie funzioni per la gestione delle
770 date e del tempo in un sistema unix-like, e quelle per convertire i vari
771 tempi nelle differenti rappresentazioni che vengono utilizzate.
772
773
774 \subsection{La misura del tempo in unix}
775 \label{sec:sys_unix_time}
776
777 Storicamente i sistemi unix-like hanno sempre mantenuto due distinti
778 valori per i tempi all'interno del sistema, essi sono rispettivamente
779 chiamati \textit{calendar time} e \textit{process time}, secondo le
780 definizioni:
781 \begin{itemize}
782 \item \textit{calendar time}: è il numero di secondi dalla mezzanotte del
783   primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene
784   usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the
785     Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time)
786   dato che l'UTC corrisponde all'ora locale di Greenwich.  È il tempo su cui
787   viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per
788   indicare le date di modifica dei file o quelle di avvio dei processi. Per
789   memorizzare questo tempo è stato riservato il tipo primitivo \type{time\_t}.
790 \item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato
791   in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate
792   dal timer di sistema, e che per Linux avvengono ogni centesimo di
793   secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni
794     millesimo di secondo}. Il dato primitivo usato per questo tempo è
795   \type{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di
796   operazione del timer, e corrisponde dunque al numero di tick al secondo.  Lo
797   standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK});
798   questo valore può comunque essere ottenuto con \func{sysconf} (vedi
799   \secref{sec:sys_limits}).
800 \end{itemize}
801
802 In genere si usa il \textit{calendar time} per tenere le date dei file e le
803 informazioni analoghe che riguardano i tempi di ``orologio'', usati ad esempio
804 per i demoni che compiono lavori amministrativi ad ore definite, come
805 \cmd{cron}. Di solito questo vene convertito automaticamente dal valore in UTC
806 al tempo locale, utilizzando le opportune informazioni di localizzazione
807 (specificate in \file{/etc/timezone}). E da tenere presente che questo tempo è
808 mantenuto dal sistema e non corrisponde all'orologio hardware del calcolatore.
809
810 Il \textit{process time} di solito si esprime in secondi e viene usato appunto
811 per tenere conto dei tempi di esecuzione dei processi. Per ciascun processo il
812 kernel tiene tre di questi tempi: 
813 \begin{itemize*}
814 \item \textit{clock time}
815 \item \textit{user time}
816 \item \textit{system time}
817 \end{itemize*}
818 il primo è il tempo ``reale'' (viene anche chiamato \textit{wall clock time})
819 dall'avvio del processo, e misura il tempo trascorso fino alla sua
820 conclusione; chiaramente un tale tempo dipende anche dal carico del sistema e
821 da quanti altri processi stavano girando nello stesso periodo. Il secondo
822 tempo è quello che la CPU ha speso nell'esecuzione delle istruzioni del
823 processo in user space. Il terzo è il tempo impiegato dal kernel per eseguire
824 delle system call per conto del processo medesimo (tipo quello usato per
825 eseguire una \func{write} su un file). In genere la somma di user e system
826 time viene chiamato \textit{CPU time}. 
827
828
829
830
831
832 \section{La gestione degli errori}
833 \label{sec:sys_errors}
834
835 La gestione degli errori è in genere una materia complessa. Inoltre il modello
836 utilizzato dai sistema unix-like è basato sull'architettura a processi, e
837 presenta una serie di problemi nel caso lo si debba usare con i thread.
838 Esamineremo in questa sezione le sue caratteristiche principali.
839
840
841 \subsection{La variabile \var{errno}}
842 \label{sec:sys_errno}
843
844 Quasi tutte le funzioni delle librerie del C sono in grado di individuare e
845 riportare condizioni di errore, ed è una buona norma di programmazione
846 controllare sempre che le funzioni chiamate si siano concluse correttamente.
847
848 In genere le funzioni di libreria usano un valore speciale per indicare che
849 c'è stato un errore. Di solito questo valore è -1 o un puntatore nullo o la
850 costante \macro{EOF} (a seconda della funzione); ma questo valore segnala solo
851 che c'è stato un errore, non il tipo di errore. 
852
853 Per riportare il tipo di errore il sistema usa la variabile globale
854 \var{errno}\footnote{L'uso di una variabile globale può comportare alcuni
855   problemi (ad esempio nel caso dei thread) ma lo standard ISO C consente
856   anche di definire \var{errno} come un \textit{modifiable lvalue}, quindi si
857   può anche usare una macro, e questo è infatti il modo usato da Linux per
858   renderla locale ai singoli thread.}, definita nell'header \file{errno.h}; la
859 variabile è in genere definita come \type{volatile} dato che può essere
860 cambiata in modo asincrono da un segnale (per una descrizione dei segnali si
861 veda \secref{cha:signals}), ma dato che un manipolatore di segnale scritto
862 bene salva e ripristina il valore della variabile, di questo non è necessario
863 preoccuparsi nella programmazione normale.
864
865 I valori che può assumere \var{errno} sono riportati in \capref{cha:errors},
866 nell'header \file{errno.h} sono anche definiti i nomi simbolici per le
867 costanti numeriche che identificano i vari errori; essi iniziano tutti per
868 \macro{E} e si possono considerare come nomi riservati. In seguito faremo
869 sempre riferimento a tali valori, quando descriveremo i possibili errori
870 restituiti dalle funzioni. Il programma di esempio \cmd{errcode} stampa il
871 codice relativo ad un valore numerico con l'opzione \cmd{-l}.
872
873 Il valore di \var{errno} viene sempre settato a zero all'avvio di un
874 programma, gran parte delle funzioni di libreria settano \var{errno} ad un
875 valore diverso da zero in caso di errore. Il valore è invece indefinito in
876 caso di successo, perché anche se una funzione ha successo, può chiamarne
877 altre al suo interno che falliscono, modificando così \var{errno}.
878
879 Pertanto un valore non nullo di \var{errno} non è sintomo di errore (potrebbe
880 essere il risultato di un errore precedente) e non lo si può usare per
881 determinare quando o se una chiamata a funzione è fallita.  La procedura da
882 seguire è sempre quella di controllare \var{errno} immediatamente dopo aver
883 verificato il fallimento della funzione attraverso il suo codice di ritorno.
884
885
886 \subsection{Le funzioni \func{strerror} e \func{perror}}
887 \label{sec:sys_strerror}
888
889 Benché gli errori siano identificati univocamente dal valore numerico di
890 \var{errno} le librerie provvedono alcune funzioni e variabili utili per
891 riportare in opportuni messaggi le condizioni di errore verificatesi.  La
892 prima funzione che si può usare per ricavare i messaggi di errore è
893 \func{strerror}, il cui prototipo è:
894 \begin{prototype}{string.h}{char *strerror(int errnum)} 
895   Ritorna una stringa (statica) che descrive l'errore il cui codice è passato
896   come parametro.
897 \end{prototype}
898
899 In generale \func{strerror} viene usata passando \var{errno} come parametro;
900 nel caso si specifichi un codice sbagliato verrà restituito un messaggio di
901 errore sconosciuto. La funzione utilizza una stringa statica che non deve
902 essere modificata dal programma e che è utilizzabile solo fino ad una chiamata
903 successiva a \func{strerror}; nel caso si usino i thread è
904 provvista\footnote{questa funzione è una estensione GNU, non fa parte dello
905   standard POSIX} una versione apposita:
906 \begin{prototype}{string.h}
907 {char *strerror\_r(int errnum, char *buff, size\_t size)} 
908   Analoga a \func{strerror} ma ritorna il messaggio in un buffer
909   specificato da \param{buff} di lunghezza massima (compreso il terminatore)
910   \param{size}.
911 \end{prototype}
912 \noindent
913 che utilizza un buffer che il singolo thread deve allocare, per evitare i
914 problemi connessi alla condivisione del buffer statico. Infine, per completare
915 la caratterizzazione dell'errore, si può usare anche la variabile
916 globale\footnote{anche questa è una estensione GNU}
917 \var{program\_invocation\_short\_name} che riporta il nome del programma
918 attualmente in esecuzione.
919
920 Una seconda funzione usata per riportare i codici di errore in maniera
921 automatizzata sullo standard error (vedi \secref{sec:file_std_descr}) è
922 \func{perror}, il cui prototipo è:
923 \begin{prototype}{stdio.h}{void perror (const char *message)} 
924   Stampa il messaggio di errore relativo al valore corrente di \var{errno}
925   sullo standard error; preceduto dalla stringa \var{message}.
926 \end{prototype}
927 i messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati
928 in \capref{cha:errors}), e, usando il valore corrente di \var{errno}, si
929 riferiscono all'ultimo errore avvenuto. La stringa specificata con
930 \var{message} viene stampato prime del messaggio d'errore, seguita dai due
931 punti e da uno spazio, il messaggio è terminato con un a capo.
932
933 Il messaggio può essere riportato anche usando altre variabili globali
934 dichiarate in \file{errno.h}:
935 \begin{verbatim}
936    const char *sys_errlist[];
937    int sys_nerr;
938 \end{verbatim}
939 la prima contiene i puntatori alle stringhe di errore indicizzati da
940 \var{errno}; la seconda esprime il valore più alto per un codice di errore,
941 l'utilizzo di questa stringa è sostanzialmente equivalente a quello di
942 \func{strerror}.
943
944 In \nfig\ è riportata la sezione attinente del codice del programma
945 \cmd{errcode}, che può essere usato per stampare i messaggi di errore e le
946 costanti usate per identificare i singoli errori; il sorgente completo del
947 programma è allegato nel file \file{ErrCode.c} e contiene pure la gestione
948 delle opzioni e tutte le definizioni necessarie ad associare il valore
949 numerico alla costante simbolica. In particolare si è riportata la sezione che
950 converte la stringa passata come parametro in un intero (\texttt{\small
951   1--2}), controllando con i valori di ritorno di \func{strtol} che la
952 conversione sia avvenuta correttamente (\texttt{\small 4--10}), e poi stampa,
953 a seconda dell'opzione scelta il messaggio di errore (\texttt{\small 11--14})
954 o la macro (\texttt{\small 15--17}) associate a quel codice.
955
956 \begin{figure}[!htb]
957   \footnotesize
958   \begin{lstlisting}{}
959     /* convert string to number */
960     err = strtol(argv[optind], NULL, 10);
961     /* testing error condition on conversion */
962     if (err==LONG_MIN) {
963         perror("Underflow on error code");
964         return 1;
965     } else if (err==LONG_MIN) {
966         perror("Overflow on error code");
967         return 1;
968     }
969     /* conversion is fine */
970     if (message) {
971         printf("Error message for %d is %s\n", err, strerror(err));
972     }
973     if (label) {
974         printf("Error label for %d is %s\n", err, err_code[err]);
975     }
976   \end{lstlisting}
977   \caption{Codice per la stampa del messaggio di errore standard.}
978   \label{fig:sys_err_mess}
979 \end{figure}
980
981
982
983 %%% Local Variables: 
984 %%% mode: latex
985 %%% TeX-master: "gapil"
986 %%% End: