Come accennato le interfacce con cui i programmi possono accedere all'hardware
vanno sotto il nome di chiamate al sistema (le cosiddette \textit{system
- call}), si tratta di un insieme di funzioni che un programma può chiamare, w
-per le quali viene generata un'interruzione del processo ed il controllo passa
+ call}), si tratta di un insieme di funzioni che un programma può chiamare,
+per le quali viene generata un'interruzione del processo passando il controllo
dal programma al kernel. Sarà poi quest'ultimo che (oltre a compiere una serie
di operazioni interne come la gestione del multitasking e l'allocazione della
memoria) eseguirà la funzione richiesta in \textit{kernel space} restituendo i
risultati al chiamante.
Ogni versione di Unix ha storicamente sempre avuto un certo numero di queste
-chiamate, che sono riportate nella seconda sezione del \textsl{Manuale della
+chiamate, che sono riportate nella seconda sezione del \textsl{Manuale di
programmazione di Unix} (quella cui si accede con il comando \cmd{man 2
- nome}) e inux non fa eccezione. Queste sono poi state codificate da vari
+ <nome>}) e Linux non fa eccezione. Queste sono poi state codificate da vari
standard, che esamineremo brevemente in \secref{sec:intro_standard}.
Normalmente ciascuna di queste chiamate al sistema viene rimappata in
Questo è importante da capire perché programmare in Linux significa anzitutto
essere in grado di usare le varie interfacce contenute nella Libreria Standard
del C, in quanto né il kernel, né il linguaggio C, implementano direttamente
-operazioni comuni come la allocazione dinamica della memoria, l'input/output
+operazioni comuni come l'allocazione dinamica della memoria, l'input/output
bufferizzato o la manipolazione delle stringhe, presenti in qualunque
programma.
-Anche questo ci mostra in maniera evidente come nella stragrande magggioranza
-dei casi,\footnote{esistono implementazioni diverse delle librerie del C, come
- le \textit{libc5}, che non derivano dal progetto GNU, ma oggi sono, tranne
- casi particolari, completamente soppiantate dalle \acr{glibc}.} quello che
-si sta utilizzando è un sistema GNU/Linux, in quanto una parte essenziale del
-sistema (senza la quale niente può funzionare) è la realizzazione fatta dalla
-Free Software Foundation della suddetta libreria (la GNU Standard C Library,
-detta in breve \textit{glibc}), in cui sono state implementate tutte le
-funzioni essenziali definite negli standard POSIX e ANSI C, che vengono
-utilizzate da qualunque programma.
+Quanto appena illustrato mette in evidenza il fatto che nella stragrande
+maggioranza dei casi,\footnote{esistono implementazioni diverse delle librerie
+ del C, come le \textit{libc5} o le \textit{uclib}, che non derivano dal
+ progetto GNU, ma oggi sono, tranne casi particolari, completamente
+ soppiantate dalle \acr{glibc}.} si dovrebbe usare il nome GNU/Linux
+(piuttosto che soltanto Linux) in quanto una parte essenziale del sistema
+(senza la quale niente funzionerebbe) è la GNU Standard C Library (in breve
+\acr{glibc}), ovvero la libreria realizzata dalla Free Software Foundation
+nella quale sono state implementate tutte le funzioni essenziali definite
+negli standard POSIX e ANSI C, utilizzabili da qualunque programma.
Le funzioni di questa libreria sono quelle riportate dalla terza sezione del
-Manuale di Programmazione di Unix (cioè accessibili con il comando \cmd{man 3
- nome}) e sono costruite sulla base delle chiamate al sistema del kernel; è
-importante avere presente questa distinzione, fondamentale dal punto di vista
-dell'implementazione, anche se poi, nella realizzazione di normali programmi,
-non si hanno differenze pratiche fra l'uso di una funzione di libreria e
-quello di una chiamata al sistema.
+\textsl{Manuale di Programmazione di Unix }(cioè accessibili con il comando
+\cmd{man 3 <nome>}) e sono costruite sulla base delle chiamate al sistema del
+kernel; è importante avere presente questa distinzione, fondamentale dal punto
+di vista dell'implementazione, anche se poi, nella realizzazione di normali
+programmi, non si hanno differenze pratiche fra l'uso di una funzione di
+libreria e quello di una chiamata al sistema.
\subsection{Un sistema multiutente}
ed una serie di permessi e protezioni per impedire che utenti diversi possano
danneggiarsi a vicenda o danneggiare il sistema.
-Ad ogni utente è dato un nome \textit{username}, che è quello che viene
-richiesto all'ingresso nel sistema dalla procedura di \textit{login}. Questa
-procedura si incarica di verificare l'identità dell'utente, in genere
-attraverso la richiesta di una parola d'ordine, anche se sono possibili
-meccanismi diversi.\footnote{Ad esempio usando la libreria PAM
+Ogni utente è identificato da un nome (l'\textit{username}), che è quello che
+viene richiesto all'ingresso nel sistema dalla procedura di \textit{login}
+(descritta in dettaglio in \secref{sec:sess_login}). Questa procedura si
+incarica di verificare l'identità dell'utente, in genere attraverso la
+richiesta di una parola d'ordine (la \textit{password}), anche se sono
+possibili meccanismi diversi.\footnote{Ad esempio usando la libreria PAM
(\textit{Pluggable Autentication Methods}) è possibile astrarre
- completamente i meccanismi di autenticazione e sostituire ad esempio l'uso
+ completamente dai meccanismi di autenticazione e sostituire ad esempio l'uso
delle password con meccanismi di identificazione biometrica.}
Eseguita la procedura di riconoscimento in genere il sistema manda in
il nome di standard ISO C.
Scopo dello standard è quello di garantire la portabilità dei programmi C fra
-sistemi operativi diversi, ma oltre alla sintassi e alla semantica del
+sistemi operativi diversi, ma oltre alla sintassi ed alla semantica del
linguaggio C (operatori, parole chiave, tipi di dati) lo standard prevede
anche una libreria di funzioni che devono poter essere implementate su
qualunque sistema operativo.
moderni, provvede la compatibilità con questo standard, fornendo le funzioni
di libreria da esso previste. Queste sono dichiarate in quindici header file
(anch'essi provvisti dalla \acr{glibc}), uno per ciascuna delle quindici aree
-in cui è stata suddivisa una libreria standard. In (\ntab\ da fare) si sono
-riportati questi header, insieme a quelli definiti negli altri standard
-descritti nelle sezioni successive.
+in cui è stata suddivisa una libreria standard. In
+\tabref{tab:intro_posix_header} si sono riportati questi header, insieme a
+quelli definiti negli altri standard descritti nelle sezioni successive.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Standard} & \textbf{Contenuto} \\
+ \hline
+ \hline
+ \texttt{stdio.h} & I/O bufferizzato in standard ANSI C.\\
+ \texttt{stdlib.h} & definizioni della libreria standard.\\
+ \texttt{...} & Da completare.\\
+ \hline
+ \end{tabular}
+ \caption{Elenco dei vari file di include definiti dallo standard POSIX.}
+ \label{tab:intro_posix_header}
+\end{table}
+
+
In realtà \acr{glibc} ed i relativi header file definiscono un insieme di
funzionalità in cui sono incluse come sottoinsieme anche quelle previste dallo
Ma gli standard POSIX non si limitano alla standardizzazione delle funzioni di
libreria, e in seguito sono stati prodotti anche altri standard per la shell e
i comandi di sistema (1003.2), per le estensioni realtime e per i thread
-(1003.1d e 1003.1c) e vari altri. In \tabref{tab:intro_posix_std} si è
-riportata una classificazione sommaria dei principali documenti prodotti, e di
-come sono identificati fra IEEE ed ISO; si tenga conto inoltre che molto
-spesso si usa l'estensione IEEE anche come aggiunta al nome POSIX (ad esempio
-si può parlare di POSIX.4 come di POSIX.1b).
-
-Si tenga presente però che nuove specificazioni e proposte di
-standardizzazione si aggiungono continuamente, mentre le versioni precedenti
-vengono riviste; talvolta poi i riferimenti cambiamo nome, per cui anche solo
-seguire le denominazioni usate diventa particolarmente faticoso; una pagina
-dove si possono recuperare varie (e di norma piuttosto intricate) informazioni
-è: \href{http://www.pasc.org/standing/sd11.html}
+(1003.1d e 1003.1c) e vari altri. In \tabref{tab:intro_posix_std} è riportata
+una classificazione sommaria dei principali documenti prodotti, e di come sono
+identificati fra IEEE ed ISO; si tenga conto inoltre che molto spesso si usa
+l'estensione IEEE anche come aggiunta al nome POSIX (ad esempio si può parlare
+di POSIX.4 come di POSIX.1b).
+
+Si tenga presente però che nuove specifiche e proposte di standardizzazione si
+aggiungono continuamente, mentre le versioni precedenti vengono riviste;
+talvolta poi i riferimenti cambiamo nome, per cui anche solo seguire le
+denominazioni usate diventa particolarmente faticoso; una pagina dove si
+possono recuperare varie (e di norma piuttosto intricate) informazioni è:
+\href{http://www.pasc.org/standing/sd11.html}
{http://www.pasc.org/standing/sd11.html}.
Nelle versioni più recenti del kernel e delle librerie sono inoltre supportate
ulteriori funzionalità aggiunte dallo standard POSIX.1c per quanto riguarda i
-\textit{thread} (vedi ...), e dallo standard POSIX.1b per quanto riguarda i
-segnali e lo scheduling real-time (\secref{sec:sig_real_time} e
-\secref{sec:proc_real_time}), la misura del tempo, i meccanismi di
-intercomunicazione (\secref{sec:ipc_posix}) e l'I/O asincrono
-(\secref{sec:file_asyncronous_io}).
+\textit{thread} (vedi \capref{cha:threads}), e dallo standard POSIX.1b per
+quanto riguarda i segnali e lo scheduling real-time
+(\secref{sec:sig_real_time} e \secref{sec:proc_real_time}), la misura del
+tempo, i meccanismi di intercomunicazione (\secref{sec:ipc_posix}) e l'I/O
+asincrono (\secref{sec:file_asyncronous_io}).
Questo standard, detto anche XPG3 dal nome della suddetta guida, è sempre
basato sullo standard POSIX.1, ma prevede una serie di funzionalità aggiuntive
-fra cui le specifiche delle API per l'interfaccia grafica (X11).
+fra cui le specifiche delle API (\textit{Application Programmable Interface})
+per l'interfaccia grafica (X11).
Nel 1992 lo standard venne rivisto con una nuova versione della guida, la
Issue 4 (da cui la sigla XPG4) che aggiungeva l'interfaccia XTI (\textit{X
\label{sec:intro_bsd}
Lo sviluppo di BSD iniziò quando la fine della collaborazione fra l'Università
-di Berkley e la AT/T generò una delle prime e più importanti fratture del
+di Berkley e la AT\&T generò una delle prime e più importanti fratture del
mondo Unix. L'Università di Berkley proseguì nello sviluppo della base di
codice di cui disponeva, e che presentava parecchie migliorie rispetto alle
allora versioni disponibili, fino ad arrivare al rilascio di una versione
completa di Unix, chiamata appunto BSD, del tutto indipendente dal codice
-della AT/T.
+della AT\&T.
Benché BSD non sia uno standard formalizzato, l'implementazione di Unix
dell'Università di Berkley, ha provveduto nel tempo una serie di estensioni e
-di API grande rilievo, come il link simbolici, la funzione \code{select}, i
+API di grande rilievo, come il link simbolici, la funzione \code{select}, i
socket.
Queste estensioni sono state via via aggiunte al sistema nelle varie versioni
\subsection{Lo standard System V}
\label{sec:intro_sysv}
-Come noto Unix nasce nei laboratori della AT/T, che ne registrò il nome come
+Come noto Unix nasce nei laboratori della AT\&T, che ne registrò il nome come
marchio depositato, sviluppandone una serie di versioni diverse; nel 1983 la
versione supportata ufficialmente venne rilasciata al pubblico con il nome di
-Unix System V. Negli anni successivi l'AT/T proseguì lo sviluppo rilasciando
+Unix System V. Negli anni successivi l'AT\&T proseguì lo sviluppo rilasciando
varie versioni con aggiunte e integrazioni; nel 1989 un accordo fra vari
-venditori (AT/T, Sun, HP, e altro) portò ad una versione che provvedeva
-un'unificazione dell interfacce comprendente Xenix e BSD, la System V release
+venditori (AT\&T, Sun, HP, e altro) portò ad una versione che provvedeva
+un'unificazione delle interfacce comprendente Xenix e BSD, la System V release
4.
L'interfaccia di questa ultima release è descritta in un documento dal titolo
-\textit{System V Interface Description}, o SVID; spesso però si riferimento a
-questo standard con il nome della sua implementazione, usando la sigla SVr4.
+\textit{System V Interface Description}, o SVID; spesso però si fa riferimento
+a questo standard con il nome della sua implementazione, usando la sigla SVr4.
Anche questo costituisce un sovrainsieme delle interfacce definite dallo
standard POSIX. Nel 1992 venne rilasciata una seconda versione del sistema:
-la SVr4.2. L'anno successivo la divisione della AT/T (già a suo tempo
+la SVr4.2. L'anno successivo la divisione della AT\&T (già a suo tempo
rinominata in Unix System Laboratories) venne acquistata dalla Novell, che poi
trasferì il marchio Unix al consorzio X/Open; l'ultima versione di System V fu
la SVr4.2MP rilasciata nel Dicembre 93.
\subsection{Il comportamento standard del \cmd{gcc} e delle \acr{glibc}}
\label{sec:intro_gcc_glibc_std}
-In Linux grazie alle \acr{glibc} gli standard appena descritti sono ottenibili
-sia attraverso l'uso di opzioni del compilatore (il \cmd{gcc}) che definendo
-opportune costanti prima della inclusione dei file degli header.
+In Linux, grazie alle \acr{glibc}, gli standard appena descritti sono
+ottenibili sia attraverso l'uso di opzioni del compilatore (il \cmd{gcc}) che
+definendo opportune costanti prima dell'inclusione dei file degli header.
Se si vuole che i programmi seguano una stretta attinenza allo standard ANSI C
si può usare l'opzione \cmd{-ansi} del compilatore, e non sarà riconosciuta
\subsection{Come chiudere un programma}
\label{sec:proc_conclusion}
-Normalmente un programma finisce è quando la funzione \func{main} ritorna, una
+Normalmente un programma finisce quando la funzione \func{main} ritorna, una
modalità equivalente di chiudere il programma è quella di chiamare
direttamente la funzione \func{exit} (che viene comunque chiamata
automaticamente quando \func{main} ritorna). Una forma alternativa è quella
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. Al ritorno della
- funzione lo spazio è automaticamente 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 ``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.
dimensione di un'area di memoria precedentemente allocata, la funzione vuole
in ingresso il puntatore restituito dalla precedente chiamata ad una
\func{malloc} (se è passato un valore \macro{NULL} allora la funzione si
-comporta come \func{malloc},\footnote{questo è vero per Linux e
+comporta come \func{malloc})\footnote{questo è vero per Linux e
l'implementazione secondo lo standard ANSI C, ma non è vero per alcune
vecchie implementazioni, inoltre alcune versioni delle librerie del C
consentivano di usare \func{realloc} anche per un puntatore liberato con
\func{free} purché non ci fossero state nel frattempo altre chiamate a
funzioni di allocazione, questa funzionalità è totalmente deprecata e non è
- consentita sotto Linux.}) ad esempio quando si deve far crescere la
+ consentita sotto Linux.} ad esempio quando si deve far crescere la
dimensione di un vettore. In questo caso se è disponibile dello spazio
adiacente al precedente la funzione lo utilizza, altrimenti rialloca altrove
un blocco della dimensione voluta, copiandoci automaticamente il contenuto; lo
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è \textsl{perdita di memoria}).
+cioè \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
memoria resta così allocata fino alla terminazione del processo. Chiamate
ripetute alla stessa subroutine continueranno ad effettuare altre allocazioni,
causando a lungo andare un esaurimento della memoria disponibile (e la
-probabile l'impossibilità di proseguire l'esecuzione programma).
+probabile impossibilità di proseguire l'esecuzione del programma).
Il problema è che l'esaurimento della memoria può avvenire in qualunque
momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
\item \textsl{La sicurezza}. Se si hanno password o chiavi segrete in chiaro
in memoria queste possono essere portate su disco dal meccanismo della
paginazione. Questo rende più lungo il periodo di tempo in cui detti segreti
- sono presenti in chiaro e più complessa la loro cancellazione (ad un
- processo è possibile cancellare la memoria su cui scrive le sue variabili,
- ma non può toccare lo spazio disco su cui una pagina di memoria può essere
- stata salvata). Per questo motivo di solito i programmi di crittografia
- richiedono il blocco di alcune pagine di memoria.
+ sono presenti in chiaro e più complessa la loro cancellazione (un processo
+ può cancellare la memoria su cui scrive le sue variabili, ma non può toccare
+ lo spazio disco su cui una pagina di memoria può essere stata salvata). Per
+ questo motivo di solito i programmi di crittografia richiedono il blocco di
+ alcune pagine di memoria.
\end{itemize}
Il meccanismo che previene la paginazione di parte della memoria virtuale di
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
+permettono di gestire parametri ed opzioni, e quelle che consentono di
manipolare ed utilizzare le variabili di ambiente.
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}).
+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}
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"}.
+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
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
+\texttt{'--'} la scansione viene considerata conclusa, anche se vi sono altri
elementi di \var{argv} che cominciano con il carattere \texttt{'-'}.
\begin{figure}[htb]
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.
+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
+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})
\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.
+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}
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
+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
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
+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
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 per ciascuna fase dover gestire 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.}
+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