Inizio della revisione del formato per la suddivisione in due parti,
[gapil.git] / process.tex
index dfb5d2bbf48922aaf9347b43e1fc4e38488d282c..df94444f153016202640e3ac052cbac9c53ecb80 100644 (file)
@@ -444,10 +444,10 @@ seguenti segmenti:
     automaticamente il codice necessario, seguendo quella che viene chiamata
     una \textit{calling convention}; quella standard usata con il C ed il C++
     è detta \textit{cdecl} e prevede che gli argomenti siano caricati nello
-    \textit{stack} dal chiamante da destra a sinistra, e che si il chiamante
+    \textit{stack} dal chiamante da destra a sinistra, e che sia il chiamante
     stesso ad eseguire la ripulitura dello \textit{stack} al ritorno della
     funzione, se ne possono però utilizzare di alternative (ad esempio nel
-    pascal gli argomenti sono inseriti da sinistra a destra ed è compito del
+    Pascal gli argomenti sono inseriti da sinistra a destra ed è compito del
     chiamato ripulire lo \textit{stack}), in genere non ci si deve preoccupare
     di questo fintanto che non si mescolano funzioni scritte con linguaggi
     diversi.}
@@ -760,7 +760,7 @@ funzioni di allocazione della memoria. Per poterle utilizzare è necessario
 definire una della macro di funzionalità (vedi
 sez.~\ref{sec:intro_gcc_glibc_std}) fra \macro{\_BSD\_SOURCE},
 \macro{\_SVID\_SOURCE} e \macro{\_XOPEN\_SOURCE} (ad un valore maggiore o
-ugiale di 500). La prima funzione è \funcd{brk}, ed il suo prototipo è:
+uguale di 500). La prima funzione è \funcd{brk}, ed il suo prototipo è:
 \begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)}
   Sposta la fine del segmento dei dati.
   
@@ -851,27 +851,47 @@ però non è standardizzata da POSIX e pertanto non è disponibile su tutte le
 versioni di kernel unix-like;\footnote{nel caso di Linux devono essere
   comunque definite le macro \macro{\_BSD\_SOURCE} e \macro{\_SVID\_SOURCE}.}
 il suo prototipo è:
-\begin{functions}
-  \headdecl{unistd.h} 
-  \headdecl{sys/mman.h} 
+\begin{functions}
+  \headdecl{unistd.h} 
+  \headdecl{sys/mman.h} 
 
-  \funcdecl{int mincore(void *addr, size\_t length, unsigned char *vec)}
-  Ritorna lo stato delle pagine di memoria occupate da un processo.
+  \funcdecl{int mincore(void *addr, size\_t length, unsigned char *vec)}
+  Ritorna lo stato delle pagine di memoria occupate da un processo.
   
-  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
-    errore, nel qual caso \var{errno} assumerà uno dei valori seguenti:
-  \begin{errlist}
-  \item[\errcode{ENOMEM}] o \param{addr} + \param{length} eccede la dimensione
-    della memoria usata dal processo o l'intervallo di indirizzi specificato
-    non è mappato.
-  \item[\errcode{EINVAL}] \param{addr} non è un multiplo delle dimensioni di
-    una pagina.
-  \item[\errcode{EFAULT}] \param{vec} punta ad un indirizzo non valido.
-  \item[\errcode{EAGAIN}] il kernel è temporaneamente non in grado di fornire
-    una risposta.
-  \end{errlist}
+%   \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+%     errore, nel qual caso \var{errno} assumerà uno dei valori seguenti:
+%   \begin{errlist}
+%   \item[\errcode{ENOMEM}] o \param{addr} + \param{length} eccede la dimensione
+%     della memoria usata dal processo o l'intervallo di indirizzi specificato
+%     non è mappato.
+%   \item[\errcode{EINVAL}] \param{addr} non è un multiplo delle dimensioni di
+%     una pagina.
+%   \item[\errcode{EFAULT}] \param{vec} punta ad un indirizzo non valido.
+%   \item[\errcode{EAGAIN}] il kernel è temporaneamente non in grado di fornire
+%     una risposta.
+%   \end{errlist}
+% }
+% \end{functions}
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/mman.h}
+\fdecl{int mincore(void *addr, size\_t length, unsigned char *vec)}
+\fdesc{Ritorna lo stato delle pagine di memoria occupate da un processo.}
 }
