+Il meccanismo che previene la paginazione di parte della memoria virtuale di
+un processo è chiamato \textit{memory locking} (o \textsl{blocco della
+ memoria}). Il blocco è sempre associato alle pagine della memoria virtuale
+del processo, e non al segmento reale di RAM su cui essa viene mantenuta.
+
+La regola è che se un segmento di RAM fa da supporto ad almeno una pagina
+bloccata allora esso viene escluso dal meccanismo della paginazione. I blocchi
+non si accumulano, se si blocca due volte la stessa pagina non è necessario
+sbloccarla due volte, una pagina o è bloccata oppure no.
+
+Il \textit{memory lock} persiste fintanto che il processo che detiene la
+memoria bloccata non la sblocca. Chiaramente la terminazione del processo
+comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di
+tutti i suoi \textit{memory lock}.
+
+I \textit{memory lock} non sono ereditati dai processi figli.\footnote{ma
+ siccome Linux usa il \textit{copy on write} (vedi \secref{sec:proc_fork})
+ gli indirizzi virtuali del figlio sono mantenuti sullo stesso segmento di
+ RAM del padre, quindi fintanto che un figlio non scrive su un segmento, può
+ usufruire del memory lock del padre.} Siccome la presenza di un
+\textit{memory lock} riduce la memoria disponibile al sistema, con un impatto
+su tutti gli altri processi, solo l'amministratore ha la capacità di bloccare
+una pagina. Ogni processo può però sbloccare le pagine relative alla propria
+memoria.
+
+Il sistema pone dei limiti all'ammontare di memoria di un processo che può
+essere bloccata e al totale di memoria fisica che può dedicare a questo, lo
+standard POSIX.1 richiede che sia definita in \file{unistd.h} la costante
+\macro{\_POSIX\_MEMLOCK\_RANGE} per indicare la capacità di eseguire il
+\textit{memory locking} e la costante \macro{PAGESIZE} in \file{limits.h} per
+indicare la dimensione di una pagina in byte.
+
+Le funzioni per bloccare e sbloccare singole sezioni di memoria sono
+\func{mlock} e \func{munlock}; i loro prototipi sono:
+\begin{functions}
+ \headdecl{sys/mman.h}
+
+ \funcdecl{int mlock(const void *addr, size\_t len)}
+ Blocca la paginazione per l'intervallo di memoria da \var{addr} per
+ \var{len} byte. Tutte le pagine che contengono una parte dell'intervallo
+ sono mantenute in RAM per tutta la durata del blocco.
+
+ \funcdecl{int munlock(const void *addr, size\_t len)}
+ Sblocca l'intervallo di memoria da \var{addr} per \var{len} byte.
+
+
+ \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in
+ caso di errore, nel qual caso \var{errno} è settata ad 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 causato dal meccanismo di
+\textit{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 e 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 il settaggio 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 \curfig.
+
+
+\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 \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 \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}
+ed \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 \var{':'}; nel caso di \figref{fig:proc_argv_argc} ad esempio la
+stringa di opzioni avrebbe dovuto contenere \var{"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
+\cmd{--} 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.
+
+Anzitutto 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}
+così che 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 è settata 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 del contenuto dell'ambiente, in si è riportato un estratto delle
+variabili che normalmente sono definite dal sistema, è riportato in \nfig.
+\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 \curfig, 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. 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 \ntab. 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
+ \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 utente\\
+ \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 di default\\
+ \macro{BROWSER} & $\bullet$ & $\bullet$ & $\bullet$ & Browser di default\\
+ \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 settare e per cancellare le variabili di ambiente. Uno schema
+delle funzioni previste nei vari standard e disponibili in Linux è riportato
+in \ntab.
+
+\begin{table}[htb]
+ \centering
+ \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 \curtab\ 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)}
+ Setta 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 è
+\type{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à settato 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 \type{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
+\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 \type{float} vengono convertiti
+ automaticamente a \type{double} ed i \type{char} e gli \type{short} ad
+ \type{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
+\type{char} o \type{short} (con segno o meno). Una restrizione ulteriore di
+alcuni compilatori è di non dichiarare l'ultimo parametro fisso come
+\type{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 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 \type{char} verrà visto da
+\macro{va\_arg} come \type{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 \type{static} o \type{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 funzioni profondamente
+annidate occorre usare quello che viene chiamato un salto \textsl{non-locale};
+questo viene fatto usando 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}. Il contesto viene invalidato se la routine che ha
+ chiamato \func{setjmp} ritorna.
+
+ \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}