+\subsection{Gestione avanzata dell'allocazione della memoria}
+\label{sec:proc_memory_adv_management}
+
+La trattazione delle funzioni di allocazione di sez.~\ref{sec:proc_mem_alloc}
+si è limitata a coprire le esigenze generiche di un programma, in cui non si
+hanno dei requisiti specifici e si lascia il controllo delle modalità di
+allocazione alle funzioni di libreria. Tuttavia esistono una serie di casi in
+cui può essere necessario avere un controllo più dettagliato delle modalità
+con cui la memoria viene allocata; nel qual caso potranno venire in aiuto le
+funzioni trattate in questa sezione.
+
+Le prime funzioni che tratteremo sono quelle che consentono di richiedere di
+allocare un blocco di memoria ``\textsl{allineato}'' ad un multiplo una certa
+dimensione. Questo tipo di esigenza emerge usualmente quando si devono
+allocare dei buffer da utilizzare per eseguire dell'I/O diretto su dispositivi
+a blocchi. In questo caso infatti il trasferimento di dati viene eseguito per
+blocchi di dimensione fissa, ed è richiesto che l'indirizzo di partenza del
+buffer sia un multiplo intero di questa dimensione, usualmente 512 byte. In
+tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una
+funzione specifica.
+
+Tradizionalmente per rispondere a questa esigenza sono state crate due
+funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i
+rispettivi prototipi sono:
+\begin{functions}
+ \headdecl{malloc.h}
+
+ \funcdecl{void *valloc(size\_t size)} Alloca un blocco di memoria allineato
+ alla dimensione di una pagina di memoria.
+
+ \funcdecl{void *memalign(size\_t boundary, size\_t size)}
+ Alloca un blocco di memoria allineato ad un multiplo di \param{boundary}.
+
+ \bodydesc{Entrambe le funzioni ritornano un puntatore al blocco di memoria
+ allocato in caso di successo e \val{NULL} in caso di errore, nel qual
+ caso \var{errno} assumerà uno dei valori seguenti:
+ \begin{errlist}
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+ \item[\errcode{EINVAL}] \param{boundary} non è multiplo di due.
+ \end{errlist}
+}
+\end{functions}
+
+Le funzioni restituiscono il puntatore al buffer di memoria allocata, che per
+\func{memalign} sarà un multiplo di \param{boundary} mentre per \func{valloc}
+un multiplo della dimensione di una pagina di memoria. Nel caso della versione
+fornita dalle \acr{glibc} la memoria allocata con queste funzioni deve essere
+liberata con \func{free}, cosa che non è detto accada con altre
+implementazioni.
+
+Nessuna delle due funzioni ha una chiara standardizzazione (nessuna delle due
+compare in POSIX.1), ed inoltre ci sono indicazioni discordi sui file che ne
+contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
+ \texttt{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4} e
+ \acr{lic5} la dichiarano in \texttt{malloc.h}, lo stesso vale per
+ \func{memalign} che in alcuni sistemi è dichiarata in \texttt{stdlib.h}.}
+per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla
+nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo
+prototipo è:
+\begin{prototype}{stdlib.h}{posix\_memalign(void **memptr, size\_t alignment,
+ size\_t size) }
+ Alloca un buffer di memoria allineato ad un multiplo di \param{alignment}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e \val{NULL} in caso
+ di fallimento, o uno dei due codici di errore \errcode{ENOMEM} o
+ \errcode{EINVAL}; \var{errno} non viene impostata.}
+\end{prototype}
+
+La funzione restituisce il puntatore al buffer allocato all'indirizzo indicato
+da \param{memptr}. La funzione fallisce nelle stesse condizioni delle due
+funzioni precedenti, ma a differenza di \func{memalign} restituisce un codice
+di errore \errcode{EINVAL} anche se \param{alignment} non è un multiplo della
+la dimensione di \code{sizeof(void *)}. Come per le precedenti la memoria
+allocata con \func{posix\_memalign} può essere disallocata con
+\func{free}.\footnote{che in questo caso è quanto richiesto dallo standard.}
+
+Un secondo caso in cui risulta estremamente utile poter avere un maggior
+controllo delle modalità di allocazione della memoria è quello in cui cercano
+errori di programmazione. Esempi di questi errori sono chiamate doppie alla
+funzione \func{free} con lo stesso puntatore, o i cosiddetti
+\itindex{buffer~overrun} \textit{buffer overrun}, cioè le scritture su un buffer
+oltre le dimensioni della sua allocazione,\footnote{entrambe queste operazioni
+ causano in genere la corruzione dei dati di controllo delle funzioni di
+ allocazione, che vengono anch'essi mantenuti nello \itindex{heap}
+ \textit{heap} per tenere traccia delle zone di memoria allocata.} o i
+classici \itindex{memory~leak} \textit{memory leak}.
+
+Una prima funzionalità di ausilio nella ricerca di questi errori viene fornita
+dalla \acr{glibc} tramite l'uso della variabile di ambiente
+\var{MALLOC\_CHECK\_}. Quando questa viene definita al posto della versione
+ordinaria delle funzioni di allocazione (\func{malloc}, \func{calloc},
+\func{realloc}, e \func{free}) viene usata una versione meno efficiente ma in
+grado di rilevare (e tollerare) alcuni degli errori più semplici, come le
+doppie chiamate a \func{free} o i \itindex{buffer~overrun} \textit{buffer
+ overrun} di un byte.\footnote{uno degli errori più comuni, causato ad
+ esempio dalla scrittura di una stringa di dimensione pari a quella del
+ buffer, in cui ci si dimentica dello zero di terminazione finale.}
+
+In questo caso a seconda del valore assegnato a \var{MALLOC\_CHECK\_} si
+avranno diversi comportamenti: con 0 l'errore sarà ignorato, con 1 verrà
+stampato un messaggio sullo \textit{standard error} (vedi
+sez.~\ref{sec:file_std_stream}), con 2 verrà invocata la funzione \func{abort}
+(vedi sez.~\ref{sec:sig_alarm_abort}) che termina il programma, con 3 viene
+sia stampato il messaggio d'errore che abortito il programma. In genere è
+opportuno definire la variabile ad un valore diverso da zero che consente di
+rilevare un errore nel momento in cui avviene.
+
+Una modalità alternativa per effettuare dei controlli di consistenza sullo
+stato delle allocazioni di memoria eseguite con \func{malloc}, anche questa
+fornita come estensione specifica (e non standard) delle \acr{glibc}, è quella
+di utilizzare la funzione \funcd{mcheck}, che deve essere chiamata prima di
+eseguire qualunque allocazione con \func{malloc}; il suo prototipo è:
+\begin{prototype}{mcheck.h}{mcheck(void (*abortfn) (enum mcheck\_status
+ status))}
+ Attiva i controlli di consistenza delle allocazioni eseguite da \func{malloc}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+ fallimento; \var{errno} non viene impostata.}
+\end{prototype}
+
+La funzione consente di registrare una funzione di emergenza, da passare come
+argomento, che verrà eseguita tutte le volte che, in una successiva esecuzione
+di \func{malloc}, venissero trovate delle inconsistenze, come delle operazioni
+di scrittura oltre i limiti dei buffer allocati. Per questo motivo la funzione
+deve essere chiamata prima di qualunque allocazione di memoria, altrimenti
+fallirà con un valore di ritorno pari a $-1$.
+
+Se come argomento di \func{mcheck} si passa \var{NULL} verrà utilizzata una
+funzione predefinita che stampa un messaggio di errore ed invoca la funzione
+\func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si dovrà create
+una funzione personalizzata che verrà eseguita ricevendo un unico argomento di
+tipo \type{mcheck\_status},\footnote{trattasi in sostanza di un codice di
+ errore che la funzione di emergenza potrà utilizzare per prendere le
+ opportune azioni.} un tipo enumerato che può assumere soltanto i valori di
+tab.~\ref{tab:mcheck_status_value}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{7cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \macro{MCHECK\_OK} & riportato (a \func{mprobe}) se nessuna
+ inconsistenza è presente.\\
+ \macro{MCHECK\_DISABLED}& riportato (a \func{mprobe}) se si è chiamata
+ \func{mcheck} dopo aver già usato
+ \func{malloc}.\\
+ \macro{MCHECK\_HEAD} & i dati immediatamente precedenti il buffer sono
+ stati modificati, avviene in genere quando si
+ decrementa eccessivamente il valore di un
+ puntatore scrivendo poi prima dell'inizio del
+ buffer.\\
+ \macro{MCHECK\_TAIL} & i dati immediatamente seguenti il buffer sono
+ stati modificati, succede quando si va scrivere
+ oltre la dimensione correttta del buffer.\\
+ \macro{MCHECK\_FREE} & il buffer è già stato disallocato.\\
+ \hline
+ \end{tabular}
+ \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla
+ funzione di teminazione installata con \func{mcheck}.}
+ \label{tab:mcheck_status_value}
+\end{table}
+
+Una volta che si sia chiamata \func{mcheck} con successo si può anche
+controllare esplicitamente lo stato delle allocazioni (senza aspettare un
+errore nelle relative funzioni) utilizzando la funzione \funcd{mprobe}, il cui
+prototipo è:
+\begin{prototype}{mcheck.h}{enum mcheck\_status mprobe(ptr)}
+ Esegue un controllo di consistenza delle allocazioni.
+
+ \bodydesc{La funzione restituisce un codice fra quelli riportati in
+ tab.\ref{tab:mcheck_status_value}.}
+\end{prototype}
+
+La funzione richiede che si passi come argomento un puntatore ad un blocco di
+memoria precedentemente allocato con \func{malloc} o \func{realloc}, e
+restituisce lo stesso codice di errore che si avrebbe per la funzione di
+emergenza ad una successiva chiamata di una funzione di allocazione, e poi i
+primi due codici che indicano rispettivamente quando tutto è a posto o il
+controllo non è possibile per non aver chiamato \func{mcheck} in tempo.
+
+% TODO: trattare le altre funzionalità avanzate di \func{malloc}, mallopt,
+% mtrace, muntrace, mallinfo e gli hook con le glibc 2.10 c'è pure malloc_info
+% a sostituire mallinfo, vedi http://udrepper.livejournal.com/20948.html
+
+
+\section{Argomenti, ambiente ed altre proprietà di un processo}
+\label{sec:proc_options}
+
+
+In questa sezione esamineremo le funzioni che permettono di gestire gli
+argomenti e le opzioni, e quelle che consentono di manipolare ed utilizzare le
+variabili di ambiente. Accenneremo infine alle modalità con cui si può gestire
+la localizzazione di un programma modificandone il comportamento a seconda
+della lingua o del paese a cui si vuole faccia riferimento nelle sue
+operazioni.
+
+\subsection{Il formato degli argomenti}
+\label{sec:proc_par_format}
+
+Tutti i programmi hanno la possibilità di ricevere argomenti e opzioni quando
+vengono lanciati. Il passaggio degli argomenti e delle opzioni è effettuato
+attraverso gli argomenti \param{argc} e \param{argv} della funzione
+\func{main}, che vengono passati al programma dalla shell (o dal processo che
+esegue la \func{exec}, secondo le modalità che vedremo in
+sez.~\ref{sec:proc_exec}) quando questo viene messo in esecuzione.
+
+In genere il passaggio di argomenti ed opzioni ad un programma viene
+effettuato dalla shell, che si incarica di leggere la linea di comando e di
+effettuarne la scansione (il cosiddetto \textit{parsing}) per individuare le
+parole che la compongono, ciascuna delle quali potrà essere considerata un
+argomento o un'opzione. Di norma per individuare le parole che andranno a
+costituire la lista degli argomenti viene usato come carattere di separazione
+lo spazio o il tabulatore, ma la cosa dipende ovviamente dalle modalità con
+cui si effettua la scansione.
+
+\begin{figure}[htb]
+ \centering
+% \includegraphics[width=13cm]{img/argv_argc}
+% \includegraphics[width=13cm]{img/argv_argc}
+ \begin{tikzpicture}[>=stealth]
+ \draw (0.5,2.5) rectangle (3.5,3);
+ \draw (2,2.75) node {\texttt{argc = 5}};
+ \draw (5,2.5) rectangle (8,3);
+ \draw (6.5,2.75) node {\texttt{argv[0]}};
+ \draw [->] (8,2.75) -- (9,2.75);
+ \draw (9,2.75) node [anchor=west] {\texttt{"touch"}};
+ \draw (5,2) rectangle (8,2.5);
+ \draw (6.5,2.25) node {\texttt{argv[1]}};
+ \draw [->] (8,2.25) -- (9,2.25);
+ \draw (9,2.25) node [anchor=west] {\texttt{"-r"}};
+ \draw (5,1.5) rectangle (8,2);
+ \draw (6.5,1.75) node {\texttt{argv[2]}};
+ \draw [->] (8,1.75) -- (9,1.75);
+ \draw (9,1.75) node [anchor=west] {\texttt{"riferimento.txt"}};
+ \draw (5,1.0) rectangle (8,1.5);
+ \draw (6.5,1.25) node {\texttt{argv[3]}};
+ \draw [->] (8,1.25) -- (9,1.25);
+ \draw (9,1.25) node [anchor=west] {\texttt{"-m"}};
+ \draw (5,0.5) rectangle (8,1.0);
+ \draw (6.5,0.75) node {\texttt{argv[4]}};
+ \draw [->] (8,0.75) -- (9,0.75);
+ \draw (9,0.75) node [anchor=west] {\texttt{"questofile.txt"}};
+ \draw (4.25,3.5) node{\texttt{"touch -r riferimento.txt -m questofile.txt"}};
+
+ \end{tikzpicture}
+ \caption{Esempio dei valori di \param{argv} e \param{argc} generati nella
+ scansione di una riga di comando.}
+ \label{fig:proc_argv_argc}
+\end{figure}
+
+Indipendentemente da come viene eseguita, il risultato della scansione deve
+essere la costruzione del vettore di puntatori \param{argv} in cui si devono
+inserire in successione i puntatori alle stringhe costituenti i vari argomenti
+ed opzioni, e della variabile \param{argc} che deve essere inizializzata al
+numero di stringhe passate. Nel caso della shell questo comporta che il primo
+argomento sia sempre il nome del programma; un esempio di questo meccanismo è
+mostrato in fig.~\ref{fig:proc_argv_argc}.
+
+
+\subsection{La gestione delle opzioni}
+\label{sec:proc_opt_handling}
+
+In generale un programma Unix riceve da linea di comando sia gli argomenti che
+le opzioni, queste ultime sono standardizzate per essere riconosciute come
+tali: un elemento di \param{argv} che inizia con il carattere \texttt{'-'} e
+che non sia un singolo \texttt{'-'} o un \texttt{'-{}-'} viene considerato
+un'opzione. In genere le opzioni sono costituite da una lettera singola
+(preceduta dal carattere \cmd{'-'}) e possono avere o no un parametro
+associato; un comando tipico può essere quello mostrato in
+fig.~\ref{fig:proc_argv_argc}. In quel caso le opzioni sono \cmd{-r} e \cmd{-m}
+e la prima vuole un parametro mentre la seconda no (\cmd{questofile.txt} è un
+argomento del programma, non un parametro di \cmd{-m}).
+
+Per gestire le opzioni all'interno dei argomenti a linea di comando passati in
+\param{argv} le librerie standard del C forniscono la funzione \funcd{getopt},
+che ha il seguente prototipo:
+\begin{prototype}{unistd.h}
+{int getopt(int argc, char *const argv[], const char *optstring)}
+Esegue il parsing degli argomenti passati da linea di comando
+riconoscendo le possibili opzioni segnalate con \param{optstring}.
+
+\bodydesc{Ritorna il carattere che segue l'opzione, \cmd{':'} se manca un
+ parametro all'opzione, \cmd{'?'} se l'opzione è sconosciuta, e $-1$ se non
+ esistono altre opzioni.}
+\end{prototype}
+
+Questa funzione prende come argomenti le due variabili \param{argc} e
+\param{argv} passate a \func{main} ed una stringa che indica quali sono le
+opzioni valide; la funzione effettua la scansione della lista degli argomenti
+ricercando ogni stringa che comincia con \cmd{-} e ritorna ogni volta che
+trova un'opzione valida.
+
+La stringa \param{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 di fig.~\ref{fig:proc_argv_argc} ad esempio la
+stringa di opzioni avrebbe dovuto contenere \texttt{"r:m"}.
+
+La modalità di uso di \func{getopt} è pertanto quella di chiamare più volte la
+funzione all'interno di un ciclo, fintanto che essa non ritorna il valore $-1$
+che indica che non ci sono più opzioni. Nel caso si incontri un'opzione non
+dichiarata in \param{optstring} viene ritornato il carattere \texttt{'?'}
+mentre se un'opzione che lo richiede non è seguita da un parametro viene
+ritornato il carattere \texttt{':'}, infine se viene incontrato il valore
+\texttt{'-{}-'} la scansione viene considerata conclusa, anche se vi sono altri
+elementi di \param{argv} che cominciano con il carattere \texttt{'-'}.
+
+\begin{figure}[htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/option_code.c}
+ \end{minipage}
+ \normalsize
+ \caption{Esempio di codice per la gestione delle opzioni.}
+ \label{fig:proc_options_code}
+\end{figure}
+
+Quando la funzione trova un'opzione essa ritorna il valore numerico del
+carattere, in questo modo si possono eseguire azioni specifiche usando uno
+\code{switch}; \func{getopt} inoltre inizializza alcune variabili globali:
+\begin{itemize*}
+\item \var{char *optarg} contiene il puntatore alla stringa parametro
+ dell'opzione.
+\item \var{int optind} alla fine della scansione restituisce l'indice del
+ primo elemento di \param{argv} che non è un'opzione.
+\item \var{int opterr} previene, se posto a zero, la stampa di un messaggio
+ di errore in caso di riconoscimento di opzioni non definite.
+\item \var{int optopt} contiene il carattere dell'opzione non riconosciuta.
+\end{itemize*}
+
+In fig.~\ref{fig:proc_options_code} è mostrata la sezione del programma
+\file{ForkTest.c} (che useremo nel prossimo capitolo per effettuare dei test
+sulla creazione dei processi) deputata alla decodifica delle opzioni a riga di
+comando.
+
+Si può notare che si è anzitutto (\texttt{\small 1}) disabilitata la stampa di
+messaggi di errore per opzioni non riconosciute, per poi passare al ciclo per
+la verifica delle opzioni (\texttt{\small 2-27}); per ciascuna delle opzioni
+possibili si è poi provveduto ad un'azione opportuna, ad esempio per le tre
+opzioni che prevedono un parametro si è effettuata la decodifica del medesimo
+(il cui indirizzo è contenuto nella variabile \var{optarg}) avvalorando la
+relativa variabile (\texttt{\small 12-14}, \texttt{\small 15-17} e
+\texttt{\small 18-20}). Completato il ciclo troveremo in \var{optind} l'indice
+in \code{argv[]} del primo degli argomenti rimanenti nella linea di comando.
+
+Normalmente \func{getopt} compie una permutazione degli elementi di
+\param{argv} cosicché alla fine della scansione gli elementi che non sono
+opzioni sono spostati in coda al vettore. Oltre a questa esistono altre due
+modalità di gestire gli elementi di \param{argv}; se \param{optstring} inizia
+con il carattere \texttt{'+'} (o è impostata la variabile di ambiente
+\macro{POSIXLY\_CORRECT}) la scansione viene fermata non appena si incontra un
+elemento che non è un'opzione.
+
+L'ultima modalità, usata quando un programma può gestire la mescolanza fra
+opzioni e argomenti, ma se li aspetta in un ordine definito, si attiva
+quando \param{optstring} inizia con il carattere \texttt{'-'}. In questo caso
+ogni elemento che non è un'opzione viene considerato comunque un'opzione e
+associato ad un valore di ritorno pari ad 1, questo permette di identificare
+gli elementi che non sono opzioni, ma non effettua il riordinamento del
+vettore \param{argv}.
+
+
+\subsection{Le variabili di ambiente}
+\label{sec:proc_environ}
+
+Oltre agli argomenti passati a linea di comando esiste un'altra modalità che
+permette di trasferire ad un processo delle informazioni in modo da
+modificarne il comportamento. Ogni processo infatti riceve dal sistema, oltre
+alle variabili \param{argv} e \param{argc} anche un \textsl{ambiente} (in
+inglese \textit{environment}); questo viene espresso nella forma di una lista
+(chiamata \textit{environment list}) delle cosiddette \textsl{variabili di
+ ambiente}, i valori di queste variabili possono essere poi usati dal
+programma.
+
+Anche in questo caso la lista delle \textsl{variabili di ambiente} deve essere
+costruita ed utilizzata nella chiamata alla funzione \func{exec} (torneremo su
+questo in sez.~\ref{sec:proc_exec}) quando questo viene lanciato. Come per la
+lista degli argomenti anche questa lista è un vettore di puntatori a
+caratteri, ciascuno dei quali punta ad una stringa, terminata da un
+\val{NULL}. A differenza di \code{argv[]} in questo caso non si ha una
+lunghezza del vettore data da un equivalente di \param{argc}, ma la lista è
+terminata da un puntatore nullo.
+
+L'indirizzo della lista delle variabili di ambiente è passato attraverso la
+variabile globale \var{environ}, che viene definita automaticamente per
+cisascun processo, e a cui si può accedere attraverso una semplice
+dichiarazione del tipo:
+\includecodesnip{listati/env_ptr.c}
+un esempio della struttura di questa lista, contenente alcune delle variabili
+più comuni che normalmente sono definite dal sistema, è riportato in
+fig.~\ref{fig:proc_envirno_list}.
+\begin{figure}[htb]
+ \centering
+% \includegraphics[width=15 cm]{img/environ_var}
+ \begin{tikzpicture}[>=stealth]
+ \draw (2,3.5) node {\textsf{Environment pointer}};
+ \draw (6,3.5) node {\textsf{Environment list}};
+ \draw (10.5,3.5) node {\textsf{Environment string}};
+ \draw (0.5,2.5) rectangle (3.5,3);
+ \draw (2,2.75) node {\texttt{environ}};
+ \draw [->] (3.5,2.75) -- (4.5,2.75);
+ \draw (4.5,2.5) rectangle (7.5,3);
+ \draw (6,2.75) node {\texttt{environ[0]}};
+ \draw (4.5,2) rectangle (7.5,2.5);
+ \draw (6,2.25) node {\texttt{environ[1]}};
+ \draw (4.5,1.5) rectangle (7.5,2);
+ \draw (4.5,1) rectangle (7.5,1.5);
+ \draw (4.5,0.5) rectangle (7.5,1);
+ \draw (4.5,0) rectangle (7.5,0.5);
+ \draw (6,0.25) node {\texttt{NULL}};
+ \draw [->] (7.5,2.75) -- (8.5,2.75);
+ \draw (8.5,2.75) node[right] {\texttt{HOME=/home/piccardi}};
+ \draw [->] (7.5,2.25) -- (8.5,2.25);
+ \draw (8.5,2.25) node[right] {\texttt{PATH=:/bin:/usr/bin}};
+ \draw [->] (7.5,1.75) -- (8.5,1.75);
+ \draw (8.5,1.75) node[right] {\texttt{SHELL=/bin/bash}};
+ \draw [->] (7.5,1.25) -- (8.5,1.25);
+ \draw (8.5,1.25) node[right] {\texttt{EDITOR=emacs}};
+ \draw [->] (7.5,0.75) -- (8.5,0.75);
+ \draw (8.5,0.75) node[right] {\texttt{OSTYPE=linux-gnu}};
+ \end{tikzpicture}
+ \caption{Esempio di lista delle variabili di ambiente.}
+ \label{fig:proc_envirno_list}
+\end{figure}
+
+Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo
+\textsl{\texttt{nome=valore}} ed in questa forma che le funzioni di gestione
+che vedremo a breve se le aspettano, se pertanto si dovesse costruire
+manualemente un ambiente si abbia cura di rispettare questa convenzione.
+Inoltre alcune variabili, come quelle elencate in
+fig.~\ref{fig:proc_envirno_list}, sono definite dal sistema per essere usate
+da diversi programmi e funzioni: per queste c'è l'ulteriore convenzione di
+usare nomi espressi in caratteri maiuscoli.\footnote{ma si tratta solo di una
+ convenzione, niente vieta di usare caratteri minuscoli.}
+
+Il kernel non usa mai queste variabili, il loro uso e la loro interpretazione è
+riservata alle applicazioni e ad alcune funzioni di libreria; in genere esse
+costituiscono un modo comodo per definire un comportamento specifico senza
+dover ricorrere all'uso di opzioni a linea di comando o di file di
+configurazione. É di norma cura della shell, quando esegue un comando, passare
+queste variabili al programma messo in esecuzione attraverso un uso opportuno
+delle relative chiamate (si veda sez.~\ref{sec:proc_exec}).
+
+La shell ad esempio ne usa molte per il suo funzionamento, come \texttt{PATH}
+per indicare la lista delle directory in cui effettuare la ricerca dei comandi
+o \texttt{PS1} per impostare il proprio \textit{prompt}. Alcune di esse, come
+\texttt{HOME}, \texttt{USER}, ecc. sono invece definite al login (per i
+dettagli si veda sez.~\ref{sec:sess_login}), ed in genere è cura della propria
+distribuzione definire le opportune variabili di ambiente in uno script di
+avvio. Alcune servono poi come riferimento generico per molti programmi, come
+\texttt{EDITOR} che indica l'editor preferito da invocare in caso di
+necessità. Una in particolare, \texttt{LANG}, serve a controllare la
+localizzazione del programma (su cui torneremo in
+sez.~\ref{sec:proc_localization}) per adattarlo alla lingua ed alle convezioni
+dei vari paesi.
+
+Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più
+comuni), come riportato in tab.~\ref{tab:proc_env_var}. GNU/Linux le supporta
+tutte e ne definisce anche altre, in particolare poi alcune funzioni di
+libreria prevedono la presenza di specifiche variabili di ambiente che ne
+modificano il comportamento, come quelle usate per indicare una localizzazione
+e quelle per indicare un fuso orario; una lista più completa che comprende
+queste ed ulteriori variabili si può ottenere con il comando \cmd{man 7
+ environ}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|p{7cm}|}
+ \hline
+ \textbf{Variabile} & \textbf{POSIX} & \textbf{XPG3}
+ & \textbf{Linux} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \texttt{USER} &$\bullet$&$\bullet$&$\bullet$& Nome utente\\
+ \texttt{LOGNAME}&$\bullet$&$\bullet$&$\bullet$& Nome di login\\
+ \texttt{HOME} &$\bullet$&$\bullet$&$\bullet$& Directory base
+ dell'utente\\
+ \texttt{LANG} &$\bullet$&$\bullet$&$\bullet$& Localizzazione\\
+ \texttt{PATH} &$\bullet$&$\bullet$&$\bullet$& Elenco delle directory
+ dei programmi\\
+ \texttt{PWD} &$\bullet$&$\bullet$&$\bullet$& Directory corrente\\
+ \texttt{SHELL} &$\bullet$&$\bullet$&$\bullet$& Shell in uso\\
+ \texttt{TERM} &$\bullet$&$\bullet$&$\bullet$& Tipo di terminale\\
+ \texttt{PAGER} &$\bullet$&$\bullet$&$\bullet$& Programma per vedere i
+ testi\\
+ \texttt{EDITOR} &$\bullet$&$\bullet$&$\bullet$& Editor preferito\\
+ \texttt{BROWSER}&$\bullet$&$\bullet$&$\bullet$& Browser preferito\\
+ \texttt{TMPDIR} &$\bullet$&$\bullet$&$\bullet$& Directory dei file
+ temporanei\\
+ \hline
+ \end{tabular}
+ \caption{Esempi delle variabili di ambiente più comuni definite da vari
+ standard.}
+ \label{tab:proc_env_var}
+\end{table}
+
+Lo standard ANSI C prevede l'esistenza di un ambiente, e pur non entrando
+nelle specifiche di come sono strutturati i contenuti, definisce la funzione
+\funcd{getenv} che permette di ottenere i valori delle variabili di ambiente;
+il suo prototipo è:
+\begin{prototype}{stdlib.h}{char *getenv(const char *name)}
+ Esamina l'ambiente del processo cercando una stringa che corrisponda a
+ quella specificata da \param{name}.
+
+ \bodydesc{La funzione ritorna \val{NULL} se non trova nulla, o il
+ puntatore alla stringa che corrisponde (di solito nella forma
+ \cmd{NOME=valore}).}
+\end{prototype}
+
+Oltre a questa funzione di lettura, che è l'unica definita dallo standard ANSI
+C, nell'evoluzione dei sistemi Unix ne sono state proposte altre, da
+utilizzare per impostare e per cancellare le variabili di ambiente. Uno schema
+delle funzioni previste nei vari standard e disponibili in Linux è riportato
+in tab.~\ref{tab:proc_env_func}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|c|c|c|}
+ \hline
+ \textbf{Funzione} & \textbf{ANSI C} & \textbf{POSIX.1} & \textbf{XPG3} &
+ \textbf{SVr4} & \textbf{BSD} & \textbf{Linux} \\
+ \hline
+ \hline
+ \func{getenv} & $\bullet$ & $\bullet$ & $\bullet$
+ & $\bullet$ & $\bullet$ & $\bullet$ \\
+ \func{setenv} & -- & -- & --
+ & -- & $\bullet$ & $\bullet$ \\
+ \func{unsetenv}& -- & -- & --
+ & -- & $\bullet$ & $\bullet$ \\
+ \func{putenv} & -- & opz. & $\bullet$
+ & -- & $\bullet$ & $\bullet$ \\
+ \func{clearenv}& -- & opz. & --
+ & -- & -- & $\bullet$ \\
+ \hline
+ \end{tabular}
+ \caption{Funzioni per la gestione delle variabili di ambiente.}
+ \label{tab:proc_env_func}
+\end{table}
+
+In Linux\footnote{in realtà nelle libc4 e libc5 sono definite solo le prime
+ quattro, \func{clearenv} è stata introdotta con le \acr{glibc} 2.0.} sono
+definite tutte le funzioni elencate in tab.~\ref{tab:proc_env_func}. La prima,
+\func{getenv}, l'abbiamo appena esaminata; delle restanti le prime due,
+\funcd{putenv} e \funcd{setenv}, servono per assegnare nuove variabili di
+ambiente, i loro prototipi sono i seguenti:
+\begin{functions}
+ \headdecl{stdlib.h}
+
+ \funcdecl{int setenv(const char *name, const char *value, int overwrite)}
+ Imposta la variabile di ambiente \param{name} al valore \param{value}.
+
+ \funcdecl{int putenv(char *string)} Aggiunge la stringa \param{string}
+ all'ambiente.
+
+ \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ per un
+ errore, che è sempre \errval{ENOMEM}.}
+\end{functions}
+
+La terza funzione della lista, \funcd{unsetenv}, serve a cancellare una
+variabile dall'ambiente, il suo prototipo è:
+\begin{functions}
+ \headdecl{stdlib.h}
+
+ \funcdecl{void unsetenv(const char *name)} Rimuove la variabile di ambiente
+ \param{name}.
+\end{functions}
+
+\noindent la funzione elimina ogni occorrenza della variabile specificata; se la
+variabile non esiste non succede nulla. Non è prevista (dato che la funzione è
+\ctyp{void}) nessuna segnalazione di errore.
+
+Per modificare o aggiungere una variabile di ambiente si possono usare sia
+\func{setenv} che \func{putenv}. La prima permette di specificare
+separatamente nome e valore della variabile di ambiente, inoltre il valore di
+\param{overwrite} specifica il comportamento della funzione nel caso la
+variabile esista già, sovrascrivendola se diverso da zero, lasciandola
+immutata se uguale a zero.
+
+La seconda funzione prende come argomento una stringa analoga a quella
+restituita da \func{getenv}, e sempre nella forma \code{NOME=valore}. Se la
+variabile specificata non esiste la stringa sarà aggiunta all'ambiente, se
+invece esiste il suo valore sarà impostato a quello specificato da
+\param{string}.
+
+Si tenga presente che, seguendo lo standard SUSv2, le \acr{glibc} successive
+alla versione 2.1.2 aggiungono \param{string} alla lista delle variabili di
+ambiente;\footnote{il comportamento è lo stesso delle vecchie \acr{libc4} e
+ \acr{libc5}; nelle \acr{glibc}, dalla versione 2.0 alla 2.1.1, veniva invece
+ fatta una copia, seguendo il comportamento di BSD4.4; dato che questo può
+ dar luogo a perdite di memoria e non rispetta lo standard. Il comportamento
+ è stato modificato a partire dalle 2.1.2, eliminando anche, sempre in
+ conformità a SUSv2, l'attributo \direct{const} dal prototipo.} pertanto ogni
+cambiamento alla stringa in questione si riflette automaticamente
+sull'ambiente, e quindi si deve evitare di passare a questa funzione una
+variabile automatica (per evitare i problemi esposti in
+sez.~\ref{sec:proc_auto_var}). Si tenga infine presente che se si passa a
+\func{putenv} solo il nome di una variabile (cioè \param{string} è nella forma
+\texttt{NAME} e non contiene un carattere \texttt{'='}) allora questa viene
+cancellata dall'ambiente.
+
+Infine quando chiamata a \func{putenv} comporta la necessità di creare una
+nuova versione del vettore \var{environ} questo sarà allocato automaticamente,
+ma la versione corrente sarà deallocata solo se anch'essa è risultante da
+un'allocazione fatta in precedenza da un'altra \func{putenv}. Questo avviene
+perché il vettore delle variabili di ambiente iniziale, creato dalla chiamata
+ad \func{exec} (vedi sez.~\ref{sec:proc_exec}) è piazzato nella memoria al di
+sopra dello \itindex{stack} stack, (vedi fig.~\ref{fig:proc_mem_layout}) e non
+nello \itindex{heap} \textit{heap} e quindi non può essere deallocato.
+Inoltre la memoria associata alle variabili di ambiente eliminate non viene
+liberata.
+
+L'ultima funzione per la gestione dell'ambiente è \funcd{clearenv}, che viene
+usata per cancellare completamente tutto l'ambiente; il suo prototipo è:
+\begin{functions}
+ \headdecl{stdlib.h}
+
+ \funcdecl{int clearenv(void)}
+ Cancella tutto l'ambiente.
+
+ \bodydesc{la funzione restituisce 0 in caso di successo e un valore diverso
+ da zero per un errore.}
+\end{functions}
+
+In genere si usa questa funzione in maniera precauzionale per evitare i
+problemi di sicurezza connessi nel trasmettere ai programmi che si invocano un
+ambiente che può contenere dei dati non controllati. In tal caso si provvede
+alla cancellazione di tutto l'ambiente per costruirne una versione
+``\textsl{sicura}'' da zero.
+
+\subsection{La localizzazione}
+\label{sec:proc_localization}
+
+Abbiamo accennato in sez.~\ref{sec:proc_environ} come la variabile di ambiente
+\texttt{LANG} sia usata per indicare ai processi il valore della cosiddetta
+\textsl{localizzazione}. Si tratta di una funzionalità fornita dalle librerie
+di sistema\footnote{prenderemo in esame soltanto il caso delle \acr{glibc}.}
+che consente di gestire in maniera automatica sia la lingua in cui vengono
+stampati i vari messaggi (come i messaggi associati agli errori che vedremo in
+sez.~\ref{sec:sys_strerror}) che le convenzioni usate nei vari paesi per una
+serie di aspetti come il formato dell'ora, quello delle date, gli ordinamenti
+alfabetici, le espressioni della valute, ecc.
+
+La localizzazione di un programma si può selezionare con la
+
+
+In realtà perché un programma sia effettivamente localizzato non è sufficiente
+
+% TODO trattare, quando ci sarà tempo, setlocale ed il resto
+
+
+%\subsection{Opzioni in formato esteso}
+%\label{sec:proc_opt_extended}
+
+%Oltre alla modalità ordinaria di gestione delle opzioni trattata in
+%sez.~\ref{sec:proc_opt_handling} le \acr{glibc} forniscono una modalità
+%alternativa costituita dalle cosiddette \textit{long-options}, che consente di
+%esprimere le opzioni in una forma più descrittiva che nel caso più generale è
+%qualcosa del tipo di ``\texttt{-{}-option-name=parameter}''.
+
+%(NdA: questa parte verrà inserita in seguito).
+
+% TODO opzioni in formato esteso
+
+\section{Problematiche di programmazione generica}
+\label{sec:proc_gen_prog}
+
+Benché questo non sia un libro di C, è opportuno affrontare alcune delle
+problematiche generali che possono emergere nella programmazione e di quali
+precauzioni o accorgimenti occorre prendere per risolverle. Queste
+problematiche non sono specifiche di sistemi unix-like o multitasking, ma
+avendo trattato in questo capitolo il comportamento dei processi visti come
+entità a sé stanti, le riportiamo qui.
+
+
+\subsection{Il passaggio delle variabili e dei valori di ritorno}
+\label{sec:proc_var_passing}
+
+Una delle caratteristiche standard del C è che le variabili vengono passate
+alle subroutine attraverso un meccanismo che viene chiamato \textit{by value}
+(diverso ad esempio da quanto avviene con il Fortran, dove le variabili sono
+passate, come suol dirsi, \textit{by reference}, o dal C++ dove la modalità
+del passaggio può essere controllata con l'operatore \cmd{\&}).
+
+Il passaggio di una variabile \textit{by value} significa che in realtà quello
+che viene passato alla subroutine è una copia del valore attuale di quella
+variabile, copia che la subroutine potrà modificare a piacere, senza che il
+valore originale nella funzione chiamante venga toccato. In questo modo non
+occorre preoccuparsi di eventuali effetti delle operazioni della subroutine
+sulla variabile passata come argomento.
+
+Questo però va inteso nella maniera corretta. Il passaggio \textit{by value}
+vale per qualunque variabile, puntatori compresi; quando però in una
+subroutine si usano dei puntatori (ad esempio per scrivere in un buffer) in
+realtà si va a modificare la zona di memoria a cui essi puntano, per cui anche
+se i puntatori sono copie, i dati a cui essi puntano sono sempre gli stessi, e
+le eventuali modifiche avranno effetto e saranno visibili anche nella funzione
+chiamante.
+
+Nella maggior parte delle funzioni di libreria e delle system call i puntatori
+vengono usati per scambiare dati (attraverso buffer o strutture) e le
+variabili semplici vengono usate per specificare argomenti; in genere le
+informazioni a riguardo dei risultati vengono passate alla funzione chiamante
+attraverso il valore di ritorno. È buona norma seguire questa pratica anche
+nella programmazione normale.
+
+Talvolta però è necessario che la funzione possa restituire indietro alla
+funzione chiamante un valore relativo ad uno dei suoi argomenti. Per far
+questo si usa il cosiddetto \itindex{value~result~argument} \textit{value
+ result argument}, si passa cioè, invece di una normale variabile, un
+puntatore alla stessa; vedremo alcuni esempi di questa modalità nelle funzioni
+che gestiscono i socket (in sez.~\ref{sec:TCP_functions}), in cui, per
+permettere al kernel di restituire informazioni sulle dimensioni delle
+strutture degli indirizzi utilizzate, viene usato questo meccanismo.
+
+
+\subsection{Il passaggio di un numero variabile di argomenti}
+\label{sec:proc_variadic}
+
+Come vedremo nei capitoli successivi, non sempre è possibile specificare un
+numero fisso di argomenti per una funzione. Lo standard ISO C prevede nella
+sua sintassi la possibilità di definire delle \index{variadic}
+\textit{variadic function} che abbiano un numero variabile di argomenti,
+attraverso l'uso nella dichiarazione della funzione dello speciale costrutto
+``\texttt{\textellipsis}'', che viene chiamato \textit{ellipsis}.
+
+Lo standard però non provvede a livello di linguaggio alcun meccanismo con cui
+dette funzioni possono accedere ai loro argomenti. L'accesso viene pertanto
+realizzato a livello delle librerie standard del C che provvedono gli
+strumenti adeguati. L'uso di una \textit{variadic function} prevede quindi
+tre punti:
+\begin{itemize*}
+\item \textsl{Dichiarare} la funzione come \textit{variadic} usando un
+ prototipo che contenga una \textit{ellipsis}.
+\item \textsl{Definire} la funzione come \textit{variadic} usando la stessa
+ \textit{ellipsis}, ed utilizzare le apposite macro che consentono la
+ gestione di un numero variabile di argomenti.
+\item \textsl{Invocare} la funzione specificando prima gli argomenti fissi, ed
+ a seguire quelli addizionali.
+\end{itemize*}
+
+Lo standard ISO C prevede che una \index{variadic} \textit{variadic function}
+abbia sempre almeno un argomento fisso; prima di effettuare la dichiarazione
+deve essere incluso l'apposito header file \file{stdarg.h}; un esempio di
+dichiarazione è il prototipo della funzione \func{execl} che vedremo in
+sez.~\ref{sec:proc_exec}:
+\includecodesnip{listati/exec_sample.c}
+in questo caso la funzione prende due argomenti fissi ed un numero variabile
+di altri argomenti (che verranno a costituire gli elementi successivi al primo
+del vettore \param{argv} passato al nuovo processo). Lo standard ISO C
+richiede inoltre che l'ultimo degli argomenti fissi sia di tipo
+\textit{self-promoting}\footnote{il linguaggio C prevede che quando si
+ mescolano vari tipi di dati, alcuni di essi possano essere \textsl{promossi}
+ per compatibilità; ad esempio i tipi \ctyp{float} vengono convertiti
+ automaticamente a \ctyp{double} ed i \ctyp{char} e gli \ctyp{short} ad
+ \ctyp{int}. Un tipo \textit{self-promoting} è un tipo che verrebbe promosso
+ a sé stesso.} il che esclude vettori, puntatori a funzioni e interi di tipo
+\ctyp{char} o \ctyp{short} (con segno o meno). Una restrizione ulteriore di
+alcuni compilatori è di non dichiarare l'ultimo argomento fisso come
+\direct{register}.
+
+Una volta dichiarata la funzione il secondo passo è accedere ai vari argomenti
+quando la si va a definire. Gli argomenti fissi infatti hanno un loro nome, ma
+quelli variabili vengono indicati in maniera generica dalla \textit{ellipsis}.
+
+L'unica modalità in cui essi possono essere recuperati è pertanto quella
+sequenziale; essi verranno estratti dallo \itindex{stack} \textit{stack}
+secondo l'ordine in cui sono stati scritti. Per fare questo in \file{stdarg.h}
+sono definite delle apposite macro; la procedura da seguire è la seguente:
+\begin{enumerate*}
+\item Inizializzare un puntatore alla lista degli argomenti di tipo
+ \macro{va\_list} attraverso la macro \macro{va\_start}.
+\item Accedere ai vari argomenti opzionali con chiamate successive alla macro
+ \macro{va\_arg}, la prima chiamata restituirà il primo argomento, la seconda
+ il secondo e così via.
+\item Dichiarare la conclusione dell'estrazione degli argomenti invocando la
+ macro \macro{va\_end}.
+\end{enumerate*}
+In generale è perfettamente legittimo richiedere meno argomenti di quelli che
+potrebbero essere stati effettivamente forniti, e nella esecuzione delle
+\macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti
+saranno ignorati; se invece si richiedono più argomenti di quelli forniti si
+otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso della macro
+\macro{va\_end} è inutile, ma si consiglia di usarlo ugualmente per
+compatibilità.
+
+Le definizioni delle tre macro sono le seguenti:
+\begin{functions}
+ \headdecl{stdarg.h}
+
+ \funcdecl{void va\_start(va\_list ap, last)} Inizializza il puntatore alla
+ lista di argomenti \param{ap}; il parametro \param{last} \emph{deve} essere
+ l'ultimo degli argomenti fissi.
+
+ \funcdecl{type va\_arg(va\_list ap, type)} Restituisce il valore del
+ successivo argomento opzionale, modificando opportunamente \param{ap}; la
+ macro richiede che si specifichi il tipo dell'argomento attraverso il
+ parametro \param{type} che deve essere il nome del tipo dell'argomento in
+ questione. Il tipo deve essere \textit{self-promoting}.
+
+ \funcdecl{void va\_end(va\_list ap)} Conclude l'uso di \param{ap}.
+\end{functions}
+
+In generale si possono avere più puntatori alla lista degli argomenti,
+ciascuno andrà inizializzato con \macro{va\_start} e letto con \macro{va\_arg}
+e ciascuno potrà scandire la lista degli argomenti per conto suo.
+
+Dopo l'uso di \macro{va\_end} la variabile \param{ap} diventa indefinita e
+successive chiamate a \macro{va\_arg} non funzioneranno. Si avranno risultati
+indefiniti anche chiamando \macro{va\_arg} specificando un tipo che non
+corrisponde a quello dell'argomento.
+
+Un altro limite delle macro è che i passi 1) e 3) devono essere eseguiti nel
+corpo principale della funzione, il passo 2) invece può essere eseguito anche
+in una subroutine passandole il puntatore alla lista di argomenti; in questo
+caso però si richiede che al ritorno della funzione il puntatore non venga più
+usato (lo standard richiederebbe la chiamata esplicita di \macro{va\_end}),
+dato che il valore di \param{ap} risulterebbe indefinito.
+
+Esistono dei casi in cui è necessario eseguire più volte la scansione degli
+argomenti e poter memorizzare una posizione durante la stessa. La cosa più
+naturale in questo caso sembrerebbe quella di copiarsi il puntatore alla lista
+degli argomenti con una semplice assegnazione. Dato che una delle
+realizzazioni più comuni di \macro{va\_list} è quella di un puntatore nello
+\itindex{stack} \textit{stack} all'indirizzo dove sono stati salvati gli
+argomenti, è assolutamente normale pensare di poter effettuare questa
+operazione.
+
+In generale però possono esistere anche realizzazioni diverse, per questo
+motivo \macro{va\_list} è definito come \index{tipo!opaco} \textsl{tipo opaco}
+e non può essere assegnato direttamente ad un'altra variabile dello stesso
+tipo. Per risolvere questo problema lo standard ISO C99\footnote{alcuni
+ sistemi che non hanno questa macro provvedono al suo posto
+ \macro{\_\_va\_copy} che era il nome proposto in una bozza dello standard.}
+ha previsto una macro ulteriore che permette di eseguire la copia di un
+puntatore alla lista degli argomenti:
+\begin{prototype}{stdarg.h}{void va\_copy(va\_list dest, va\_list src)}
+ Copia l'attuale valore \param{src} del puntatore alla lista degli argomenti
+ su \param{dest}.
+\end{prototype}
+\noindent anche in questo caso è buona norma chiudere ogni esecuzione di una
+\macro{va\_copy} con una corrispondente \macro{va\_end} sul nuovo puntatore
+alla lista degli argomenti.
+
+La chiamata di una funzione con un numero variabile di argomenti, posto che la
+si sia dichiarata e definita come tale, non prevede nulla di particolare;
+l'invocazione è identica alle altre, con gli argomenti, sia quelli fissi che
+quelli opzionali, separati da virgole. Quello che però è necessario tenere
+presente è come verranno convertiti gli argomenti variabili.
+
+In Linux gli argomenti dello stesso tipo sono passati allo stesso modo, sia
+che siano fissi sia che siano opzionali (alcuni sistemi trattano diversamente
+gli opzionali), ma dato che il prototipo non può specificare il tipo degli
+argomenti opzionali, questi verranno sempre promossi, pertanto nella ricezione
+dei medesimi occorrerà tenerne conto (ad esempio un \ctyp{char} verrà visto da
+\macro{va\_arg} come \ctyp{int}).
+
+Uno dei problemi che si devono affrontare con le funzioni con un numero
+variabile di argomenti è che non esiste un modo generico che permetta di
+stabilire quanti sono gli argomenti passati effettivamente in una chiamata.
+
+Esistono varie modalità per affrontare questo problema; una delle più
+immediate è quella di specificare il numero degli argomenti opzionali come uno
+degli argomenti fissi. Una variazione di questo metodo è l'uso di un argomento
+per specificare anche il tipo degli argomenti (come fa la stringa di formato
+per \func{printf}).
+
+Una modalità diversa, che può essere applicata solo quando il tipo degli
+argomenti lo rende possibile, è quella che prevede di usare un valore speciale
+come ultimo argomento (come fa ad esempio \func{execl} che usa un puntatore
+\val{NULL} per indicare la fine della lista degli argomenti).
+
+
+\subsection{Potenziali problemi con le variabili automatiche}
+\label{sec:proc_auto_var}
+
+Uno dei possibili problemi che si possono avere con le subroutine è quello di
+restituire alla funzione chiamante dei dati che sono contenuti in una
+variabile automatica. Ovviamente quando la subroutine ritorna la sezione
+dello \itindex{stack} \textit{stack} che conteneva la variabile automatica
+potrà essere riutilizzata da una nuova funzione, con le immaginabili
+conseguenze di sovrapposizione e sovrascrittura dei dati.
+
+Per questo una delle regole fondamentali della programmazione in C è che
+all'uscita di una funzione non deve restare nessun riferimento alle variabili
+locali; qualora sia necessario utilizzare variabili che possano essere viste
+anche dalla funzione chiamante queste devono essere allocate esplicitamente, o
+in maniera statica (usando variabili di tipo \ctyp{static} o \ctyp{extern}), o
+dinamicamente con una delle funzioni della famiglia \func{malloc}.
+
+
+\subsection{Il controllo di flusso non locale}
+\label{sec:proc_longjmp}
+
+Il controllo del flusso di un programma in genere viene effettuato con le
+varie istruzioni del linguaggio C; fra queste la più bistrattata è il
+\code{goto}, che viene deprecato in favore dei costrutti della programmazione
+strutturata, che rendono il codice più leggibile e mantenibile. Esiste però un
+caso in cui l'uso di questa istruzione porta all'implementazione più
+efficiente e più chiara anche dal punto di vista della struttura del
+programma: quello dell'uscita in caso di errore.
+
+\index{salto~non-locale|(}
+
+Il C però non consente di effettuare un salto ad una etichetta definita in
+un'altra funzione, per cui se l'errore avviene in una funzione, e la sua
+gestione ordinaria è in un'altra, occorre usare quello che viene chiamato un
+\textsl{salto non-locale}. Il caso classico in cui si ha questa necessità,
+citato sia in \cite{APUE} che in \cite{glibc}, è quello di un programma nel
+cui corpo principale vengono letti dei dati in ingresso sui quali viene
+eseguita, tramite una serie di funzioni di analisi, una scansione dei
+contenuti, da cui si ottengono le indicazioni per l'esecuzione di opportune
+operazioni.
+
+Dato che l'analisi può risultare molto complessa, ed opportunamente suddivisa
+in fasi diverse, la rilevazione di un errore nei dati in ingresso può accadere
+all'interno di funzioni profondamente annidate l'una nell'altra. In questo
+caso si dovrebbe gestire, per ciascuna fase, tutta la casistica del passaggio
+all'indietro di tutti gli errori rilevabili dalle funzioni usate nelle fasi
+successive. Questo comporterebbe una notevole complessità, mentre sarebbe
+molto più comodo poter tornare direttamente al ciclo di lettura principale,
+scartando l'input come errato.\footnote{a meno che, come precisa \cite{glibc},
+ alla chiusura di ciascuna fase non siano associate operazioni di pulizia
+ specifiche (come deallocazioni, chiusure di file, ecc.), che non potrebbero
+ essere eseguite con un salto non-locale.}
+
+Tutto ciò può essere realizzato proprio con un salto non-locale; questo di
+norma viene realizzato salvando il contesto dello \itindex{stack}
+\textit{stack} nel punto in cui si vuole tornare in caso di errore, e
+ripristinandolo, in modo da tornare nella funzione da cui si era partiti,
+quando serve. La funzione che permette di salvare il contesto dello
+\itindex{stack} \textit{stack} è \funcd{setjmp}, il cui prototipo è:
+\begin{functions}
+ \headdecl{setjmp.h}
+ \funcdecl{int setjmp(jmp\_buf env)}
+
+ Salva il contesto dello stack.
+
+ \bodydesc{La funzione ritorna zero quando è chiamata direttamente e un
+ valore diverso da zero quando ritorna da una chiamata di \func{longjmp}
+ che usa il contesto salvato in precedenza.}
+\end{functions}
+
+Quando si esegue la funzione il contesto corrente dello \itindex{stack}
+\textit{stack} viene salvato nell'argomento \param{env}, una variabile di tipo
+\type{jmp\_buf}\footnote{questo è un classico esempio di variabile di
+ \index{tipo!opaco} \textsl{tipo opaco}. Si definiscono così strutture ed
+ altri oggetti usati da una libreria, la cui struttura interna non deve
+ essere vista dal programma chiamante (da cui il nome) che li devono
+ utilizzare solo attraverso dalle opportune funzioni di gestione.} che deve
+essere stata definita in precedenza. In genere le variabili di tipo
+\type{jmp\_buf} vengono definite come variabili globali in modo da poter
+essere viste in tutte le funzioni del programma.
+
+Quando viene eseguita direttamente la funzione ritorna sempre zero, un valore
+diverso da zero viene restituito solo quando il ritorno è dovuto ad una
+chiamata di \func{longjmp} in un'altra parte del programma che ripristina lo
+\itindex{stack} \textit{stack} effettuando il salto non-locale. Si tenga conto
+che il contesto salvato in \param{env} viene invalidato se la funzione che ha
+chiamato \func{setjmp} ritorna, nel qual caso un successivo uso di
+\func{longjmp} può comportare conseguenze imprevedibili (e di norma fatali)
+per il processo.
+
+Come accennato per effettuare un salto non-locale ad
+un punto precedentemente stabilito con \func{setjmp} si usa la funzione
+\funcd{longjmp}; il suo prototipo è:
+\begin{functions}
+ \headdecl{setjmp.h}
+ \funcdecl{void longjmp(jmp\_buf env, int val)}
+
+ Ripristina il contesto dello stack.
+
+ \bodydesc{La funzione non ritorna.}
+\end{functions}
+
+La funzione ripristina il contesto dello \itindex{stack} \textit{stack}
+salvato da una chiamata a \func{setjmp} nell'argomento \param{env}. Dopo
+l'esecuzione della funzione il programma prosegue nel codice successivo al
+ritorno della \func{setjmp} con cui si era salvato \param{env}, che restituirà
+il valore
+\param{val} invece di zero. Il valore di \param{val} specificato nella
+chiamata deve essere diverso da zero, se si è specificato 0 sarà comunque
+restituito 1 al suo posto.
+
+In sostanza un \func{longjmp} è analogo ad un \code{return}, solo che invece
+di ritornare alla riga successiva della funzione chiamante, il programma
+ritorna alla posizione della relativa \func{setjmp}, l'altra differenza è che
+il ritorno può essere effettuato anche attraverso diversi livelli di funzioni
+annidate.
+
+L'implementazione di queste funzioni comporta alcune restrizioni dato che esse
+interagiscono direttamente con la gestione dello \itindex{stack}
+\textit{stack} ed il funzionamento del compilatore stesso. In particolare
+\func{setjmp} è implementata con una macro, pertanto non si può cercare di
+ottenerne l'indirizzo, ed inoltre delle chiamate a questa funzione sono sicure
+solo in uno dei seguenti casi:
+\begin{itemize}
+\item come espressione di controllo in un comando condizionale, di selezione
+ o di iterazione (come \code{if}, \code{switch} o \code{while});
+\item come operando per un operatore di uguaglianza o confronto in una
+ espressione di controllo di un comando condizionale, di selezione o di
+ iterazione;
+\item come operando per l'operatore di negazione (\code{!}) in una espressione
+ di controllo di un comando condizionale, di selezione o di iterazione;
+\item come espressione a sé stante.
+\end{itemize}