+\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
+(\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[]} però 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), 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{Variabile di ambiente più comuni definite da vari standard}
+ \label{tab:proc_env_var}
+\end{table}
+
+Lo standard ANSI C, pur non entrando nelle specifiche di come sono strutturati
+i contenuti, definisce la funzione \func{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 \macro{NULL} se non trova nulla, o il
+ puntatore alla stringa che corrisponde (di solito nella forma
+ \texttt{NOME=valore}).}
+\end{prototype}
+
+Oltre a questa funzione di lettura, che è l'unica definita dallo standard ANSI
+C, in seguito sono state proposte altre da utilizzare per settare e per
+cancellare le variabili di ambiente presenti; uno schema delle funzioni
+previste nei vari standard unix 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; 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 putenv(char *string)} Aggiunge la stringa \param{string}
+ all'ambiente.
+
+ \funcdecl{int setenv(const char *name, const char *value, int overwrite)}
+ Setta la variabile di ambiente \param{name} al valore \param{value}.
+
+ \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 per un
+ errore, che è sempre \macro{ENOMEM}.}
+\end{functions}
+\noindent la terza è:
+\begin{functions}
+ \headdecl{stdlib.h}
+
+ \funcdecl{void unsetenv(const char *name)}
+ Rimuove la variabile di ambiente \param{name}.
+\end{functions}
+
+Per cancellare una variabile di ambiente si usa \func{unsetenv}, che elimina
+ogni occorrenza della variabile, se la variabile specificata non esiste non
+succede nulla, e non è previsto (dato che la funzione è \type{void}) nessuna
+segnalazione di errore.
+
+Per modificare o aggiungere una variabile di ambiente si possono usare le
+funzioni \func{setenv} e \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 \texttt{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
+\func{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.} \func{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
+alla funzione variabili automatiche (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
+\var{=}) 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 una allocazione fatta in precedenza
+da un'altra \func{putenv}, il vettore originale (in genere piazzato al di
+sopra dello stack, vedi \figref{fig:proc_mem_layout}), o la memoria associata
+alle variabili di ambiente eliminate non viene comunque 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 se 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; 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 la possibilità di definire delle \textit{varadic function} che
+abbiano un numero variabile di argomenti, ma non provvede nessun
+meccanismo con cui queste funzioni possono accedere a questi argomenti.
+
+(NdT il resto è da fare).
+
+\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 conseguenze immaginabili di sovrapposizione.
+
+Per questo una delle regole fondamentali della programmazione in C è che
+all'uscita di una funzione non deve restare nessun riferimento a variabili
+locali di quella funzione; qualora necessiti di 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, la più bistrattata delle quali è il
+\func{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste
+però un caso in l'uso di questa istruzione porta all'implementazione più
+efficiente, 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}
+
+
+Per poter effettuare un salto non locale 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 dall'ultima chiamata di
+ \func{setjmp} con l'argomento \param{env}. Il programma prosegue dal ritorno
+ di \func{setjmp} con un valore \param{val}. Il valore di \param{val} deve
+ essere diverso da zero, se viene specificato 0 sarà usato 1 al suo posto.
+
+ \bodydesc{La funzione non ritorna.}
+\end{functions}