Si prosegue con la reindicizzazione delle funzioni, con relativa revizione
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 24 Dec 2002 23:52:49 +0000 (23:52 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 24 Dec 2002 23:52:49 +0000 (23:52 +0000)
delle medesime.

filedir.tex
process.tex
prochand.tex
signal.tex

index 2a634b9..9b4025e 100644 (file)
@@ -56,26 +56,24 @@ Come spiegato in \secref{sec:file_filesystem} l'accesso al contenuto di un
 file su disco avviene passando attraverso il suo inode\index{inode}, che è la
 struttura usata dal kernel che lo identifica univocamente all'interno di un
 singolo filesystem. Il nome del file che si trova nella voce di una directory
-è solo un'etichetta che viene associata ad un puntatore che fa riferimento al
-suddetto inode.  
+è solo un'etichetta, mantenuta all'interno della directory, che viene
+associata ad un puntatore che fa riferimento al suddetto inode.
 
 Questo significa che, fintanto che si resta sullo stesso filesystem, la
 realizzazione di un link è immediata, ed uno stesso file può avere tanti nomi
-diversi allo stesso tempo, dati da altrettante diverse associazioni allo
-stesso inode\index{inode}. Si noti anche che nessuno di questi nomi viene ad
-assumere una particolare preferenza o originalità rispetto agli altri.
+diversi, dati da altrettante diverse associazioni allo stesso
+inode\index{inode} di etichette diverse in directory diverse. Si noti anche
+che nessuno di questi nomi viene ad assumere una particolare preferenza o
+originalità rispetto agli altri, in quanto tutti fanno comunque riferimento
+allo stesso inode\index{inode}.
 
 Per aggiungere ad una directory una voce che faccia riferimento ad un
 inode\index{inode} già esistente si utilizza la funzione \func{link}; si suole
 chiamare questo tipo di associazione un collegamento diretto (o \textit{hard
-  link}).  
-
-Il prototipo della funzione e le sue caratteristiche principali,
-come risultano dalla pagina di manuale, sono le seguenti:
+  link}).  Il prototipo della funzione è:
 \begin{prototype}{unistd.h}
 {int link(const char *oldpath, const char *newpath)}
-  Crea un nuovo collegamento diretto al file indicato da \param{oldpath}
-  dandogli nome \param{newpath}.
+  Crea un nuovo collegamento diretto.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
     errore nel qual caso \var{errno} viene impostata ai valori:
@@ -95,12 +93,14 @@ come risultano dalla pagina di manuale, sono le seguenti:
   \errval{ENOSPC}, \errval{EIO}.}
 \end{prototype}
 
-La creazione di un nuovo collegamento diretto non copia il contenuto del file,
-ma si limita a creare una voce nella directory specificata con \param{newpath}
-e ad aumentare di uno il numero di riferimenti al file (riportato nel campo
-\var{st\_nlink} della struttura \struct{stat}, vedi \secref{sec:file_stat})
-aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può
-essere così chiamato con vari nomi in diverse directory.
+La funzione crea sul pathname \param{newpath} un collegamento diretto al file
+indicato da \param{oldpath}.  Per quanto detto la creazione di un nuovo
+collegamento diretto non copia il contenuto del file, ma si limita a creare
+una voce nella directory specificata da \param{newpath} e ad aumentare di uno
+il numero di riferimenti al file (riportato nel campo \var{st\_nlink} della
+struttura \struct{stat}, vedi \secref{sec:file_stat}) aggiungendo il nuovo
+nome ai precedenti. Si noti che uno stesso file può essere così chiamato con
+vari nomi in diverse directory.
  
 Per quanto dicevamo in \secref{sec:file_filesystem} la creazione di un
 collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
@@ -125,7 +125,7 @@ disabilitata, e al tentativo di creare un link diretto ad una directory la
 funzione restituisce l'errore \errcode{EPERM}.
 
 La rimozione di un file (o più precisamente della voce che lo referenzia
-all'interno di una directory) si effettua con la funzione \func{unlink}; il
+all'interno di una directory) si effettua con la funzione \funcd{unlink}; il
 suo prototipo è il seguente:
 \begin{prototype}{unistd.h}{int unlink(const char *pathname)}
 
@@ -152,12 +152,12 @@ suo prototipo 
   \errcode{EPERM} in caso l'operazione non sia consentita o il processo non
   abbia privilegi sufficienti.}
 
-La funzione cancella il nome specificato dal pathname nella relativa directory
-e decrementa il numero di riferimenti nel relativo inode\index{inode}. Nel
-caso di link simbolico cancella il link simbolico; nel caso di
-socket\index{socket}, fifo o file di dispositivo\index{file!di dispositivo}
-rimuove il nome, ma come per i file i processi che hanno aperto uno di questi
-oggetti possono continuare ad utilizzarlo.
+La funzione cancella il nome specificato da \param{pathname} nella relativa
+directory e decrementa il numero di riferimenti nel relativo
+inode\index{inode}. Nel caso di link simbolico cancella il link simbolico; nel
+caso di socket\index{socket}, fifo o file di dispositivo\index{file!di
+  dispositivo} rimuove il nome, ma come per i file i processi che hanno aperto
+uno di questi oggetti possono continuare ad utilizzarlo.
 
 Per cancellare una voce in una directory è necessario avere il permesso di
 scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e
@@ -204,7 +204,7 @@ processo (quando tutti i file vengono chiusi).
 Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
 \func{unlink} sulle directory; per cancellare una directory si può usare la
 funzione \func{rmdir} (vedi \secref{sec:file_dir_creat_rem}), oppure la