-\end{functions}
+{La funzione ritorna 0 in caso di successo e $-1$ in caso di errore, nel qual
+caso \var{errno} assumerà uno dei valori seguenti:
+\begin{errlist}
+   \item[\errcode{ENOMEM}] o \param{addr} + \param{length} eccede la dimensione
+     della memoria usata dal processo o l'intervallo di indirizzi specificato
+     non è mappato.
+   \item[\errcode{EINVAL}] \param{addr} non è un multiplo delle dimensioni di
+     una pagina.
+   \item[\errcode{EFAULT}] \param{vec} punta ad un indirizzo non valido.
+   \item[\errcode{EAGAIN}] il kernel è temporaneamente non in grado di fornire
+     una risposta.
+\end{errlist}}
+\end{funcproto}
 
 La funzione permette di ottenere le informazioni sullo stato della mappatura
 della memoria per il processo chiamante, specificando l'intervallo da
@@ -960,16 +980,39 @@ fintanto che ci sarà almeno un processo che la blocca.
 Le funzioni per bloccare e sbloccare la \index{paginazione} paginazione di
 singole sezioni di memoria sono \funcd{mlock} e \funcd{munlock}; i loro
 prototipi sono:
-\begin{functions}
-  \headdecl{sys/mman.h} 
+\begin{functions}
+  \headdecl{sys/mman.h} 
 
-  \funcdecl{int mlock(const void *addr, size\_t len)}
-  Blocca la paginazione su un intervallo di memoria.
+  \funcdecl{int mlock(const void *addr, size\_t len)}
+  Blocca la paginazione su un intervallo di memoria.
 
-  \funcdecl{int munlock(const void *addr, size\_t len)}
-  Rimuove il blocco della paginazione su un intervallo di memoria.
+  \funcdecl{int munlock(const void *addr, size\_t len)}
+  Rimuove il blocco della paginazione su un intervallo di memoria.
   
-  \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ in
+%   \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ in
+%     caso di errore, nel qual caso \var{errno} assumerà uno dei
+%     valori seguenti:
+%   \begin{errlist}
+%   \item[\errcode{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[\errcode{EINVAL}] \param{len} non è un valore positivo.
+%   \item[\errcode{EPERM}] con un kernel successivo al 2.6.9 il processo non è
+%     privilegiato e si un limite nullo per \const{RLIMIT\_MEMLOCK}.
+%   \end{errlist}
+%   e, per \func{mlock}, anche \errval{EPERM} quando il processo non ha i
+%   privilegi richiesti per l'operazione.}
+% \end{functions}
+
+\begin{funcproto}{
+  \fhead{sys/mman.h} 
+  \fdecl{int mlock(const void *addr, size\_t len)}
+  \fdesc{Blocca la paginazione su un intervallo di memoria.}
+
+  \fdecl{int munlock(const void *addr, size\_t len)}
+  \fdesc{Rimuove il blocco della paginazione su un intervallo di memoria.}
+  }
+{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ in
     caso di errore, nel qual caso \var{errno} assumerà uno dei
     valori seguenti:
   \begin{errlist}
@@ -982,7 +1025,8 @@ prototipi sono:
   \end{errlist}
   e, per \func{mlock}, anche \errval{EPERM} quando il processo non ha i
   privilegi richiesti per l'operazione.}
-\end{functions}
+\end{funcproto}
+
 
 Le due funzioni permettono rispettivamente di bloccare e sbloccare la
 \index{paginazione} paginazione per l'intervallo di memoria specificato dagli
@@ -1071,7 +1115,7 @@ buffer sia un multiplo intero di questa dimensione, usualmente 512 byte. In
 tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una
 funzione specifica.
 
-Tradizionalmente per rispondere a questa esigenza sono state crate due
+Tradizionalmente per rispondere a questa esigenza sono state create due
 funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i
 rispettivi prototipi sono:
 \begin{functions}
@@ -1104,7 +1148,7 @@ Nessuna delle due funzioni ha una chiara standardizzazione (nessuna delle due
 compare in POSIX.1), ed inoltre ci sono indicazioni discordi sui file che ne
 contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
   \texttt{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4} e
-  \acr{lic5} la dichiarano in \texttt{malloc.h}, lo stesso vale per
+  \acr{libc5} la dichiarano in \texttt{malloc.h}, lo stesso vale per
   \func{memalign} che in alcuni sistemi è dichiarata in \texttt{stdlib.h}.}
 per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla
 nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo
@@ -1177,7 +1221,7 @@ di scrittura oltre i limiti dei buffer allocati. Per questo motivo la funzione
 deve essere chiamata prima di qualunque allocazione di memoria, altrimenti
 fallirà con un valore di ritorno pari a $-1$.
 
-Se come argomento di \func{mcheck} si passa \var{NULL} verrà utilizzata una
+Se come argomento di \func{mcheck} si passa \val{NULL} verrà utilizzata una
 funzione predefinita che stampa un messaggio di errore ed invoca la funzione
 \func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si dovrà create
 una funzione personalizzata che verrà eseguita ricevendo un unico argomento di
@@ -1206,12 +1250,12 @@ tab.~\ref{tab:mcheck_status_value}.
                               buffer.\\
     \macro{MCHECK\_TAIL}    & i dati immediatamente seguenti il buffer sono
                               stati modificati, succede quando si va scrivere
-                              oltre la dimensione correttta del buffer.\\
+                              oltre la dimensione corretta del buffer.\\
     \macro{MCHECK\_FREE}    & il buffer è già stato disallocato.\\
     \hline
   \end{tabular}
   \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla
-    funzione di teminazione installata con \func{mcheck}.} 
+    funzione di terminazione installata con \func{mcheck}.} 
   \label{tab:mcheck_status_value}
 \end{table}
 
