le librerie condivise che servono al programma, poi effettua il link dinamico
del codice e alla fine lo esegue. Infatti, a meno di non aver specificato il
flag \texttt{-static} durante la compilazione, tutti i programmi in Linux sono
-incompleti e necessitano di essere linkati alle librerie condivise quando
-vengono avviati. La procedura è controllata da alcune variabili di ambiente e
-dal contenuto di \file{/etc/ld.so.conf}. I dettagli sono riportati nella man
-page di \cmd{ld.so}.
+incompleti e necessitano di essere \textit{linkati} alle librerie condivise
+quando vengono avviati. La procedura è controllata da alcune variabili di
+ambiente e dal contenuto di \file{/etc/ld.so.conf}. I dettagli sono riportati
+nella man page di \cmd{ld.so}.
Il sistema fa partire qualunque programma chiamando la funzione \func{main};
sta al programmatore chiamare così la funzione principale del programma da cui
si suppone iniziare l'esecuzione; in ogni caso senza questa funzione lo stesso
-linker darebbe luogo ad errori.
+\textit{linker} darebbe luogo ad errori.
Lo standard ISO C specifica che la funzione \func{main} può non avere
argomenti o prendere due argomenti che rappresentano gli argomenti passati da
di chiamare direttamente la system call \func{\_exit}, che restituisce il
controllo direttamente alla routine di conclusione dei processi del kernel.
-Oltre alla conclusione ``normale'' esiste anche la possibilità di una
-conclusione ``anomala'' del programma a causa della ricezione di un segnale
-(si veda \capref{cha:signals}) o della chiamata alla funzione \func{abort};
-torneremo su questo in \secref{sec:proc_termination}.
+Oltre alla conclusione ``\textsl{normale}'' esiste anche la possibilità di una
+conclusione ``\textsl{anomala}'' del programma a causa della ricezione di un
+segnale (si veda \capref{cha:signals}) o della chiamata alla funzione
+\func{abort}; torneremo su questo in \secref{sec:proc_termination}.
Il valore di ritorno della funzione \func{main}, o quello usato nelle chiamate
ad \func{exit} e \func{\_exit}, viene chiamato \textsl{stato di uscita} (o
\subsection{Le funzioni \func{exit} e \func{\_exit}}
\label{sec:proc_exit}
-Come accennato le funzioni usate per effettuare un'uscita ``normale'' da un
-programma sono due, la prima è la funzione \funcd{exit}, che è definita dallo
-standard ANSI C ed il cui prototipo è:
+Come accennato le funzioni usate per effettuare un'uscita ``\textit{normale}''
+da un programma sono due, la prima è la funzione \funcd{exit}, che è definita
+dallo standard ANSI C ed il cui prototipo è:
\begin{prototype}{stdlib.h}{void exit(int status)}
Causa la conclusione ordinaria del programma.
del chiamante (tipo il contenuto di alcuni registri della CPU). Poi la
funzione chiamata alloca qui lo spazio per le sue variabili locali: in
questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno
- della funzione lo spazio è automaticamente rilasciato e ``ripulito''. La
- pulizia in C e C++ viene fatta dal chiamante.\footnote{a meno che non sia
- stato specificato l'utilizzo di una calling convention diversa da quella
- standard.}
+ della funzione lo spazio è automaticamente rilasciato e
+ ``\textsl{ripulito}''. La pulizia in C e C++ viene fatta dal
+ chiamante.\footnote{a meno che non sia stato specificato l'utilizzo di una
+ calling convention diversa da quella standard.}
La dimensione di questo segmento aumenta seguendo la crescita dello stack
del programma, ma non viene ridotta quando quest'ultimo si restringe.
ad un adeguato aggiornamento di tutti gli altri puntatori all'interno del
blocco di dati ridimensionato.
-Un errore abbastanza frequente (specie se si ha a che fare con array di
+Un errore abbastanza frequente (specie se si ha a che fare con vettori di
puntatori) è quello di chiamare \func{free} più di una volta sullo stesso
puntatore; per evitare questo problema una soluzione di ripiego è quella di
assegnare sempre a \val{NULL} ogni puntatore liberato con \func{free}, dato
Le \acr{glibc} hanno un'implementazione delle routine di allocazione che è
controllabile dall'utente attraverso alcune variabili di ambiente, in
particolare diventa possibile tracciare questo tipo di errori usando la
-variabile d'ambiente \val{MALLOC\_CHECK\_} che quando viene definita mette in
+variabile di ambiente \val{MALLOC\_CHECK\_} che quando viene definita mette in
uso una versione meno efficiente delle funzioni suddette, che però è più
tollerante nei confronti di piccoli errori come quello di chiamate doppie a
\func{free}. In particolare:
Il problema più comune e più difficile da risolvere che si incontra con le
routine di allocazione è quando non viene opportunamente liberata la memoria
-non più utilizzata, quello che in inglese viene chiamato \textit{memory-leak},
-cioè una \textsl{perdita di memoria}.
+non più utilizzata, quello che in inglese viene chiamato \textit{memory
+ leak}\index{memory leak}, cioè una \textsl{perdita di memoria}.
Un caso tipico che illustra il problema è quello in cui in una subroutine si
alloca della memoria per uso locale senza liberarla prima di uscire. La
momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
essere in una sezione del codice che non ha alcuna relazione con la subroutine
che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
-\textit{memory leak}.
+\textit{memory leak}\index{memory leak}.
In C e C++ il problema è particolarmente sentito. In C++, per mezzo della
programmazione ad oggetti, il problema dei \textit{memory leak} è notevolmente
\label{sec:proc_mem_alloca}
Una possibile alternativa all'uso di \func{malloc}, che non soffre dei
-problemi di \textit{memory leak} descritti in precedenza, è la funzione
-\funcd{alloca}, che invece di allocare la memoria nello heap usa il segmento
-di stack della funzione corrente. La sintassi è identica a quella di
-\func{malloc}, il suo prototipo è:
+problemi di \textit{memory leak}\index{memory leak} descritti in precedenza, è
+la funzione \funcd{alloca}, che invece di allocare la memoria nello heap usa
+il segmento di stack della funzione corrente. La sintassi è identica a quella
+di \func{malloc}, il suo prototipo è:
\begin{prototype}{stdlib.h}{void *alloca(size\_t size)}
Alloca \param{size} byte nello stack.
rilasciata automaticamente al ritorno della funzione.
Come è evidente questa funzione ha molti vantaggi, anzitutto permette di
-evitare alla radice i problemi di memory leak, dato che non serve più la
-deallocazione esplicita; inoltre la deallocazione automatica funziona anche
-quando si usa \func{longjmp} per uscire da una subroutine con un salto non
-locale da una funzione (vedi \secref{sec:proc_longjmp}).
+evitare alla radice i problemi di memory leak\index{memory leak}, dato che non
+serve più la deallocazione esplicita; inoltre la deallocazione automatica
+funziona anche quando si usa \func{longjmp} per uscire da una subroutine con
+un salto non locale da una funzione (vedi \secref{sec:proc_longjmp}).
Un altro vantaggio è che in Linux la funzione è molto più veloce di
\func{malloc} e non viene sprecato spazio, infatti non è necessario gestire un
fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.}
\end{prototype}
-La funzione è un'interfaccia diretta all'ominima system call ed imposta
+La funzione è un'interfaccia diretta all'omonima system call ed imposta
l'indirizzo finale del segmento dati di un processo all'indirizzo specificato
da \param{end\_data\_segment}. Quest'ultimo deve essere un valore ragionevole,
ed inoltre la dimensione totale del segmento non deve comunque eccedere un
La seconda funzione per la manipolazione delle dimensioni del segmento
dati\footnote{in questo caso si tratta soltanto di una funzione di libreria, e
- non di una sistem call.} è \funcd{sbrk}, ed il suo prototipo è:
+ non di una system call.} è \funcd{sbrk}, ed il suo prototipo è:
\begin{prototype}{unistd.h}{void *sbrk(ptrdiff\_t increment)}
Incrementa la dimensione dello spazio dati.
usage();
return -1;
break;
- case 'c': /* take wait time for childen */
+ case 'c': /* take wait time for children */
wait_child = strtol(optarg, NULL, 10); /* convert input */
break;
- case 'p': /* take wait time for childen */
+ case 'p': /* take wait time for children */
wait_parent = strtol(optarg, NULL, 10); /* convert input */
break;
case 'e': /* take wait before parent exit */
\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
+Come per la lista dei parametri anche questa lista è un vettore di puntatori a
caratteri, ciascuno dei quali punta ad una stringa, terminata da un
\val{NULL}. A differenza di \code{argv[]} in questo caso non si ha una
-lunghezza dell'array data da un equivalente di \param{argc}, ma la lista è
+lunghezza del vettore data da un equivalente di \param{argc}, ma la lista è
terminata da un puntatore nullo.
L'indirizzo della lista delle variabili di ambiente è passato attraverso la
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
+ a sé stesso.} il che esclude vettori, puntatori a funzioni e interi di tipo
\ctyp{char} o \ctyp{short} (con segno o meno). Una restrizione ulteriore di
alcuni compilatori è di non dichiarare l'ultimo parametro fisso come
\ctyp{register}.