-funzione \func{remove}. 
+funzione \funcd{remove}. 
 
 Questa è la funzione prevista dallo standard ANSI C per cancellare un file o
 una directory (e funziona anche per i sistemi che non supportano i link
@@ -230,7 +230,7 @@ protocollo NFS utilizzare questa funzione pu
 ancora in uso.
 
 Per cambiare nome ad un file o a una directory (che devono comunque essere
-nello stesso filesystem) si usa invece la funzione \func{rename},\footnote{la
+nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la
   funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo
   standard POSIX estende la funzione anche alle directory.} il cui prototipo
 è:
@@ -324,7 +324,7 @@ al kernel (analogamente a quanto avviene per le directory) per cui per alcune
 funzioni di libreria (come \func{open} o \func{stat}) dare come parametro un
 link simbolico comporta l'applicazione della funzione al file da esso
 specificato. La funzione che permette di creare un nuovo link simbolico è
-\func{symlink}; il suo prototipo è:
+\funcd{symlink}; il suo prototipo è:
 \begin{prototype}{unistd.h}
   {int symlink(const char *oldpath, const char *newpath)} 
   Crea un nuovo link simbolico di nome \param{newpath} il cui contenuto è
@@ -403,7 +403,7 @@ Dato che, come indicato in \tabref{tab:file_symb_effect}, funzioni come la
 \func{open} seguono i link simbolici, occorrono funzioni apposite per accedere
 alle informazioni del link invece che a quelle del file a cui esso fa
 riferimento. Quando si vuole leggere il contenuto di un link simbolico si usa
-la funzione \func{readlink}, il cui prototipo è:
+la funzione \funcd{readlink}, il cui prototipo è:
 \begin{prototype}{unistd.h}
 {int readlink(const char *path, char *buff, size\_t size)} 
   Legge il contenuto del link simbolico indicato da \param{path} nel buffer
@@ -479,12 +479,18 @@ ci mostrerebbe invece l'esistenza di \file{temporaneo}.
 \subsection{La creazione e la cancellazione delle directory} 
 \label{sec:file_dir_creat_rem}
 
-Per creare e cancellare delle directory si usano le due funzioni (omonime
-degli analoghi comandi di shell) \func{mkdir} e \func{rmdir}.  Per poter
-accedere ai tipi usati da queste funzioni si deve includere il file
-\file{sys/types.h}, il prototipo della prima è:
-\begin{prototype}{sys/stat.h}
-  {int mkdir(const char *dirname, mode\_t mode)} Crea una nuova directory.
+Benché in sostanza le directory non siano altro che dei file contenenti
+elenchi di nomi ed inode, non è possibile trattarle come file ordinari e
+devono essere create direttamente dal kernel attraverso una opportuna system
+call.\footnote{questo permette anche, attraverso l'uso del VFS, l'utilizzo di
+  diversi formati per la gestione dei suddetti elenchi.}  La funzione usata
+per creare una directory è \funcd{mkdir}, ed il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/stat.h}
+  \headdecl{sys/types.h}
+  \funcdecl{int mkdir(const char *dirname, mode\_t mode)} 
+
+  Crea una nuova directory.
   
   \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
     errore, nel qual caso \var{errno} assumerà i valori:
@@ -506,7 +512,7 @@ accedere ai tipi usati da queste funzioni si deve includere il file
   ed inoltre anche \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG},
   \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
   \errval{EROFS}.}
-\end{prototype}
+\end{functions}
 
 La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
 standard \file{.} e \file{..}, con il nome indicato dall'argomento
@@ -520,9 +526,8 @@ creazione dei file (si veda \secref{sec:file_umask}).  La titolarit
 nuova directory è impostata secondo quanto riportato in
 \secref{sec:file_ownership}.
 
-La seconda funzione serve ad eliminare una directory già vuota (la directory
-deve cioè contenere soltanto le due voci standard \file{.} e \file{..}); il
-suo prototipo è:
+La funzione per la cancellazione di una directory è \funcd{rmdir}, il suo
+prototipo è:
 \begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)} 
   Cancella una directory.
 
@@ -545,8 +550,9 @@ suo prototipo 
   \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.}
 \end{prototype}
 
-La funzione cancella la directory \param{dirname}, che deve essere vuota.  Il
-nome può essere indicato con il pathname assoluto o relativo.
+La funzione cancella la directory \param{dirname}, che deve essere vuota (la
+directory deve cioè contenere soltanto le due voci standard \file{.} e
+\file{..}).  Il nome può essere indicato con il pathname assoluto o relativo.
 
 La modalità con cui avviene la cancellazione è analoga a quella di
 \func{unlink}: fintanto che il numero di link all'inode\index{inode} della
index d3e98e4..5a3e630 100644 (file)
@@ -817,10 +817,10 @@ prototipi sono:
 Le due funzioni permettono rispettivamente di bloccare e sbloccare la
 paginazione per l'intervallo di memoria specificato dagli argomenti, che ne
 indicano nell'ordine l'indirizzo iniziale e la lunghezza.  Tutte le pagine che
-contengono una parte dell'intervallo sono mantenute in RAM per tutta la durata
-del blocco.
+contengono una parte dell'intervallo bloccato sono mantenute in RAM per tutta
+la durata del blocco.
 
-Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono poi di
+Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono di
 bloccare genericamente la paginazione\index{paginazione} per l'intero spazio
 di indirizzi di un processo.  I prototipi di queste funzioni sono:
 \begin{functions}
@@ -842,25 +842,25 @@ costanti:
 \begin{basedescript}{\desclabelwidth{2.5cm}}
 \item[\const{MCL\_CURRENT}] blocca tutte le pagine correntemente mappate nello
   spazio di indirizzi del processo.
