1 \chapter{L'interfaccia base con i processi}
2 \label{cha:process_interface}
4 Come accennato nell'introduzione il processo è l'unità di base con cui un
5 sistema unix alloca ed utilizza le risorse. Questo capitolo tratterà
6 l'interfaccia base fra il sistema e i processi, su come vengono passati i
7 parametri, come viene gestita e allocata la memoria, su come un processo può
8 richiedere servizi al sistema, su cosa deve fare quando ha finito la sua
11 In genere un programma viene eseguito quando un processo lo fa partire
12 eseguendo una funzione della famiglia \texttt{exec}; torneremo su questo e
13 sulla la creazione e gestione dei processi nel prossimo capitolo, in questo
14 affronteremo l'avvio e il funzionamento di un singolo processo partendo dal
15 punto di vista del programma posto in esecuzione.
19 \section{Esecuzione e conclusione di un programma}
21 Una delle concetti base relativi ai processi è che un processo esegue sempre
22 uno ed un solo programma: si possono avere più processi che eseguono lo stesso
23 programma ma ciascun processo vedrà la sua copia del codice (in realtà il
24 kernel fa si che tutte le parti uguali siano condivise) avrà un suo spazio di
25 indirizzi, variabili proprie e sarà eseguito in maniera completamente
26 indipendente da tutti gli altri.
28 Anche quando all'interno di un programma possono essere presenti più
29 \textsl{filoni} di esecuzione (i cosiddetti \textit{thread}), o questo possa
30 essere composto da moduli multipli completamente separati, quando questo sarà
31 posto in esecuzione esso apparirà al sistema come un solo processo (il
32 discorso dei \textit{thread} comunque in linux necessita di una trattazione a
33 parte per la peculiarità dell'implementazione).
35 \section{La funzione \texttt{main}}
38 Quando un programma viene lanciato il kernel esegue una opportuna routine di
39 avvio, usando il programma \texttt{ld-linux.so}, è questo programma che prima
40 carica le librerie condivise che servono al programma, effettua il link
41 dinamico del codice e poi alla fine lo esegue. Infatti, a meno di non aver
42 specificato il flag \texttt{-static} durante la compilazione, tutti i
43 programmi in linux sono incompleti e necessitano di essere linkati alle
44 librerie condivise quando vengono avviati. La procedura è controllata da
45 alcune variabili di ambiente e dal contenuto di \texttt{/etc/ld.so.conf}, i
46 dettagli sono riportati nella man page di \texttt{ld.so}.
48 Il sistema fa partire qualunque programma chiamando la funzione \texttt{main};
49 sta al programmatore chiamare così la funzione principale del programma da cui
50 si suppone iniziale l'esecuzione; in ogni caso senza questa funzione lo stesso
51 linker darebbe luogo ad errori.
53 Lo stadard ISO C specifica che la funzione \texttt{main} può o non avere
54 argomenti o prendere due argomenti che rappresentano gli argomenti passati da
55 linea di comando, in sostanza un prototipo che va sempre bene è il seguente:
57 int main (int argc, char *argv[])
60 In realtà nei sistemi unix esiste un'altro modo per definire la funzione
61 \texttt{main}, che prevede la presenza di un terzo parametro, \texttt{char
62 *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{proc_environ}) del
63 programma; questa forma però non è prevista dallo standard POSIX.1 per cui se
64 si vogliono scrivere programmi portabili è meglio evitarla.
67 \subsection{Come chiudere un programma}
68 \label{sec:proc_termination}
70 La via normale per la quale un programma finisce è quando la funzione main
71 ritorna, una modalità equivalente di conclusione è quella di chiamare
72 direttamente la funzione \texttt{exit} (che viene comunque chiamata dalla
73 routine di avvio del programma quando la funzione main ritorna). Una forma
74 alternativa è quella di chiamare direttamente la system call \texttt{\_exit}
75 che passa il controllo direttamente al kernel.
77 Oltre alla conclusione ``normale'' esiste anche la possibilità di una
78 conclusione ``anomala'' del programma a causa di segnali o della chiamata alla
79 funzione \texttt{abort} (che comunque genera un segnale che termina il
80 programma); torneremo su questo in \secref{sec:sig_abort}.
82 Il valore di ritorno della funzione main, o quello usato nelle chiamate ad
83 \texttt{exit} e \texttt{\_exit}, viene chiamato \textit{exit status} e passato
84 al processo padre che aveva lanciato il programma (in genere la shell). In
85 generale si usa questo valore per fornire un'informazione generica sulla
86 riuscita o il fallimento del programma; l'informazione è necessariamente
87 generica, ed il valore deve essere compreso fra 0 e 255.
89 In generale si usa la convenzione di restituire 0 in caso di successo e 1 in
90 caso di fallimento, i programmi che effettuano dei confronti (come
91 \texttt{diff}) usano invece una notazione leggermente diversa, usando 0 per
92 indicare la corrispondenza, 1 per indicare la non corrispondenza e 2 per
93 indicare l'incapacità di effettuare il confronto. È opportuno adottare una di
94 queste convenzioni a seconda dei casi. Si tenga presente che se si raggiunge
95 la fine della funzione \texttt{main} senza ritornare esplicitamente si ha un
96 valore di uscita indefinito, è pertanto consigliabile di concludere sempre in
97 maniera esplicita detta funzione.
99 Una altra convenzione riserva i valori da 128 in sù per usi speciali, ad
100 esempio 128 viene usato per indicare l'incapacità di eseguire un altro
101 programma in un sottoprocesso. Benché anche questa convenzione non sia
102 universalmente seguita è una buona idea tenerne conto.
104 Si tenga presente inoltre che non è una buona idea usare il valore dell'errore
105 restituito dalla variabile \texttt{errno} come stato di uscita, in generale
106 una shell non si cura di tutto questo e comunque il valore dello stato di
107 uscita è sempre troncato ad 8 bit, per cui si potrebbe incorrere nel caso in
108 cui l'errore 256, diventando zero, verrebbe interpretato come un successo. In
109 \texttt{stdlib.h} sono definite due macro \texttt{EXIT\_SUCCESS} e
110 \texttt{EXIT\_FAILURE}, che in linux sono poste rispettivamente ai valori 0 e
111 1 (di tipo \texttt{int}), seguendo lo standard POSIX.
113 Infine occorre distinguere fra lo stato di uscita di un programma
114 (l'\textit{exit status}) e lo stato di conclusione di un processo (il
115 \textit{termination status}), abbiamo già accennato infatti che è comunque
116 possibile un processo possa essere terminato (da un segnale) prima che il
117 programma in esecuzione si sia concluso. In caso di conclusione normale del
118 programma però lo stato di uscita diventa parte dello stato di conclusione del
119 processo (vedi \secref{sec:prochand_XXX}).
122 \subsection{Le funzioni \texttt{exit} e \texttt{\_exit}}
123 \label{sec:proc_exit}
125 Come accennato funzioni per l'uscita ``normale'' da un programma sono due, la
126 prima è la funzione \texttt{exit} che è definita dallo standard ANSI C, il
127 prototipo della funzione è il seguente:
128 \begin{prototype}{stdlib.h}{void exit(int status)}
129 Causa la conclusione ordinaria del programma restituendo il valore
130 \texttt{status} al processo padre.
132 La funzione non ritorna. Il processo viene terminato
135 La funzione \texttt{exit} è pensata per una conclusione pulita di un programma
136 che usa le librerie standard del C; essa esegue tutte le funzioni che sono
137 state registrate con \texttt{atexit} e \texttt{on\_exit} (vedi
138 \secref{sec:proc_atexit}), e chiude tutti gli stream di I/O effettuando il
139 salvataggio dei dati sospesi (chiamando \texttt{fclose}, vedi
140 \secref{sec:filestd_close}), infine ripassa il controllo al kernel chiamando
141 \texttt{\_exit} e passando il valore \texttt{status} come stato di uscita.
143 La system call \texttt{\_exit} restituisce direttamente il controllo al
144 kernel, concludendo immediatamente il processo, le eventuali funzioni
145 registrate con \texttt{atexit} e \texttt{on\_exit} non vengono eseguite. Il
146 prototipo della funzione è il seguente:
147 \begin{prototype}{unistd.h}{void \_exit(int status)}
148 Causa la conclusione immediata del programma restituendo il valore
149 \texttt{status} al processo padre.
151 La funzione non ritorna. Il processo viene terminato.
154 La funzione chiude tutti i file descriptor appartenenti al processo (sui tenga
155 presente che questo non comporta il salvataggio dei dati bufferizzati degli
156 stream), fa si che ogni figlio del processo sia ereditato da \texttt{init}
157 (vedi \secref{cha:process_handling}), manda un segnale \texttt{SIGCHLD} al
158 processo padre (vedi \ref{sec:sig_sigchild}) ed infine ritorna lo stato di
159 uscita specificato in \texttt{status} che può essere raccolto usando la
160 funzione \texttt{wait} (vedi \secref{sec:prochand_wait}).
163 \subsection{Le funzioni \texttt{atexit} e \texttt{on\_exit}}
164 \label{sec:proc_atexit}
166 Come accennato l'uso di \texttt{exit} al posto della \texttt{\_exit} è fatto
167 principalmente per permettere una uscita pulita dalle funzioni delle librerie
168 standard del C (in particolare per quel che riguarda la chiusura degli
171 Quando si realizza una libreria da usare in varie applicazioni può essere
172 perciò utile evitare di richiedere di chiamare esplicitamente un funzione di
173 uscita che esegua tutte le operazioni di pulizia prima di uscire (come quella
174 di salvare eventuali dati sospesi). È invece molto meno soggetto ad errori e
175 completamente trasparente all'utente poter effettuare una chiamata automatica
176 di una funzione che effettui tali operazioni all'uscita dal programma.
178 A questo scopo lo standard ANSI C prevede la possibilità di registrare un
179 certo numero funzioni che verranno eseguite all'uscita dal programma (sia per
180 la chiamata ad \textit{exit} che per il ritorno di \texttt{main}). La prima
181 funzione che si può utilizzare a tal fine è:
182 \begin{prototype}{stdlib.h}{void atexit(void (*function)(void))}
183 Registra la funzione \texttt{function} per essere chiamata all'uscita dal
186 La funzione restituisce 0 in caso di successo e -1 in caso di fallimento,
187 \texttt{errno} non viene settata.
190 La funzione richiede come argomento l'indirizzo della opportuna da chiamare
191 all'uscita che non deve prendere argomenti e non deve ritornare niente. Una
192 estensione di \texttt{atexit} è la funzione \texttt{on\_exit} (che la glibc
193 include per compatibilità con SunOS e che non è detta sia definita su altri
194 sistemi), il cui prototipo è:
195 \begin{prototype}{stdlib.h}
196 {void on\_exit(void (*function)(int status, void *arg), void *arg)}
197 Registra la funzione \texttt{function} per essere chiamata all'uscita dal
198 programma. Tutte le funzioni registrate vengono chiamate in ordine inverso
199 rispetto a quello di registrazione.
201 La funzione restituisce 0 in caso di successo e -1 in caso di fallimento,
202 \texttt{errno} non viene settata.
205 In questo caso la funzione da chiamare prende due parametri, il primo dei
206 quali sarà inizializzato allo stato di uscita con cui è stata chiamata
207 \texttt{exit} ed il secondo al puntatore generico specificato come secondo
208 argomento nella chiamata di \texttt{on\_exit}.
210 Tutte le funzioni registrate vengono chiamate in ordine inverso rispetto a
211 quello di registrazione (ed una stessa funzione registrata più volte sarà
212 chiamata più volte); poi vengono chiusi tutti gli stream aperti, infine viene
213 chiamata \texttt{\_exit}.
216 \subsection{Conclusioni}
217 \label{sec:proc_term_conclusion}
219 Data l'importanza dell'argomento è opportuno sottolineare ancora una volta che
220 in un sistema unix l'unico modo in cui un programma può essere eseguito dal
221 kernel è attraverso la chiamata alla system call \texttt{execve} (in genere
222 attraveso una delle funzioni \texttt{exec} che vedremo in
223 \secref{sec:prochand_exec}).
225 Allo stesso modo l'unico modo in cui un programma può concludere
226 volontariamente la sua esecuzione è attraverso una chiamata alla system call
227 \texttt{\_exec} sia esplicitamnte o che in maniera indiretta attraverso l'uso
228 di \texttt{exit} o il ritorno della funzione \texttt{main}.
230 Lo schema delle modalità con cui si avvia e conclude normalmente un programma
231 è riportato in \nfig.
236 \caption{Schema dell'avvio e della conclusione di un programma.}
237 \label{fig:proc_prog_start_stop}
240 Si ricordi infine che un programma può anche essere interrotto dall'esterno
241 attraverso l'uso di un segnale (modalità di conclusione non mostrata in
242 \curfig); torneremo su questo aspetto in \secref{cha:signals}.
246 \section{I processi e l'uso della memoria}
247 \label{sec:proc_memory}
249 Una delle risorse base che ciascun processo ha a disposizione è la memoria, ed
250 uno degli aspetti più complessi di un sistema unix (ed in particolar modo di
251 linux) è appunto la gestione della memoria. Qui ci occuperemo però di come la
252 memoria viene vista dal punto di vista di un programma in esecuzione in un
256 \subsection{I concetti generali}
257 \label{sec:proc_mem_gen}
259 Ci sono vari modi in cui i vari sistemi organizzano la memoria (ed i dettagli
260 di basso livello dipendono in maniera diretta dall'architettura
261 dell'hardware), ma quello più tipico, usato da unix (e da linux) è quello di
262 assegnare ad ogni processo uno spazio virtuale di indirizzamento lineare in
263 cui gli indirizzi vanno da zero ad un qualche valore massimo (nel caso di
264 linux fino al kernel 2.2 detto massimo era per macchine a 32bit di 2Gb, con il
265 kernel 2.4 il limite è stato esteso).
267 Come accennato nell'introduzione questo spazio di indirizzi è virtuale e non
268 corrisponde all'effettiva posizione dei dati nella ram del computer; in genere
269 detto spazio non è neanche continuo (cioè non tutti gli indirizzi sono
270 utilizzabili e/o utilizzati).
272 La memoria virtuale viene divisa in pagine (che ad esempio sono di 4kb su
273 macchine a 32 bit e 8kb sulle alpha, valori strettamente connessi all'hardware
274 di gestione della memoria) di dimensione fissa, e ciascuna pagina della
275 memoria virtuale è associata ad un supporto che può essere una pagina di
276 memoria reale o ad un dipositivo di stoccaggio secondario (in genere lo spazio
277 disco riservato alla swap, o i file che contengono il codice).
279 Lo stesso pezzo di memoria reale (o di spazio disco) può fare da supporto a
280 diverse pagine di memoria virtuale appartenenti a processi diversi (come
281 accade in genere per le pagine che contengono il codice delle librerie
282 condivise). Ad esempio il codice della fuzione \texttt{printf} starà su una
283 sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria
284 virtuale di tutti i processi hanno detta funzione nel loro codice.
286 La corrispondenza fra le pagine della memoria virtuale e quelle della memoria
287 fisica della macchina viene gestita in maniera trasparente dall'hardware di
288 gestione della memoria (dalla \textit{Memory Management Unit} del processore),
289 ma poiché in genere quest'ultima è solo una piccola frazione della memoria
290 virtuale è necessario un meccanismo che permetta di trasferire le pagine
291 virtuali che servono dal supporto su cui si trovano in memoria eliminando
292 quelle che non servono. Questo meccanismo è detto \textit{paging}, ed è uno
293 dei compiti principali del kernel.
295 Quando un processo cerca di accedere ad una pagina che non è nella memoria
296 reale avviene quello che viene chiamato un \textit{page fault}, l'hardware di
297 gestione della memoria (la MMU del processore) genera una interruzione e passa
298 il controllo al kernel il quale sospende il processo e si incarica di mettere
299 in ram la pagina richiesta (effettuando tutte le operazioni necessarie per
300 reperire lo spazio necessario), per poi restituire il controllo al
303 Dal punto di vista di un processo questo meccanismo è completamente
304 trasparente e tutto avviene come se tutte le pagine fossero sempre disponibili
305 in memoria. L'unica differenza avvertibile è quella dei tempi di esecuzione,
306 che passano dai pochi nanosecondi necessari per l'accesso a tempi molto più
307 lunghi, dovuti all'intervento del kernel. Normalemente questo è il prezzo da
308 pagare per avere un multitasking reale, ed in genere il sistema è molto
309 efficiente in questo lavoro; quando però ci siano esigenze specifiche di
310 prestazioni è possibile usare delle funzioni che permettono di bloccare il
311 meccanismo del paging e mantenere fisse delle pagine in memoria (vedi
312 \ref{sec:proc_mem_lock}).
315 \subsection{La struttura della memoria di un processo}
316 \label{sec:proc_mem_layout}
318 Benché lo spazio di indirizzi virtuali copra un intervallo molto ampio, solo
319 una parte di essi è effettivamente allocato ed utilizzabile dal processo; il
320 tentativo di accedere ad un indirizzo non allocato è un tipico errore che si
321 commette quando si è manipolato male un puntatore e genera quello che viene
322 chiamato un \textit{segmentation fault}, si tenta cioè di leggere e scrivere
323 da un indirizzo per il quale non esiste una associazione della pagina virtuale
324 ed il kernel riponde al relativo \textit{page fault} mandando un segnale
325 \texttt{SIGSEGV} al processo, che normalmente ne causa la terminazione
328 È pertanto importante capire come viene strutturata la memoria virtuale di un
329 processo; essa viene divisa in \textsl{segmenti}, cioè un insieme contiguo di
330 indirizzi virtuali ai quali il processo può accedere. Storicamente un
331 programma C viene suddiviso nei seguenti segmenti:
334 \item Il segmento di testo (\textit{text segment}). Contiene il codice
335 macchina del programma e le costanti statiche. Normalente viene condiviso
336 così che più processi (anche diversi nel caso di librerie) possano
337 utilizzarlo e marcato in sola lettura per evitare sovrascritture accidentali
338 (o maliziose) che ne modifichino le istruzioni.
340 Viene allocato da \texttt{exec} all'avvio del programma e resta invariato
341 per tutto il tempo dell'esecuzione.
343 \item Il segmento dei dati (\textit{data segment}). Contiene le varibili
344 globali (cioè quelle definite al di fuori di tutte le funzioni). Di norma è
347 La prima è il segmento dei dati inizializzati, che contiene le variabili
348 globali il cui valore è stato assegnato esplicitamente. Ad esempio se si
353 questo valore sarà immagazzinato in questo segmento. La memoria di questo
354 segmento viene preallocato dalla \texttt{exec} e inizializzata ai valori
357 La seconda è il segmento dei dati non inizializzati, che contiene le
358 variabili globali il cui valore è stato non è assegnato esplicitamente. Ad
359 esempio se si definisce:
363 questo valore sarà immagazzinato in questo segmento. Anch'esso viene
364 allocato all'avvio, e tutte le varibili vengono inizializzate a
365 zero (ed i puntatori a \texttt{NULL}).
367 Storicamente questo segmento viene chiamato BBS (da \textit{block started by
368 symbol}. La sua dimensione è fissa.
370 \item Lo \textit{heap}. Tecnicamente lo si può considerare l'estensione del
371 segmento dati, a cui di solito è posto giusto di seguito. È qui che avviene
372 l'allocazione dinamica della memoria; può essere ridimensionato allocando e
373 disallocando la memoria dinamica con le apposite funzioni (vedi
374 \secref{sec:proc_mem_alloc}), ma il suo limite inferiore (quello adiacente
375 al segmento dati) ha una posizione fissa.
377 \item Il segmento di \textit{stack}, che contiene lo \textit{stack} del
378 programma. Tutte le volte che si effettua una chiamata ad una funzione è
379 qui che viene salvato l'indirizzo di ritorno e le informazioni dello stato
380 del chiamante (tipo il contenuto di alcuni registri della CPU); poi la
381 funzione chiamata alloca qui lo spazio per le sue variabili locali, in
382 questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno
383 della funzione lo spazio è automaticamente rilasciato.
385 La dimensione di questo segmento aumenta seguendo la crescita dello stack
386 del programma, ma non viene ridotta quando quest'ultimo si restringe.
392 \caption{Disposizione tipica dei segmenti di memoria di un processo}
393 \label{fig:proc_mem_layout}
396 Una disposizione tipica di questi segmenti è riportata in \nfig. Usando il
397 comando \texttt{size} su un programma se ne può stampare le dimensioni dei
398 segmenti di testo e di dati (inizializzati e BSS); il BSS però non è mai
399 salvato sul file, in quanto viene inizializzato a zero al caricamento del
403 \subsection{La librerie condivise}
404 \label{sec:proc_mem_shlib}
409 \subsection{Allocazione e disallocazione della memoria}
410 \label{sec:proc_mem_alloc}
416 \section{La gestione di parametri e opzioni}
417 \label{sec:parameter_options}
419 Il passaggio dei parametri e delle variabili di ambiente dalla riga di comando
420 al singolo programma quando viene lanciato è effettuato attraverso le
421 variabili \texttt{argc}, \texttt{argv} che vengono passate al programma
422 come argomenti della funzione principale.
424 \subsection{Il formato dei parametri}
425 \label{sec:proc_par_format}
426 In genere passaggio dei parametri al programma viene effettuato dalla shell,
427 che si incarica di leggere la linea di comando e di effettuarne la scansione
428 (il cosiddetto \textit{parsing}) per individuare le parole che la compongono,
429 ciascuna delle quali viene considerata un parametro; di default per
430 individuare le parole viene usato come separatore lo spazio (comportamento
431 modificabile attraverso il settaggio della variabile di ambiente IFS).
433 Nella scansione viene costruito l'array di puntatori \texttt{argv} inserendo
434 in successione il puntatore alla stringa costituente l'$n$-simo parametro; la
435 variabile \texttt{argc} viene inizializzata al numero di parametri trovati, in
436 questo modo il primo parametro è sempre il nome del programma (vedi \nfig).
438 \subsection{La gestione delle opzioni}
439 \label{sec:proc_opt_handling}
441 In generale un programma unix riceve da linea di comando sia i parametri che
442 le opzioni, queste ultime sono standardizzate per essere riconosciute come
443 tali: un elemento di \texttt{argv} che inizia con \texttt{-} e che non sia un
444 singolo \texttt{-} o \texttt{--} viene considerato un'opzione. In in genere
445 le opzioni sono costituite da un lettera preceduta dal meno e possono avere o
446 no un parametro associato; un comando tipico può essere cioè qualcosa del
449 touch -r riferimento.txt -m questofile.txt
451 ed in questo caso le opzioni sono \texttt{m} ed \texttt{r}.
453 Per gestire le opzioni all'interno dei parametri passati in \texttt{argv} le
454 librerie standard del C forniscono la funzione \texttt{getopt} (accessibile
455 includendo \texttt{unistd.h}), che ha il prototipo:
457 int getopt(int argc, char * const argv[], const char * optstring);
460 Questa funzione prende come argomenti le due variabili \texttt{argc} e
461 \texttt{argv} ed una stringa che indica quali sono le opzioni valide; la
462 funzione effettua la scansione della lista dei parametri ricercando ogni
463 stringa che comincia con \texttt{-} e ritorna ogni volta che trova una opzione
466 La stringa \texttt{optstring} indica quali sono le opzioni riconosciute ed è
467 costituita da tutti i caratteri usati per identificare le singole opzioni, se
468 l'opzione ha un parametro al carattere deve essere fatto seguire un segno di
469 due punti \texttt{:} nel caso appena accennato ad esempio la stringa di
470 opzioni sarebbe \texttt{"r:m"}.
472 La modalità di uso è pertanto quella di chiamare più volte la funzione
473 all'interno di un ciclo di while fintanto che essa non ritorna il valore
474 \texttt{-1} che indica che non ci sono più opzioni. Nel caso si incontri
475 un'opzione non dichiarata in \texttt{optstring} viene ritornato un \texttt{?}
476 mentre se l'opzione non è seguita da un parametro viene ritornato un
477 \texttt{:} infine se viene incontrato il valore \texttt{--} la scansione viene
478 considerata conclusa.
480 Quando la funzione trova un'opzione essa ritorna il valore numerico del
481 carattere, in questo modo si possono prendere le azioni relative usando un
482 case; la funzione inizializza inoltre alcune varibili globali:
484 \item \texttt{char * optarg} contiene il puntatore alla stringa argomento
486 \item \texttt{int optind} alla fine della scansione restituisce l'indice del
487 primo argomento che non è un'opzione.
488 \item \texttt{int opterr} previene, se posto a zero, la stampa di un messaggio
489 di errore in caso di riconoscimento di opzioni non definite.
490 \item \texttt{int optopt} contiene il carattere dell'opzione non riconosciuta.
493 In \nfig è mostrato un programma di esempio,
499 opterr = 0; /* don't want writing to stderr */
500 while ( (i = getopt(argc, argv, "o:a:i:hve")) != -1) {
502 case 'i': /* input file */
503 in_file=open(optarg,O_RDONLY);
505 perror("Cannot open input file");
509 case 'o': /* output file (overwrite) */
510 out_file=open(optarg,O_WRONLY|O_CREAT);
512 perror("Cannot open output file");
517 case 'a': /* output file (append) */
518 out_file=open(optarg,O_WRONLY|O_CREAT|O_APPEND);
520 case 'h': /* print help usage */
523 case 'v': /* set verbose mode */
524 debug("Option -v active\n");
527 case '?': /* unrecognized options */
528 printf("Unrecognized options -%c\n",optopt);
530 default: /* should not reached */
531 debug("default option\n");
535 debug("Optind %d, argc %d\n",optind,argc);
537 \caption{Esempio di codice per la gestione delle opzioni.}
538 \label{fig:proc_options_code}
541 \subsection{Opzioni in formato esteso}
542 \label{sec:proc_opt_extended}
544 Un'estensione di questo schema è costituito dalle cosiddette
545 \textit{long-options} espresse nella forma \texttt{--option=parameter}, anche
546 la gestione di queste ultime è stata standardizzata attraverso l'uso di una
547 versione estesa di \texttt{getopt}.
550 \subsection{Le variabili di ambiente}
551 \label{sec:proc_env_var}