@@ -1360,9 +1404,9 @@ ritornato il carattere \texttt{':'}, infine se viene incontrato il valore
 \texttt{'-{}-'} la scansione viene considerata conclusa, anche se vi sono altri
 elementi di \param{argv} che cominciano con il carattere \texttt{'-'}.
 
-\begin{figure}[htb]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
   \includecodesample{listati/option_code.c}
   \end{minipage}
   \normalsize
@@ -1438,7 +1482,7 @@ terminata da un puntatore nullo.
 
 L'indirizzo della lista delle variabili di ambiente è passato attraverso la
 variabile globale \var{environ}, che viene definita automaticamente per
-cisascun processo, e a cui si può accedere attraverso una semplice
+ciascun processo, e a cui si può accedere attraverso una semplice
 dichiarazione del tipo:
 \includecodesnip{listati/env_ptr.c}
 un esempio della struttura di questa lista, contenente alcune delle variabili
@@ -1481,7 +1525,7 @@ fig.~\ref{fig:proc_envirno_list}.
 Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo
 \textsl{\texttt{nome=valore}} ed in questa forma che le funzioni di gestione
 che vedremo a breve se le aspettano, se pertanto si dovesse costruire
-manualemente un ambiente si abbia cura di rispettare questa convenzione.
+manualmente un ambiente si abbia cura di rispettare questa convenzione.
 Inoltre alcune variabili, come quelle elencate in
 fig.~\ref{fig:proc_envirno_list}, sono definite dal sistema per essere usate
 da diversi programmi e funzioni: per queste c'è l'ulteriore convenzione di
@@ -1832,15 +1876,14 @@ sono definite delle apposite macro; la procedura da seguire è la seguente:
 \item Dichiarare la conclusione dell'estrazione degli argomenti invocando la
   macro \macro{va\_end}.
 \end{enumerate*}
+
 In generale è perfettamente legittimo richiedere meno argomenti di quelli che
 potrebbero essere stati effettivamente forniti, e nella esecuzione delle
 \macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti
 saranno ignorati; se invece si richiedono più argomenti di quelli forniti si
-otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso della macro
-\macro{va\_end} è inutile, ma si consiglia di usarlo ugualmente per
-compatibilità.
-
-Le definizioni delle tre macro sono le seguenti:
+otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso di
+\macro{va\_end} è inutile, ma si consiglia di usarla ugualmente per
+compatibilità. Le definizioni delle macro citate sono le seguenti:
 \begin{functions}
   \headdecl{stdarg.h}
   
@@ -1859,12 +1902,11 @@ Le definizioni delle tre macro sono le seguenti:
 
 In generale si possono avere più puntatori alla lista degli argomenti,
 ciascuno andrà inizializzato con \macro{va\_start} e letto con \macro{va\_arg}
-e ciascuno potrà scandire la lista degli argomenti per conto suo. 
-
-Dopo l'uso di \macro{va\_end} la variabile \param{ap} diventa indefinita e
-successive chiamate a \macro{va\_arg} non funzioneranno. Si avranno risultati
-indefiniti anche chiamando \macro{va\_arg} specificando un tipo che non
-corrisponde a quello dell'argomento.
+e ciascuno potrà scandire la lista degli argomenti per conto suo. Dopo l'uso
+di \macro{va\_end} la variabile \param{ap} diventa indefinita e successive
+chiamate a \macro{va\_arg} non funzioneranno. Si avranno risultati indefiniti
+anche chiamando \macro{va\_arg} specificando un tipo che non corrisponde a
+quello dell'argomento.
 
 Un altro limite delle macro è che i passi 1) e 3) devono essere eseguiti nel
 corpo principale della funzione, il passo 2) invece può essere eseguito anche
@@ -1874,13 +1916,12 @@ usato (lo standard richiederebbe la chiamata esplicita di \macro{va\_end}),
 dato che il valore di \param{ap} risulterebbe indefinito.
 
 Esistono dei casi in cui è necessario eseguire più volte la scansione degli
-argomenti e poter memorizzare una posizione durante la stessa.  La cosa più
-naturale in questo caso sembrerebbe quella di copiarsi il puntatore alla lista
-degli argomenti con una semplice assegnazione. Dato che una delle
-realizzazioni più comuni di \macro{va\_list} è quella di un puntatore nello
-\itindex{stack} \textit{stack} all'indirizzo dove sono stati salvati gli
-argomenti, è assolutamente normale pensare di poter effettuare questa
-operazione.
+argomenti e poter memorizzare una posizione durante la stessa. In questo caso
+sembrerebbe naturale copiarsi il puntatore alla lista degli argomenti con una
+semplice assegnazione. Dato che una delle realizzazioni più comuni di
+\macro{va\_list} è quella di un puntatore nello \itindex{stack} \textit{stack}
+all'indirizzo dove sono stati salvati gli argomenti, è assolutamente normale
+pensare di poter effettuare questa operazione.
 
 In generale però possono esistere anche realizzazioni diverse, per questo
 motivo \macro{va\_list} è definito come \index{tipo!opaco} \textsl{tipo opaco}
@@ -2050,7 +2091,7 @@ interagiscono direttamente con la gestione dello \itindex{stack}
 \func{setjmp} è implementata con una macro, pertanto non si può cercare di
 ottenerne l'indirizzo, ed inoltre delle chiamate a questa funzione sono sicure
 solo in uno dei seguenti casi:
-\begin{itemize}
+\begin{itemize*}
 \item come espressione di controllo in un comando condizionale, di selezione
   o di iterazione (come \code{if}, \code{switch} o \code{while});
 \item come operando per un operatore di uguaglianza o confronto in una
@@ -2059,11 +2100,12 @@ solo in uno dei seguenti casi:
 \item come operando per l'operatore di negazione (\code{!}) in una espressione
   di controllo di un comando condizionale, di selezione o di iterazione;
 \item come espressione a sé stante.
-\end{itemize}
+\end{itemize*}
 
 In generale, dato che l'unica differenza fra la chiamata diretta e quella
