Lo standard ISO C specifica che la funzione \texttt{main} può o non avere
argomenti o prendere due argomenti che rappresentano gli argomenti passati da
linea di comando, in sostanza un prototipo che va sempre bene è il seguente:
-\begin{verbatim}
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
int main (int argc, char *argv[])
-\end{verbatim}
+\end{lstlisting}
In realtà nei sistemi unix esiste un'altro modo per definire la funzione
\texttt{main}, che prevede la presenza di un terzo parametro, \texttt{char
- *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{proc_environ}) del
-programma; questa forma però non è prevista dallo standard POSIX.1 per cui se
-si vogliono scrivere programmi portabili è meglio evitarla.
+ *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{sec:proc_environ})
+del programma; questa forma però non è prevista dallo standard POSIX.1 per cui
+se si vogliono scrivere programmi portabili è meglio evitarla.
\subsection{Come chiudere un programma}
Oltre alla conclusione ``normale'' esiste anche la possibilità di una
conclusione ``anomala'' del programma a causa di segnali o della chiamata alla
funzione \texttt{abort} (che comunque genera un segnale che termina il
-programma); torneremo su questo in \secref{sec:sig_abort}.
+programma); torneremo su questo in \secref{sec:sig_prog_error}.
Il valore di ritorno della funzione main, o quello usato nelle chiamate ad
\texttt{exit} e \texttt{\_exit}, viene chiamato \textit{exit status} e passato
possibile un processo possa essere terminato (da un segnale) prima che il
programma in esecuzione si sia concluso. In caso di conclusione normale del
programma però lo stato di uscita diventa parte dello stato di conclusione del
-processo (vedi \secref{sec:prochand_XXX}).
+processo (vedi \secref{sec:prochand_xxx}).
\subsection{Le funzioni \texttt{exit} e \texttt{\_exit}}
presente che questo non comporta il salvataggio dei dati bufferizzati degli
stream), fa si che ogni figlio del processo sia ereditato da \texttt{init}
(vedi \secref{cha:process_handling}), manda un segnale \texttt{SIGCHLD} al
-processo padre (vedi \ref{sec:sig_sigchild}) ed infine ritorna lo stato di
+processo padre (vedi \ref{sec:sig_job_control}) ed infine ritorna lo stato di
uscita specificato in \texttt{status} che può essere raccolto usando la
funzione \texttt{wait} (vedi \secref{sec:prochand_wait}).
La prima parte è il segmento dei dati inizializzati, che contiene le
variabili globali il cui valore è stato assegnato esplicitamente. Ad esempio
se si definisce:
-\begin{verbatim}
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
double pi = 3.14;
-\end{verbatim}
+\end{lstlisting}
questo valore sarà immagazzinato in questo segmento. La memoria di questo
segmento viene preallocato dalla \texttt{exec} e inizializzata ai valori
specificati.
La seconda parte è il segmento dei dati non inizializzati, che contiene le
variabili globali il cui valore è stato non è assegnato esplicitamente. Ad
esempio se si definisce:
-\begin{verbatim}
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
int vect[100];
-\end{verbatim}
+\end{lstlisting}
questo valore sarà immagazzinato in questo segmento. Anch'esso viene
allocato all'avvio, e tutte le variabili vengono inizializzate a
zero (ed i puntatori a \texttt{NULL}).
\begin{figure}[htb]
\centering
-
+ \includegraphics[width=5cm]{img/memory_layout.eps}
\caption{Disposizione tipica dei segmenti di memoria di un processo}
\label{fig:proc_mem_layout}
\end{figure}
voluta copiandoci automaticamente il contenuto, lo spazio in più non viene
inizializzato.
-Il fatto che il blocco di memoria restituito da \texttt{realloc} possa
-camabiare comporta che si deve sempre riassegnare al puntatore passato per il
+Il fatto che il blocco di memoria restituito da \func{realloc} possa
+cambiare comporta che si deve sempre riassegnare al puntatore passato per il
ridimensionamento il valore di ritorno della funzione, e che non ci devono
essere altri puntatori che puntino all'interno di un'area che si vuole
ridimensionare.
-
Uno degli errori più comuni (specie se si ha a che fare con array di
puntatori) è infatti quello di chiamare \texttt{free} più di una volta sullo
stesso puntatore; per evitare questo problema una soluzione di ripiego è
Per questo motivo l'implementazione delle routine di allocazione delle glibc
mette a disposizione una serie di funzionalità (su cui torneremo in
-\secref{sec:proc_mem_advanced}) che permettono di tracciare le allocazioni e
+\secref{sec:xxx_advanced}) che permettono di tracciare le allocazioni e
le disallocazione, e definisce anche una serie di possibili agganci che
permettono di sostituire alle funzioni di libreria una propria versione (che
può essere più o meno specializzata per il debugging).
+
\subsection{La funzione \texttt{alloca}}
\label{sec:proc_mem_alloca}
Come è evidente questa funzione ha molti vantaggi, e permette di evitare i
problemi di memory leak non essendo più necessaria la deallocazione esplicita;
una delle ragioni principali per usarla è però che funziona anche quando si
-usa \texttt{longjump} per uscire con un salto non locale da una funzione (vedi
-\secref{sec:proc_longjmp}),
+usa \func{longjump} per uscire con un salto non locale da una funzione (vedi
+\secref{sec:proc_longjmp}),
Un altro vantaggio e che in Linux la funzione è molto veloce e non viene
sprecato spazio, infatti non è necessario gestire un pool di memoria da
segnale di \textit{segmentation violation} analogo a quello che si avrebbe da
una ricorsione infinita.
+Inoltre non è chiaramente possibile usare questa funzione per allocare memoria
+che deve poi essere usata anche al di fuori della funzione in cui questa viene
+chiamata, in quanto all'uscita dalla funzione lo spazio allocato diventerebbe
+libero, e potrebbe essere sovrascritto all'invocazione di nuove funzioni con
+conseguenze imprevedibili.
+
+Questo è lo stesso problema potenziale che si può avere con le variabili
+automatiche; un errore comune infatti è quello di restituire al chiamante un
+puntatore ad una di queste variabili, che sarà automaticamente distrutta
+all'uscita della funzione, con gli stessi problemi appena citati per
+\func{alloca}.
\subsection{Le funzioni \texttt{brk} e \texttt{sbrk}}
\label{sec:proc_mem_sbrk}
\subsection{Il controllo della memoria virtuale}
-\label{sec:proc_mem_mlock}
+\label{sec:proc_mem_lock}
Come spiegato in \secref{sec:proc_mem_gen} il kernel gestisce la memoria in
maniera trasparente ai processi, decidendo quando rimuovere pagine dalla
che può dedicare a questo.
-
-
\section{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
-\texttt{goto} ampiamente deprecato in favore di costrutti più puliti; esiste
+\texttt{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.
\subsection{Le variabili di ambiente}
-\label{sec:proc_env_var}
+\label{sec:proc_environ}
+
+Oltre ai parametri passati da 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 costruita nella
+chiamata ad \func{exec} che lo ha 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 null). A
+differenza di \var{argv[]} però in questo caso non si ha la lunghezza
+dell'array dato 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.eps}
+ \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 queste c'è la convezione di usare
+nomi espressi in caratteri maiuscoli.
+
+Il kernel non usa mai queste variabili, il loro uso e la loro intepretazione è
+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 comadi), 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 ncessità).
+
+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 parziale si può controllare \cmd{man environ}