+
+ \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in
+ caso di errore, nel qual caso \var{errno} assumerà uno dei
+ valori seguenti:
+ \begin{errlist}
+ \item[\macro{ENOMEM}] alcuni indirizzi dell'intervallo specificato non
+ corrispondono allo spazio di indirizzi del processo o si è ecceduto
+ il numero massimo consentito di pagine bloccate.
+ \item[\macro{EINVAL}] \var{len} non è un valore positivo.
+ \end{errlist}
+ e, per \func{mlock}, anche \macro{EPERM} quando il processo non ha i
+ privilegi richiesti per l'operazione.}
+\end{functions}
+
+Altre due funzioni, \func{mlockall} e \func{munlockall}, consentono di
+bloccare genericamente lo spazio di indirizzi di un processo. I prototipi di
+queste funzioni sono:
+
+\begin{functions}
+ \headdecl{sys/mman.h}
+
+ \funcdecl{int mlockall(int flags)}
+ Blocca la paginazione per lo spazio di indirizzi del processo corrente.
+
+ \funcdecl{int munlockall(void)}
+ Sblocca la paginazione per lo spazio di indirizzi del processo corrente.
+
+ \bodydesc{Codici di ritorno ed errori sono gli stessi di \func{mlock}
+ e \func{munlock}.}
+\end{functions}
+
+Il parametro \var{flags} di \func{mlockall} permette di controllarne il
+comportamento; esso può essere specificato come l'OR aritmetico delle due
+costanti:
+\begin{basedescript}{\desclabelwidth{2.5cm}}
+\item[\macro{MCL\_CURRENT}] blocca tutte le pagine correntemente mappate nello
+ spazio di indirizzi del processo.
+\item[\macro{MCL\_FUTURE}] blocca tutte le pagine che saranno mappate nello
+ spazio di indirizzi del processo.
+\end{basedescript}
+
+Con \func{mlockall} si può bloccare tutte le pagine mappate nello spazio di
+indirizzi del processo, sia che comprendano il segmento di testo, di dati, lo
+stack, lo heap e pure le funzioni di libreria chiamate, i file mappati in
+memoria, i dati del kernel mappati in user space, la memoria condivisa. L'uso
+dei flag permette di selezionare con maggior finezza le pagine da bloccare, ad
+esempio limitandosi a tutte le pagine allocate a partire da un certo momento.
+
+In ogni caso un processo real-time che deve entrare in una sezione critica
+deve provvedere a riservare memoria sufficiente prima dell'ingresso, per
+scongiurare in partenza un eventuale page fault\index{page fault} causato dal
+meccanismo di \textit{copy on write}\index{copy on write}. Infatti se nella
+sezione critica si va ad utilizzare memoria che non è ancora stata riportata
+in RAM si potrebbe avere un page fault durante l'esecuzione della stessa, con
+conseguente rallentamento (probabilmente inaccettabile) dei tempi di
+esecuzione.
+
+In genere si ovvia a questa problematica chiamando una funzione che ha
+allocato una quantità sufficientemente ampia di variabili automatiche, in modo
+che esse vengano mappate in RAM dallo stack, dopo di che, per essere sicuri
+che esse siano state effettivamente portate in memoria, ci si scrive sopra.
+
+
+
+\section{Parametri, opzioni ed ambiente di un processo}
+\label{sec:proc_options}
+
+Tutti i programmi hanno la possibilità di ricevere parametri e opzioni quando
+vengono lanciati. Il passaggio dei parametri è effettuato attraverso gli
+argomenti \var{argc} e \var{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 \secref{sec:proc_exec}) quando questo viene
+messo in esecuzione.
+
+Oltre al passaggio dei parametri, un'altra modalità che permette di passare
+delle informazioni che modifichino il comportamento di un programma è quello
+dell'uso del cosiddetto \textit{environment} (cioè l'uso delle
+\textsl{variabili di ambiente}). In questa sezione esamineremo le funzioni che
+permettono di gestire parametri ed opzioni, e quelle che consentono di
+manipolare ed utilizzare le variabili di ambiente.
+
+
+\subsection{Il formato dei parametri}
+\label{sec:proc_par_format}
+In genere passaggio dei parametri al 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 viene considerata un parametro. Di norma per individuare
+le parole viene usato come carattere di separazione lo spazio o il tabulatore,
+ma il comportamento è modificabile attraverso l'impostazione della variabile
+di ambiente \cmd{IFS}.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=11cm]{img/argv_argc}
+ \caption{Esempio dei valori di \var{argv} e \var{argc} generati nella
+ scansione di una riga di comando.}
+ \label{fig:proc_argv_argc}
+\end{figure}
+
+Nella scansione viene costruito il vettore di puntatori \var{argv} inserendo
+in successione il puntatore alla stringa costituente l'$n$-simo parametro; la
+variabile \var{argc} viene inizializzata al numero di parametri trovati, in
+questo modo il primo parametro è sempre il nome del programma; un esempio di
+questo meccanismo è mostrato in \figref{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 \var{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
+\figref{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
+\var{argv} le librerie standard del C forniscono la funzione \func{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 \var{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 \var{argc} e \var{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 \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 di \figref{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 \var{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 \var{argv} che cominciano con il carattere \texttt{'-'}.
+
+\begin{figure}[htb]
+ \footnotesize
+ \begin{lstlisting}{}
+ opterr = 0; /* don't want writing to stderr */
+ while ( (i = getopt(argc, argv, "hp:c:e:")) != -1) {
+ switch (i) {
+ /*
+ * Handling options
+ */
+ case 'h': /* help option */
+ printf("Wrong -h option use\n");
+ usage();
+ return -1;
+ break;
+ case 'c': /* take wait time for childen */
+ wait_child = strtol(optarg, NULL, 10); /* convert input */
+ break;
+ case 'p': /* take wait time for childen */
+ wait_parent = strtol(optarg, NULL, 10); /* convert input */
+ break;
+ case 'e': /* take wait before parent exit */
+ wait_end = strtol(optarg, NULL, 10); /* convert input */
+ break;
+ case '?': /* unrecognized options */
+ printf("Unrecognized options -%c\n",optopt);
+ usage();
+ default: /* should not reached */
+ usage();
+ }
+ }
+ debug("Optind %d, argc %d\n",optind,argc);
+ \end{lstlisting}
+ \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 \var{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 \figref{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 \var{argv[]} del primo degli argomenti rimanenti nella linea di comando.
+
+Normalmente \func{getopt} compie una permutazione degli elementi di \var{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 \var{argv}; se \var{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 \var{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 \var{argv}.
+
+
+\subsection{Opzioni in formato esteso}
+\label{sec:proc_opt_extended}
+
+Un'estensione di questo schema è costituito dalle cosiddette
+\textit{long-options} espresse nella forma \cmd{--option=parameter}, anche la
+gestione di queste ultime è stata standardizzata attraverso l'uso di una
+versione estesa di \func{getopt}.
+
+(NdA: da finire).
+
+
+\subsection{Le variabili di ambiente}
+\label{sec:proc_environ}
+
+Oltre agli argomenti passati a linea di comando ogni processo riceve dal
+sistema un \textsl{ambiente}, nella forma di una lista di variabili (detta
+\textit{environment list}) messa a disposizione dal processo, e costruita
+nella chiamata alla funzione \func{exec} quando questo viene lanciato.
+
+Come per la lista dei parametri anche questa lista è un array di puntatori a
+caratteri, ciascuno dei quali punta ad una stringa, terminata da un
+\macro{NULL}. A differenza di \var{argv[]} in questo caso non si ha una
+lunghezza dell'array data da un equivalente di \var{argc}, ma la lista è
+terminata da un puntatore nullo.
+
+L'indirizzo della lista delle variabili di ambiente è passato attraverso la
+variabile globale \var{environ}, a cui si può accedere attraverso una semplice
+dichiarazione del tipo:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+extern char ** environ;
+\end{lstlisting}
+un esempio della struttura di questa lista, contenente alcune delle variabili
+più comuni che normalmente sono definite dal sistema, è riportato in
+\figref{fig:proc_envirno_list}.
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=11cm]{img/environ_var}
+ \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}}. Inoltre alcune variabili, come quelle elencate
+in \figref{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.
+
+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.
+
+La shell ad esempio ne usa molte per il suo funzionamento (come \var{PATH} per
+la ricerca dei comandi, o \cmd{IFS} per la scansione degli argomenti), e
+alcune di esse (come \var{HOME}, \var{USER}, etc.) sono definite al login (per
+i dettagli si veda \secref{sec:sess_login}). In genere è cura
+dell'amministratore definire le opportune variabili di ambiente in uno script
+di avvio. Alcune servono poi come riferimento generico per molti programmi
+(come \var{EDITOR} che indica l'editor preferito da invocare in caso di
+necessità).
+
+Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più
+comuni), come riportato in \tabref{tab:proc_env_var}. GNU/Linux le supporta
+tutte e ne definisce anche altre: per una lista più completa si può
+controllare \cmd{man 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
+ \macro{USER} & $\bullet$ & $\bullet$ & $\bullet$ & Nome utente\\
+ \macro{LOGNAME} & $\bullet$ & $\bullet$ & $\bullet$ & Nome di login\\
+ \macro{HOME} & $\bullet$ & $\bullet$ & $\bullet$ &
+ Directory base dell'utente\\
+ \macro{LANG} & $\bullet$ & $\bullet$ & $\bullet$ & Localizzazione\\
+ \macro{PATH} & $\bullet$ & $\bullet$ & $\bullet$ & Elenco delle directory
+ dei programmi\\
+ \macro{PWD} & $\bullet$ & $\bullet$ & $\bullet$ & Directory corrente\\
+ \macro{SHELL} & $\bullet$ & $\bullet$ & $\bullet$ & Shell in uso\\
+ \macro{TERM} & $\bullet$ & $\bullet$ & $\bullet$ & Tipo di terminale\\
+ \macro{PAGER} & $\bullet$ & $\bullet$ & $\bullet$ & Programma per vedere i
+ testi\\
+ \macro{EDITOR} & $\bullet$ & $\bullet$ & $\bullet$ & Editor preferito\\
+ \macro{BROWSER} & $\bullet$ & $\bullet$ & $\bullet$ & Browser preferito\\
+ \hline
+ \end{tabular}
+ \caption{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, pur non entrando nelle
+specifiche di come sono strutturati i contenuti, e definisce la funzione
+\func{getenv} che permette di ottenere i valori delle variabili di ambiente,
+il cui 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 \macro{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 \tabref{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. & &
+ & & \\
+ \hline
+ \end{tabular}
+ \caption{Funzioni per la gestione delle variabili di ambiente.}
+ \label{tab:proc_env_func}
+\end{table}
+
+In Linux solo le prime quattro funzioni di \tabref{tab:proc_env_func} sono
+definite, \func{getenv} l'abbiamo già esaminata; delle tre restanti le prime
+due, \func{putenv} e \func{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 \macro{ENOMEM}.}
+\end{functions}
+\noindent la terza, \func{unsetenv}, serve a cancellare una variabile di
+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 questa funzione elimina ogni occorrenza della variabile specificata;
+se essa 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 parametro una stringa analoga quella
+restituita da \func{getenv}, e sempre nella forma \var{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\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 \ctyp{const} dal prototipo.} \param{string} alla lista delle
+variabili di ambiente; 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
+\secref{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
+se la chiamata di \func{putenv} comporta la necessità di allocare una nuova
+versione del vettore \var{environ} questo sarà allocato, ma la versione
+corrente sarà deallocata solo se anch'essa è risultante da un'allocazione
+fatta in precedenza da un'altra \func{putenv}. Questo perché il vettore delle
+variabili di ambiente iniziale, creato dalla chiamata ad \func{exec} (vedi
+\secref{sec:proc_exec}) è piazzato al di sopra dello stack, (vedi
+\figref{fig:proc_mem_layout}) e non nello heap e non può essere deallocato.
+Inoltre la memoria associata alle variabili di ambiente eliminate non viene
+liberata.
+
+
+\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 routine chiamante venga toccato. In questo modo non
+occorre preoccuparsi di eventuali effetti delle operazioni della subroutine
+sulla variabile passata come parametro.
+
+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 routine
+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 parametri; in genere le
+informazioni a riguardo dei risultati vengono passate alla routine 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 parametri. Per far
+questo si usa il cosiddetto \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
+\secref{sec:TCPel_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 parametri per una funzione. Lo standard ISO C prevede nella
+sua sintassi la possibilità di definire delle \textit{variadic function} che
+abbiano un numero variabile di argomenti, attraverso l'uso della
+\textit{ellipsis} \var{...} nella dichiarazione della funzione; ma non
+provvede a livello di linguaggio alcun meccanismo con cui dette funzioni
+possono accedere ai loro argomenti.
+
+L'accesso viene invece realizzato dalle librerie standard che provvedono gli
+strumenti adeguati. L'uso delle \textit{variadic function} prevede 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 lo stesso
+ \textit{ellipsis}, ed utilizzare le apposite macro che consentono la
+ gestione di un numero variabile di argomenti.
+\item \textsl{Chiamare} la funzione specificando prima gli argomenti fissi, e
+ a seguire gli addizionali.
+\end{itemize*}
+
+Lo standard ISO C prevede che una \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
+\secref{sec:proc_exec}:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+ int execl(const char *path, const char *arg, ...);
+\end{lstlisting}
+in questo caso la funzione prende due parametri fissi ed un numero variabile
+di altri parametri (che verranno a costituire gli elementi successivi al primo
+del vettore \var{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 array, 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 parametro fisso come
+\ctyp{register}.
+
+Una volta dichiarata la funzione il secondo passo è accedere ai vari parametri
+quando la si va a definire. I parametri fissi infatti hanno un loro nome, ma
+quelli variabili vengono indicati in maniera generica dalla ellipsis.
+
+L'unica modalità in cui essi possono essere recuperati è pertanto quella
+sequenziale; essi verranno estratti dallo 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
+ \type{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 dei parametri 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 dei parametri fissi.
+
+ \funcdecl{type va\_arg(va\_list ap, type)} Restituisce il valore del
+ successivo parametro 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 \var{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 del parametro.
+
+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 \var{ap} risulterebbe indefinito.
+
+Esistono dei casi in cui è necessario eseguire più volte la scansione dei
+parametri 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
+stack all'indirizzo dove sono stati salvati i parametri, è assolutamente
+normale pensare di poter effettuare questa operazione.
+
+In generale però possono esistere anche realizzazioni diverse, per questo
+motivo \macro{va\_list} è definito come \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 i parametri, 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 i parametri 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 parametro
+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 dei
+parametri lo rende possibile, è quella che prevede di usare un valore speciale
+come ultimo argomento (come fa ad esempio \func{execl} che usa un puntatore
+\macro{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 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 chiara anche dal punto di vista della struttura del programma:
+quello dell'uscita in caso di errore.
+
+Il C però non consente di effettuare un salto ad una label 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 da \cite{APUE} che da da \cite{glibc}, è quello di un programma nel
+cui corpo principale in cui viene letto un input del quale viene eseguita,
+attraverso una serie di funzioni di analisi, una scansione dei contenuti da cui
+ottenere 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 nell'input 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, 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 salvando il contesto dello stack nel punto in
+cui si vuole tornare in caso di errore, e ripristinandolo quando l'occorrenza
+capita. La funzione che permette di salvare il contesto dello stack è
+\func{setjmp}, il cui prototipo è:
+\begin{functions}
+ \headdecl{setjmp.h}
+ \funcdecl{void setjmp(jmp\_buf env)}
+
+ Salva il contesto dello stack in \param{env} per un successivo uso da parte
+ di \func{longjmp}.
+
+ \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 viene salvato in appositi oggetti (di
+tipo \type{jmp\_buf}), passati come primo argomento alla funzione, in genere
+questi vengono definiti come variabili globali in modo da poter essere visti
+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. Si tenga conto che
+il contesto salvato in \param{env} viene invalidato se la routine che ha
+chiamato \func{setjmp} ritorna, nel qual caso l'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 \func{longjmp}; il suo
+prototipo è:
+\begin{functions}
+ \headdecl{setjmp.h}
+ \funcdecl{void longjmp(jmp\_buf env, int val)}
+
+ Ripristina il contesto dello stack salvato nell'ultima chiamata di
+ \func{setjmp} con l'argomento \param{env}.
+
+ \bodydesc{La funzione non ritorna.}
+\end{functions}
+
+Dopo l'esecuzione della funzione programma prosegue dal 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}, ed 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 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}