-ottenuta da un \func{longjmp} è costituita dal valore di ritorno di
-\func{setjmp}, essa è usualmente chiamata all'interno di un comando \code{if}.
+ottenuta nell'uscita con un \func{longjmp} è costituita dal valore di ritorno
+di \func{setjmp}, quest'ultima usualmente viene chiamata all'interno di un
+comando \code{if}.
 
 Uno dei punti critici dei salti non-locali è quello del valore delle
 variabili, ed in particolare quello delle variabili automatiche della funzione
@@ -2099,13 +2141,122 @@ dichiarandole tutte come \direct{volatile}.\footnote{la direttiva
 \index{salto~non-locale|)}
 
 
+\subsection{La \textit{endianess}}
+\label{sec:sock_endianess}
+
+\itindbeg{endianess} 
+
+Uno dei problemi di programmazione che può dar luogo ad effetti imprevisti è
+quello relativo alla cosiddetta \textit{endianess}.  Questa è una
+caratteristica generale dell'architettura hardware di un computer che dipende
+dal fatto che la rappresentazione di un numero binario può essere fatta in due
+modi, chiamati rispettivamente \textit{big endian} e \textit{little endian} a
+seconda di come i singoli bit vengono aggregati per formare le variabili
+intere (ed in genere in diretta corrispondenza a come sono poi in realtà
+cablati sui bus interni del computer).
+
+\begin{figure}[!htb]
+  \centering \includegraphics[height=3cm]{img/endianess}
+  \caption{Schema della disposizione dei dati in memoria a seconda della
+    \textit{endianess}.}
+  \label{fig:sock_endianess}
+\end{figure}
+
+Per capire meglio il problema si consideri un intero a 32 bit scritto in una
+locazione di memoria posta ad un certo indirizzo. Come illustrato in
+fig.~\ref{fig:sock_endianess} i singoli bit possono essere disposti in memoria
+in due modi: a partire dal più significativo o a partire dal meno
+significativo.  Così nel primo caso si troverà il byte che contiene i bit più
+significativi all'indirizzo menzionato e il byte con i bit meno significativi
+nell'indirizzo successivo; questo ordinamento è detto \textit{big endian},
+dato che si trova per prima la parte più grande. Il caso opposto, in cui si
+parte dal bit meno significativo è detto per lo stesso motivo \textit{little
+  endian}.
+
+Si può allora verificare quale tipo di \textit{endianess} usa il proprio
+computer con un programma elementare che si limita ad assegnare un valore ad
+una variabile per poi ristamparne il contenuto leggendolo un byte alla volta.
+Il codice di detto programma, \file{endtest.c}, è nei sorgenti allegati,
+allora se lo eseguiamo su un normale PC compatibile, che è \textit{little
+  endian} otterremo qualcosa del tipo:
+\begin{verbatim}
+[piccardi@gont sources]$ ./endtest
+Using value ABCDEF01
+val[0]= 1
+val[1]=EF
+val[2]=CD
+val[3]=AB
+\end{verbatim}%$
+mentre su un vecchio Macintosh con PowerPC, che è \textit{big endian} avremo
+qualcosa del tipo:
+\begin{verbatim}
+piccardi@anarres:~/gapil/sources$ ./endtest
+Using value ABCDEF01
+val[0]=AB
+val[1]=CD
+val[2]=EF
+val[3]= 1
+\end{verbatim}%$
+
+L'attenzione alla \textit{endianess} nella programmazione è importante, perché
+se si fanno assunzioni relative alla propria architettura non è detto che
+queste restino valide su un'altra architettura. Inoltre, come vedremo ad
+esempio in sez.~\ref{sec:sock_addr_func}, si possono avere problemi quando ci
+si trova a usare valori di un formato con una infrastruttura che ne usa
+un altro. 
+
+La \textit{endianess} di un computer dipende essenzialmente dalla architettura
+hardware usata; Intel e Digital usano il \textit{little endian}, Motorola,
+IBM, Sun (sostanzialmente tutti gli altri) usano il \textit{big endian}. Il
+formato dei dati contenuti nelle intestazioni dei protocolli di rete (il
+cosiddetto \textit{network order} è anch'esso \textit{big endian}; altri
+esempi di uso di questi due diversi formati sono quello del bus PCI, che è
+\textit{little endian}, o quello del bus VME che è \textit{big endian}.
+
+Esistono poi anche dei processori che possono scegliere il tipo di formato
+all'avvio e alcuni che, come il PowerPC o l'Intel i860, possono pure passare
+da un tipo di ordinamento all'altro con una specifica istruzione. In ogni caso
+in Linux l'ordinamento è definito dall'architettura e dopo l'avvio del sistema
+in genere resta sempre lo stesso,\footnote{su architettura PowerPC è possibile
+  cambiarlo, si veda sez.~\ref{sec:process_prctl}.} anche quando il processore
+permetterebbe di eseguire questi cambiamenti.
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/endian.c}
+  \end{minipage} 
+  \normalsize
+  \caption{La funzione \func{endian}, usata per controllare il tipo di
+    architettura della macchina.}
+  \label{fig:sock_endian_code}
+\end{figure}
+
+Per controllare quale tipo di ordinamento si ha sul proprio computer si è
+scritta una piccola funzione di controllo, il cui codice è riportato
+fig.~\ref{fig:sock_endian_code}, che restituisce un valore nullo (falso) se
+l'architettura è \textit{big endian} ed uno non nullo (vero) se l'architettura
+è \textit{little endian}.
+
+Come si vede la funzione è molto semplice, e si limita, una volta assegnato
+(\texttt{\small 9}) un valore di test pari a \texttt{0xABCD} ad una variabile
+di tipo \ctyp{short} (cioè a 16 bit), a ricostruirne una copia byte a byte.
+Per questo prima (\texttt{\small 10}) si definisce il puntatore \var{ptr} per
+accedere al contenuto della prima variabile, ed infine calcola (\texttt{\small
+  11}) il valore della seconda assumendo che il primo byte sia quello meno
+significativo (cioè, per quanto visto in fig.~\ref{fig:sock_endianess}, che sia
+\textit{little endian}). Infine la funzione restituisce (\texttt{\small 12})
+il valore del confronto delle due variabili. 
+\itindend{endianess}
+
+
 
 % LocalWords:  like exec kernel thread main ld linux static linker char envp Gb
 % LocalWords:  sez POSIX exit system call cap abort shell diff errno stdlib int
 % LocalWords:  SUCCESS FAILURE void atexit stream fclose unistd descriptor init
 % LocalWords:  SIGCHLD wait function glibc SunOS arg argp execve fig high kb Mb
 % LocalWords:  memory alpha swap table printf Unit MMU paging fault SIGSEGV BSS
