Passata generale di ispell
[gapil.git] / process.tex
index a096d6a866c6d87f152ad5888b92fb17e9e8f294..ed4cb07879c6cb45c815df2f58bf61127140bbe6 100644 (file)
@@ -6,7 +6,7 @@ sistema unix alloca ed utilizza le risorse.  Questo capitolo tratter
 l'interfaccia base fra il sistema e i processi, su come vengono passati i
 parametri, come viene gestita e allocata la memoria, su come un processo può
 richiedere servizi al sistema, su cosa deve fare quando ha finito la sua
-esecuzione. Nella sezione finale acceneremo ad alcune problematiche generiche
+esecuzione. Nella sezione finale accenneremo ad alcune problematiche generiche
 di programmazione.
 
 In genere un programma viene eseguito quando un processo lo fa partire
@@ -33,6 +33,7 @@ posto in esecuzione esso apparir
 discorso dei \textit{thread} comunque in Linux necessita di una trattazione a
 parte per la peculiarità dell'implementazione).
 
+
 \subsection{La funzione \func{main}} 
 \label{sec:proc_main}
 
@@ -152,7 +153,7 @@ prototipo della funzione 
   La funzione non ritorna. Il processo viene terminato.
 \end{prototype}
 
-La funzione chiude tutti i file descriptor appartenenti al processo (sui tenga
+La funzione chiude tutti i file descriptor appartenenti al processo (si tenga
 presente che questo non comporta il salvataggio dei dati bufferizzati degli
 stream), fa si che ogni figlio del processo sia ereditato da \cmd{init}
 (vedi \secref{cha:process_handling}), manda un segnale \macro{SIGCHLD} al
@@ -233,11 +234,12 @@ Lo schema delle modalit
 
 \begin{figure}[htb]
   \centering
-  
+  \includegraphics[width=12cm]{img/proc_beginend}
   \caption{Schema dell'avvio e della conclusione di un programma.}
   \label{fig:proc_prog_start_stop}
 \end{figure}
 
+
 Si ricordi infine che un programma può anche essere interrotto dall'esterno
 attraverso l'uso di un segnale (modalità di conclusione non mostrata in
 \curfig); torneremo su questo aspetto in \secref{cha:signals}.
@@ -389,7 +391,7 @@ programma C viene suddiviso nei seguenti segmenti:
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=5cm]{img/memory_layout.eps}
+  \includegraphics[width=5cm]{img/memory_layout}
   \caption{Disposizione tipica dei segmenti di memoria di un processo}
   \label{fig:proc_mem_layout}
 \end{figure}
@@ -460,7 +462,7 @@ quattro, i prototipi sono i seguenti:
 \funcdecl{void free(void *ptr)}
   Disalloca lo spazio di memoria puntato da \var{ptr}.
 
-  La funzione non ritorna nulla.
+  La funzione non ritorna nulla e non riporta errori.
 \end{functions}
 Il puntatore che le funzioni di allocazione ritornano è garantito essere
 sempre correttamente allineato per tutti i tipi di dati; ad esempio sulle
@@ -494,14 +496,16 @@ comporta come \func{malloc}\footnote{questo 
   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 spazio in più non viene
+voluta copiandoci automaticamente il contenuto, lo spazio aggiunto non viene
 inizializzato. 
 
-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.
+Si deve sempre avere ben presente il fatto che il blocco di memoria restituito
+da \func{realloc} può non essere una estensione di quello che gli si è passato
+come parametro; pertanto esso deve essere trattato allo stesso modo di una
+nuova allocazione; in particolare si dovrà \emph{sempre} eseguire la
+riassegnazione di \var{ptr} al valore di ritorno della funzione, e
+reinizializzare (o provvedere ad un adeguato aggiornamento qualora ancora
+servano) tutti gli altri puntatori al blocco di dati ridimensionato.
 
 Uno degli errori più comuni (specie se si ha a che fare con array di
 puntatori) è infatti quello di chiamare \func{free} più di una volta sullo
@@ -520,7 +524,7 @@ particolare:
 \begin{itemize*}
 \item se la variabile è posta a zero gli errori vengono ignorati.
 \item se è posta ad 1 viene stampato un avviso sullo \textit{standard error}
-  (vedi \secref{sec:file_stdfiles}).
+  (vedi \secref{sec:file_std_stream}).
 \item se è posta a 2 viene chiamata \func{abort}, che in genere causa
   l'immediata conclusione del programma.
 \end{itemize*}
@@ -545,59 +549,58 @@ 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}}  
+\subsection{La funzione \func{alloca}}  
 \label{sec:proc_mem_alloca}
 
-Una alternativa possibile all'uso di \texttt{malloc}, che non soffre del tipo
+Una alternativa possibile all'uso di \func{malloc}, che non soffre del tipo
 di problemi di memory leak descritti in precedenza è la funzione