-\item[\const{MCL\_FUTURE}] blocca tutte le pagine che saranno mappate nello
+\item[\const{MCL\_FUTURE}] blocca tutte le pagine che verranno mappate nello
   spazio di indirizzi del processo.
 \end{basedescript}
 
-Con \func{mlockall} si può bloccare tutte le pagine mappate nello spazio di
-indirizzi del processo, sia che comprendano il segmento di testo, di dati, lo
-stack, lo heap e pure le funzioni di libreria chiamate, i file mappati in
+Con \func{mlockall} si possono bloccare tutte le pagine mappate nello spazio
+di indirizzi del processo, sia che comprendano il segmento di testo, di dati,
+lo stack, 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, per
-scongiurare in partenza un eventuale page fault\index{page fault} causato dal
-meccanismo di \textit{copy on write}\index{copy on write}.  Infatti se nella
-sezione critica si va ad utilizzare memoria che non è ancora stata riportata
-in RAM si potrebbe avere un page fault durante l'esecuzione della stessa, con
-conseguente rallentamento (probabilmente inaccettabile) dei tempi di
-esecuzione.
+scongiurare l'occorrenza di un eventuale \textit{page fault}\index{page fault}
+causato dal meccanismo di \textit{copy on write}\index{copy on write}.
+Infatti se nella sezione critica si va ad utilizzare memoria che non è ancora
+stata riportata in RAM si potrebbe avere un page fault durante l'esecuzione
+della stessa, con conseguente rallentamento (probabilmente inaccettabile) dei
+tempi di esecuzione.
 
 In genere si ovvia a questa problematica chiamando una funzione che ha
 allocato una quantità sufficientemente ampia di variabili automatiche, in modo
@@ -1138,7 +1138,7 @@ controllare \cmd{man environ}.
                                                        temporanei\\
     \hline
   \end{tabular}
-  \caption{Esempi di variabili di ambiente più comuni definite da vari
+  \caption{Esempi delle variabili di ambiente più comuni definite da vari
     standard.} 
   \label{tab:proc_env_var}
 \end{table}
@@ -1180,18 +1180,19 @@ in \tabref{tab:proc_env_func}.
     \func{putenv} &  & opz.  & $\bullet$ & 
         & $\bullet$ & $\bullet$ \\
     \func{clearenv} &  & opz.  &    & 
-        &  &  \\
+        &  &  $\bullet$ \\
     \hline
   \end{tabular}
   \caption{Funzioni per la gestione delle variabili di ambiente.}
   \label{tab:proc_env_func}
 \end{table}
 
-In Linux sono definite solo le prime quattro delle funzioni elencate in
-\tabref{tab:proc_env_func}. La prima, \func{getenv}, l'abbiamo appena
-esaminata; delle tre restanti le prime due, \funcd{putenv} e \funcd{setenv},
-servono per assegnare nuove variabili di ambiente, i loro prototipi sono i
-seguenti:
+In Linux\footnote{in realtà nelle libc4 e libc5 sono definite solo le prime
+  quattro, \func{clearenv} è stata introdotta con le \acr{glibc} 2.0.} sono
+definite tutte le funzioni elencate in \tabref{tab:proc_env_func}. La prima,
+\func{getenv}, l'abbiamo appena esaminata; delle restanti le prime due,
+\funcd{putenv} e \funcd{setenv}, servono per assegnare nuove variabili di
+ambiente, i loro prototipi sono i seguenti:
 \begin{functions}
   \headdecl{stdlib.h} 
   
@@ -1253,6 +1254,24 @@ variabili di ambiente iniziale, creato dalla chiamata ad \func{exec} (vedi
 Inoltre la memoria associata alle variabili di ambiente eliminate non viene
 liberata.
 
+L'ultima funzione è \funcd{clearenv}, che viene usata per cancellare
+completamente tutto l'ambiente; il suo prototipo è:
+\begin{functions}
+  \headdecl{stdlib.h}
+  
+  \funcdecl{int clearenv(void)} 
+  Cancella tutto l'ambiente.
+  
+  \bodydesc{la funzione restituisce 0 in caso di successo e un valore diverso
+    da zero per un errore.}
+\end{functions}
+
+In genere si usa questa funzione in maniera precauzionale per evitare i
+problemi di sicurezza connessi nel trasmettere ai programmi che si invocano un
+ambiente che può contenere dei dati non controllati. In tal caso si provvede
+alla cancellazione di tutto l'ambiente per costruirne una versione
+``\textsl{sicura}'' da zero.
+
 
 \section{Problematiche di programmazione generica}
 \label{sec:proc_gen_prog}
@@ -1485,82 +1504,88 @@ dinamicamente con una delle funzioni della famiglia \func{malloc}.
 Il controllo del flusso di un programma in genere viene effettuato con le
 varie istruzioni del linguaggio C; fra queste la più bistrattata è il
 \code{goto}, che viene deprecato in favore dei costrutti della programmazione
-strutturata, che rendono il codice più leggibile e mantenibile . Esiste però
-un caso in cui l'uso di questa istruzione porta all'implementazione più
-efficiente e chiara anche dal punto di vista della struttura del programma:
-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 una funzione e la sua
-gestione ordinaria è in un'altra occorre usare quello che viene chiamato un
-\textsl{salto non-locale}.  Il caso classico in cui si ha questa necessità,
-citato sia da \cite{APUE} che da da \cite{glibc}, è quello di un programma nel
-cui corpo principale in cui viene letto un input del quale viene eseguita,
-attraverso una serie di funzioni di analisi, una scansione dei contenuti da cui
-ottenere le indicazioni per l'esecuzione di opportune operazioni.
+strutturata, che rendono il codice più leggibile e mantenibile. Esiste però un
+caso in cui l'uso di questa istruzione porta all'implementazione più
+efficiente e più chiara anche dal punto di vista della struttura del
+programma: quello dell'uscita in caso di errore.
+
+Il C però non consente di effettuare un salto ad una etichetta definita in
+un'altra funzione, per cui se l'errore avviene in una funzione, e la sua
+gestione ordinaria è in un'altra, occorre usare quello che viene chiamato un
+\textsl{salto non-locale}\index{salto non-locale}.  Il caso classico in cui si
+ha questa necessità, citato sia da \cite{APUE} che da \cite{glibc}, è quello
+di un programma nel cui corpo principale vengono letti dei dati in ingresso
+sui quali viene eseguita, tramite una serie di funzioni di analisi, una
+scansione dei contenuti da si ottengono le indicazioni per l'esecuzione delle
+opportune operazioni.
 
 Dato che l'analisi può risultare molto complessa, ed opportunamente suddivisa
-in fasi diverse, la rilevazione di un errore nell'input può accadere
+in fasi diverse, la rilevazione di un errore nei dati in ingresso può accadere
 all'interno di funzioni profondamente annidate l'una nell'altra. In questo
 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
-capita. La funzione che permette di salvare il contesto dello stack è
-\funcd{setjmp}, il cui prototipo è:
+successive.  Questo comporterebbe una notevole complessità, 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\index{salto non-locale}.}
+
+Tutto ciò può essere realizzato proprio con un salto non-locale; questo di
+norma viene realizzato salvando il contesto dello stack nel punto in cui si
+vuole tornare in caso di errore, e ripristinandolo, in modo da tornare nella
+funzione da cui si era partiti, quando serve.  La funzione che permette di
+salvare il contesto dello stack è \funcd{setjmp}, il cui prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void setjmp(jmp\_buf env)}
   