-% LocalWords:  multitasking text segment NULL Block Started Symbol
+% LocalWords:  multitasking text segment NULL Block Started Symbol fill black
 % LocalWords:  heap stack calling convention size malloc calloc realloc nmemb
 % LocalWords:  ENOMEM ptr uClib cfree error leak smartpointers hook Dmalloc brk
 % LocalWords:  Gray Watson Electric Fence Bruce Perens sbrk longjmp SUSv BSD ap
@@ -2119,8 +2270,14 @@ dichiarandole tutte come \direct{volatile}.\footnote{la direttiva
 % LocalWords:  clearenv libc value overwrite string reference result argument
 % LocalWords:  socket variadic ellipsis header stdarg execl self promoting last
 % LocalWords:  float double short register type dest src extern setjmp jmp buf
-% LocalWords:  env return if while Di page cdecl 
-% LocalWords:  environment
+% LocalWords:  env return if while Di page cdecl  rectangle node anchor west PS
+% LocalWords:  environment rounded corners dashed south width height draw east
+% LocalWords:  exithandler handler violation inline SOURCE SVID XOPEN mincore
+% LocalWords:  length unsigned vec EFAULT EAGAIN dell'I memalign valloc posix
+% LocalWords:  boundary memptr alignment sizeof overrun mcheck abortfn enum big
+% LocalWords:  mprobe DISABLED HEAD TAIL touch right emacs OSTYPE endianess IBM
+% LocalWords:  endian little endtest Macintosh PowerPC Intel Digital Motorola
+% LocalWords:  Sun order VME 
 
 %%% Local Variables: 
 %%% mode: latex