-\texttt{alloca} che invece che allocare la memoria nello heap usa lo il
+\func{alloca} che invece che allocare la memoria nello heap usa lo il
 segmento di stack della funzione corrente. La sintassi è identica:
 \begin{prototype}{stdlib.h}{void *alloca(size\_t size)}
-  Alloca \texttt{size} byte nel segmento di stack della funzione chiamante.
+  Alloca \var{size} byte nel segmento di stack della funzione chiamante.
   La memoria non viene inizializzata.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \texttt{NULL} in caso di fallimento, nel qual caso
-  \texttt{errno} viene settata a \texttt{ENOMEM}.
+  di successo e \macro{NULL} in caso di fallimento, nel qual caso
+  \var{errno} viene settata a \macro{ENOMEM}.
 \end{prototype}
-ma in questo caso non è più necessario liberare la memoria in quanto questa
-viene rilasciata automaticamente al ritorno della funzione.
+\noindent ma in questo caso non è più necessario liberare la memoria in quanto
+questa viene rilasciata automaticamente al ritorno della funzione.
 
 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 \func{longjump} per uscire con un salto non locale da una funzione (vedi
+usa \func{longjmp} 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
-riservare e si evitano anche problemi di frammentazione.
+riservare e si evitano anche i problemi di frammentazione di quest'ultimo che
+comportano inefficienze sia nell'allocazione della memoria che nell'esecuzione
+della funzione.
 
-Gli svantaggi sono che la funzione non è disponibile su tutti gli unix, quando
-non è possibile aumentare le dimensioni dello stack una volta chiamata una
-funzione e quindi l'uso limita la portabilità dei programmi, inoltre se si
-cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma un
-segnale di \textit{segment violation} analogo a quello che si avrebbe da una
-ricorsione infinita.
+Gli svantaggi sono che questa funzione non è disponibile su tutti gli unix,
+(quando non è possibile aumentare le dimensioni dello stack una volta chiamata
+una funzione) e quindi l'uso limita la portabilità dei programmi, inoltre se
+si cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma
+un segnale di \textit{segment 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. 
+conseguenze imprevedibili. Questo è lo stesso problema potenziale che si può
+avere con le variabili automatiche, su cui torneremo in
+\secref{sec:proc_auto_var}.
 
-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 \func{brk} e \func{sbrk}}  
 \label{sec:proc_mem_sbrk}
 
 L'uso di queste funzioni è necessario solo quando si voglia accedere alle
 analoghe system call a cui fanno da interfaccia (ad esempio per implementare
-una propria versione di \func{malloc}. Le  funzione sono:
+una propria versione di \func{malloc}. Le funzioni sono:
 \begin{prototype}{unistd.h}{int *brk(void end\_data\_segment)}
   Sposta la fine del segmento dei dati all'indirizzo specificato da
   \var{end\_data\_segment}.
@@ -633,11 +636,11 @@ maniera trasparente ai processi, decidendo quando rimuovere pagine dalla
 memoria per metterle nello swap sulla base dell'utilizzo corrente da parte dei
 vari processi. 
 
-Nell'uso comune un processo non deve preoccuparsi di tutto ciò in quanto il
+Nell'uso comune un processo non deve preoccuparsi di tutto ciò, in quanto il
 meccanismo della paginazione riporta in RAM, ed in maniera trasparente, tutte
 le pagine che gli occorrono; esistono però esigenze particolari in cui non si
-vuole che il meccanismo dello \textit{swapping}, in generale i motivi per cui
-si possono avere queste necessità sono sostanzialmente due:
+vuole che si attivi il meccanismo dello \textit{swapping}, in generale i
+motivi per cui si possono avere queste necessità sono sostanzialmente due:
 \begin{itemize}
 \item La velocità. Il processo della paginazione è trasparente solo se il
   programma in esecuzione se non è sensibile al tempo che occorre a riportare
@@ -654,11 +657,12 @@ si possono avere queste necessit
   
 \item La sicurezza. Se si tengono password o chiavi in memoria queste possono
   essere portate su disco dal meccanismo della paginazione, questo rende più
-  lungo il periodo di tempo in cui i segreti sono presenti in chiaro, e
-  complessa la loro cancellazione (in genere è possibile cancellare della RAM
-  ma altrettanto non vale per il disco su cui la pagina contenente i segreti
-  può essere stata salvata). Per questo motivo programmi di crittografia
-  richiedono il blocco di alcune pagine di memoria.
+  lungo il periodo di tempo in cui i 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 la pagina contenente i segreti 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
@@ -674,50 +678,101 @@ sbloccarla due volte, una pagina o 
 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 \textit{memory lock}.
+tutti i suoi \textit{memory lock}.
 
 I \textit{memory lock} non sono ereditati dai processi figli\footnote{ma
   siccome Linux usa il copy on write 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 dei memory lock del padre}.
-Siccome la presenza di \textit{memory lock} ha un impatto sugli altri processi
-solo l'amministratore ha la capacità di bloccare una pagina; ogni processo
-però può sbloccare le sue pagine. 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.
+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 però può sbloccare le sue
+pagine. 
+
+
+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{stdlib.h}
-\funcdecl{void *calloc(size\_t size)}
-  Alloca \var{size} byte nello heap. La memoria viene inizializzata a 0.
+  \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.
+
+  La funzione ritorna 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{EPERM} il processo non ha i privilegi richiesti per
+    l'operazione. 
+  \item \macro{EINVAL} \var{len} non è un valore positivo.
+  \end{errlist}
   
-  La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene settata a \macro{ENOMEM}.
-\funcdecl{void *malloc(size\_t size)}
+  \funcdecl{int munlock(const void *addr, size\_t len)}
   Alloca \var{size} byte nello heap. La memoria non viene inizializzata.
 
-  La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene settata a \macro{ENOMEM}.
-\funcdecl{void *realloc(void *ptr, size\_t size)}
-  Cambia la dimensione del blocco allocato all'indirizzo \var{ptr}
-  portandola a \var{size}.
+  Sblocca l'intervallo di memoria da \var{addr} per \var{len} byte.  La
+  funzione ritorna 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.
+  \item \macro{EINVAL} \var{len} non è un valore positivo.
+  \end{errlist}
+\end{functions}
 
-  La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene settata a \macro{ENOMEM}.
-\funcdecl{void free(void *ptr)}
-  Disalloca lo spazio di memoria puntato da \var{ptr}.
+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:
 
-  La funzione non ritorna nulla.
-\end{functions}
+\begin{functions}
+  \headdecl{sys/mman.h} 
 
+  \funcdecl{int mlockall(int flags)}
+  Blocca la paginazione per lo spazio di indirizzi del processo corrente. 
+  
+  Codici di ritorno ed errori sono gli stessi di \func{mlock}.
 
+  \funcdecl{int munlockall(void)}
+  Sblocca la paginazione per lo spazio di indirizzi del processo corrente. 
+  
+  Codici di ritorno ed errori sono gli stessi di \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{description*}
+\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{description*}
+
+Con \func{mlockall} si può bloccare tutte le pagine mappate nello spazio di
+indirizzi del processo, sia che comprendano il segmento di testi, di dati, lo
+stack e 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, in genere
+questo si fa chiamando una funzione che ha allocato una quantità sufficiente
+ampia di variabili automatiche, in modo che esse vengano mappate in RAM dallo
+stack e poi ci scrive sopra, per scongiurare in partenza un eventuale page
+fault causato dal meccanismo di copy on write.
 
 
 \section{La gestione di parametri e opzioni}
@@ -848,7 +903,7 @@ 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
-opioni possibili si è poi provveduto ad una opportuna azione, ad esempio per
+opzioni possibili si è poi provveduto ad una opportuna azione, 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
@@ -906,7 +961,7 @@ un esempio del contenuto dell'ambiente, in si 
 variabili che normalmente sono definite dal sistema, è riportato in \nfig.
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=11cm]{img/environ_var.eps}
+  \includegraphics[width=11cm]{img/environ_var}
   \caption{Esempio di lista delle variabili di ambiente.}
   \label{fig:proc_envirno_list}
 \end{figure}
@@ -914,7 +969,7 @@ variabili che normalmente sono definite dal sistema, 
 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 convezione di usare nomi espressi in
+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 è
@@ -932,8 +987,46 @@ 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 parziale si può controllare \cmd{man environ}.
+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{6cm}|}
+    \hline
+    \textbf{Variabile} & POSIX & XPG & 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 lasciando alle varie implementazioni i contenuti,
+definisce la funzione \func{getenv} che permetta 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}. 
+  
+  La funzione \macro{NULL} se non trova nulla, o il puntatore alla stringa che
+  corrisponde (di solito nella forma \texttt{NOME=valore}).
+\end{prototype}
 
 
 
@@ -953,9 +1046,9 @@ entit
 
 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 variabli sono
-passate, come suol dirsi, \textit{by reference}, o dal C++ dove la modalità del
-passaggio può essere controllata con l'operatore \cmd{\&}). 
+(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
@@ -1018,6 +1111,27 @@ 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 la funzione \func{longjump}. 
+annidate occorre usare la funzioni \func{setjmp} e \func{longjmp}, il cui
+prototipo è:
+\begin{functions}
+  \headdecl{setjmp.h}
+  \funcdecl{void setjmp(jmp\_buf env)}
+  
+  La funzione 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.
+  
+  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.
 
+  \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.
+
+  La funzione non ritorna.
+\end{functions}