-  Salva il contesto dello stack in \param{env} per un successivo uso da parte
-  di \func{longjmp}. 
+  Salva il contesto dello stack. 
 
   \bodydesc{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.}
 \end{functions}
-
-Quando si esegue la funzione il contesto viene salvato in appositi oggetti (di
-tipo \type{jmp\_buf}), passati come primo argomento alla funzione, in genere
-questi vengono definiti come variabili globali in modo da poter essere visti
-in tutte le funzioni del programma.
+  
+Quando si esegue la funzione il contesto corrente dello stack viene salvato
+nell'argomento \param{env}, una variabile di tipo \type{jmp\_buf} che deve
+essere stata definita in precedenza. In genere le variabili di tipo
+\type{jmp\_buf} vengono definite come variabili globali in modo da poter
+essere viste in tutte le funzioni del programma.
 
 Quando viene eseguita direttamente la funzione ritorna sempre zero, un valore
 diverso da zero viene restituito solo quando il ritorno è dovuto ad una
-chiamata di \func{longjmp} in un'altra parte del programma. Si tenga conto che
-il contesto salvato in \param{env} viene invalidato se la routine che ha
-chiamato \func{setjmp} ritorna, nel qual caso l'uso di \func{longjmp} può
-comportare conseguenze imprevedibili (e di norma fatali per il processo).
+chiamata di \func{longjmp} in un'altra parte del programma che ripristina lo
+stack effettuando il salto non-locale\index{salto non-locale}. Si tenga conto
+che il contesto salvato in \param{env} viene invalidato se la routine che ha
+chiamato \func{setjmp} ritorna, nel qual caso un successivo uso di
+\func{longjmp} può comportare conseguenze imprevedibili (e di norma fatali)
+per il processo.
   
-Come accennato per effettuare un salto non-locale ad un punto precedentemente
-stabilito con \func{setjmp} si usa la funzione \funcd{longjmp}; il suo
-prototipo è:
+Come accennato per effettuare un salto non-locale\index{salto non-locale} ad
+un punto precedentemente stabilito con \func{setjmp} si usa la funzione
+\funcd{longjmp}; il suo prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void longjmp(jmp\_buf env, int val)}
   
-  Ripristina il contesto dello stack salvato nell'ultima chiamata di
-  \func{setjmp} con l'argomento \param{env}.
+  Ripristina il contesto dello stack.
   
   \bodydesc{La funzione non ritorna.}
 \end{functions}
 
-Dopo l'esecuzione della funzione programma prosegue dal codice successivo al
-ritorno della \func{setjmp} con cui si era salvato \param{env}, che restituirà
-il valore \param{val} invece di zero.  Il valore di \param{val} specificato
-nella chiamata deve essere diverso da zero, se si è specificato 0 sarà
-comunque restituito 1 al suo posto.
+La funzione ripristina il contesto dello stack salvato da una chiamata a
+\func{setjmp} nell'argomento \param{env}. Dopo l'esecuzione della funzione
+programma prosegue nel codice successivo al ritorno della \func{setjmp} con
+cui si era salvato \param{env}, che restituirà il valore \param{val} invece di
+zero.  Il valore di \param{val} specificato nella chiamata deve essere diverso
+da zero, se si è specificato 0 sarà comunque restituito 1 al suo posto.
 
 In sostanza un \func{longjmp} è analogo ad un \code{return}, solo che invece
 di ritornare alla riga successiva della funzione chiamante, il programma
-ritorna alla posizione della relativa \func{setjmp}, ed il ritorno può essere
-effettuato anche attraverso diversi livelli di funzioni annidate.
+ritorna alla posizione della relativa \func{setjmp}, l'altra differenza è che
+il ritorno può essere effettuato anche attraverso diversi livelli di funzioni
+annidate.
 
 L'implementazione di queste funzioni comporta alcune restrizioni dato che esse
 interagiscono direttamente con la gestione dello stack ed il funzionamento del
