esecuzione.
In genere un programma viene eseguito quando un processo lo fa partire
-eseguendo una funzione della famiglia \texttt{exec}; torneremo su questo e
+eseguendo una funzione della famiglia \func{exec}; torneremo su questo e
sulla la creazione e gestione dei processi nel prossimo capitolo, in questo
affronteremo l'avvio e il funzionamento di un singolo processo partendo dal
punto di vista del programma posto in esecuzione.
discorso dei \textit{thread} comunque in Linux necessita di una trattazione a
parte per la peculiarità dell'implementazione).
-\section{La funzione \texttt{main}}
+\subsection{La funzione \func{main}}
\label{sec:proc_main}
Quando un programma viene lanciato il kernel esegue una opportuna routine di
-avvio, usando il programma \texttt{ld-linux.so}, è questo programma che prima
+avvio, usando il programma \cmd{ld-linux.so}, è questo programma che prima
carica le librerie condivise che servono al programma, effettua il link
dinamico del codice e poi alla fine lo esegue. Infatti, a meno di non aver
specificato il flag \texttt{-static} durante la compilazione, tutti i
programmi in Linux sono incompleti e necessitano di essere linkati alle
librerie condivise quando vengono avviati. La procedura è controllata da
-alcune variabili di ambiente e dal contenuto di \texttt{/etc/ld.so.conf}, i
-dettagli sono riportati nella man page di \texttt{ld.so}.
+alcune variabili di ambiente e dal contenuto di \file{/etc/ld.so.conf}, i
+dettagli sono riportati nella man page di \cmd{ld.so}.
-Il sistema fa partire qualunque programma chiamando la funzione \texttt{main};
+Il sistema fa partire qualunque programma chiamando la funzione \func{main};
sta al programmatore chiamare così la funzione principale del programma da cui
si suppone iniziale l'esecuzione; in ogni caso senza questa funzione lo stesso
linker darebbe luogo ad errori.
-Lo standard ISO C specifica che la funzione \texttt{main} può non avere
+Lo standard ISO C specifica che la funzione \func{main} può non avere
argomenti o prendere due argomenti che rappresentano gli argomenti passati da
linea di comando, in sostanza un prototipo che va sempre bene è il seguente:
\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
\end{lstlisting}
In realtà nei sistemi unix esiste un'altro modo per definire la funzione
-\texttt{main}, che prevede la presenza di un terzo parametro, \texttt{char
+\func{main}, che prevede la presenza di un terzo parametro, \var{char
*envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{sec:proc_environ})
del programma; questa forma però non è prevista dallo standard POSIX.1 per cui
se si vogliono scrivere programmi portabili è meglio evitarla.
\subsection{Come chiudere un programma}
\label{sec:proc_termination}
-La via normale per la quale un programma finisce è quando la funzione main
-ritorna, una modalità equivalente di conclusione è quella di chiamare
-direttamente la funzione \texttt{exit} (che viene comunque chiamata dalla
-routine di avvio del programma quando la funzione main ritorna). Una forma
-alternativa è quella di chiamare direttamente la system call \texttt{\_exit}
-che passa il controllo direttamente al kernel.
+La via normale per la quale un programma finisce è quando la funzione
+\func{main} ritorna, una modalità equivalente di conclusione è quella di
+chiamare direttamente la funzione \func{exit} (che viene comunque chiamata
+dalla routine di avvio del programma quando la funzione \func{main} ritorna).
+Una forma alternativa è quella di chiamare direttamente la system call
+\func{\_exit} che passa il controllo direttamente al kernel.
Oltre alla conclusione ``normale'' esiste anche la possibilità di una
conclusione ``anomala'' del programma a causa di segnali o della chiamata alla
-funzione \texttt{abort} (che comunque genera un segnale che termina il
+funzione \func{abort} (che comunque genera un segnale che termina il
programma); torneremo su questo in \secref{sec:sig_prog_error}.
Il valore di ritorno della funzione main, o quello usato nelle chiamate ad
-\texttt{exit} e \texttt{\_exit}, viene chiamato \textit{exit status} e passato
+\func{exit} e \func{\_exit}, viene chiamato \textit{exit status} e passato
al processo padre che aveva lanciato il programma (in genere la shell). In
generale si usa questo valore per fornire un'informazione generica sulla
riuscita o il fallimento del programma; l'informazione è necessariamente
In generale si usa la convenzione di restituire 0 in caso di successo e 1 in
caso di fallimento, i programmi che effettuano dei confronti (come
-\texttt{diff}) usano invece una notazione leggermente diversa, usando 0 per
+\cmd{diff}) usano invece una notazione leggermente diversa, usando 0 per
indicare la corrispondenza, 1 per indicare la non corrispondenza e 2 per
indicare l'incapacità di effettuare il confronto. È opportuno adottare una di
queste convenzioni a seconda dei casi. Si tenga presente che se si raggiunge
-la fine della funzione \texttt{main} senza ritornare esplicitamente si ha un
+la fine della funzione \func{main} senza ritornare esplicitamente si ha un
valore di uscita indefinito, è pertanto consigliabile di concludere sempre in
maniera esplicita detta funzione.
universalmente seguita è una buona idea tenerne conto.
Si tenga presente inoltre che non è una buona idea usare il valore dell'errore
-restituito dalla variabile \texttt{errno} come stato di uscita, in generale
+restituito dalla variabile \var{errno} come stato di uscita, in generale
una shell non si cura di tutto questo e comunque il valore dello stato di
uscita è sempre troncato ad 8 bit, per cui si potrebbe incorrere nel caso in
cui l'errore 256, diventando zero, verrebbe interpretato come un successo. In
-\texttt{stdlib.h} sono definite due macro \texttt{EXIT\_SUCCESS} e
-\texttt{EXIT\_FAILURE}, che in Linux sono poste rispettivamente ai valori 0 e
-1 (di tipo \texttt{int}), seguendo lo standard POSIX.
+\file{stdlib.h} sono definite due macro \macro{EXIT\_SUCCESS} e
+\macro{EXIT\_FAILURE}, che in Linux sono poste rispettivamente ai valori 0 e
+1 (di tipo \type{int}), seguendo lo standard POSIX.
Infine occorre distinguere fra lo stato di uscita di un programma
(l'\textit{exit status}) e lo stato di conclusione di un processo (il
processo (vedi \secref{sec:proc_xxx}).
-\subsection{Le funzioni \texttt{exit} e \texttt{\_exit}}
+\subsection{Le funzioni \func{exit} e \func{\_exit}}
\label{sec:proc_exit}
Come accennato funzioni per l'uscita ``normale'' da un programma sono due, la
-prima è la funzione \texttt{exit} che è definita dallo standard ANSI C; il
+prima è la funzione \func{exit} che è definita dallo standard ANSI C; il
prototipo della funzione è il seguente:
\begin{prototype}{stdlib.h}{void exit(int status)}
Causa la conclusione ordinaria del programma restituendo il valore
- \texttt{status} al processo padre.
+ \var{status} al processo padre.
La funzione non ritorna. Il processo viene terminato
\end{prototype}
-La funzione \texttt{exit} è pensata per una conclusione pulita di un programma
+La funzione \func{exit} è pensata per una conclusione pulita di un programma
che usa le librerie standard del C; essa esegue tutte le funzioni che sono
-state registrate con \texttt{atexit} e \texttt{on\_exit} (vedi
+state registrate con \func{atexit} e \func{on\_exit} (vedi
\secref{sec:proc_atexit}), e chiude tutti gli stream di I/O effettuando il
-salvataggio dei dati sospesi (chiamando \texttt{fclose}, vedi
+salvataggio dei dati sospesi (chiamando \func{fclose}, vedi
\secref{sec:file_fclose}), infine ripassa il controllo al kernel chiamando
-\texttt{\_exit} e passando il valore \texttt{status} come stato di uscita.
+\func{\_exit} e passando il valore \var{status} come stato di uscita.
-La system call \texttt{\_exit} restituisce direttamente il controllo al
+La system call \func{\_exit} restituisce direttamente il controllo al
kernel, concludendo immediatamente il processo, le eventuali funzioni
-registrate con \texttt{atexit} e \texttt{on\_exit} non vengono eseguite. Il
+registrate con \func{atexit} e \func{on\_exit} non vengono eseguite. Il
prototipo della funzione è il seguente:
\begin{prototype}{unistd.h}{void \_exit(int status)}
Causa la conclusione immediata del programma restituendo il valore
- \texttt{status} al processo padre.
+ \var{status} al processo padre.
La funzione non ritorna. Il processo viene terminato.
\end{prototype}
La funzione chiude tutti i file descriptor appartenenti al processo (sui tenga
presente che questo non comporta il salvataggio dei dati bufferizzati degli
-stream), fa si che ogni figlio del processo sia ereditato da \texttt{init}
-(vedi \secref{cha:process_handling}), manda un segnale \texttt{SIGCHLD} al
+stream), fa si che ogni figlio del processo sia ereditato da \cmd{init}
+(vedi \secref{cha:process_handling}), manda un segnale \macro{SIGCHLD} al
processo padre (vedi \ref{sec:sig_job_control}) ed infine ritorna lo stato di
-uscita specificato in \texttt{status} che può essere raccolto usando la
-funzione \texttt{wait} (vedi \secref{sec:proc_wait}).
+uscita specificato in \var{status} che può essere raccolto usando la
+funzione \func{wait} (vedi \secref{sec:proc_wait}).
-\subsection{Le funzioni \texttt{atexit} e \texttt{on\_exit}}
+\subsection{Le funzioni \func{atexit} e \func{on\_exit}}
\label{sec:proc_atexit}
-Come accennato l'uso di \texttt{exit} al posto della \texttt{\_exit} è fatto
+Come accennato l'uso di \func{exit} al posto della \func{\_exit} è fatto
principalmente per permettere una uscita pulita dalle funzioni delle librerie
standard del C (in particolare per quel che riguarda la chiusura degli
stream).
A questo scopo lo standard ANSI C prevede la possibilità di registrare un
certo numero funzioni che verranno eseguite all'uscita dal programma (sia per
-la chiamata ad \textit{exit} che per il ritorno di \texttt{main}). La prima
+la chiamata ad \func{exit} che per il ritorno di \func{main}). La prima
funzione che si può utilizzare a tal fine è:
\begin{prototype}{stdlib.h}{void atexit(void (*function)(void))}
- Registra la funzione \texttt{function} per essere chiamata all'uscita dal
+ Registra la funzione \var{function} per essere chiamata all'uscita dal
programma.
La funzione restituisce 0 in caso di successo e -1 in caso di fallimento,
La funzione richiede come argomento l'indirizzo della opportuna da chiamare
all'uscita che non deve prendere argomenti e non deve ritornare niente. Una
-estensione di \texttt{atexit} è la funzione \texttt{on\_exit} (che la glibc
+estensione di \func{atexit} è la funzione \func{on\_exit} (che la glibc
include per compatibilità con SunOS e che non è detto sia definita su altri
sistemi), il cui prototipo è:
\begin{prototype}{stdlib.h}
{void on\_exit(void (*function)(int status, void *arg), void *arg)}
- Registra la funzione \texttt{function} per essere chiamata all'uscita dal
+ Registra la funzione \var{function} per essere chiamata all'uscita dal
programma. Tutte le funzioni registrate vengono chiamate in ordine inverso
rispetto a quello di registrazione.
La funzione restituisce 0 in caso di successo e -1 in caso di fallimento,
- \texttt{errno} non viene settata.
+ \var{errno} non viene settata.
\end{prototype}
In questo caso la funzione da chiamare prende due parametri, il primo dei
quali sarà inizializzato allo stato di uscita con cui è stata chiamata
-\texttt{exit} ed il secondo al puntatore generico specificato come secondo
-argomento nella chiamata di \texttt{on\_exit}.
+\func{exit} ed il secondo al puntatore generico specificato come secondo
+argomento nella chiamata di \func{on\_exit}.
Nella sequenza di chiusura tutte le funzioni registrate verranno chiamate in
ordine inverso rispetto a quello di registrazione (ed una stessa funzione
registrata più volte sarà chiamata più volte); poi verranno chiusi tutti gli
-stream aperti, infine verrà chiamata \texttt{\_exit}.
+stream aperti, infine verrà chiamata \func{\_exit}.
\subsection{Conclusioni}
Data l'importanza dell'argomento è opportuno sottolineare ancora una volta che
in un sistema unix l'unico modo in cui un programma può essere eseguito dal
-kernel è attraverso la chiamata alla system call \texttt{execve} (in genere
-attraverso una delle funzioni \texttt{exec} che vedremo in
+kernel è attraverso la chiamata alla system call \func{execve} (in genere
+attraverso una delle funzioni \func{exec} che vedremo in
\secref{sec:proc_exec}).
Allo stesso modo l'unico modo in cui un programma può concludere
volontariamente la sua esecuzione è attraverso una chiamata alla system call
-\texttt{\_exit} sia esplicitamente o che in maniera indiretta attraverso l'uso
-di \texttt{exit} o il ritorno della funzione \texttt{main}.
+\func{\_exit} sia esplicitamente o che in maniera indiretta attraverso l'uso
+di \func{exit} o il ritorno della funzione \func{main}.
Lo schema delle modalità con cui si avvia e conclude normalmente un programma
è riportato in \nfig.
Lo stesso pezzo di memoria reale (o di spazio disco) può fare da supporto a
diverse pagine di memoria virtuale appartenenti a processi diversi (come
accade in genere per le pagine che contengono il codice delle librerie
-condivise). Ad esempio il codice della funzione \texttt{printf} starà su una
+condivise). Ad esempio il codice della funzione \func{printf} starà su una
sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria
virtuale di tutti i processi hanno detta funzione nel loro codice.
chiamato un \textit{segmentation fault}. Se si tenta cioè di leggere o
scrivere da un indirizzo per il quale non esiste una associazione della pagina
virtuale il kernel risponde al relativo \textit{page fault}, mandando un
-segnale \texttt{SIGSEGV} al processo, che normalmente ne causa la terminazione
+segnale \macro{SIGSEGV} al processo, che normalmente ne causa la terminazione
immediata.
È pertanto importante capire come viene strutturata la memoria virtuale di un
utilizzarlo, e viene marcato in sola lettura per evitare sovrascritture
accidentali (o maliziose) che ne modifichino le istruzioni.
- Viene allocato da \texttt{exec} all'avvio del programma e resta invariato
+ Viene allocato da \func{exec} all'avvio del programma e resta invariato
per tutto il tempo dell'esecuzione.
\item Il segmento dei dati (\textit{data segment}). Contiene le variabili
double pi = 3.14;
\end{lstlisting}
questo valore sarà immagazzinato in questo segmento. La memoria di questo
- segmento viene preallocato dalla \texttt{exec} e inizializzata ai valori
+ segmento viene preallocato dalla \func{exec} e inizializzata ai valori
specificati.
La seconda parte è il segmento dei dati non inizializzati, che contiene le
\end{lstlisting}
questo valore sarà immagazzinato in questo segmento. Anch'esso viene
allocato all'avvio, e tutte le variabili vengono inizializzate a
- zero (ed i puntatori a \texttt{NULL}).
+ zero (ed i puntatori a \macro{NULL}).
Storicamente questo segmento viene chiamato BBS (da \textit{block started by
symbol}. La sua dimensione è fissa.
\end{figure}
Una disposizione tipica di questi segmenti è riportata in \nfig. Usando il
-comando \texttt{size} su un programma se ne può stampare le dimensioni dei
+comando \cmd{size} su un programma se ne può stampare le dimensioni dei
segmenti di testo e di dati (inizializzati e BSS); il BSS però non è mai
salvato sul file, in quanto viene inizializzato a zero al caricamento del
programma.
quella in cui vanno le variabili globali e le variabili statiche (e viene
effettuata nel segmento dei dati), lo spazio per queste variabili viene
allocati all'avvio del programma (come parte delle operazioni svolte da
-\texttt{exec}) e non viene liberato fino alla sua conclusione.
+\func{exec}) e non viene liberato fino alla sua conclusione.
L'allocazione automatica è quella che avviene per le cosiddette variabili
automatiche, cioè gli argomenti delle funzioni o le variabili locali. Lo
possano essere modificate durante l'esecuzione del programma; però le librerie
del C forniscono una serie opportuna di funzioni per permettere l'allocazione
dinamica di spazio in memoria (in genere nello heap, usando la system call
-\texttt{sbrk}), solo che a questo punto detto spazio sarà accessibile solo in
+\func{sbrk}), solo che a questo punto detto spazio sarà accessibile solo in
maniera indiretta attraverso dei puntatori.
-\subsection{Le funzioni \texttt{malloc}, \texttt{calloc}, \texttt{realloc} e
- \texttt{free}}
+\subsection{Le funzioni \func{malloc}, \func{calloc}, \func{realloc} e
+ \func{free}}
\label{sec:proc_mem_malloc}
Le funzioni previste dallo standard ANSI C per la gestione della memoria sono
\begin{functions}
\headdecl{stdlib.h}
\funcdecl{void *calloc(size\_t size)}
- Alloca \texttt{size} bytes nello heap. La memoria viene inizializzata a 0.
+ Alloca \var{size} bytes nello heap. La memoria viene inizializzata a 0.
La funzione restituisce il puntatore alla zona di memoria allocata in caso
- di successo e \texttt{NULL} in caso di fallimento, nel qual caso
- \texttt{errno} viene settata a \texttt{ENOMEM}.
+ di successo e \macro{NULL} in caso di fallimento, nel qual caso
+ \var{errno} viene settata a \macro{ENOMEM}.
\funcdecl{void *malloc(size\_t size)}
- Alloca \texttt{size} bytes nello heap. La memoria non viene inizializzata.
+ Alloca \var{size} bytes nello heap. La memoria non viene inizializzata.
La funzione restituisce il puntatore alla zona di memoria allocata in caso
- di successo e \texttt{NULL} in caso di fallimento, nel qual caso
- \texttt{errno} viene settata a \texttt{ENOMEM}.
+ di successo e \macro{NULL} in caso di fallimento, nel qual caso
+ \var{errno} viene settata a \macro{ENOMEM}.
\funcdecl{void *realloc(void *ptr, size\_t size)}
- Cambia la dimensione del blocco allocato all'indirizzo \texttt{ptr}
- portandola a \texttt{size}.
+ Cambia la dimensione del blocco allocato all'indirizzo \var{ptr}
+ portandola a \var{size}.
La funzione restituisce il puntatore alla zona di memoria allocata in caso
- di successo e \texttt{NULL} in caso di fallimento, nel qual caso
- \texttt{errno} viene settata a \texttt{ENOMEM}.
+ di successo e \macro{NULL} in caso di fallimento, nel qual caso
+ \var{errno} viene settata a \macro{ENOMEM}.
\funcdecl{void free(void *ptr)}
- Disalloca lo spazio di memoria puntato da \texttt{ptr}.
+ Disalloca lo spazio di memoria puntato da \var{ptr}.
La funzione non ritorna nulla.
\end{functions}
macchine a 32 bit in genere è allineato a multipli di 4 byte e sulle macchine
a 64 bit a multipli di 8 byte.
-In genere su usano le funzioni \texttt{malloc} e \texttt{calloc} per allocare
+In genere su usano le funzioni \func{malloc} e \func{calloc} per allocare
dinamicamente la memoria necessaria al programma, siccome i puntatori
ritornati sono di tipo generico non è necessario effettuare un cast per
assegnarli a puntatori al tipo di variabile per la quale si effettua la
allocazione.
La memoria allocata dinamicamente deve essere esplicitamente rilasciata usando
-\texttt{free}\footnote{le glibc provvedono anche una funzione \texttt{cfree}
+\func{free}\footnote{le glibc provvedono anche una funzione \func{cfree}
defininita per compatibilità con SunOS, che è deprecata} una volta che non
sia più necessaria. Questa funzione vuole come parametro un puntatore
restituito da una precedente chiamata a una qualunque delle funzioni di
allocazione e che non sia già stato liberato da un'altra chiamata a
-\texttt{free}, in caso contrario il comportamento della funzione è indefinito.
+\func{free}, in caso contrario il comportamento della funzione è indefinito.
-La funzione \texttt{realloc} si usa invece per cambiare (in genere aumentare)
+La funzione \func{realloc} si usa invece per cambiare (in genere aumentare)
la dimensione di un'area di memoria precedentemente allocata, la funzione
vuole in ingresso il puntatore restituito dalla precedente chiamata ad una
-\texttt{malloc} (se è passato un valore \texttt{NULL} allora la funzione si
-comporta come \texttt{malloc}\footnote{questo è vero per linux e
+\func{malloc} (se è passato un valore \macro{NULL} allora la funzione si
+comporta come \func{malloc}\footnote{questo è vero per linux e
l'implementazione secondo lo standard ANSI C, ma non è vero per alcune
vecchie implementazioni, inoltre alcune versioni delle librerie del C
- consentivano di usare \texttt{realloc} anche per un puntatore liberato con
- \texttt{free} purché non ci fossero state altre chiamate a funzioni di
+ consentivano di usare \func{realloc} anche per un puntatore liberato con
+ \func{free} purché non ci fossero state altre chiamate a funzioni di
allocazione, questa funzionalità è totalmente deprecata e non è consentita
sotto linux}), ad esempio quando si deve far crescere la dimensione di un
vettore; in questo caso se è disponibile dello spazio adiacente al precedente
ridimensionare.
Uno degli errori più comuni (specie se si ha a che fare con array di
-puntatori) è infatti quello di chiamare \texttt{free} più di una volta sullo
+puntatori) è infatti quello di chiamare \func{free} più di una volta sullo
stesso puntatore; per evitare questo problema una soluzione di ripiego è
-quella di assegnare sempre a \texttt{NULL} ogni puntatore liberato con
-\texttt{free}, dato che, quando il parametro è un puntatore nullo,
-\texttt{free} non esegue nessuna operazione.
+quella di assegnare sempre a \macro{NULL} ogni puntatore liberato con
+\func{free}, dato che, quando il parametro è un puntatore nullo,
+\func{free} non esegue nessuna operazione.
Linux e le glibc hanno una implementazione delle routine di allocazione che è
controllabile dall'utente attraverso alcune variabili di ambiente, in
particolare diventa possibile tracciare questo tipo di errori usando la
-variabile \texttt{MALLOC\_CHECK\_} che quando viene settata mette in uso una
+variabile \macro{MALLOC\_CHECK\_} che quando viene settata mette in uso una
versione meno efficiente delle funzioni, che però è più tollerante nei
-confronti di piccoli errori come quello di chiamate doppie a \texttt{free}; in
-particolare se la variabile è posta a zero gli errori vengono ignorati, se è
-posta ad 1 viene stampato un avviso sullo standard error e se
+confronti di piccoli errori come quello di chiamate doppie a \func{free}; in
+particolare:
+\begin{itemize}
+\item se la variabile è posta a zero gli errori vengono ignorati.
+\item se è posta ad 1 viene stampato un avviso sullo \textit{standard error}
+ (vedi \secref{sec:file_stdfiles}).
+\item se è posta a 2 viene chiamata \func{abort}, che in genere causa
+ l'immediata conclusione del programma.
+\end{itemize}
Il problema più comune e più difficile da tracciare che si incontra con
l'allocazione della memoria è però quando la memoria non più utilizzata non
Il passaggio dei parametri e delle variabili di ambiente dalla riga di comando
al singolo programma quando viene lanciato è effettuato attraverso le
-variabili \texttt{argc}, \texttt{argv} che vengono passate al programma
+variabili \var{argc}, \var{argv} che vengono passate al programma
come argomenti della funzione principale.
\subsection{Il formato dei parametri}
individuare le parole viene usato come separatore lo spazio (comportamento
modificabile attraverso il settaggio della variabile di ambiente IFS).
-Nella scansione viene costruito il vettore di puntatori \texttt{argv} inserendo
+Nella scansione viene costruito il vettore di puntatori \var{argv} inserendo
in successione il puntatore alla stringa costituente l'$n$-simo parametro; la
-variabile \texttt{argc} viene inizializzata al numero di parametri trovati, in
+variabile \var{argc} viene inizializzata al numero di parametri trovati, in
questo modo il primo parametro è sempre il nome del programma (vedi \nfig).
\subsection{La gestione delle opzioni}
In generale un programma unix riceve da linea di comando sia i parametri che
le opzioni, queste ultime sono standardizzate per essere riconosciute come
-tali: un elemento di \texttt{argv} che inizia con \texttt{-} e che non sia un
+tali: un elemento di \var{argv} che inizia con \texttt{-} e che non sia un
singolo \texttt{-} o \texttt{--} viene considerato un'opzione. In in genere
le opzioni sono costituite da una lettera preceduta dal meno e possono avere o
no un parametro associato; un comando tipico può essere cioè qualcosa del
\end{verbatim}
ed in questo caso le opzioni sono \texttt{m} ed \texttt{r}.
-Per gestire le opzioni all'interno dei parametri passati in \texttt{argv} le
-librerie standard del C forniscono la funzione \texttt{getopt} (accessibile
-includendo \texttt{unistd.h}), che ha il prototipo:
-\begin{verbatim}
-int getopt(int argc, char * const argv[], const char * optstring);
-\end{verbatim}
+Per gestire le opzioni all'interno dei parametri passati in \func{argv} le
+librerie standard del C forniscono la funzione \func{getopt} che ha il
+prototipo:
+\begin{prototype}{unistd.h}
+{int getopt(int argc, char * const argv[], const char * optstring)}
+La funzione esegue il parsing degli argomenti passati da linea di comando
+riconoscendo le possibili opzioni segnalate con \var{optstring}.
+
+Ritorna il carattere che segue l'opzione, \cmd{:} se manca un paramatro
+all'opzione, \cmd{?} se l'opzione è sconosciuta, e -1 se non esistono altre
+opzioni.
+\end{prototype}
-Questa funzione prende come argomenti le due variabili \texttt{argc} e
-\texttt{argv} ed una stringa che indica quali sono le opzioni valide; la
+Questa funzione prende come argomenti le due variabili \var{argc} e
+\var{argv} ed una stringa che indica quali sono le opzioni valide; la
funzione effettua la scansione della lista dei parametri ricercando ogni
-stringa che comincia con \texttt{-} e ritorna ogni volta che trova una opzione
+stringa che comincia con \cmd{-} e ritorna ogni volta che trova una opzione
valida.
-La stringa \texttt{optstring} indica quali sono le opzioni riconosciute ed è
+La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è
costituita da tutti i caratteri usati per identificare le singole opzioni, se
l'opzione ha un parametro al carattere deve essere fatto seguire un segno di
due punti \texttt{:} nel caso appena accennato ad esempio la stringa di
un'opzione non dichiarata in \texttt{optstring} viene ritornato un \texttt{?}
mentre se l'opzione non è seguita da un parametro viene ritornato un
\texttt{:} infine se viene incontrato il valore \texttt{--} la scansione viene
-considerata conclusa.
+considerata conclusa, anche se vi sono altri parametri che cominciano con
+\texttt{-}.
Quando la funzione trova un'opzione essa ritorna il valore numerico del
carattere, in questo modo si possono prendere le azioni relative usando un
\item \texttt{int optopt} contiene il carattere dell'opzione non riconosciuta.
\end{itemize}
-In \nfig\ è mostrato un programma di esempio,
-
+In \nfig\ è mostrato un programma di esempio:
\begin{figure}[htbp]
\footnotesize
\begin{lstlisting}{}
Un'estensione di questo schema è costituito dalle cosiddette
\textit{long-options} espresse nella forma \texttt{--option=parameter}, anche
la gestione di queste ultime è stata standardizzata attraverso l'uso di una
-versione estesa di \texttt{getopt}.
+versione estesa di \func{getopt}.
+(NdA: da finire).
\subsection{Le variabili di ambiente}
\label{sec:proc_environ}
anche altre per una lista parziale si può controllare \cmd{man environ}
-