1 \chapter{La gestione del sistema, delle risorse, e degli errori}
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.
12 \section{La lettura delle caratteristiche del sistema}
13 \label{sec:sys_characteristics}
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.
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
31 \subsection{Limiti e parametri di sistema}
32 \label{sec:sys_limits}
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à:
43 \item la possibilità di determinare limiti ed opzioni al momento della
45 \item la possibilità di determinare limiti ed opzioni durante l'esecuzione.
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}).
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.
72 \begin{tabular}[c]{|l|r|l|}
74 \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
77 \macro{MB\_LEN\_MAX}& 16 & massima dimensione di un
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}\\
96 \caption{Macro definite in \file{limits.h} in conformità allo standard
98 \label{tab:sys_ansic_macro}
101 \footnotetext[1]{il valore può essere 0 o \macro{SCHAR\_MIN} a seconda che il
102 sistema usi caratteri con segno o meno.}
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.}
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}.
114 \begin{tabular}[c]{|l|r|l|}
116 \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
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}\\
125 \caption{Macro definite in \file{limits.h} in conformità allo standard
127 \label{tab:sys_isoc90_macro}
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}.
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}).
146 \begin{tabular}[c]{|l|r|p{8cm}|}
148 \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
151 \macro{ARG\_MAX} &131072& dimensione massima degli argomenti
152 passati ad una funzione della famiglia
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}.\\
169 \label{tab:sys_generic_macro}
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.
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}.
188 \begin{tabular}[c]{|l|r|p{8cm}|}
190 \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
193 \macro{\_POSIX\_ARG\_MAX} & 4096& dimensione massima degli argomenti
194 passati ad una funzione della famiglia
196 \macro{\_POSIX\_CHILD\_MAX} & 6& numero massimo di processi
197 contemporanei che un utente può
199 \macro{\_POSIX\_OPEN\_MAX} & 16& numero massimo di file che un processo
200 può mantenere aperti in
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
208 \secref{sec:proc_access_id}).\\
209 \macro{\_POSIX\_SSIZE\_MAX} &32767& valore massimo del tipo
211 \macro{\_POSIX\_AIO\_LISTIO\_MAX}&2& \\
212 \macro{\_POSIX\_AIO\_MAX} & 1& \\
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}
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}.
230 \begin{tabular}[c]{|l|p{8cm}|}
232 \textbf{Macro}&\textbf{Significato}\\
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
246 \caption{Alcune macro definite in \file{limits.h} in conformità allo standard
248 \label{tab:sys_posix1_other}
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
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}.
270 \subsection{La funzione \func{sysconf}}
271 \label{sec:sys_sysconf}
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
279 \begin{prototype}{unistd.h}{long sysconf(int name)}
280 Restituisce il valore del parametro di sistema \param{name}.
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).}
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}.
296 \begin{tabular}[c]{|l|l|p{9cm}|}
298 \textbf{Parametro}&\textbf{Macro sostituita} &\textbf{Significato}\\
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ò
307 \texttt{\_SC\_OPEN\_MAX}&\macro{\_OPEN\_MAX}&
308 Il numero massimo di file che un processo può mantenere aperti in
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.\\
336 \caption{Parametri del sistema leggibili dalla funzione \func{sysconf}.}
337 \label{tab:sys_sysconf_par}
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 specificando 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.
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]{}
355 int val = sysconf(_SC_CHILD_MAX);
357 perror("fatal error");
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
368 \subsection{I limiti dei file}
369 \label{sec:sys_file_limits}
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}.
380 \begin{tabular}[c]{|l|r|p{8cm}|}
382 \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
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
395 \caption{Macro per i limiti sulle caratteristiche dei file.}
396 \label{tab:sys_file_macro}
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}.
408 \begin{tabular}[c]{|l|r|p{8cm}|}
410 \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
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
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
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 & \\
429 \caption{Macro dei valori minimi delle caratteristiche dei file per la
430 conformità allo standard POSIX.1.}
431 \label{tab:sys_posix1_file}
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.
439 \subsection{La funzione \func{pathconf}}
440 \label{sec:sys_pathconf}
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}.
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}).}
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
460 \begin{prototype}{unistd.h}{long fpathconf(int fd, int name)}
461 Restituisce il valore del parametro \param{name} per il file \param{fd}.
463 \bodydesc{È identica a \func{pathconf} solo che utilizza un file descriptor
464 invece di un pathname; pertanto gli errori restituiti cambiano di
467 \noindent ed il suo comportamento è identico a quello di \func{fpathconf}.
470 \subsection{La funzione \func{uname}}
471 \label{sec:sys_uname}
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
476 \begin{prototype}{sys/utsname.h}{int uname(struct utsname *info)}
477 Restituisce informazioni sul sistema nella struttura \param{info}.
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}.}
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]{}
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];
494 char domainname[_UTSNAME_DOMAIN_LENGTH];
498 e le informazioni memorizzate nei suoi membri indicano rispettivamente:
500 \item il nome del sistema 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.
507 (l'ultima informazione è stata aggiunta di recente e non è prevista dallo
511 \section{Opzioni e configurazione del sistema}
512 \label{sec:sys_config}
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.
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.
526 Affronteremo questi argomenti in questa sezione, insieme alle funzioni che si
527 usano per il controllo di altre caratteristiche generali del sistema, come
528 quelle per la gestione dei filesystem e di utenti e gruppi.
531 \subsection{La funzione \func{sysctl} ed il filesystem \file{/proc}}
532 \label{sec:sys_sysctl}
534 La funzione che permette la lettura ed il settaggio dei parametri del kernel è
535 \func{sysctl}, è una funzione derivata da BSD4.4, ma l'implementazione è
536 specifica di Linux; il suo prototipo è:
539 \headdecl{linux/unistd.h}
540 \headdecl{linux/sysctl.h}
541 \funcdecl{int sysctl(int *name, int nlen, void *oldval, size\_t *oldlenp, void
542 *newval, size\_t newlen)}
545 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
546 errore, nel qual caso \var{errno} viene settato ai valori:
548 \item[\macro{EPERM}] il processo non ha il permesso di accedere ad uno dei
549 componenti nel cammino specificato per il parametro, o non ha il permesso
550 di accesso al parametro nella modalità scelta.
551 \item[\macro{ENOTDIR}] non esiste un parametro corrispondente al nome
553 \item[\macro{EFAULT}] si è specificato \param{oldlenp} zero quando
554 \param{oldval} è non nullo.
555 \item[\macro{EINVAL}] o si è specificato un valore non valido per il
556 parametro che si vuole settare o lo spazio provvisto per il ritorno di un
557 valore non è delle giuste dimensioni.
558 \item[\macro{ENOMEM}] talvolta viene usato più correttamente questo errore
559 quando non si è specificato sufficiente spazio per ricevere il valore di un
565 I parametri a cui la funzione permettere di accedere sono organizzati in
566 maniera gerarchica ad albero, e per accedere ad uno di essi occorre
567 specificare un cammino attraverso i vari nodi dell'albero, in maniera analoga
568 a come si specifica un pathname (da cui l'uso alternativo del filesystem
569 \file{/proc} che vedremo dopo).
571 Ciascun nodo è identificato da un valore intero, ed il cammino che arriva ad
572 identificare un parametro specifico è passato attraverso l'array \param{name},
573 di lunghezza \param{nlen}, che contiene la sequenza dei vari nodi da
574 attraversare. Il formato del valore di un parametro dipende dallo stesso e può
575 essere un intero, una stringa o anche una struttura complessa.
577 L'indirizzo a cui il valore deve essere letto è specificato da
578 \param{oldvalue}, e lo spazio ivi disponibile è specificato da \param{oldlenp}
579 (passato come puntatore per avere indietro la dimensione effettiva di quanto
580 letto); il valore che si vuole scrivere è passato in \param{newval} e la sua
581 dimensione in \param{newlen}.
583 Si può effettuare anche una lettura e scrittura simultanea, nel qual caso il
584 valore letto è quello precedente alla scrittura.
586 I parametri accessibili attraverso questa funzione sono moltissimi, e possono
587 essere trovati in \file{sysctl.h}, essi inoltre dipendono anche dallo stato
588 corrente del kernel (ad esempio dai moduli che sono stati caricati nel
589 sistema) e in genere i loro nomi possono variare da una versione di kernel
590 all'altra; per questo è sempre il caso di evitare l'uso di \func{sysctl}
591 quando esistono modalità alternative per ottenere le stesse informazioni.
592 Alcuni esempi di parametri ottenibili sono:
594 \item il nome di dominio
595 \item i parametri del meccanismo di \textit{paging}.
596 \item il filesystem montato come radice
597 \item la data di compilazione del kernel
598 \item i parametri dello stack TCP
599 \item il numero massimo di file aperti
602 Come accennato in Linux si ha una modalità alternativa per accedere alle
603 stesse informazioni di \func{sysctl} attraverso l'uso del filesystem
604 \file{/proc}. Questo è un filesystem virtuale, generato direttamente dal
605 kernel, che non fa riferimento a nessun dispositivo fisico, ma presenta in
606 forma di file alcune delle strutture interne del kernel stesso.
608 In particolare l'albero dei valori di \func{sysctl} viene presentato in forma
609 di file nella directory \file{/proc/sys}, cosicché è possibile accedervi
610 specificando un pathname e leggendo e scrivendo sul file corrispondente al
611 parametro scelto. Il kernel si occupa di generare al volo il contenuto ed i
612 nomi dei file corrispondenti, e questo ha il grande vantaggio di rendere
613 accessibili i vari parametri a qualunque comando di shell e di permettere la
614 navigazione dell'albero dei valori.
616 Alcune delle corrispondenze con i valori di \func{sysctl} sono riportate nei
617 commenti in \file{linux/sysctl.h}, la informazione disponibile in
618 \file{/proc/sys} è riportata inoltre nella documentazione inclusa nei sorgenti
619 del kernel, nella directory \file{Documentation/sysctl}.
622 \subsection{La gestione delle proprietà dei filesystem}
623 \label{sec:sys_file_config}
625 Come accennato in \secref{sec:file_organization} per poter accedere ai file
626 occorre prima rendere disponibile al sistema il filesystem su cui essi sono
627 memorizzati; l'operazione di attivazione del filesystem è chiamata
628 \textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica
629 di Linux e non è portabile} si usa la funzione \func{mount} il cui prototipo
631 \begin{prototype}{sys/mount.h}
632 {mount(const char *source, const char *target, const char *filesystemtype,
633 unsigned long mountflags, const void *data)}
635 Monta il filesystem di tipo \param{filesystemtype} contenuto in \param{source}
636 sulla directory \param{target}.
638 \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
639 fallimento, nel qual caso gli errori comuni a tutti i filesystem che possono
640 essere restituiti in \var{errno} sono:
642 \item[\macro{EPERM}] il processo non ha i privilegi di amministratore.
643 \item[\macro{ENODEV}] \param{filesystemtype} non esiste o non è configurato
645 \item[\macro{ENOTBLK}] non si è usato un \textit{block device} per
646 \param{source} quando era richiesto.
647 \item[\macro{EBUSY}] \param{source} è già montato, o non può essere
648 rimontato in read-only perché ci sono ancora file aperti in scrittura, o
649 \param{target} è ancora in uso.
650 \item[\macro{EINVAL}] il device \param{source} presenta un
651 \textit{superblock} non valido, o si è cercato di rimontare un filesystem
652 non ancora montato, o di montarlo senza che \param{target} sia un
653 \type{mount point} o di spostarlo quando \param{target} non è un
654 \type{mount point} o è \file{/}.
655 \item[\macro{EACCES}] non si ha il permesso di accesso su uno dei componenti
656 del pathname, o si è cercato di montare un filesystem disponibile in sola
657 lettura senza averlo specificato o il device \param{source} è su un
658 filesystem montato con l'opzione \macro{MS\_NODEV}.
659 \item[\macro{ENXIO}] il \textit{major number} del device \param{source} è
661 \item[\macro{EMFILE}] la tabella dei device \textit{dummy} è piena.
663 ed inoltre \macro{ENOTDIR}, \macro{EFAULT}, \macro{ENOMEM},
664 \macro{ENAMETOOLONG}, \macro{ENOENT} o \macro{ELOOP}.}
668 La funzione monta sulla directory \param{target}, detta \textit{mount point},
669 il filesystem contenuto in \param{source}. In generale un filesystem è
670 contenuto su un disco, e l'operazione di montaggio corrisponde a rendere
671 visibile al sistema il contenuto del suddetto disco, identificato attraverso
672 il file di dispositivo ad esso associato.
674 Ma la struttura del virtual filesystem vista in \secref{sec:file_vfs} è molto
675 più flessibile e può essere usata anche per oggetti diversi da un disco. Ad
676 esempio usando il \textit{loop device} si può montare un file qualunque (come
677 l'immagine di un CD-ROM o di un floppy) che contiene un filesystem, inoltre
678 alcuni filesystem, come \file{proc} o \file{devfs} sono del tutto virtuali, i
679 loro dati sono generati al volo ad ogni lettura, e passati al kernel ad ogni
682 Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere
683 una delle stringhe riportate in \file{/proc/filesystems}, che contiene
684 l'elenco dei filesystem supportati dal kernel; nel caso si sia indicato uno
685 dei filesystem virtuali, il contenuto di \param{source} viene ignorato.
687 Dopo l'esecuzione della funzione il contenuto del filesystem viene resto
688 disponibile nella directory specificata come \textit{mount point}, il
689 precedente contenuto di detta directory viene mascherato dal contenuto della
690 directory radice del filesystem montato.
692 Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un
693 \textit{mount point} da una directory ad un'altra, che montare in diversi
694 \textit{mount point} lo stesso filesystem, che montare più filesystem sullo
695 stesso \textit{mount point} (nel qual caso vale quanto appena detto, e solo il
696 contenuto dell'ultimo filesystem montato sarà visibile).
698 Ciascun filesystem è dotato di caratteristiche specifiche che possono essere
699 attivate o meno, alcune di queste sono generali (anche se non è detto siano
700 disponibili in ogni filesystem), e vengono specificate come opzioni di
701 montaggio con l'argomento \param{mountflags}.
703 In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più
704 significativi sono un \textit{magic number}\footnote{cioè un numero speciale
705 usato come identificativo, che nel caso è \code{0xC0ED}; si può usare la
706 costante \macro{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags}
707 riservata al \textit{magic number}.} mentre i 16 meno significativi sono
708 usati per specificare le opzioni; essi sono usati come maschera binaria e
709 vanno settati con un OR aritmetico della costante \macro{MS\_MGC\_VAL} con i
710 valori riportati in \ntab.
714 \begin{tabular}[c]{|l|r|l|}
716 \textbf{Parametro} & \textbf{Valore}&\textbf{Significato}\\
719 \macro{MS\_RDONLY} & 1 & monta in sola lettura\\
720 \macro{MS\_NOSUID} & 2 & ignora i bit \acr{suid} e \acr{sgid}\\
721 \macro{MS\_NODEV} & 4 & impedisce l'accesso ai file di dispositivo\\
722 \macro{MS\_NOEXEC} & 8 & impedisce di eseguire programmi \\
723 \macro{MS\_SYNCHRONOUS}& 16 & abilita la scrittura sincrona \\
724 \macro{MS\_REMOUNT} & 32 & rimonta il filesystem cambiando i flag\\
725 \macro{MS\_MANDLOCK} & 64 & consente il \textit{mandatory locking} (vedi
726 \secref{sec:file_mand_locking})\\
727 \macro{S\_WRITE} & 128 & scrive normalmente \\
728 \macro{S\_APPEND} & 256 & consente la scrittura solo in \textit{append
729 mode} (vedi \secref{sec:file_sharing})\\
730 \macro{S\_IMMUTABLE} & 512 & impedisce che si possano modificare i file \\
731 \macro{MS\_NOATIME} &1024 & non aggiorna gli \textit{access time} (vedi
732 \secref{sec:file_file_times})\\
733 \macro{MS\_NODIRATIME}&2048 & non aggiorna gli \textit{access time} delle
735 \macro{MS\_BIND} &4096 & monta il filesystem altrove\\
736 \macro{MS\_MOVE} &8192 & sposta atomicamente il punto di montaggio \\
739 \caption{Tabella dei codici dei flag di montaggio di un filesystem.}
740 \label{tab:sys_mount_flags}
743 Per il settaggio delle caratteristiche particolari di ciascun filesystem si
744 usa invece l'argomento \param{data} che serve per passare le ulteriori
745 informazioni necessarie, che ovviamente variano da filesystem a filesystem.
747 La funzione \func{mount} può essere utilizzata anche per effettuare il
748 \textsl{rimontaggio} di un filesystem, cosa che permette di cambiarne al volo
749 alcune delle caratteristiche di funzionamento (ad esempio passare da sola
750 lettura a lettura/scrittura). Questa operazione è attivata attraverso uno dei
751 bit di \param{mountflags}, \macro{MS\_REMOUNT}, che se settato specifica che
752 deve essere effettuato il rimontaggio del filesystem (con le opzioni
753 specificate dagli altri bit), anche in questo caso il valore di \param{source}
757 Una volta che non si voglia più utilizzare un certo filesystem è possibile
758 \textsl{smontarlo} usando la funzione \func{umount}, il cui prototipo è:
759 \begin{prototype}{sys/mount.h}{umount(const char *target)}
761 Smonta il filesystem montato sulla directory \param{target}.
763 \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
764 fallimento, nel qual caso \var{errno} viene settata a:
766 \item[\macro{EPERM}] il processo non ha i privilegi di amministratore.
767 \item[\macro{EBUSY}] \param{target} è la directory di lavoro di qualche
768 processo, o contiene dei file aperti, o un altro mount point.
770 ed inoltre \macro{ENOTDIR}, \macro{EFAULT}, \macro{ENOMEM},
771 \macro{ENAMETOOLONG}, \macro{ENOENT} o \macro{ELOOP}.}
773 \noindent la funzione prende il nome della directory su cui il filesystem è
774 montato e non il file o il dispositivo che è stato montato\footnote{questo è
775 vero a partire dal kernel 2.3.99-pre7, prima esistevano due chiamate
776 separate e la funzione poteva essere usata anche specificando il file di
777 dispositivo.}, in quanto con il kernel 2.4.x è possibile montare lo stesso
778 dispositivo in più punti. Nel caso più di un filesystem sia stato montato
779 sullo stesso \textit{mount point} viene smontato quello che è stato montato
782 Linux provvede inoltre una seconda funzione \func{umount2}, che, in alcuni
783 casi, permette di forzare lo smontaggio di un filesystem nei casi in cui mount
784 fallirebbe; il suo prototipo è:
788 Due funzioni, utili per ottenere in maniera diretta informazioni riguardo al
789 filesystem su cui si trova un certo file, sono \func{statfs} e \func{fstatfs},
790 i cui prototipi sono:
792 \headdecl{sys/vfs.h} \funcdecl{int statfs(const char *path, struct statfs
793 *buf)} \funcdecl{int fstatfs(int fd, struct statfs *buf)} Restituisce in
794 \param{buf} le informazioni relative al filesystem su cui è posto il file
797 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
798 errore, nel qual caso \var{errno} viene settato ai valori:
800 \item[\macro{ENOSYS}] il filesystem su cui si trova il file specificato non
801 supporta la funzione.
803 e \macro{EFAULT} ed \macro{EIO} per entrambe, \macro{EBADF} per
804 \func{fstatfs}, \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT},
805 \macro{EACCES}, \macro{ELOOP} per \func{statfs}.}
810 \subsection{La gestione di utenti e gruppi}
811 \label{sec:sys_user_group}
815 \section{Limitazione ed uso delle risorse}
816 \label{sec:sys_res_limits}
818 In questa sezione esamineremo le funzioni che permettono di esaminare e
819 controllare come le varie risorse del sistema (CPU, memoria, ecc.) vengono
820 utilizzate dai processi, e le modalità con cui è possibile imporre dei limiti
825 \subsection{L'uso delle risorse}
826 \label{sec:sys_resource_use}
831 \subsection{Limiti sulle risorse}
832 \label{sec:sys_resource_limit}
835 \subsection{Le risorse di memoria}
836 \label{sec:sys_memory_res}
839 \subsection{Le risorse di processore}
840 \label{sec:sys_cpu_load}
847 \begin{minipage}[c]{15cm}
848 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
850 struct timeval ru_utime; /* user time used */
851 struct timeval ru_stime; /* system time used */
852 long ru_maxrss; /* maximum resident set size */
853 long ru_ixrss; /* integral shared memory size */
854 long ru_idrss; /* integral unshared data size */
855 long ru_isrss; /* integral unshared stack size */
856 long ru_minflt; /* page reclaims */
857 long ru_majflt; /* page faults */
858 long ru_nswap; /* swaps */
859 long ru_inblock; /* block input operations */
860 long ru_oublock; /* block output operations */
861 long ru_msgsnd; /* messages sent */
862 long ru_msgrcv; /* messages received */
863 long ru_nsignals; ; /* signals received */
864 long ru_nvcsw; /* voluntary context switches */
865 long ru_nivcsw; /* involuntary context switches */
870 \caption{La struttura \var{rusage} per la lettura delle informazioni dei
871 delle risorse usate da un processo.}
872 \label{fig:sys_rusage_struct}
878 \var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime}
882 \section{La gestione dei tempi del sistema}
885 In questa sezione tratteremo le varie funzioni per la gestione delle
886 date e del tempo in un sistema unix-like, e quelle per convertire i vari
887 tempi nelle differenti rappresentazioni che vengono utilizzate.
890 \subsection{La misura del tempo in unix}
891 \label{sec:sys_unix_time}
893 Storicamente i sistemi unix-like hanno sempre mantenuto due distinti
894 valori per i tempi all'interno del sistema, essi sono rispettivamente
895 chiamati \textit{calendar time} e \textit{process time}, secondo le
898 \item \textit{calendar time}: è il numero di secondi dalla mezzanotte del
899 primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene
900 usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the
901 Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time)
902 dato che l'UTC corrisponde all'ora locale di Greenwich. È il tempo su cui
903 viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per
904 indicare le date di modifica dei file o quelle di avvio dei processi. Per
905 memorizzare questo tempo è stato riservato il tipo primitivo \type{time\_t}.
906 \item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato
907 in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate
908 dal timer di sistema, e che per Linux avvengono ogni centesimo di
909 secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni
910 millesimo di secondo}. Il dato primitivo usato per questo tempo è
911 \type{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di
912 operazione del timer, e corrisponde dunque al numero di tick al secondo. Lo
913 standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK});
914 questo valore può comunque essere ottenuto con \func{sysconf} (vedi
915 \secref{sec:sys_limits}).
918 In genere si usa il \textit{calendar time} per tenere le date dei file e le
919 informazioni analoghe che riguardano i tempi di ``orologio'', usati ad esempio
920 per i demoni che compiono lavori amministrativi ad ore definite, come
921 \cmd{cron}. Di solito questo vene convertito automaticamente dal valore in UTC
922 al tempo locale, utilizzando le opportune informazioni di localizzazione
923 (specificate in \file{/etc/timezone}). E da tenere presente che questo tempo è
924 mantenuto dal sistema e non corrisponde all'orologio hardware del calcolatore.
926 Il \textit{process time} di solito si esprime in secondi e viene usato appunto
927 per tenere conto dei tempi di esecuzione dei processi. Per ciascun processo il
928 kernel tiene tre di questi tempi:
930 \item \textit{clock time}
931 \item \textit{user time}
932 \item \textit{system time}
934 il primo è il tempo ``reale'' (viene anche chiamato \textit{wall clock time})
935 dall'avvio del processo, e misura il tempo trascorso fino alla sua
936 conclusione; chiaramente un tale tempo dipende anche dal carico del sistema e
937 da quanti altri processi stavano girando nello stesso periodo. Il secondo
938 tempo è quello che la CPU ha speso nell'esecuzione delle istruzioni del
939 processo in user space. Il terzo è il tempo impiegato dal kernel per eseguire
940 delle system call per conto del processo medesimo (tipo quello usato per
941 eseguire una \func{write} su un file). In genere la somma di user e system
942 time viene chiamato \textit{CPU time}.
948 \section{La gestione degli errori}
949 \label{sec:sys_errors}
951 La gestione degli errori è in genere una materia complessa. Inoltre il modello
952 utilizzato dai sistema unix-like è basato sull'architettura a processi, e
953 presenta una serie di problemi nel caso lo si debba usare con i thread.
954 Esamineremo in questa sezione le sue caratteristiche principali.
957 \subsection{La variabile \var{errno}}
958 \label{sec:sys_errno}
960 Quasi tutte le funzioni delle librerie del C sono in grado di individuare e
961 riportare condizioni di errore, ed è una buona norma di programmazione
962 controllare sempre che le funzioni chiamate si siano concluse correttamente.
964 In genere le funzioni di libreria usano un valore speciale per indicare che
965 c'è stato un errore. Di solito questo valore è -1 o un puntatore nullo o la
966 costante \macro{EOF} (a seconda della funzione); ma questo valore segnala solo
967 che c'è stato un errore, non il tipo di errore.
969 Per riportare il tipo di errore il sistema usa la variabile globale
970 \var{errno}\footnote{L'uso di una variabile globale può comportare alcuni
971 problemi (ad esempio nel caso dei thread) ma lo standard ISO C consente
972 anche di definire \var{errno} come un \textit{modifiable lvalue}, quindi si
973 può anche usare una macro, e questo è infatti il modo usato da Linux per
974 renderla locale ai singoli thread.}, definita nell'header \file{errno.h}; la
975 variabile è in genere definita come \type{volatile} dato che può essere
976 cambiata in modo asincrono da un segnale (per una descrizione dei segnali si
977 veda \secref{cha:signals}), ma dato che un manipolatore di segnale scritto
978 bene salva e ripristina il valore della variabile, di questo non è necessario
979 preoccuparsi nella programmazione normale.
981 I valori che può assumere \var{errno} sono riportati in \capref{cha:errors},
982 nell'header \file{errno.h} sono anche definiti i nomi simbolici per le
983 costanti numeriche che identificano i vari errori; essi iniziano tutti per
984 \macro{E} e si possono considerare come nomi riservati. In seguito faremo
985 sempre riferimento a tali valori, quando descriveremo i possibili errori
986 restituiti dalle funzioni. Il programma di esempio \cmd{errcode} stampa il
987 codice relativo ad un valore numerico con l'opzione \cmd{-l}.
989 Il valore di \var{errno} viene sempre settato a zero all'avvio di un
990 programma, gran parte delle funzioni di libreria settano \var{errno} ad un
991 valore diverso da zero in caso di errore. Il valore è invece indefinito in
992 caso di successo, perché anche se una funzione ha successo, può chiamarne
993 altre al suo interno che falliscono, modificando così \var{errno}.
995 Pertanto un valore non nullo di \var{errno} non è sintomo di errore (potrebbe
996 essere il risultato di un errore precedente) e non lo si può usare per
997 determinare quando o se una chiamata a funzione è fallita. La procedura da
998 seguire è sempre quella di controllare \var{errno} immediatamente dopo aver
999 verificato il fallimento della funzione attraverso il suo codice di ritorno.
1002 \subsection{Le funzioni \func{strerror} e \func{perror}}
1003 \label{sec:sys_strerror}
1005 Benché gli errori siano identificati univocamente dal valore numerico di
1006 \var{errno} le librerie provvedono alcune funzioni e variabili utili per
1007 riportare in opportuni messaggi le condizioni di errore verificatesi. La
1008 prima funzione che si può usare per ricavare i messaggi di errore è
1009 \func{strerror}, il cui prototipo è:
1010 \begin{prototype}{string.h}{char *strerror(int errnum)}
1011 Ritorna una stringa (statica) che descrive l'errore il cui codice è passato
1015 In generale \func{strerror} viene usata passando \var{errno} come parametro;
1016 nel caso si specifichi un codice sbagliato verrà restituito un messaggio di
1017 errore sconosciuto. La funzione utilizza una stringa statica che non deve
1018 essere modificata dal programma e che è utilizzabile solo fino ad una chiamata
1019 successiva a \func{strerror}; nel caso si usino i thread è
1020 provvista\footnote{questa funzione è una estensione GNU, non fa parte dello
1021 standard POSIX} una versione apposita:
1022 \begin{prototype}{string.h}
1023 {char *strerror\_r(int errnum, char *buff, size\_t size)}
1024 Analoga a \func{strerror} ma ritorna il messaggio in un buffer
1025 specificato da \param{buff} di lunghezza massima (compreso il terminatore)
1029 che utilizza un buffer che il singolo thread deve allocare, per evitare i
1030 problemi connessi alla condivisione del buffer statico. Infine, per completare
1031 la caratterizzazione dell'errore, si può usare anche la variabile
1032 globale\footnote{anche questa è una estensione GNU}
1033 \var{program\_invocation\_short\_name} che riporta il nome del programma
1034 attualmente in esecuzione.
1036 Una seconda funzione usata per riportare i codici di errore in maniera
1037 automatizzata sullo standard error (vedi \secref{sec:file_std_descr}) è
1038 \func{perror}, il cui prototipo è:
1039 \begin{prototype}{stdio.h}{void perror (const char *message)}
1040 Stampa il messaggio di errore relativo al valore corrente di \var{errno}
1041 sullo standard error; preceduto dalla stringa \var{message}.
1043 i messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati
1044 in \capref{cha:errors}), e, usando il valore corrente di \var{errno}, si
1045 riferiscono all'ultimo errore avvenuto. La stringa specificata con
1046 \var{message} viene stampato prime del messaggio d'errore, seguita dai due
1047 punti e da uno spazio, il messaggio è terminato con un a capo.
1049 Il messaggio può essere riportato anche usando altre variabili globali
1050 dichiarate in \file{errno.h}:
1052 const char *sys_errlist[];
1055 la prima contiene i puntatori alle stringhe di errore indicizzati da
1056 \var{errno}; la seconda esprime il valore più alto per un codice di errore,
1057 l'utilizzo di questa stringa è sostanzialmente equivalente a quello di
1060 In \nfig\ è riportata la sezione attinente del codice del programma
1061 \cmd{errcode}, che può essere usato per stampare i messaggi di errore e le
1062 costanti usate per identificare i singoli errori; il sorgente completo del
1063 programma è allegato nel file \file{ErrCode.c} e contiene pure la gestione
1064 delle opzioni e tutte le definizioni necessarie ad associare il valore
1065 numerico alla costante simbolica. In particolare si è riportata la sezione che
1066 converte la stringa passata come parametro in un intero (\texttt{\small
1067 1--2}), controllando con i valori di ritorno di \func{strtol} che la
1068 conversione sia avvenuta correttamente (\texttt{\small 4--10}), e poi stampa,
1069 a seconda dell'opzione scelta il messaggio di errore (\texttt{\small 11--14})
1070 o la macro (\texttt{\small 15--17}) associate a quel codice.
1072 \begin{figure}[!htb]
1074 \begin{lstlisting}{}
1075 /* convert string to number */
1076 err = strtol(argv[optind], NULL, 10);
1077 /* testing error condition on conversion */
1078 if (err==LONG_MIN) {
1079 perror("Underflow on error code");
1081 } else if (err==LONG_MIN) {
1082 perror("Overflow on error code");
1085 /* conversion is fine */
1087 printf("Error message for %d is %s\n", err, strerror(err));
1090 printf("Error label for %d is %s\n", err, err_code[err]);
1093 \caption{Codice per la stampa del messaggio di errore standard.}
1094 \label{fig:sys_err_mess}
1099 %%% Local Variables:
1101 %%% TeX-master: "gapil"