@@ -1582,11 +1607,11 @@ In generale, dato che l'unica differenza fra la chiamata diretta e quella
 ottenuta da un \func{longjmp}, è il valore di ritorno di \func{setjmp}, essa è
 usualmente 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
-a cui si ritorna. In generale le variabili globali e statiche mantengono i
-valori che avevano al momento della chiamata di \func{longjmp}, ma quelli
-delle variabili automatiche (o di quelle dichiarate
+Uno dei punti critici dei salti non-locali\index{salto non-locale} è quello
+del valore delle variabili, ed in particolare quello delle variabili
+automatiche della funzione a cui si ritorna. In generale le variabili globali
+e statiche mantengono i valori che avevano al momento della chiamata di
+\func{longjmp}, ma quelli delle variabili automatiche (o di quelle dichiarate
 \direct{register}\footnote{la direttiva \direct{register} del compilatore
   chiede che la variabile dichiarata tale sia mantenuta, nei limiti del
   possibile, all'interno di un registro del processore. Questa direttiva
index 7505cad..a1b36fc 100644 (file)
@@ -1051,12 +1051,12 @@ le apposite funzioni trattate in \secref{sec:sig_strsignal}.
 \label{sec:proc_wait4}
 
 Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la
-lettura dello stato di terminazione di un processo \func{wait3} e
-\func{wait4}, analoghe alle precedenti ma che prevedono un ulteriore
-parametro attraverso il quale il kernel può restituire al padre informazioni
-sulle risorse usate dal processo terminato e dai vari figli.  I prototipi di
-queste funzioni, che diventano accessibili definendo la costante
-\macro{\_USE\_BSD}, sono:
+lettura dello stato di terminazione di un processo, analoghe alle precedenti
+ma che prevedono un ulteriore parametro attraverso il quale il kernel può
+restituire al padre informazioni sulle risorse usate dal processo terminato e
+dai vari figli.  Le due funzioni sono \funcd{wait3} e \funcd{wait4}, che
+diventano accessibili definendo la macro \macro{\_USE\_BSD}; i loro prototipi
+sono:
 \begin{functions}
   \headdecl{sys/times.h} \headdecl{sys/types.h} \headdecl{sys/wait.h}
   \headdecl{sys/resource.h} 
@@ -1093,7 +1093,7 @@ disco.
 Ci sono sei diverse versioni di \func{exec} (per questo la si è chiamata
 famiglia di funzioni) che possono essere usate per questo compito, in realtà
 (come mostrato in \figref{fig:proc_exec_relat}), sono tutte un front-end a
-\func{execve}. Il prototipo di quest'ultima è:
+\funcd{execve}. Il prototipo di quest'ultima è:
 \begin{prototype}{unistd.h}
 {int execve(const char *filename, char *const argv[], char *const envp[])}
   Esegue il programma contenuto nel file \param{filename}.
@@ -1117,10 +1117,11 @@ famiglia di funzioni) che possono essere usate per questo compito, in realt
     interprete.
   \item[\errcode{ELIBBAD}] Un interprete ELF non è in un formato
     riconoscibile.
+  \item[\errcode{E2BIG}] La lista degli argomenti è troppo grande.
   \end{errlist}
   ed inoltre anche \errval{EFAULT}, \errval{ENOMEM}, \errval{EIO},
-  \errval{ENAMETOOLONG}, \errval{E2BIG}, \errval{ELOOP}, \errval{ENOTDIR},
-  \errval{ENFILE}, \errval{EMFILE}.}
+  \errval{ENAMETOOLONG}, \errval{ELOOP}, \errval{ENOTDIR}, \errval{ENFILE},
+  \errval{EMFILE}.}
 \end{prototype}
 
 La funzione \func{exec} esegue il file o lo script indicato da
@@ -1428,9 +1429,10 @@ impostati all'utente e al gruppo proprietari del file. Questo consente, per
 programmi in cui ci sia necessità, di dare a qualunque utente normale
 privilegi o permessi di un'altro (o dell'amministratore).
 
-Come nel caso del \acr{pid} e del \acr{ppid} tutti questi identificatori
-possono essere letti dal processo attraverso delle opportune funzioni, i cui
-prototipi sono i seguenti:
+Come nel caso del \acr{pid} e del \acr{ppid}, anche tutti questi
+identificatori possono essere letti attraverso le opportune funzioni:
+\funcd{getuid}, \funcd{geteuid}, \funcd{getgid} e \funcd{getegid}, i loro
+prototipi sono:
 \begin{functions}
   \headdecl{unistd.h}
   \headdecl{sys/types.h}  
@@ -1488,8 +1490,8 @@ ignorarne l'esistenza, in quanto saranno del tutto equivalenti ai precedenti.
 \label{sec:proc_setuid}
 
 Le due funzioni che vengono usate per cambiare identità (cioè utente e gruppo
-di appartenenza) ad un processo sono rispettivamente \func{setuid} e
-\func{setgid}; come accennato in \secref{sec:proc_access_id} in Linux esse
+di appartenenza) ad un processo sono rispettivamente \funcd{setuid} e
+\funcd{setgid}; come accennato in \secref{sec:proc_access_id} in Linux esse
 seguono la semantica POSIX che prevede l'esistenza dell'\textit{userid
   salvato} e del \textit{groupid salvato}; i loro prototipi sono:
 \begin{functions}
@@ -1583,7 +1585,7 @@ l'\textsl{userid effettivo} del processo per cedere i privilegi occorre
 ricorrere ad altre funzioni (si veda ad esempio \secref{sec:proc_seteuid}).
 
 
