From cdc1b275bbd83ad0dbf1ba4be801118724a51085 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 26 Dec 2001 14:20:36 +0000 Subject: [PATCH 1/1] Inserita l'indicizzazione delle funzioni. Ricontrollate le chiamate alla macro \func{} per eliminare quelle improprie --- elemtcp.tex | 2 +- filedir.tex | 210 ++++++++++++++++++++++++++++++++++---------------- fileintro.tex | 28 +++---- filestd.tex | 50 ++++++------ fileunix.tex | 20 ++--- gapil.tex | 7 +- intro.tex | 4 +- macro.tex | 5 +- process.tex | 14 ++-- prochand.tex | 19 ++--- signal.tex | 47 +++++++---- simpltcp.tex | 36 ++++----- socket.tex | 17 ++-- system.tex | 6 +- 14 files changed, 279 insertions(+), 186 deletions(-) diff --git a/elemtcp.tex b/elemtcp.tex index f092de0..46bffaf 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -1001,7 +1001,7 @@ quello creato all'inizio e messo in ascolto con \func{listen}, e non viene toccato dalla funzione. Se non ci sono connessioni pendenti da accettare la funzione mette in attesa il processo\footnote{a meno che non si sia settato il socket per essere - non-bloccante, nel qual caso ritorna con l'errore \func{EAGAIN}, + non-bloccante, nel qual caso ritorna con l'errore \macro{EAGAIN}, torneremo su questa modalità di operazione in \secref{sec:xxx_sock_noblock}} fintanto che non ne arriva una. diff --git a/filedir.tex b/filedir.tex index 00ea801..b09d760 100644 --- a/filedir.tex +++ b/filedir.tex @@ -53,7 +53,7 @@ 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 man page, sono le seguenti: \begin{prototype}{unistd.h} -{int link(const char * oldpath, const char * newpath)} +{int link(const char *oldpath, const char *newpath)} Crea un nuovo collegamento diretto al file indicato da \var{oldpath} dandogli nome \var{newpath}. @@ -108,7 +108,7 @@ funzione restituisce l'errore \macro{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 suo prototipo è il seguente: -\begin{prototype}{unistd.h}{int unlink(const char * pathname)} +\begin{prototype}{unistd.h}{int unlink(const char *pathname)} Cancella il nome specificato dal pathname nella relativa directory e decrementa il numero di riferimenti nel relativo inode. Nel caso di link simbolico cancella il link simbolico; nel caso di socket, fifo o file di @@ -275,19 +275,19 @@ 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 è: \begin{prototype}{unistd.h} - {int symlink(const char * oldpath, const char * newpath)} - Crea un nuovo link simbolico di nome \func{newpath} il cui contenuto è - \func{oldpath}. + {int symlink(const char *oldpath, const char *newpath)} + Crea un nuovo link simbolico di nome \param{newpath} il cui contenuto è + \param{oldpath}. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, nel qual caso la variabile \var{errno} restituisce i valori: \begin{errlist} - \item[\macro{EPERM}] il filesystem che contiene \var{newpath} non supporta i + \item[\macro{EPERM}] il filesystem che contiene \param{newpath} non supporta i link simbolici. - \item[\macro{ENOENT}] una componente di \var{newpath} non esiste o - \func{oldpath} è una stringa vuota. - \item[\macro{EEXIST}] esiste già un file \var{newpath}. - \item[\macro{EROFS}] \var{newpath} è su un filesystem montato in sola + \item[\macro{ENOENT}] una componente di \param{newpath} non esiste o + \param{oldpath} è una stringa vuota. + \item[\macro{EEXIST}] esiste già un file \param{newpath}. + \item[\macro{EROFS}] \param{newpath} è su un filesystem montato in sola lettura. \end{errlist} ed inoltre \macro{EFAULT}, \macro{EACCES}, \macro{ENAMETOOLONG}, @@ -296,10 +296,10 @@ specificato. La funzione che permette di creare un nuovo link simbolico \end{prototype} Si tenga presente che la funzione non effettua nessun controllo sull'esistenza -di un file di nome \var{oldpath}, ma si limita ad inserire quella stringa nel -link simbolico. Pertanto un link simbolico può anche riferirsi ad un file che -non esiste: quello che viene chiamato un \textit{dangling link}, letteralmente -\textsl{link ciondolante}. +di un file di nome \param{oldpath}, ma si limita ad inserire quella stringa +nel link simbolico. Pertanto un link simbolico può anche riferirsi ad un file +che non esiste: quello che viene chiamato un \textit{dangling link}, +letteralmente \textsl{link ciondolante}. Come accennato i link simbolici sono risolti automaticamente dal kernel @@ -354,7 +354,7 @@ 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 è: \begin{prototype}{unistd.h} -{int readlink(const char * path, char * buff, size\_t size)} +{int readlink(const char *path, char *buff, size\_t size)} Legge il contenuto del link simbolico indicato da \var{path} nel buffer \var{buff} di dimensione \var{size}. @@ -401,8 +401,8 @@ interno un link simbolico che punta di nuovo a \file{/boot}\footnote{Questo Questo può causare problemi per tutti quei programmi che effettuano la scansione di una directory senza tener conto dei link simbolici, ad esempio se lanciassimo un comando del tipo \cmd{grep -r linux *}, il loop nella directory -porterebbe il comando ad esaminare \file{/boot}, \file/{boot/boot}, -\file/{boot/boot/boot} e così via. +porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot}, +\file{/boot/boot/boot} e così via. Per questo motivo il kernel e le librerie prevedono che nella risoluzione di un pathname possano essere seguiti un numero limitato di link simbolici, il @@ -428,15 +428,15 @@ con un errore che pu mostrerebbe l'esistenza di \file{temporaneo}. -\subsection{Le funzioni \func{mkdir} e \func{rmdir}} +\subsection{La creazione e la cancellazione delle directory} \label{sec:file_dir_creat_rem} -Queste due funzioni servono per creare e cancellare delle directory e sono -omonime degli analoghi comandi di shell. Per poter accedere ai tipi usati -da queste funzioni si deve includere il file \file{sys/types.h}, il -prototipo della prima è: +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)} + {int mkdir(const char *dirname, mode\_t mode)} Crea una nuova directory vuota con il nome indicato da \var{dirname}, assegnandole i permessi indicati da \var{mode}. Il nome può essere indicato con il pathname assoluto o relativo. @@ -472,10 +472,9 @@ titolarit 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 è: -\begin{prototype}{sys/stat.h} - {int rmdir (const char * dirname)} Cancella la directory \var{dirname}, che - deve essere vuota. Il nome può essere indicato con il pathname assoluto o - relativo. +\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)} + Cancella la directory \var{dirname}, che deve essere vuota. Il nome può + essere indicato con il pathname assoluto o relativo. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, nel qual caso \var{errno} assumerà i valori: @@ -497,12 +496,78 @@ suo prototipo \end{prototype} La modalità con cui avviene la cancellazione è analoga a quella di -\func{unlink}, fintanto che il numero di link all'inode della directory non +\func{unlink}: fintanto che il numero di link all'inode della directory non diventa nullo e nessun processo ha la directory aperta lo spazio occupato su disco non viene rilasciato. Se un processo ha la directory aperta la funzione rimuove il link all'inode e nel caso sia l'ultimo, pure le voci standard -\file{.} e \file{..}, ed il kernel non consentirà di creare più nuovi file -nella directory. +\file{.} e \file{..}, a questo punto il kernel non consentirà di creare più +nuovi file nella directory. + + +\subsection{La creazione di file speciali} +\label{sec:file_mknod} + +Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in +\secref{sec:file_file_types} abbiamo visto però che il sistema preveda pure +degli altri tipi di file, come i file di dispositivo e le fifo (i socket sono +un caso a parte, che vedremo in \secref{cha:socket_intro}). + +La manipolazione delle caratteristiche di questi filee e la loro cancellazione +può essere effettuata con le stesse funzioni che operano sui file normali; ma +quando li si devono creare sono necessarie delle funzioni apposite. + +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/stat.h} + \headdecl{fnctl.h} + \headdecl{unistd.h} + \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} + + \bodydesc{La funzione restituisce zero in caso di successo e -1 per un + errore, nel qual caso \var{errno} assumerà i valori: + \begin{errlist} + \item[\macro{EPERM}] Il filesystem non supporta la cancellazione di + directory, oppure la directory che contiene \var{dirname} ha lo sticky bit + settato e l'\textit{effective user id} del processo non corrisponde al + proprietario della directory. + \item[\macro{EACCESS}] Non c'è il permesso di scrittura per la directory che + contiene la directory che si vuole cancellare, o non c'è il permesso di + attraversare (esecuzione) una delle directory specificate in + \var{dirname}. + \item[\macro{EBUSY}] La directory specificata è la directory di lavoro o la + radice di qualche processo. + \item[\macro{ENOTEMPTY}] La directory non è vuota. + \end{errlist} + ed inoltre anche \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT}, + \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP}, \macro{EROFS}.} +\end{functions} + + +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/stat.h} + \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} + + \bodydesc{La funzione restituisce zero in caso di successo e -1 per un + errore, nel qual caso \var{errno} assumerà i valori: + \begin{errlist} + \item[\macro{EPERM}] Il filesystem non supporta la cancellazione di + directory, oppure la directory che contiene \var{dirname} ha lo sticky bit + settato e l'\textit{effective user id} del processo non corrisponde al + proprietario della directory. + \item[\macro{EACCESS}] Non c'è il permesso di scrittura per la directory che + contiene la directory che si vuole cancellare, o non c'è il permesso di + attraversare (esecuzione) una delle directory specificate in + \var{dirname}. + \item[\macro{EBUSY}] La directory specificata è la directory di lavoro o la + radice di qualche processo. + \item[\macro{ENOTEMPTY}] La directory non è vuota. + \end{errlist} + ed inoltre anche \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT}, + \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP}, \macro{EROFS}.} +\end{functions} + + \subsection{Accesso alle directory} @@ -511,17 +576,17 @@ nella directory. Benché le directory siano oggetti del filesystem come tutti gli altri non ha ovviamente senso aprirle come fossero dei file di dati. Può però essere utile poterne leggere il contenuto ad esempio per fare la lista dei file che esse -contengono o ricerche sui medesimi. Solo il kernel scrivere direttamente in -una directory (onde evitare inconsistenze all'interno del filesystem), i +contengono o ricerche sui medesimi. Solo il kernel può scrivere direttamente +in una directory (onde evitare inconsistenze all'interno del filesystem), i processi devono creare i file usando le apposite funzioni. Per accedere al contenuto delle directory si usano i cosiddetti -\textit{directory streams} (chiamati così per l'analogia con i file stream); -la funzione \func{opendir} apre uno di questi stream e la funzione -\func{readdir} legge il contenuto della directory, i cui elementi sono le -\textit{directory entry} (da distinguersi da quelle della cache di cui -parlavamo in \secref{sec:file_vfs}) in una opportuna struttura \var{struct - dirent}. +\textit{directory streams} (chiamati così per l'analogia con i file stream di +\capref{che:file_std_interface}); la funzione \func{opendir} apre uno di +questi stream e la funzione \func{readdir} legge il contenuto della directory, +i cui elementi sono le \textit{directory entry} (da distinguersi da quelle +della cache di cui parlavamo in \secref{sec:file_vfs}) in una opportuna +struttura \var{struct dirent}. (NdA Il resto va scritto!!! É noioso e lo farò più avanti). @@ -545,7 +610,7 @@ directory corrente di qualunque comando da essa lanciato. In genere il kernel tiene traccia per ciascun processo dell'inode della directory di lavoro corrente, per ottenere il pathname occorre usare una apposita funzione di libreria, \func{getcwd}, il cui prototipo è: -\begin{prototype}{unistd.h}{char * getcwd (char * buffer, size\_t size)} +\begin{prototype}{unistd.h}{char *getcwd(char *buffer, size\_t size)} Restituisce il filename completo della directory di lavoro corrente nella stringa puntata da \var{buffer}, che deve essere precedentemente allocata, per una dimensione massima di \var{size}. @@ -574,7 +639,7 @@ qualora questa sia diversa da zero, o della lunghezza esatta del pathname altrimenti. In questo caso ci si deve ricordare di disallocare la stringa una volta cessato il suo utilizzo. -Di questa funzione esiste una versione \func{char * getwd(char * buffer)} +Di questa funzione esiste una versione \code{char *getwd(char *buffer)} fatta per compatibilità all'indietro con BSD, che non consente di specificare la dimensione del buffer; esso deve essere allocato in precedenza ed avere una dimensione superiore a \macro{PATH\_MAX} (di solito 256 byte, vedi @@ -583,11 +648,11 @@ superiore per un pathname, per cui non contenere il nome del file, e questa è la ragione principale per cui questa funzione è deprecata. -Una seconda funzione simile è \func{char * get\_current\_dir\_name(void)} che -è sostanzialmente equivalente ad una \func{getcwd(NULL, 0)}, con la sola +Una seconda funzione simile è \code{char *get\_current\_dir\_name(void)} che è +sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore della variabile di ambiente \macro{PWD}, che essendo costruita dalla shell può contenere anche dei riferimenti -simbolici; nel caso di \func{getcwd} infatti, essendo il pathname ricavato +simbolici; nel caso di \func{getcwd} infatti, essendo il pathname ricavato risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni passaggio attraverso eventuali pathname. @@ -598,20 +663,21 @@ ad esse anche tramite il file descriptor dell'interfaccia a basso livello, e non solo tramite il filename, i prototipi di queste funzioni sono: \begin{functions} \headdecl{unistd.h} - \funcdecl{int chdir (const char * path)} + \funcdecl{int chdir(const char *path)} Cambia la directory di lavoro corrente a quella specificata dal pathname contenuto nella stringa \var{path}. - \funcdecl{int fchdir (int fd)} Analoga alla precedente, ma - usa un file descriptor invece del pathname. + \funcdecl{int fchdir(int fd)} Analoga alla precedente, ma usa un file + descriptor invece del pathname. \bodydesc{Entrambe le funzioni restituiscono zero in caso di successo e -1 per un errore, in caso di errore \var{errno} viene settata per \func{chdir} ai valori: \begin{errlist} - \item[\macro{ENOTDIR}] Uno dei componenti di \var{path} non è una directory. + \item[\macro{ENOTDIR}] Uno dei componenti di \param{path} non è una + directory. \item[\macro{EACCESS}] Manca il permesso di ricerca su uno dei componenti di - \func{path}. + \param{path}. \end{errlist} ed inoltre \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOMEM}, \macro{ELOOP} e \macro{EIO}. Per \func{fchdir} invece gli @@ -620,6 +686,15 @@ non solo tramite il filename, i prototipi di queste funzioni sono: +\subsection{I file temporanei} +\label{sec:file_temp_file} + +Un'altra serie di funzioni definite dalle librerie standard del C sono quelle +che riguardano la creazione di file temporanei. + + + + \section{La manipolazione delle caratteristiche dei files} \label{sec:file_infos} @@ -813,7 +888,7 @@ Si tenga conto che lunghezza del file riportata in \var{st\_size} non che corrisponda all'occupazione dello spazio su disco per via della possibile esistenza dei cosiddetti \textsl{buchi} (detti normalmente \textit{holes}) che si formano tutte le volte che si va a scrivere su un file dopo aver eseguito -una \func{seek} (vedi \secref{sec:file_lseek}) oltre la sua conclusione +una \func{lseek} (vedi \secref{sec:file_lseek}) oltre la sua conclusione corrente. In tal caso si avranno differenti risultati a seconda del modi in cui si @@ -824,7 +899,7 @@ caso per le parti non scritte vengono restituiti degli zeri, si avr risultato di \cmd{ls}. Se è sempre possibile allargare un file, scrivendoci sopra od usando la -funzione \func{seek} per spostarsi oltre la sua fine, esistono anche casi in +funzione \func{lseek} per spostarsi oltre la sua fine, esistono anche casi in cui si può avere bisogno di effettuare un troncamento, scartando i dati presenti al di là della dimensione scelta come nuova fine del file. @@ -1016,17 +1091,17 @@ avr I tempi di ultimo accesso e modifica possono essere cambiati usando la funzione \func{utime}, il cui prototipo è: \begin{prototype}{utime.h} -{int utime(const char * filename, struct utimbuf *times)} +{int utime(const char *filename, struct utimbuf *times)} Cambia i tempi di ultimo accesso e modifica dell'inode specificato da -\var{filename} secondo i campi \var{actime} e \var{modtime} di \var{times}. Se -questa è \macro{NULL} allora viene usato il tempo corrente. +\param{filename} secondo i campi \var{actime} e \var{modtime} di +\param{times}. Se questa è \macro{NULL} allora viene usato il tempo corrente. \bodydesc{La funzione restituisce zero in caso di successo e -1 in caso di errore, nel qual caso \var{errno} è settata opportunamente. \begin{errlist} \item[\macro{EACCESS}] non si ha il permesso di scrittura sul file. -\item[\macro{ENOENT}] \var{filename} non esiste. +\item[\macro{ENOENT}] \param{filename} non esiste. \end{errlist}} \end{prototype} @@ -1039,7 +1114,7 @@ struct utimbuf { \end{lstlisting} L'effetto della funzione e i privilegi necessari per eseguirla dipendono da -cosa è l'argomento \var{times}; se è \macro{NULL} la funzione setta il tempo +cosa è l'argomento \param{times}; se è \macro{NULL} la funzione setta il tempo corrente ed è sufficiente avere accesso in scrittura al file; se invece si è specificato un valore la funzione avrà successo solo se si è proprietari del file (o si hanno i privilegi di amministratore). @@ -1204,7 +1279,7 @@ dell'utente che ha lanciato il processo, mentre i \textit{supplementary group I passi attraverso i quali viene stabilito se il processo possiede il diritto di accesso sono i seguenti: -\begin{itemize} +\begin{enumerate} \item Se l'\textit{effective user id} del processo è zero (corrispondente all'amministratore) l'accesso è sempre garantito senza nessun ulteriore controllo. Per questo motivo \textsl{root} ha piena libertà di accesso a @@ -1212,24 +1287,24 @@ di accesso sono i seguenti: \item Se l'\textit{effective user id} del processo è uguale all'\acr{uid} del proprietario del file (nel qual caso si dice che il processo è proprietario del file) allora: - \begin{itemize} + \begin{itemize*} \item se il relativo\footnote{per relativo si intende il bit di user-read se il processo vuole accedere in scrittura, quello di user-write per l'accesso in scrittura, etc.} bit dei permessi d'accesso dell'utente è settato, l'accesso è consentito \item altrimenti l'accesso è negato - \end{itemize} + \end{itemize*} \item Se l'\textit{effective group id} del processo o uno dei \textit{supplementary group id} dei processi corrispondono al \acr{gid} del file allora: - \begin{itemize} + \begin{itemize*} \item se il bit dei permessi d'accesso del gruppo è settato, l'accesso è consentito, \item altrimenti l'accesso è negato - \end{itemize} + \end{itemize*} \item se il bit dei permessi d'accesso per tutti gli altri è settato, l'accesso è consentito, altrimenti l'accesso è negato. -\end{itemize} +\end{enumerate} Si tenga presente che questi passi vengono eseguiti esattamente in quest'ordine. Questo vuol dire che se un processo è il proprietario di un file @@ -1331,11 +1406,11 @@ assunto un uso corrente per le directory\footnote{lo \textsl{sticky bit} per la supporta, così come BSD e SVR4}, in questo caso se il bit è settato un file potrà essere rimosso dalla directory soltanto se l'utente ha il permesso di scrittura ed inoltre è vera una delle seguenti condizioni: -\begin{itemize} +\begin{itemize*} \item l'utente è proprietario del file \item l'utente è proprietario della directory \item l'utente è l'amministratore -\end{itemize} +\end{itemize*} un classico esempio di directory che ha questo bit settato è \file{/tmp}, i permessi infatti di solito sono settati come: \begin{verbatim} @@ -1360,12 +1435,12 @@ descritto in \secref{sec:file_dir_creat_rem}). Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda all'\textit{effective user id} del processo che lo crea; per il \acr{gid} invece prevede due diverse possibilità: -\begin{itemize} +\begin{itemize*} \item il \acr{gid} del file corrisponde all'\textit{effective group id} del processo. \item il \acr{gid} del file corrisponde al \acr{gid} della directory in cui esso è creato. -\end{itemize} +\end{itemize*} in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata semantica BSD. Linux invece segue quella che viene chiamata semantica SVr4; di norma cioè il nuovo file viene creato, seguendo la prima opzione, con il @@ -1518,7 +1593,7 @@ Il cambiamento dei permessi di un file attraverso queste funzioni ha comunque alcune limitazioni, provviste per motivi di sicurezza. Questo significa che anche se si è proprietari del file non tutte le operazioni sono permesse, in particolare: -\begin{itemize} +\begin{enumerate} \item siccome solo l'amministratore può settare lo \textit{sticky bit}; se l'\textit{effective user id} del processo non è zero esso viene automaticamente cancellato (senza notifica di errore) qualora sia stato @@ -1531,7 +1606,7 @@ particolare: notifica di errore) da \var{mode} qualora il gruppo del file non corrisponda a quelli associati al processo (la cosa non avviene quando l'\textit{effective user id} del processo è zero). -\end{itemize} +\end{enumerate} Per alcuni filesystem\footnote{il filesystem \acr{ext2} supporta questa caratteristica, che è mutuata da BSD.} è inoltre prevista una ulteriore @@ -1637,4 +1712,3 @@ che per il file %completo vedi \ntab), i permessi (vedi \secref{sec:file_perms}), le date (vedi %\secref{sec:file_times}). - diff --git a/fileintro.tex b/fileintro.tex index 24fec34..47e002c 100644 --- a/fileintro.tex +++ b/fileintro.tex @@ -359,7 +359,7 @@ e file, corrispondenti a tre apposite strutture definite nel kernel. Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun filesystem supportato: quando si vuole inserire il supporto di un nuovo filesystem tutto quello che occorre è chiamare la funzione -\func{register\_filesystem} passandole un'apposita struttura +\code{register\_filesystem} passandole un'apposita struttura (\var{file\_system\_type}) che contiene i dettagli per il riferimento all'implementazione del medesimo, che sarà aggiunta alla citata tabella. @@ -423,7 +423,7 @@ per i quali pathname il VFS deve creare una nuova \textit{dentry} e caricare l'inode corrispondente in memoria. -Questo procedimento viene eseguito dal metodo \func{lookup()} dell'inode +Questo procedimento viene eseguito dal metodo \code{lookup()} dell'inode della directory che contiene il file; questo viene installato nelle relative strutture in memoria quando si effettua il montaggio lo specifico filesystem su cui l'inode va a vivere. @@ -450,20 +450,20 @@ operazioni previste dal kernel \textbf{Funzione} & \textbf{Operazione} \\ \hline \hline - \textsl{\func{open}} & apre il file \\ - \textsl{\func{read}} & legge dal file \\ - \textsl{\func{write}} & scrive sul file \\ - \textsl{\func{llseek}} & sposta la posizione corrente sul file \\ - \textsl{\func{ioctl}} & accede alle operazioni di controllo + \textsl{\code{open}} & apre il file \\ + \textsl{\code{read}} & legge dal file \\ + \textsl{\code{write}} & scrive sul file \\ + \textsl{\code{llseek}} & sposta la posizione corrente sul file \\ + \textsl{\code{ioctl}} & accede alle operazioni di controllo (tramite la \func{ioctl})\\ - \textsl{\func{readdir}}& per leggere il contenuto di una directory \\ - \textsl{\func{poll}} & \\ - \textsl{\func{mmap}} & chiamata dalla system call \func{mmap}. + \textsl{\code{readdir}}& per leggere il contenuto di una directory \\ + \textsl{\code{poll}} & \\ + \textsl{\code{mmap}} & chiamata dalla system call \func{mmap}. mappa il file in memoria\\ - \textsl{\func{release}}& chiamata quando l'ultima referenza a un file + \textsl{\code{release}}& chiamata quando l'ultima referenza a un file aperto è chiusa\\ - \textsl{\func{fsync}} & chiamata dalla system call \func{fsync} \\ - \textsl{\func{fasync}} & chiamate da \func{fcntl} quando è abilitato + \textsl{\code{fsync}} & chiamata dalla system call \func{fsync} \\ + \textsl{\code{fasync}} & chiamate da \func{fcntl} quando è abilitato il modo asincrono per l'I/O su file. \\ \hline \end{tabular} @@ -479,7 +479,7 @@ di file in questione. Così sarà possibile scrivere sulla porta seriale come su un file di dati normale; ovviamente certe operazioni (nel caso della seriale ad esempio la -\func{seek}) non saranno disponibili, però con questo sistema l'utilizzo di +\code{seek}) non saranno disponibili, però con questo sistema l'utilizzo di diversi filesystem (come quelli usati da Windows o MacOs) è immediato e (relativamente) trasparente per l'utente ed il programmatore. diff --git a/filestd.tex b/filestd.tex index 6348a7d..13934c3 100644 --- a/filestd.tex +++ b/filestd.tex @@ -228,7 +228,7 @@ prototipi sono: viene settata al valore ricevuto dalla funzione sottostante di cui è fallita l'esecuzione. - Gli errori pertanto possono essere quelli di \func{malloc} per tutte + Gli errori pertanto possono essere quelli di \code{malloc} per tutte e tre le funzioni, quelli \func{open} per \func{fopen}, quelli di \func{fcntl} per \func{fdopen} e quelli di \func{fopen}, \func{fclose} e \func{fflush} per \func{freopen}.} @@ -284,7 +284,7 @@ possono essere aperti con le funzioni delle librerie standard del C. In realtà lo standard ANSI C prevede un totale di 15 possibili valori diversi per \param{mode}, ma in \tabref{tab:file_fopen_mode} si sono riportati solo i sei valori effettivi, ad essi può essere aggiunto pure -il carattere \func{b} (come ultimo carattere o nel mezzo agli altri per +il carattere \texttt{b} (come ultimo carattere o nel mezzo agli altri per le stringhe di due caratteri) che in altri sistemi operativi serve a distinguere i file binari dai file di testo; in un sistema POSIX questa distinzione non esiste e il valore viene accettato solo per @@ -330,7 +330,7 @@ una scrittura una delle funzioni \func{fflush}, \func{fseek}, \func{fsetpos} o \func{rewind} prima di eseguire una rilettura; viceversa nel caso in cui si voglia fare una scrittura subito dopo aver eseguito una lettura occorre prima usare una delle funzioni \func{fseek}, \func{fsetpos} o \func{rewind}. Anche -una operazione nominalmente nulla come \func{fseek(file, 0, SEEK\_CUR)} è +una operazione nominalmente nulla come \code{fseek(file, 0, SEEK\_CUR)} è sufficiente a garantire la sincronizzazione. Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione @@ -396,7 +396,7 @@ notificato come tale dai valori di uscita delle varie funzioni. Nella maggior parte dei casi questo avviene con la restituzione del valore intero (di tipo \type{int}) \macro{EOF}\footnote{la costante deve essere negativa, le \acr{glibc} usano -1, altre implementazioni possono avere - valori diversi.} definito anch'esso nell'header \func{stdlib.h}. + valori diversi.} definito anch'esso nell'header \file{stdlib.h}. Dato che le funzioni dell'interfaccia degli stream sono funzioni di libreria che si appoggiano a delle system call, esse non settano direttamente la @@ -504,7 +504,7 @@ in cui si specifica la dimensione dell'intera struttura ed un solo elemento. In realtà quello che conta nel trasferimento dei dati sono le dimensioni -totali, che sono sempre pari al prodotto \func{size * nelem}; la sola +totali, che sono sempre pari al prodotto \code{size * nelem}; la sola differenza è che le funzioni non ritornano il numero di byte scritti, ma il numero di elementi. @@ -580,7 +580,7 @@ rispettivi prototipi sono: \funcdecl{int fgetc(FILE *stream)} Legge un byte da \param{stream} e lo restituisce come intero. È una sempre una funzione. - \funcdecl{int getchar(void)} Equivalente a \func{getc(stdin)}. + \funcdecl{int getchar(void)} Equivalente a \code{getc(stdin)}. \bodydesc{Tutte queste funzioni leggono un byte alla volta, che viene restituito come intero; in caso di errore o fine del file il valore @@ -621,7 +621,7 @@ byte restituiscono un carattere in formato esteso (cio \funcdecl{wint\_t fgetwc(FILE *stream)} Legge un carattere esteso da \param{stream} È una sempre una funzione. - \funcdecl{wint\_t getwchar(void)} Equivalente a \func{getwc(stdin)}. + \funcdecl{wint\_t getwchar(void)} Equivalente a \code{getwc(stdin)}. \bodydesc{Tutte queste funzioni leggono un carattere alla volta, in caso di errore o fine del file il valore di ritorno è \macro{WEOF}.} @@ -639,7 +639,7 @@ precedenti usate per leggere: \func{putc}, \func{fputc} e \funcdecl{int fputc(FILE *stream)} Scrive il carattere \param{c} su \param{stream}. È una sempre una funzione. - \funcdecl{int putchar(void)} Equivalente a \func{putc(stdin)}. + \funcdecl{int putchar(void)} Equivalente a \code{putc(stdin)}. \bodydesc{Le funzioni scrivono sempre un carattere alla volta, il cui valore viene restituito in caso di successo; in caso di errore o @@ -654,7 +654,7 @@ sempre un intero; in caso di errore o fine del file il valore di ritorno Come nel caso dell'I/O binario le \acr{glibc} provvedono per ciascuna delle funzioni precedenti, come estensione GNU, una seconda funzione, il -cui nome è ottenuto aggiungendo un \func{\_unlocked}, che esegue +cui nome è ottenuto aggiungendo un \code{\_unlocked}, che esegue esattamente le stesse operazioni evitando però il lock implicito dello stream. @@ -825,7 +825,7 @@ anzich Come nel caso dell'I/O binario e a caratteri nelle \acr{glibc} sono previste una serie di altre funzioni, estensione di tutte quelle illustrate finora (eccetto \func{gets} e \func{puts}), il cui nome si -ottiene aggiungendo un \func{\_unlocked}, e che eseguono esattamente le +ottiene aggiungendo un \code{\_unlocked}, e che eseguono esattamente le stesse operazioni delle loro equivalenti, evitando però il lock implicito dello stream (vedi \secref{sec:file_stream_thread}). @@ -1151,8 +1151,8 @@ pi Infine una ulteriore estensione GNU definisce le due funzioni \func{dprintf} e \func{vdprintf}, che prendono un file descriptor al posto dello stream. Altre estensioni permettono di scrivere con caratteri estesi. Anche queste funzioni, -il cui nome è generato dalle precedenti funzioni aggiungendo una \func{w} -davanti a \func{print}, sono trattate in dettaglio nella documentazione delle +il cui nome è generato dalle precedenti funzioni aggiungendo una \texttt{w} +davanti a \texttt{print}, sono trattate in dettaglio nella documentazione delle \acr{glibc}. In corrispondenza alla famiglia di funzioni \func{printf} che si usano per @@ -1253,7 +1253,7 @@ particolare \param{whence} assume gli stessi valori gi \secref{sec:file_lseek}. La funzione restituisce 0 in caso di successo e -1 in caso di errore. La funzione \func{rewind} riporta semplicemente la posizione corrente all'inzio dello stream, ma non esattamente equivalente ad -una \func{fseek(stream, 0L, SEEK\_SET)} in quanto vengono cancellati anche i +una \code{fseek(stream, 0L, SEEK\_SET)} in quanto vengono cancellati anche i flag di errore e fine del file. Per ottenere la posizione corrente si usa invece la funzione \func{ftell}, il @@ -1278,10 +1278,10 @@ pu \headdecl{stdio.h} \funcdecl{int fsetpos(FILE *stream, fpos\_t *pos)} Setta la posizione - corrente nello stream \param{stream} al valore specificato da \func{pos}. + corrente nello stream \param{stream} al valore specificato da \param{pos}. \funcdecl{int fgetpos(FILE *stream, fpos\_t *pos)} Scrive la posizione - corrente nello stream \param{stream} in \func{pos}. + corrente nello stream \param{stream} in \param{pos}. \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di errore.} @@ -1367,8 +1367,8 @@ suo prototipo \begin{prototype}{stdio.h}{int setvbuf(FILE *stream, char *buf, int mode, size\_t size)} - Setta la bufferizzazione dello stream \func{stream} nella modalità indicata - da \param{mode}, usando \func{buf} come buffer di lunghezza \param{size}. + Setta la bufferizzazione dello stream \param{stream} nella modalità indicata + da \param{mode}, usando \param{buf} come buffer di lunghezza \param{size}. \bodydesc{Restituisce zero in caso di successo, ed un valore qualunque in caso di errore.} @@ -1377,7 +1377,7 @@ suo prototipo La funzione permette di controllare tutti gli aspetti della bufferizzazione; l'utente può specificare un buffer da usare al posto di quello allocato dal sistema passandone alla funzione l'indirizzo in \param{buf} e la dimensione in -\func{size}. +\param{size}. Ovviamente se si usa un buffer specificato dall'utente questo deve essere stato allocato e restare disponibile per tutto il tempo in cui si opera sullo @@ -1421,11 +1421,11 @@ e \func{setlinebuf}, i loro prototipi sono: \headdecl{stdio.h} \funcdecl{void setbuf(FILE *stream, char *buf)} Disabilita la - bufferizzazione se \param{buf} è \macro{NULL}, altrimenti usa \func{buf} + bufferizzazione se \param{buf} è \macro{NULL}, altrimenti usa \param{buf} come buffer di dimensione \macro{BUFSIZ} in modalità \textit{fully buffered}. \funcdecl{void setbuffer(FILE *stream, char *buf, size\_t size)} Disabilita - la bufferizzazione se \param{buf} è \macro{NULL}, altrimenti usa \func{buf} + la bufferizzazione se \param{buf} è \macro{NULL}, altrimenti usa \param{buf} come buffer di dimensione \param{size} in modalità \textit{fully buffered}. \funcdecl{void setlinebuf(FILE *stream)} Pone lo stream in modalità @@ -1495,7 +1495,7 @@ blocco non sono del tutto indolori, e quando il locking dello stream non necessario (come in tutti i programmi che non usano i thread), tutta la procedura può comportare dei pesanti costi in termini di prestazioni. Per questo motivo abbiamo visto in come per tutte le funzioni di I/O non -formattato esistano delle versioni \func{\_unlocked} (alcune previste dallo +formattato esistano delle versioni \code{\_unlocked} (alcune previste dallo standard POSIX stesso, altre aggiunte come estenzioni dalle \acr{glibc}) che possono essere usate in tutti questi casi\footnote{in certi casi dette funzioni possono essere usate, visto che sono molto più efficiente, anche in @@ -1505,7 +1505,7 @@ possono essere usate in tutti questi casi\footnote{in certi casi dette pertanto in grado di garantire prestazione enormemente più elevate. La sostituizione di tutte le funzioni di I/O con le relative versioni -\func{\_unlocked} in un programma che non usa i thread è però un lavoro +\code{\_unlocked} in un programma che non usa i thread è però un lavoro abbastanza noioso, e che appesantisce il codice; per questo motivo le \acr{glibc} provvedono un'altra via per poter utilizzare disabilitare il locking, anch'essa mutuata da estensioni introdotte in Solaris, cioè l'uso @@ -1528,9 +1528,3 @@ della funzione \func{\_\_fsetlocking}, il cui prototipo di blocco dello stream. \end{basedescript} - -\subsection{File temporanei} -\label{sec:file_temp_file} - -Un'altra serie di funzioni definite dalle librerie standard del C sono quelle -che riguardano la creazione di file temporanei. diff --git a/fileunix.tex b/fileunix.tex index bfbe893..d321ee9 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -364,7 +364,7 @@ prototipo \begin{prototype}{fcntl.h} {int creat(const char *pathname, mode\_t mode)} Crea un nuovo file vuoto, con i permessi specificati da \var{mode}. É del - tutto equivalente a \func{open(filedes, O\_CREAT|O\_WRONLY|O\_TRUNC, mode)}. + tutto equivalente a \code{open(filedes, O\_CREAT|O\_WRONLY|O\_TRUNC, mode)}. \end{prototype} \noindent adesso questa funzione resta solo per compatibilità con i vecchi programmi. @@ -437,14 +437,14 @@ un valore qualsiasi con la funzione \func{lseek}, il cui prototipo successo e -1 in caso di errore nel qual caso \var{errno} viene settata ad uno dei valori: \begin{errlist} - \item[\macro{ESPIPE}] \var{fd} è una pipe, un socket o una fifo. - \item[\macro{EINVAL}] \var{whence} non è un valore valido. + \item[\macro{ESPIPE}] \param{fd} è una pipe, un socket o una fifo. + \item[\macro{EINVAL}] \param{whence} non è un valore valido. \end{errlist} ed inoltre \macro{EBADF}.} \end{functions} -La nuova posizione è settata usando il valore specificato da \var{offset}, -sommato al riferimento dato da \var{whence}; quest'ultimo può assumere i +La nuova posizione è settata usando il valore specificato da \param{offset}, +sommato al riferimento dato da \param{whence}; quest'ultimo può assumere i seguenti valori\footnote{per compatibilità con alcune vecchie notazioni questi valori possono essere rimpiazzati rispettivamente con 0, 1 e 2 o con \macro{L\_SET}, \macro{L\_INCR} e \macro{L\_XTND}}: @@ -464,8 +464,8 @@ attivit kernel (cioè \var{f\_pos} in \var{file}, vedi \figref{fig:file_proc_file}). Dato che la funzione ritorna la nuova posizione, usando il valore zero per -\func{offset} si può riottenere la posizione corrente nel file chiamando la -funzione con \func{lseek(fd, 0, SEEK\_CUR}. +\param{offset} si può riottenere la posizione corrente nel file chiamando la +funzione con \code{lseek(fd, 0, SEEK\_CUR}. Si tenga presente inoltre che usare \macro{SEEK\_END} non assicura affatto che successiva scrittura avvenga alla fine del file, infatti se questo è stato @@ -542,8 +542,8 @@ Lo stesso comportamento avviene caso di lettura dalla rete (cio come vedremo in \secref{sec:sock_io_behav}), o per certi dispositivi, come le unità a nastro, che restituiscono un singolo blocco di dati alla volta. -In realtà anche le due condizioni segnalate dagli errori \func{EINTR} e -\func{EAGAIN} non sono errori. La prima si verifica quando la \func{read} è +In realtà anche le due condizioni segnalate dagli errori \macro{EINTR} e +\macro{EAGAIN} non sono errori. La prima si verifica quando la \func{read} è bloccata in attesa di dati in ingresso e viene interrotta da un segnale; in tal caso l'azione da prendere è quella di rieseguire la funzione. Torneremo sull'argomento in \secref{sec:signal_xxx}. @@ -915,7 +915,7 @@ La duplicazione dei file descriptor pu funzione di controllo dei file \func{fnctl} (che esamineremo in \secref{sec:file_fcntl}) con il parametro \macro{F\_DUPFD}. -L'operazione ha la sintassi \func{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0 +L'operazione ha la sintassi \code{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per \param{newfd} diventa equivalente a \func{dup}. La sola differenza, a parte i codici di errore, è che \func{dup2} chiude il nuovo file se è già aperto mentre \func{fcntl} apre il primo disponibile con un valore diff --git a/gapil.tex b/gapil.tex index 916b47b..053bc85 100644 --- a/gapil.tex +++ b/gapil.tex @@ -8,6 +8,7 @@ \documentclass[a4paper,11pt,twoside,italian]{book} \usepackage[latin1]{inputenc} \usepackage[bookmarks=true]{hyperref} +\usepackage{makeidx} \usepackage{booktabs} \usepackage{pstcol} \usepackage{pst-node} @@ -45,6 +46,8 @@ \author{Simone Piccardi} +\makeindex + \begin{document} \pagenumbering{roman} @@ -128,5 +131,7 @@ %\bibliographystyle{phaip} %\bibliography{biblio} +\printindex + +\end{document} -\end{document} \ No newline at end of file diff --git a/intro.tex b/intro.tex index e50e8b9..d6e2a45 100644 --- a/intro.tex +++ b/intro.tex @@ -379,8 +379,8 @@ 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 (vedi \secref{sec:file_symlink}, -la funzione \func{select}, i socket. +di API grande rilievo, come il link simbolici, la funzione \code{select}, i +socket. Queste estensioni sono state via via aggiunte al sistema nelle varie versioni del sistema (BSD 4.2, BSD 4.3 e BSD 4.4) come pure in alcuni derivati diff --git a/macro.tex b/macro.tex index 842859c..7045267 100644 --- a/macro.tex +++ b/macro.tex @@ -119,7 +119,10 @@ tab.~\thechapter.\theusercount} % variables, macros, and everything can be useul, % \newcommand{\cmd}[1]{\texttt{#1}} % shell command -\newcommand{\func}[1]{\texttt{#1}} % library function (or system call) +\newcommand{\code}[1]{\texttt{#1}} % for simple code +\newcommand{\func}[1]{% +\index{\texttt{#1}}\texttt{#1}% +} % library function (or system call) \newcommand{\macro}[1]{\texttt{#1}} % macro constant \newcommand{\var}[1]{\texttt{#1}} % variable \newcommand{\file}[1]{\texttt{#1}} % file name diff --git a/process.tex b/process.tex index f616206..b092b2d 100644 --- a/process.tex +++ b/process.tex @@ -179,7 +179,7 @@ pu \end{prototype} \noindent la funzione richiede come argomento l'indirizzo della opportuna funzione di pulizia da chiamare all'uscita, che non deve prendere argomenti e -non deve ritornare niente (deve essere essere cioè definita come \func{void +non deve ritornare niente (deve essere essere cioè definita come \code{void function(void)}). Una estensione di \func{atexit} è la funzione \func{on\_exit}, che le @@ -841,7 +841,7 @@ ed \cmd{-m} e la prima vuole un parametro mentre la seconda no \cmd{-m}). Per gestire le opzioni all'interno dei argomenti a linea di comando passati in -\func{argv} le librerie standard del C forniscono la funzione \func{getopt} +\var{argv} le librerie standard del C forniscono la funzione \func{getopt} che ha il seguente prototipo: \begin{prototype}{unistd.h} {int getopt(int argc, char * const argv[], const char * optstring)} @@ -912,9 +912,9 @@ elementi di \var{argv} che cominciano con il carattere \texttt{'-'}. Quando la funzione trova un'opzione essa ritorna il valore numerico del carattere, in questo modo si possono eseguire azioni specifiche usando uno -\func{switch}; \func{getopt} inoltre inizializza alcune variabili globali: +\code{switch}; \func{getopt} inoltre inizializza alcune variabili globali: \begin{itemize*} -\item \var{char * optarg} contiene il puntatore alla stringa parametro +\item \var{char *optarg} contiene il puntatore alla stringa parametro dell'opzione. \item \var{int optind} alla fine della scansione restituisce l'indice del primo elemento di \var{argv} che non è un'opzione. @@ -1128,7 +1128,7 @@ La seconda funzione prende come parametro una stringa analoga quella restituita da \func{getenv}, e sempre nella forma \var{NOME=valore}. Se la variabile specificata non esiste la stringa sarà aggiunta all'ambiente, se invece esiste il suo valore sarà settato a quello specificato da -\func{string}. Si tenga presente che, seguendo lo standard SUSv2, le +\param{string}. Si tenga presente che, seguendo lo standard SUSv2, le \acr{glibc} successive alla versione 2.1.2 aggiungono\footnote{il comportamento è lo stesso delle vecchie \acr{libc4} e \acr{libc5}; nelle \acr{glibc}, dalla versione 2.0 alla 2.1.1, veniva invece fatta una copia, @@ -1143,7 +1143,7 @@ questa funzione una variabile automatica (per evitare i problemi esposti in 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 -\var{=}) allora questa viene cancellata dall'ambiente. Infine se la chiamata +\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 una allocazione fatta in @@ -1383,7 +1383,7 @@ 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, la più bistrattata delle quali è il -\func{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste +\code{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste però un caso in l'uso di questa istruzione porta all'implementazione più efficiente, quello dell'uscita in caso di errore. diff --git a/prochand.tex b/prochand.tex index e50895c..7a7bef4 100644 --- a/prochand.tex +++ b/prochand.tex @@ -965,10 +965,11 @@ accessibili definendo la costante \macro{\_USE\_BSD}, sono: \funcdecl{pid\_t wait4(pid\_t pid, int * status, int options, struct rusage * rusage)} È identica a \func{waitpid} sia per comportamento che per i - valori dei parametri, ma restituisce in \var{rusage} un sommario delle + valori dei parametri, ma restituisce in \param{rusage} un sommario delle risorse usate dal processo (per i dettagli vedi \secref{sec:sys_xxx}) + \funcdecl{pid\_t wait3(int *status, int options, struct rusage *rusage)} - Prima versione, equivalente a \func{wait4(-1, \&status, opt, rusage)} è + Prima versione, equivalente a \code{wait4(-1, \&status, opt, rusage)} è ormai deprecata in favore di \func{wait4}. \end{functions} \noindent @@ -1064,7 +1065,7 @@ e come ambiente la lista di stringhe indicata da \var{envp}; entrambe le liste devono essere terminate da un puntatore nullo. I vettori degli argomenti e dell'ambiente possono essere acceduti dal nuovo programma quando la sua funzione \func{main} è dichiarata nella forma -\func{main(int argc, char *argv[], char *envp[])}. +\code{main(int argc, char *argv[], char *envp[])}. Le altre funzioni della famiglia servono per fornire all'utente una serie possibile di diverse interfacce per la creazione di un nuovo processo. I loro @@ -1093,7 +1094,7 @@ le modalit argomenti a linea di comando (cioè i valori di \var{argv} e \var{argc} visti dalla funzione \func{main} del programma chiamato). -Queste modalità sono due e sono riassunte dagli mnenonici \func{v} e \func{l} +Queste modalità sono due e sono riassunte dagli mnenonici \code{v} e \code{l} che stanno rispettivamente per \textit{vector} e \textit{list}. Nel primo caso gli argomenti sono passati tramite il vettore di puntatori \var{argv[]} a stringhe terminate con zero che costituiranno gli argomenti a riga di comando, @@ -1136,7 +1137,7 @@ per indicare il nome del file che contiene il programma che verr \end{table} La seconda differenza fra le funzioni riguarda le modalità con cui si -specifica il programma che si vuole eseguire. Con lo mnemonico \func{p} si +specifica il programma che si vuole eseguire. Con lo mnemonico \code{p} si indicano le due funzioni che replicano il comportamento della shell nello specificare il comando da eseguire; quando il parametro \var{file} non contiene una \file{/} esso viene considerato come un nome di programma, e @@ -1160,7 +1161,7 @@ indicato dal parametro \var{path}, che viene interpretato come il \end{figure} La terza differenza è come viene passata la lista delle variabili di ambiente. -Con lo mnemonico \func{e} vengono indicate quelle funzioni che necessitano di +Con lo mnemonico \code{e} vengono indicate quelle funzioni che necessitano di un vettore di parametri \var{envp[]} analogo a quello usato per gli argomenti a riga di comando (terminato quindi da un \macro{NULL}), le altre usano il valore della variabile \var{environ} (vedi \secref{sec:proc_environ}) del @@ -1473,7 +1474,7 @@ situazione degli identificatori \end{eqnarray*} in questo modo, dato che l'\textit{effective group id} è quello giusto, il programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo, a -questo punto il programma può eseguire una \func{setgid(getgid())} per settare +questo punto il programma può eseguire una \code{setgid(getgid())} per settare l'\textit{effective group id} a quello dell'utente (e dato che il \textit{real group id} corrisponde la funzione avrà successo), in questo modo non sarà possibile lanciare dal terminale programmi che modificano detto file, in tal @@ -1487,7 +1488,7 @@ caso infatti la situazione degli identificatori sarebbe: e ogni processo lanciato dal terminale avrebbe comunque \acr{gid} come \textit{effective group id}. All'uscita dal terminale, per poter di nuovo aggiornare lo stato di \file{/var/log/utmp} il programma eseguirà una -\func{setgid(utmp)} (dove \var{utmp} è il valore numerico associato al gruppo +\code{setgid(utmp)} (dove \var{utmp} è il valore numerico associato al gruppo \acr{utmp}, ottenuto ad esempio con una \func{getegid}), dato che in questo caso il valore richiesto corrisponde al \textit{saved group id} la funzione avrà successo e riporterà la situazione a: @@ -1808,7 +1809,7 @@ esempio utilizzano variabili statiche, le \acr{glibc} per disposizione due macro di compilatore, \macro{\_REENTRANT} e \macro{\_THREAD\_SAFE}, la cui definizione attiva le versioni rientranti di varie funzioni di libreria, che sono identificate aggiungendo il suffisso -\func{\_r} al nome della versione normale. +\code{\_r} al nome della versione normale. diff --git a/signal.tex b/signal.tex index 072b1d1..e67985b 100644 --- a/signal.tex +++ b/signal.tex @@ -124,7 +124,7 @@ riprende l'esecuzione all'istruzione successiva, ma essendo cambiato il flag la condizione non è più soddisfatta e il programma prosegue. Il problema con l'implementazione inaffidabile è che niente ci garantisce che -il segnale arrivi fra la valutazione della condizione del \func{while} e la +il segnale arrivi fra la valutazione della condizione del \code{while} e la chiamata a \func{pause}, nel qual caso, se il segnale non viene più generato, il processo resterà in sleep permanentemente. @@ -655,24 +655,39 @@ classificabili in maniera omogenea. Questi segnali sono: \subsection{Le funzioni \func{strsignal} e \func{psignal}} \label{sec:sig_strsignal} -Per la descrizione dei segnali il sistema mette a disposizione due funzioni -che stampano un messaggio di descrizione dato il numero. In genere si usano -quando si vuole notificare all'utente il segnale avvenuto (nel caso di -terminazione di un processo figlio o di un manipolatore che gestisce più -segnali); la prima funzione è una estensione GNU ed è analoga alla funzione -\func{strerr} per gli errori: -\begin{prototype}{string.h}{char * strsignal (int signum)} - Ritorna il puntatore ad una stringa allocata staticamente che contiene la - descrizione del segnale \var{signum}. +Per la descrizione dei segnali il sistema mette a disposizione due funzioni, +\func{strsignal} e \func{psignal}, che stampano un messaggio di descrizione +dato il numero. In genere si usano quando si vuole notificare all'utente il +segnale avvenuto (nel caso di terminazione di un processo figlio o di un +manipolatore che gestisce più segnali); la prima funzione è una estensione +GNU, accessibile avendo definito \macro{\_GNU\_SOURCE}, ed è analoga alla +funzione \func{strerror} (si veda \secref{sec:sys_strerror}) per gli errori: +\begin{prototype}{string.h}{char *strsignal(int signum)} + Ritorna il puntatore ad una stringa che contiene la descrizione del segnale + \var{signum}. \end{prototype} - -Dato che la stringa è allocata staticamente non se ne deve modificare il -contenuto, che resta valido solo fino alla successiva chiamata di -\func{strsignal}; nel caso si debba mantenere traccia del messaggio sarà +\noindent dato che la stringa è allocata staticamente non se ne deve +modificare il contenuto, che resta valido solo fino alla successiva chiamata +di \func{strsignal}. Nel caso si debba mantenere traccia del messaggio sarà necessario copiarlo. La seconda funzione deriva da BSD ed è analoga alla funzione \func{perror} -descritta in \secref{sec:sys_strerror}. +descritta in \secref{sec:sys_strerror}; il suo prototipo è: +\begin{prototype}{signal.h}{void psignal(int sig, const char *s)} + Stampa sullo standard error un messaggio costituito dalla stringa \param{s}, + seguita da due punti ed una descrizione del segnale indicato da \param{sig}. +\end{prototype} + +Una modalità alternativa per utilizzare le descrizioni restituite da +\func{strsignal} e \func{psignal} è quello di fare usare la variabile +\var{sys\_siglist}, che può essere acceduta dichiarando: +\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} + extern const char *const sys_siglist[] +\end{lstlisting} +\var{sys\_siglist} contiene le stringhe di descrizione indicizzate per numero +di segnale, per cui \code{char *decr = strsignal(SIGINT)} può essere +sostituito dall'equivalente \code{char *decr = sys\_siglist[SIGINT]}. + \section{La gestione dei segnali} @@ -713,7 +728,7 @@ comportamento, pur mantenendone immutato il prototipo\footnote{in realt In questa definizione si è usato il tipo \type{sighandler\_t} che è una estensione GNU definita in Linux che permette di riscrivere il prototipo in -forma più leggibile dell'originario \func{void (*signal(int signum, void +forma più leggibile dell'originario \code{void (*signal(int signum, void (*handler)(int)))int)}, e che è sostanzialmente equivalente alla definizione: \begin{verbatim} diff --git a/simpltcp.tex b/simpltcp.tex index e592f2f..f7260cf 100644 --- a/simpltcp.tex +++ b/simpltcp.tex @@ -44,7 +44,7 @@ una implementazione completa. \label{sec:TCPsimp_server_main} La prima versione del server, \file{ElemEchoTCPServer.c}, si compone di un -corpo principale, costituito dalla funzione \func{main}. Questa si incarica +corpo principale, costituito dalla funzione \code{main}. Questa si incarica di creare il socket, metterlo in ascolto di connessioni in arrivo e creare un processo figlio a cui delegare la gestione di ciascuna connessione. Questa parte, riportata in \nfig, è analoga a quella vista nel precedente esempio @@ -106,7 +106,7 @@ int main(int argc, char *argv[]) exit(0); } \end{lstlisting} - \caption{Codice della funzione \texttt{main} della prima versione del server + \caption{Codice della funzione \code{main} della prima versione del server per il servizio \texttt{echo}.} \label{fig:TCPsimpl_serv_code} \end{figure} @@ -116,12 +116,12 @@ quella dell'esempio citato, ed ad esso si applicano le considerazioni fatte in \secref{sec:TCPel_cunc_daytime}. Le uniche differenze rispetto all'esempio in \figref{fig:TCPel_serv_code} sono che in questo caso per il socket in ascolto viene usata la porta 7 e tutta la gestione della comunicazione è -delegata alla funzione \func{ServEcho}. +delegata alla funzione \code{ServEcho}. % Per ogni connessione viene creato un % processo figlio, il quale si incarica di lanciare la funzione % \texttt{SockEcho}. -Il codice della funzione \func{ServEcho} è invece mostrata in \nfig, la +Il codice della funzione \code{ServEcho} è invece mostrata in \nfig, la comunicazione viene gestita all'interno del ciclo (linee \texttt{\small 6--8}). I dati inviati dal client vengono letti dal socket con una semplice \func{read} (che ritorna solo in presenza di dati in arrivo), la riscrittura @@ -145,7 +145,7 @@ void ServEcho(int sockfd) { return; } \end{lstlisting} - \caption{Codice della prima versione della funzione \func{ServEcho} per la + \caption{Codice della prima versione della funzione \code{ServEcho} per la gestione del servizio \texttt{echo}.} \label{fig:TCPsimpl_server_elem_sub} \end{figure} @@ -204,14 +204,14 @@ int main(int argc, char *argv[]) \label{fig:TCPsimpl_client_elem} \end{figure} -La funzione \func{main} si occupa della creazione del socket e della +La funzione \code{main} si occupa della creazione del socket e della connessione (linee \texttt{\small 10--27}) secondo la stessa modalità spiegata in \secref{sec:net_cli_sample}, il client si connette sulla porta 7 all'indirizzo specificato dalla linea di comando (a cui si è aggiunta una elementare gestione delle opzioni non riportata in figura). Completata la connessione (quando la funzione \func{connect} ritorna) la -funzione \func{ClientEcho}, riportata in \nfig, si preoccupa di gestire la +funzione \code{ClientEcho}, riportata in \nfig, si preoccupa di gestire la comunicazione, leggendo una riga alla volta dallo \file{stdin}, scrivendola sul socket e ristampando su \file{stdout} quanto ricevuto in risposta dal server. @@ -240,9 +240,9 @@ void ClientEcho(FILE * filein, int socket) La funzione utilizza due buffer per gestire i dati inviati e letti sul socket (\texttt{\small 3}). La comunicazione viene gestita all'interno di un ciclo (linee \texttt{\small 5--10}), i dati da inviare sulla connessione vengono -presi dallo \texttt{stdin} usando la funzione \func{fgets} che legge una +presi dallo \file{stdin} usando la funzione \func{fgets} che legge una linea di testo (terminata da un \texttt{CR} e fino al massimo di -\texttt{MAXLINE} caratteri) e la salva sul buffer di invio, la funzione +\macro{MAXLINE} caratteri) e la salva sul buffer di invio, la funzione \func{SockWrite} (\texttt{\small 3}) scrive detti dati sul socket (gestendo l'invio multiplo qualora una singola \func{write} non basti, come spiegato in \secref{sec:sock_io_behav}). @@ -307,10 +307,10 @@ tcp 0 0 roke:echo gont:32981 ESTABLISHED \end{verbatim} mentre per quanto riguarda l'esecuzione dei programmi avremo che: \begin{itemize} -\item il client chiama la funzione \func{ClientEcho} che si blocca sulla +\item il client chiama la funzione \code{ClientEcho} che si blocca sulla \func{fgets} dato che non si è ancora scritto nulla sul terminale. \item il server eseguirà una \func{fork} facendo chiamare al processo figlio - la funzione \func{ServEcho}, quest'ultima si bloccherà sulla \func{read} + la funzione \code{ServEcho}, quest'ultima si bloccherà sulla \func{read} dal socket sul quale ancora non sono presenti dati. \item il processo padre del server chiamerà di nuovo \func{accept} bloccandosi fino all'arrivo di un'altra connessione. @@ -357,7 +357,7 @@ punto avremo: tcp 0 0 *:echo *:* LISTEN tcp 0 0 localhost:33032 localhost:echo TIME_WAIT \end{verbatim} %$ -con il client che entra in \macro{TIME\_WAIT}. +con il client che entra in \texttt{TIME\_WAIT}. Esaminiamo allora in dettaglio la sequenza di eventi che porta alla terminazione normale della connessione, che ci servirà poi da riferimento nei @@ -366,24 +366,24 @@ casi seguenti: \begin{enumerate} \item inviando un carattere di EOF da terminale la \func{fgets} ritorna restituendo un puntatore nullo che causa l'uscita dal ciclo di - while, così la \func{ClientEcho} ritorna. -\item al ritorno di \func{ClientEcho} ritorna anche la funzione \func{main}, e + while, così la \code{ClientEcho} ritorna. +\item al ritorno di \code{ClientEcho} ritorna anche la funzione \code{main}, e come parte del processo terminazione tutti i file descriptor vengono chiusi (si ricordi quanto detto in \secref{sec:proc_term_conclusion}); questo causa la chiusura del socket di comunicazione; il client allora invierà un FIN al server a cui questo risponderà con un ACK. A questo punto il client verrà a - trovarsi nello stato \macro{FIN\_WAIT\_2} ed il server nello stato - \macro{CLOSE\_WAIT} (si riveda quanto spiegato in + trovarsi nello stato \texttt{FIN\_WAIT\_2} ed il server nello stato + \texttt{CLOSE\_WAIT} (si riveda quanto spiegato in \secref{sec:TCPel_conn_term}). \item quando il server riceve il FIN la \func{read} del processo figlio che gestisce la connessione ritorna restituendo 0 causando così l'uscita dal - ciclo di while e il ritorno di \func{ServEcho}, a questo punto il processo + ciclo di while e il ritorno di \code{ServEcho}, a questo punto il processo figlio termina chiamando \func{exit}. \item all'uscita del figlio tutti i file descriptor vengono chiusi, la chiusura del socket connesso fa sì che venga effettuata la sequenza finale di chiusura della connessione, viene emesso un FIN dal server che riceverà un ACK dal client, a questo punto la connessione è conclusa e il client - resta nello stato \func{TIME\_WAIT}. + resta nello stato \texttt{TIME\_WAIT}. \item \end{enumerate} diff --git a/socket.tex b/socket.tex index ec88664..f38305a 100644 --- a/socket.tex +++ b/socket.tex @@ -601,11 +601,12 @@ funzioni sono: Converte l'intero a 16 bit \var{netshort} dal formato della rete a quello della macchina. \end{prototype} -I nomi sono assegnati usando la lettera \func{n} come mnemonico per indicare +I nomi sono assegnati usando la lettera \texttt{n} come mnemonico per indicare l'ordinamento usato sulla rete (da \textit{network order}) e la lettera -\func{h} come mnemonico per l'ordinamento usato sulla macchina locale (da -\textit{host order}), mentre le lettere \func{s} e \func{l} stanno ad indicare -i tipi di dato (\type{long} o \type{short}, riportati anche dai prototipi). +\texttt{h} come mnemonico per l'ordinamento usato sulla macchina locale (da +\textit{host order}), mentre le lettere \texttt{s} e \texttt{l} stanno ad +indicare i tipi di dato (\type{long} o \type{short}, riportati anche dai +prototipi). Usando queste funzioni si ha la conversione automatica: nel caso in cui la macchina che si sta usando abbia una architettura \textit{big endian} queste @@ -626,7 +627,7 @@ Le prime tre funzioni di manipolazione riguardano la conversione degli indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la cosiddetta notazione \textit{dotted-decimal}, (cioè nella forma \texttt{192.160.0.1}) al formato binario (direttamente in \textit{network - order}) e viceversa; in questo caso si usa la lettera \func{a} come + order}) e viceversa; in questo caso si usa la lettera \texttt{a} come mnemonico per indicare la stringa. Dette funzioni sono: \begin{prototype}{arpa/inet.h} {int inet\_aton(const char *src, struct in\_addr *dest)} @@ -659,9 +660,9 @@ mnemonico per indicare la stringa. Dette funzioni sono: Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo motivo è preferibile usare le due nuove funzioni \func{inet\_pton} e \func{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in -questo caso le lettere \func{n} e \func{p} sono degli mnemonici per ricordare -il tipo di conversione effettuata e stanno per \textit{presentation} e -\textit{numeric}. +questo caso le lettere \texttt{n} e \texttt{p} sono degli mnemonici per +ricordare il tipo di conversione effettuata e stanno per \textit{presentation} +e \textit{numeric}. % \begin{figure}[htb] % \centering diff --git a/system.tex b/system.tex index 6410f1a..a1aa32f 100644 --- a/system.tex +++ b/system.tex @@ -43,13 +43,13 @@ definizioni: dato che l'UTC corrisponde all'ora locale di Greenwich. È il tempo su cui viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per indicare le date di modifica dei file o quelle di avvio dei processi. Per - memorizzare questo tempo è stato riservato il tipo primitivo \func{time\_t}. + memorizzare questo tempo è stato riservato il tipo primitivo \type{time\_t}. \item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate dal timer di sistema, e che per Linux avvengono ogni centesimo di secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni millesimo di secondo}. Il dato primitivo usato per questo tempo è - \func{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di + \type{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di operazione del timer, e corrisponde dunque al numero di tick al secondo. Lo standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK}); questo valore può comunque essere ottenuto con \func{sysconf} (vedi @@ -95,7 +95,7 @@ presenta una serie di problemi nel caso lo si debba usare con i thread. Esamineremo in questa sezione le sue caratteristiche principali. -\subsection{La variabile \func{errno}} +\subsection{La variabile \var{errno}} \label{sec:sys_errno} Quasi tutte le funzioni delle librerie del C sono in grado di individuare e -- 2.30.2