-\subsection{Le funzioni \func{setreuid} e \func{setresuid}}
+\subsection{Le funzioni \funcd{setreuid} e \funcd{setresuid}}
 \label{sec:proc_setreuid}
 
 Queste due funzioni derivano da BSD che, non supportando\footnote{almeno fino
@@ -1638,7 +1640,7 @@ corrente, l'userid salvato viene automaticamente uniformato al valore
 dell'userid effettivo.
 
 
-\subsection{Le funzioni \func{seteuid} e \func{setegid}}
+\subsection{Le funzioni \funcd{seteuid} e \funcd{setegid}}
 \label{sec:proc_seteuid}
 
 Queste funzioni sono un'estensione allo standard POSIX.1 (ma sono comunque
@@ -1666,7 +1668,7 @@ all'amministratore di impostare solo l'userid effettivo, dato che l'uso
 normale di \func{setuid} comporta l'impostazione di tutti gli identificatori.
  
 
-\subsection{Le funzioni \func{setresuid} e \func{setresgid}}
+\subsection{Le funzioni \funcd{setresuid} e \funcd{setresgid}}
 \label{sec:proc_setresuid}
 
 Queste due funzioni sono un'estensione introdotta in Linux dal kernel 2.1.44,
@@ -1698,7 +1700,7 @@ pu
 lascia inalterato l'identificatore corrispondente.
 
 Per queste funzioni esistono anche due controparti che permettono di leggere
-in blocco i vari identificatori: \func{getresuid} e \func{getresgid}; i loro
+in blocco i vari identificatori: \funcd{getresuid} e \funcd{getresgid}; i loro
 prototipi sono: 
 \begin{functions}
 \headdecl{unistd.h}
@@ -1746,8 +1748,8 @@ file, mantenendo quelli originari per quanto riguarda tutti gli altri
 controlli di accesso, così che l'utente non possa inviare segnali al server
 NFS.
 
-Le due funzioni usate per cambiare questi identificatori sono \func{setfsuid}
-e \func{setfsgid}, ovviamente sono specifiche di Linux e non devono essere
+Le due funzioni usate per cambiare questi identificatori sono \funcd{setfsuid}
+e \funcd{setfsgid}, ovviamente sono specifiche di Linux e non devono essere
 usate se si intendono scrivere programmi portabili; i loro prototipi sono:
 \begin{functions}
 \headdecl{sys/fsuid.h}
@@ -1775,15 +1777,16 @@ gruppi supplementari. Ogni processo pu
 gruppi supplementari in aggiunta al gruppo primario, questi vengono ereditati
 dal processo padre e possono essere cambiati con queste funzioni.
 
-La funzione che permette di leggere i gruppi supplementari è \func{getgroups};
-questa funzione è definita nello standard POSIX ed il suo prototipo è:
+La funzione che permette di leggere i gruppi supplementari è
+\funcd{getgroups}; questa funzione è definita nello standard POSIX ed il suo
+prototipo è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{unistd.h}
   
-  \funcdecl{int getgroups(int size, gid\_t list[])} Legge gli identificatori
-  dei gruppi supplementari del processo sul vettore \param{list} di dimensione
-  \param{size}.
+  \funcdecl{int getgroups(int size, gid\_t list[])} 
+  
+  Legge gli identificatori dei gruppi supplementari.
   
   \bodydesc{La funzione restituisce il numero di gruppi letti in caso di
     successo e -1 in caso di fallimento, nel qual caso \var{errno} assumerà
@@ -1794,38 +1797,43 @@ questa funzione 
       minore del numero di gruppi supplementari del processo.
     \end{errlist}}
 \end{functions}
-\noindent non è specificato se la funzione inserisca o meno nella lista
-il groupid effettivo del processo. Se si specifica un valore di \param{size}
-uguale a 0 \param{list} non viene modificato, ma si ottiene il numero di
-gruppi supplementari.
 
-Una seconda funzione, \func{getgrouplist}, può invece essere usata per
+La funzione legge gli identificatori dei gruppi supplementari del processo sul
+vettore \param{list} di dimensione \param{size}. Non è specificato se la
+funzione inserisca o meno nella lista il groupid effettivo del processo. Se si
+specifica un valore di \param{size} uguale a 0 \param{list} non viene
+modificato, ma si ottiene il numero di gruppi supplementari.
+
+Una seconda funzione, \funcd{getgrouplist}, può invece essere usata per
 ottenere tutti i gruppi a cui appartiene un utente; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{grp.h}
   
   \funcdecl{int getgrouplist(const char *user, gid\_t group, gid\_t *groups,
-    int *ngroups)} Legge i gruppi supplementari dell'utente \param{user}.
+    int *ngroups)} Legge i gruppi supplementari.
   
   \bodydesc{La funzione legge fino ad un massimo di \param{ngroups} valori,
     restituisce 0 in caso di successo e -1 in caso di fallimento.}
 \end{functions}
-\noindent la funzione esegue una scansione del database dei gruppi (si veda
-\secref{sec:sys_user_group}) e ritorna in \param{groups} la lista di quelli a
-cui l'utente appartiene. Si noti che \param{ngroups} è passato come puntatore
-perché qualora il valore specificato sia troppo piccolo la funzione ritorna
--1, passando indietro il numero dei gruppi trovati.
+
+La funzione legge i gruppi supplementari dell'utente \param{user} eseguendo
+una scansione del database dei gruppi (si veda \secref{sec:sys_user_group}) e
+ritorna in \param{groups} la lista di quelli a cui l'utente appartiene. Si
+noti che \param{ngroups} è passato come puntatore perché qualora il valore
+specificato sia troppo piccolo la funzione ritorna -1, passando indietro il
+numero dei gruppi trovati.
 
 Per impostare i gruppi supplementari di un processo ci sono due funzioni, che
 possono essere usate solo se si hanno i privilegi di amministratore. La prima
-delle due è \func{setgroups}, ed il suo prototipo è:
+delle due è \funcd{setgroups}, ed il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{grp.h}
   
-  \funcdecl{int setgroups(size\_t size, gid\_t *list)} Imposta i gruppi
-  supplementari del processo ai valori specificati in \param{list}.
+  \funcdecl{int setgroups(size\_t size, gid\_t *list)} 
+  
+  Imposta i gruppi supplementari del processo.
 
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
     fallimento, nel qual caso \var{errno} assumerà i valori:
@@ -1833,19 +1841,25 @@ delle due 
     \item[\errcode{EFAULT}] \param{list} non ha un indirizzo valido.
     \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
     \item[\errcode{EINVAL}] il valore di \param{size} è maggiore del valore
-    massimo (\const{NGROUPS}, che per Linux è 32).
+    massimo consentito.
     \end{errlist}}
 \end{functions}
 
+La funzione imposta i gruppi supplementari del processo corrente ai valori
+specificati nel vettore passato con l'argomento \param{list}, di dimensioni
+date dall'argomento \param{size}. Il numero massimo di gruppi supplementari è
+un parametro di sistema, che può essere ricavato con le modalità spiegate in
+\secref{sec:sys_characteristics}.
+
 Se invece si vogliono impostare i gruppi supplementari del processo a quelli di
-un utente specifico, si può usare \func{initgroups} il cui prototipo è:
+un utente specifico, si può usare \funcd{initgroups} il cui prototipo è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{grp.h}
 
-  \funcdecl{int initgroups(const char *user, gid\_t group)} Imposta i gruppi
-  supplementari del processo a quelli di cui è membro l'utente \param{user},
-  aggiungendo il gruppo addizionale \param{group}.
+  \funcdecl{int initgroups(const char *user, gid\_t group)} 
+  
+  Inizializza la lista dei gruppi supplementari.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
     fallimento, nel qual caso \var{errno} assumerà gli stessi valori di
@@ -1854,13 +1868,13 @@ un utente specifico, si pu
 \end{functions}
 
 La funzione esegue la scansione del database dei gruppi (usualmente
-\file{/etc/groups}) cercando i gruppi di cui è membro \param{user} e
-costruendo una lista di gruppi supplementari a cui aggiunge \param{group}, che
-poi imposta usando \func{setgroups}.
-Si tenga presente che sia \func{setgroups} che \func{initgroups} non sono
-definite nello standard POSIX.1 e che pertanto non è possibile utilizzarle
-quando si definisce \macro{\_POSIX\_SOURCE} o si compila con il flag
-\cmd{-ansi}.
+\file{/etc/groups}) cercando i gruppi di cui è membro l'utente \param{user}
+con cui costruisce una lista di gruppi supplementari, a cui aggiunge anche
+\param{group}, infine imposta questa lista per il processo corrente usando
+\func{setgroups}.  Si tenga presente che sia \func{setgroups} che
+\func{initgroups} non sono definite nello standard POSIX.1 e che pertanto non
+è possibile utilizzarle quando si definisce \macro{\_POSIX\_SOURCE} o si
+compila con il flag \cmd{-ansi}.
 
 
 \section{La gestione della priorità di esecuzione}
@@ -2040,7 +2054,7 @@ fatto che generalmente questo viene usato per diminuire la priorit
 processo, come misura di cortesia nei confronti degli altri.  I processi
 infatti vengono creati dal sistema con lo stesso valore di \var{nice} (nullo)
 e nessuno è privilegiato rispetto agli altri; il valore può essere modificato
-solo attraverso la funzione \func{nice}, il cui prototipo è:
+solo attraverso la funzione \funcd{nice}, il cui prototipo è:
 \begin{prototype}{unistd.h}
 {int nice(int inc)}
   Aumenta il valore di \var{nice} per il processo corrente.
@@ -2065,7 +2079,7 @@ la priorit
 
 In SUSv2 la funzione ritorna il nuovo valore di \var{nice}; Linux non segue
 questa convenzione, e per leggere il nuovo valore occorre invece usare la
-funzione \func{getpriority}, derivata da BSD, il cui prototipo è:
+funzione \funcd{getpriority}, derivata da BSD, il cui prototipo è:
 \begin{prototype}{sys/resource.h}
 {int getpriority(int which, int who)}
   
@@ -2114,7 +2128,7 @@ rilevare una condizione di errore 
 prima della chiamata alla funzione, per verificare che essa resti uguale a
 zero.  
 
-Analoga a \func{getpriority} la funzione \func{setpriority} permette di
+Analoga a \func{getpriority} la funzione \funcd{setpriority} permette di
 impostare la priorità di uno o più processi; il suo prototipo è:
 \begin{prototype}{sys/resource.h}
 {int setpriority(int which, int who, int prio)}  
@@ -2192,11 +2206,11 @@ di scheduling che si 
 \end{basedescript}
 
 La funzione per impostare le politiche di scheduling (sia real-time che
-ordinarie) ed i relativi parametri è \func{sched\_setscheduler}; il suo
+ordinarie) ed i relativi parametri è \funcd{sched\_setscheduler}; il suo
 prototipo è:
 \begin{prototype}{sched.h}
 {int sched\_setscheduler(pid\_t pid, int policy, const struct sched\_param *p)}
-  Imposta priorità e politica di scheduling per il processo \param{pid}.
+  Imposta priorità e politica di scheduling.
   
   \bodydesc{La funzione ritorna la priorità in caso di successo e -1 in caso
     di errore, nel qual caso \var{errno} può assumere i valori:
@@ -2210,10 +2224,10 @@ prototipo 
   \end{errlist}}
 \end{prototype}
 
-La funzione esegue l'impostazione per il processo specificato; un valore nullo
-di \param{pid} esegue l'impostazione per il processo corrente, solo un
-processo con i privilegi di amministratore può impostare delle priorità
-assolute diverse da zero. La politica di scheduling è specificata
+La funzione esegue l'impostazione per il processo specificato dall'argomento
+\param{pid}; un valore nullo esegue l'impostazione per il processo corrente.
+Solo un processo con i privilegi di amministratore può impostare delle
+priorità assolute diverse da zero. La politica di scheduling è specificata
 dall'argomento \param{policy} i cui possibili valori sono riportati in
 \tabref{tab:proc_sched_policy}; un valore negativo per \param{policy} mantiene
 la politica di scheduling corrente.
@@ -2258,12 +2272,10 @@ struct sched_param {
   \label{fig:sig_sched_param}
 \end{figure}
 
-
-
 Lo standard POSIX.1b prevede comunque che i due valori della massima e minima
 priorità statica possano essere ottenuti, per ciascuna delle politiche di
-scheduling realtime, tramite le due funzioni \func{sched\_get\_priority\_max}
-e \func{sched\_get\_priority\_min}, i cui prototipi sono:
+scheduling realtime, tramite le due funzioni \funcd{sched\_get\_priority\_max}
+e \funcd{sched\_get\_priority\_min}, i cui prototipi sono:
 \begin{functions}
   \headdecl{sched.h}
   
@@ -2299,7 +2311,7 @@ sar
 nel caso che esso sia stato interrotto da un processo a priorità più alta.
 
 La priorità assoluta può essere riletta indietro dalla funzione
-\func{sched\_getscheduler}, il cui prototipo è:
+\funcd{sched\_getscheduler}, il cui prototipo è:
 \begin{prototype}{sched.h}
 {int sched\_getscheduler(pid\_t pid)}
   Legge la politica di scheduling per il processo \param{pid}.
@@ -2318,9 +2330,8 @@ specificato; se \param{pid} 
 chiamante.
 
 Se si intende operare solo sulla priorità assoluta di un processo si possono
-usare le funzioni \func{sched\_setparam} e \func{sched\_getparam}, i cui
+usare le funzioni \funcd{sched\_setparam} e \funcd{sched\_getparam}, i cui
 prototipi sono:
-  
 \begin{functions}
   \headdecl{sched.h}
 
@@ -2347,7 +2358,7 @@ verificata controllando la macro \macro{\_POSIX\_PRIORITY\_SCHEDULING} che 
 definita nell'header \file{sched.h}.
 
 L'ultima funzione che permette di leggere le informazioni relative ai processi
-real-time è \func{sched\_rr\_get\_interval}, che permette di ottenere la
+real-time è \funcd{sched\_rr\_get\_interval}, che permette di ottenere la
 lunghezza della \textit{time slice} usata dalla politica \textit{round robin};
 il suo prototipo è:
 \begin{prototype}{sched.h}
@@ -2369,7 +2380,7 @@ definizione si pu
 
 Come accennato ogni processo che usa lo scheduling real-time può rilasciare
 volontariamente la CPU; questo viene fatto attraverso la funzione
-\func{sched\_yield}, il cui prototipo è:
+\funcd{sched\_yield}, il cui prototipo è:
 \begin{prototype}{sched.h}
   {int sched\_yield(void)} 
   
index d287ef2..a5363ec 100644 (file)
@@ -2327,16 +2327,16 @@ caratteristiche si sono abilitate con le macro viste in
 \secref{sec:intro_gcc_glibc_std}.
 
 Lo standard POSIX però prevede anche la presenza di altre due funzioni
-\func{sigsetjmp} e \func{siglongjmp}, che permettono di decidere quale dei due
-comportamenti il programma deve assumere; i loro prototipi sono:
+\funcd{sigsetjmp} e \funcd{siglongjmp}, che permettono di decidere quale dei
+due comportamenti il programma deve assumere; i loro prototipi sono:
 \begin{functions}
   \headdecl{setjmp.h} 
   
   \funcdecl{int sigsetjmp(sigjmp\_buf env, int savesigs)} Salva il contesto
-  dello stack per un salto non locale.
+  dello stack per un salto non-locale\index{salto non-locale}.
  
-  \funcdecl{void siglongjmp(sigjmp\_buf env, int val)} Esegue un salto non
-  locale su un precedente contesto.
+  \funcdecl{void siglongjmp(sigjmp\_buf env, int val)} Esegue un salto
+  non-locale su un precedente contesto.
 
   \bodydesc{Le due funzioni sono identiche alle analoghe \func{setjmp} e
     \func{longjmp} di \secref{sec:proc_longjmp}, ma consentono di specificare
@@ -2344,10 +2344,11 @@ comportamenti il programma deve assumere; i loro prototipi sono:
 \end{functions}
 
 Le due funzioni prendono come primo argomento la variabile su cui viene
-salvato il contesto dello stack per permettere il salto non locale; nel caso
-specifico essa è di tipo \type{sigjmp\_buf}, e non \type{jmp\_buf} come per le
-analoghe di \secref{sec:proc_longjmp} in quanto in questo caso viene salvata
-anche la maschera dei segnali.
+salvato il contesto dello stack per permettere il salto non-locale
+\index{salto non-locale}; nel caso specifico essa è di tipo
+\type{sigjmp\_buf}, e non \type{jmp\_buf} come per le analoghe di
+\secref{sec:proc_longjmp} in quanto in questo caso viene salvata anche la
+maschera dei segnali.
 
 Nel caso di \func{sigsetjmp} se si specifica un valore di \param{savesigs}
 diverso da zero la maschera dei valori sarà salvata in \param{env} e