From: Simone Piccardi Date: Mon, 23 Dec 2002 23:16:00 +0000 (+0000) Subject: Inserite nuove macro per la indicizzazione della definizione delle funzioni X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=ff2d0141751ed62ef56e5bfd226c589311b8b669;p=gapil.git Inserite nuove macro per la indicizzazione della definizione delle funzioni e delle strutture dati. Inoltre si e` revisionata la forma delle definizioni delle funzioni in alcuni capitoli. --- diff --git a/elemtcp.tex b/elemtcp.tex index 1db669a..f59308a 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -644,7 +644,7 @@ Useremo questo schema anche per l'esempio di reimplementazione del servizio \subsection{La funzione \func{bind}} \label{sec:TCPel_func_bind} -La funzione \func{bind} assegna un indirizzo locale ad un socket. È usata +La funzione \funcd{bind} assegna un indirizzo locale ad un socket. È usata cioè per specificare la prima parte dalla socket pair. Viene usata sul lato server per specificare la porta (e gli eventuali indirizzi locali) su cui poi ci si porrà in ascolto. Il prototipo della funzione è il seguente: @@ -739,7 +739,7 @@ con una struttura, perch costante come operando a destra in una assegnazione. Per questo motivo nell'header \file{netinet/in.h} è definita una variabile -\type{in6addr\_any} (dichiarata come \ctyp{extern}, ed inizializzata dal +\const{in6addr\_any} (dichiarata come \direct{extern}, ed inizializzata dal sistema al valore \const{IN6ADRR\_ANY\_INIT}) che permette di effettuare una assegnazione del tipo: @@ -751,7 +751,7 @@ serv_add.sin6_addr = in6addr_any; /* connect from anywhere */ \subsection{La funzione \func{connect}} \label{sec:TCPel_func_connect} -La funzione \func{connect} è usata da un client TCP per stabilire la +La funzione \funcd{connect} è usata da un client TCP per stabilire la connessione con un server TCP, il prototipo della funzione è il seguente: \begin{prototype}{sys/socket.h} {int connect(int sockfd, const struct sockaddr *servaddr, socklen\_t addrlen)} @@ -853,7 +853,7 @@ necessario effettuare una \func{bind}. \subsection{La funzione \func{listen}} \label{sec:TCPel_func_listen} -La funzione \func{listen} è usata per usare un socket in modalità passiva, +La funzione \funcd{listen} è usata per usare un socket in modalità passiva, cioè, come dice il nome, per metterlo in ascolto di eventuali connessioni; in sostanza l'effetto della funzione è di portare il socket dallo stato \texttt{CLOSED} a quello \texttt{LISTEN}. In genere si chiama la funzione in @@ -866,20 +866,20 @@ pagina di manuale \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di errore. I codici di errore restituiti in \var{errno} sono i seguenti: \begin{errlist} - \item[\errcode{EBADF}] l'argomento \var{sockfd} non è un file descriptor + \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor valido. - \item[\errcode{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket. \item[\errcode{EOPNOTSUPP}] il socket è di un tipo che non supporta questa operazione. \end{errlist}} \end{prototype} -La funzione pone il socket specificato da \var{sockfd} in modalità passiva e +La funzione pone il socket specificato da \param{sockfd} in modalità passiva e predispone una coda per le connessioni in arrivo di lunghezza pari a -\var{backlog}. La funzione si può applicare solo a socket di tipo +\param{backlog}. La funzione si può applicare solo a socket di tipo \const{SOCK\_STREAM} o \const{SOCK\_SEQPACKET}. -Il parametro \var{backlog} indica il numero massimo di connessioni pendenti +L'argomento \param{backlog} indica il numero massimo di connessioni pendenti accettate; se esso viene ecceduto il client al momento della richiesta della connessione riceverà un errore di tipo \errcode{ECONNREFUSED}, o se il protocollo, come accade nel caso del TCP, supporta la ritrasmissione, la @@ -910,7 +910,7 @@ processo chiama la funzione \func{accept} (vedi complete è passata al programma, o, se la coda è vuota, il processo viene posto in attesa e risvegliato all'arrivo della prima connessione completa. -Storicamente il valore del parametro \var{backlog} era corrispondente al +Storicamente il valore del parametro \param{backlog} era corrispondente al massimo valore della somma del numero di entrate possibili per ciascuna di dette code. Stevens riporta che BSD ha sempre applicato un fattore di 1.5 al valore, e provvede una tabella con i risultati ottenuti con vari kernel, @@ -924,7 +924,7 @@ indirizzati verso una porta forgiati con indirizzo IP fasullo\footnote{con la perduti e la coda delle connessioni incomplete viene saturata, impedendo di fatto ulteriori connessioni. -Per ovviare a questo il significato del \var{backlog} è stato cambiato a +Per ovviare a questo il significato del \param{backlog} è stato cambiato a indicare la lunghezza della coda delle connessioni complete. La lunghezza della coda delle connessioni incomplete può essere ancora controllata usando la \func{sysctl} o scrivendola direttamente in @@ -932,7 +932,7 @@ la \func{sysctl} o scrivendola direttamente in protezione dei syncookies però (con l'opzione da compilare nel kernel e da attivare usando \file{/proc/sys/net/ipv4/tcp\_syncookies}) questo valore viene ignorato e non esiste più un valore massimo. In ogni caso in Linux il -valore di \var{backlog} viene troncato ad un massimo di \const{SOMAXCONN} +valore di \param{backlog} viene troncato ad un massimo di \const{SOMAXCONN} se è superiore a detta costante (che di default vale 128). La scelta storica per il valore di questo parametro è di 5, e alcuni vecchi @@ -967,7 +967,7 @@ trasparente dal protocollo TCP. \subsection{La funzione \func{accept}} \label{sec:TCPel_func_accept} -La funzione \func{accept} è chiamata da un server TCP per gestire la +La funzione \funcd{accept} è chiamata da un server TCP per gestire la connessione una volta che sia stato completato il three way handshake, la funzione restituisce un nuovo socket descriptor su cui si potrà operare per effettuare la comunicazione. Se non ci sono connessioni completate il processo @@ -982,9 +982,9 @@ viene messo in attesa. Il prototipo della funzione \var{errno} viene impostata ai seguenti valori: \begin{errlist} - \item[\errcode{EBADF}] l'argomento \var{sockfd} non è un file descriptor + \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor valido. - \item[\errcode{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket. \item[\errcode{EOPNOTSUPP}] il socket è di un tipo che non supporta questa operazione. \item[\errcode{EAGAIN} o \errcode{EWOULDBLOCK}] il socket è stato impostato @@ -1002,12 +1002,12 @@ viene messo in attesa. Il prototipo della funzione \errval{ERESTARTSYS}.} \end{prototype} -Estrae la prima connessione relativa al socket \var{sockfd} in attesa sulla +Estrae la prima connessione relativa al socket \param{sockfd} in attesa sulla coda delle connessioni complete, che associa ad nuovo socket con le stesse -caratteristiche di \var{sockfd} (restituito dalla funzione stessa). Il socket -originale non viene toccato. Nella struttura \var{addr} e nella variabile -\var{addrlen} vengono restituiti indirizzo e relativa lunghezza del client che -si è connesso. +caratteristiche di \param{sockfd} (restituito dalla funzione stessa). Il +socket originale non viene toccato. Nella struttura \param{addr} e nella +variabile \param{addrlen} vengono restituiti indirizzo e relativa lunghezza del +client che si è connesso. La funzione può essere usata solo con socket che supportino la connessione (cioè di tipo \const{SOCK\_STREAM}, \const{SOCK\_SEQPACKET} o @@ -1026,20 +1026,20 @@ socket flag come \const{O\_NONBLOCK}, che devono essere rispecificati volta volta, questo è un comportamento diverso rispetto a quanto accade con BSD e deve essere tenuto in conto per scrivere programmi portabili. -I due argomenti \var{cliaddr} e \var{addrlen} (si noti che quest'ultimo -è passato per indirizzo per avere indietro il valore) sono usati per ottenere +I due argomenti \param{cliaddr} e \param{addrlen} (si noti che quest'ultimo è +passato per indirizzo per avere indietro il valore) sono usati per ottenere l'indirizzo del client da cui proviene la connessione. Prima della chiamata -\var{addrlen} deve essere inizializzato alle dimensioni della struttura il -cui indirizzo è passato come argomento in \var{cliaddr}, al ritorno della -funzione \var{addrlen} conterrà il numero di byte scritti dentro -\var{cliaddr}. Se questa informazione non interessa basterà inizializzare a +\param{addrlen} deve essere inizializzato alle dimensioni della struttura il +cui indirizzo è passato come argomento in \param{cliaddr}, al ritorno della +funzione \param{addrlen} conterrà il numero di byte scritti dentro +\param{cliaddr}. Se questa informazione non interessa basterà inizializzare a \val{NULL} detti puntatori. Se la funzione ha successo restituisce il descrittore di un nuovo socket creato dal kernel (detto \textit{connected socket}) a cui viene associata la prima connessione completa (estratta dalla relativa coda, vedi \secref{sec:TCPel_func_listen}) che il client TCP ha effettuato verso il -socket \var{sockfd}. Quest'ultimo (detto \textit{listening socket}) è quello +socket \param{sockfd}. Quest'ultimo (detto \textit{listening socket}) è 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 imopstato il socket @@ -1222,10 +1222,9 @@ chiusa. \subsection{Le funzioni \func{getsockname} e \func{getpeername}} \label{sec:TCPel_get_names} -Queste due funzioni vengono usate per ottenere la socket pair associata ad un -certo socket; la prima restituisce l'indirizzo locale, la seconda quello -remoto. - +Queste due funzioni vengono usate per ottenere i dati realtivi alla socket +pair associata ad un certo socket; la prima è \funcd{getsockname} e +restituisce l'indirizzo locale; il suo prototipo è: \begin{prototype}{sys/socket.h} {int getsockname(int sockfd, struct sockaddr * name, socklen\_t * namelen)} Legge l'indirizzo locale del socket \param{sockfd} nella struttura @@ -1234,28 +1233,30 @@ remoto. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di errore. I codici di errore restituiti in \var{errno} sono i seguenti: \begin{errlist} - \item[\errcode{EBADF}] l'argomento \var{sockfd} non è un file descriptor + \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor valido. - \item[\errcode{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket. \item[\errcode{ENOBUFS}] non ci sono risorse sufficienti nel sistema per eseguire l'operazione. - \item[\errcode{EFAULT}] l'argomento \var{name} punta al di fuori dello + \item[\errcode{EFAULT}] l'argomento \param{name} punta al di fuori dello spazio di indirizzi del processo. \end{errlist}} \end{prototype} -La funzione \func{getsockname} si usa tutte le volte che si vuole avere -l'indirizzo locale di un socket; ad esempio può essere usata da un client (che -usualmente non chiama \func{bind}) per ottenere numero IP e porta locale -associati al socket restituito da una \func{connect}, o da un server che ha -chiamato \func{bind} su un socket usando 0 come porta locale per ottenere il -numero di porta effimera assegnato dal kernel. +La funzione si usa tutte le volte che si vuole avere l'indirizzo locale di un +socket; ad esempio può essere usata da un client (che usualmente non chiama +\func{bind}) per ottenere numero IP e porta locale associati al socket +restituito da una \func{connect}, o da un server che ha chiamato \func{bind} +su un socket usando 0 come porta locale per ottenere il numero di porta +effimera assegnato dal kernel. Inoltre quando un server esegue una \func{bind} su un indirizzo generico, se chiamata dopo il completamento di una connessione sul socket restituito da \func{accept}, restituisce l'indirizzo locale che il kernel ha assegnato a quella connessione. +Tutte le volte che si vuole avere l'indirizzo remoto di un socket si usa la +funzione \funcd{getpeername}, il cui prototipo è: \begin{prototype}{sys/socket.h} {int getpeername(int sockfd, struct sockaddr * name, socklen\_t * namelen)} Legge l'indirizzo remoto del socket \param{sockfd} nella struttura @@ -1264,21 +1265,17 @@ quella connessione. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di errore. I codici di errore restituiti in \var{errno} sono i seguenti: \begin{errlist} - \item[\errcode{EBADF}] l'argomento \var{sockfd} non è un file descriptor + \item[\errcode{EBADF}] l'argomento \param{sockfd} non è un file descriptor valido. - \item[\errcode{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\errcode{ENOTSOCK}] l'argomento \param{sockfd} non è un socket. \item[\errcode{ENOTCONN}] il socket non è connesso. \item[\errcode{ENOBUFS}] non ci sono risorse sufficienti nel sistema per eseguire l'operazione. - \item[\errcode{EFAULT}] l'argomento \var{name} punta al di fuori dello + \item[\errcode{EFAULT}] l'argomento \param{name} punta al di fuori dello spazio di indirizzi del processo. \end{errlist}} \end{prototype} - -La funzione \func{getpeername} si usa tutte le volte che si vuole avere -l'indirizzo remoto di un socket. - Ci si può chiedere a cosa serva questa funzione dato che dal lato client l'indirizzo remoto è sempre noto quando si esegue la \func{connect} mentre dal lato server si possono usare, come si è fatto nell'esempio precedente, i diff --git a/fileadv.tex b/fileadv.tex index 5fdc8a0..2d3ce01 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -78,7 +78,7 @@ operazione, chiamata usualmente \textit{I/O multiplexing}, BSD,\footnote{la funzione è apparsa in BSD4.2 e standardizzata in BSD4.4, ma è stata portata su tutti i sistemi che supportano i \textit{socket}\index{socket}, compreso le varianti di System V.} con la -funzione \func{select}, il cui prototipo è: +funzione \funcd{select}, il cui prototipo è: \begin{functions} \headdecl{sys/time.h} \headdecl{sys/types.h} @@ -155,9 +155,9 @@ pi Infine l'argomento \param{timeout}, specifica un tempo massimo di attesa\footnote{il tempo è valutato come \textit{elapsed time}.} prima che la funzione ritorni; se impostato a \val{NULL} la funzione attende -indefinitamente. Si può specificare anche un tempo nullo (cioè una \var{struct - timeval} con i campi impostati a zero), qualora si voglia semplicemente -controllare lo stato corrente dei file descriptor. +indefinitamente. Si può specificare anche un tempo nullo (cioè una struttura +\struct{timeval} con i campi impostati a zero), qualora si voglia +semplicemente controllare lo stato corrente dei file descriptor. La funzione restituisce il totale dei file descriptor pronti nei tre insiemi, il valore zero indica sempre che si è raggiunto un timeout. Ciascuno dei tre @@ -180,7 +180,7 @@ necessario ricalcolare tutte le volte il tempo rimanente.\footnote{questo pu Come accennato l'interfaccia di \func{select} è una estensione di BSD; anche System V ha introdotto una sua interfaccia per gestire l'\textit{I/O - multiplexing}, basata sulla funzione \func{poll},\footnote{la funzione è + multiplexing}, basata sulla funzione \funcd{poll},\footnote{la funzione è prevista dallo standard XPG4, ed è stata introdotta in Linux come system call a partire dal kernel 2.1.23 e dalle \acr{libc} 5.4.28.} il cui prototipo è: @@ -202,11 +202,11 @@ specificati da \param{ufds}. \end{prototype} La funzione tiene sotto controllo un numero \param{ndfs} di file descriptor -specificati attraverso un vettore di puntatori a strutture di tipo -\type{pollfd}, la cui definizione è riportata in \figref{fig:file_pollfd}. -Come \func{select} anche \func{poll} permette di interrompere l'attesa dopo un -certo tempo, che va specificato attraverso \param{timeout} in numero di -millisecondi (un valore negativo indica un'attesa indefinita). +specificati attraverso un vettore di puntatori a strutture \struct{pollfd}, la +cui definizione è riportata in \figref{fig:file_pollfd}. Come \func{select} +anche \func{poll} permette di interrompere l'attesa dopo un certo tempo, che +va specificato attraverso \param{timeout} in numero di millisecondi (un valore +negativo indica un'attesa indefinita). \begin{figure}[!htb] \footnotesize \centering @@ -220,13 +220,13 @@ struct pollfd { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{pollfd}, utilizzata per specificare le modalità + \caption{La struttura \struct{pollfd}, utilizzata per specificare le modalità di controllo di un file descriptor alla funzione \func{poll}.} \label{fig:file_pollfd} \end{figure} Per ciascun file da controllare deve essere opportunamente predisposta una -struttura \type{pollfd}; nel campo \var{fd} deve essere specificato il file +struttura \struct{pollfd}; nel campo \var{fd} deve essere specificato il file descriptor, mentre nel campo \var{events} il tipo di evento su cui si vuole attendere; quest'ultimo deve essere specificato come maschera binaria dei primi tre valori riportati in \tabref{tab:file_pollfd_flags} (gli altri @@ -258,14 +258,14 @@ vengono utilizzati solo per \var{revents} come valori in uscita). \hline \end{tabular} \caption{Costanti per l'identificazione dei vari bit dei campi - \var{events} e \var{revents} di \type{pollfd}.} + \var{events} e \var{revents} di \struct{pollfd}.} \label{tab:file_pollfd_flags} \end{table} La funzione ritorna, restituendo il numero di file per i quali si è verificata una delle condizioni di attesa richieste od un errore. Lo stato dei file all'uscita della funzione viene restituito nel campo \var{revents} della -relativa struttura \type{pollfd}, che viene impostato alla maschera binaria +relativa struttura \struct{pollfd}, che viene impostato alla maschera binaria dei valori riportati in \tabref{tab:file_pollfd_flags}, ed oltre alle tre condizioni specificate tramite \var{events} può riportare anche l'occorrere di una condizione di errore. @@ -275,7 +275,7 @@ Lo standard POSIX (POSIX 1003.1g-2000 e POSIX 1003.1-2001). Esso prevede che tutte le funzioni ad esso relative vengano dichiarate nell'header \file{sys/select.h}, che sostituisce i precedenti, ed aggiunge a \func{select} una nuova funzione -\func{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed +\funcd{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed l'header \file{sys/select.h}, compaiono in Linux a partire dalle \acr{glibc} 2.1. Le \acr{libc4} e \acr{libc5} non contengono questo header, le \acr{glibc} 2.0 contengono una definizione sbagliata di \func{psignal}, @@ -303,7 +303,7 @@ sostituisce i precedenti, ed aggiunge a \func{select} una nuova funzione \end{prototype} La funzione è sostanzialmente identica a \func{select}, solo che usa una -struttura \type{timespec} per indicare con maggiore precisione il timeout e +struttura \struct{timespec} per indicare con maggiore precisione il timeout e non ne aggiorna il valore in caso di interruzione, inoltre prende un argomento aggiuntivo \param{sigmask} che è il puntatore ad una maschera di segnali (si veda \secref{sec:sig_sigmask}). La maschera corrente viene sostituita da @@ -361,7 +361,7 @@ presenta notevoli problemi, dato che non più di uno, qual'è il file descriptor responsabile dell'emissione del segnale. Linux però supporta le estensioni POSIX.1b dei segnali che permettono di superare il problema facendo ricorso alle informazioni aggiuntive restituite -attraverso la struttura \type{siginfo\_t}, utilizzando la forma estesa +attraverso la struttura \struct{siginfo\_t}, utilizzando la forma estesa \var{sa\_sigaction} del manipolatore (si riveda quanto illustrato in \secref{sec:sig_sigaction}). @@ -373,7 +373,7 @@ manipolatore tutte le volte che ricever campo \var{si\_code}\footnote{il valore resta \const{SI\_SIGIO} qualunque sia il segnale che si è associato all'I/O asincrono, ed indica appunto che il segnale è stato generato a causa di attività nell'I/O asincrono.} di -\type{siginfo\_t}, troverà nel campo \var{si\_fd} il valore del file +\struct{siginfo\_t}, troverà nel campo \var{si\_fd} il valore del file descriptor che ha generato il segnale. Un secondo vantaggio dell'uso dei segnali real-time è che essendo dotati di @@ -384,7 +384,7 @@ cui l'accesso come \func{poll} e \func{select}, almeno fintanto che non si satura la coda; si eccedono le dimensioni di quest'ultima; in tal caso infatti il kernel, non potendo più assicurare il comportamento corretto per un segnale real-time, -invierà al suo posto un \var{SIGIO}, su cui si accumuleranno tutti i segnali +invierà al suo posto un \const{SIGIO}, su cui si accumuleranno tutti i segnali in eccesso, e si dovrà determinare al solito modo quali sono i file diventati attivi. @@ -409,7 +409,7 @@ completamente in user space. Esistono comunque vari progetti sperimentali supporto diretto da parte del kernel. Lo standard prevede che tutte le operazioni di I/O asincrono siano controllate -attraverso l'uso di una apposita struttura \type{aiocb} (il cui nome sta per +attraverso l'uso di una apposita struttura \struct{aiocb} (il cui nome sta per \textit{asyncronous I/O control block}), che viene passata come argomento a tutte le funzioni dell'interfaccia. La sua definizione, come effettuata in \file{aio.h}, è riportata in \figref{fig:file_aiocb}. Nello steso file è @@ -433,7 +433,7 @@ struct aiocb \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{aiocb}, usata per il controllo dell'I/O + \caption{La struttura \struct{aiocb}, usata per il controllo dell'I/O asincrono.} \label{fig:file_aiocb} \end{figure} @@ -481,12 +481,12 @@ struct sigevent \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{sigevent}, usata per specificare le modalità di + \caption{La struttura \struct{sigevent}, usata per specificare le modalità di notifica degli eventi relativi alle operazioni di I/O asincrono.} \label{fig:file_sigevent} \end{figure} -Infine il campo \var{aio\_sigevent} è una struttura di tipo \type{sigevent} +Infine il campo \var{aio\_sigevent} è una struttura di tipo \struct{sigevent} che serve a specificare il modo in cui si vuole che venga effettuata la notifica del completamento delle operazioni richieste. La struttura è riportata in \secref{fig:file_sigevent}; il campo \var{sigev\_notify} è quello @@ -497,15 +497,15 @@ che indica le modalit chiamante il segnale specificato nel campo \var{sigev\_signo}, se il manipolatore è installato con \const{SA\_SIGINFO}, il gli verrà restituito il valore di \var{sigev\_value} in come valore del campo \var{si\_value} per - \type{siginfo\_t}. + \struct{siginfo\_t}. \item[\const{SIGEV\_THREAD}] La notifica viene effettuata creando un nuovo thread che esegue la funzione specificata da \var{sigev\_notify\_function}, con gli attributi specificati da \var{sigev\_notify\_attribute}. \end{basedescript} Le due funzioni base dell'interfaccia per l'I/O asincrono sono -\func{aio\_read} ed \func{aio\_write}. Esse permettono di richiedere una -lettura od una scrittura asincrona di dati, usando la struttura \type{aiocb} +\funcd{aio\_read} ed \funcd{aio\_write}. Esse permettono di richiedere una +lettura od una scrittura asincrona di dati, usando la struttura \struct{aiocb} appena descritta; i rispettivi prototipi sono: \begin{functions} \headdecl{aio.h} @@ -546,13 +546,13 @@ richiesta. Questo comporta che occorre evitare di usare per \param{aiocbp} variabili automatiche e che non si deve riutilizzare la stessa struttura per un ulteriore operazione fintanto che la precedente non sia stata ultimata. In generale per ogni operazione di I/O asincrono si deve utilizzare una diversa -struttura \type{aiocb}. +struttura \struct{aiocb}. Dato che si opera in modalità asincrona, il successo di \func{aio\_read} o \func{aio\_write} non implica che le operazioni siano state effettivamente eseguite in maniera corretta; per verificarne l'esito l'interfaccia prevede altre due funzioni, che permettono di controllare lo stato di esecuzione. La -prima è \func{aio\_error}, che serve a determinare un eventuale stato di +prima è \funcd{aio\_error}, che serve a determinare un eventuale stato di errore; il suo prototipo è: \begin{prototype}{aio.h} {int aio\_error(const struct aiocb *aiocbp)} @@ -577,7 +577,7 @@ del caso, i codici di errore delle system call \func{read}, \func{write} e Una volta che si sia certi che le operazioni siano state concluse (cioè dopo che una chiamata ad \func{aio\_error} non ha restituito \errcode{EINPROGRESS}, -si potrà usare la seconda funzione dell'interfaccia, \func{aio\_return}, che +si potrà usare la seconda funzione dell'interfaccia, \funcd{aio\_return}, che permette di verificare il completamento delle operazioni di I/O asincrono; il suo prototipo è: \begin{prototype}{aio.h} @@ -635,7 +635,7 @@ operazioni di sincronizzazione dei dati saranno completate. In alcuni casi può essere necessario interrompere le operazioni (in genere quando viene richiesta un'uscita immediata dal programma), per questo lo -standard POSIX.1b prevede una funzioni apposita, \func{aio\_cancel}, che +standard POSIX.1b prevede una funzioni apposita, \funcd{aio\_cancel}, che permette di cancellare una operazione richiesta in precedenza; il suo prototipo è: \begin{prototype}{aio.h} @@ -678,7 +678,7 @@ corso normale, compreso quanto richiesto riguardo al meccanismo di notifica del loro avvenuto completamento. Benché l'I/O asincrono preveda un meccanismo di notifica, l'interfaccia -fornisce anche una apposita funzione, \func{aio\_suspend}, che permette di +fornisce anche una apposita funzione, \funcd{aio\_suspend}, che permette di sospendere l'esecuzione del processo chiamante fino al completamento di una specifica operazione; il suo prototipo è: \begin{prototype}{aio.h} @@ -705,12 +705,12 @@ La funzione permette di bloccare il processo fintanto che almeno una delle un tempo massimo specificato da \param{timout}, o fintanto che non arrivi un segnale.\footnote{si tenga conto che questo segnale può anche essere quello utilizzato come meccanismo di notifica.} La lista deve essere inizializzata -con delle strutture \var{aiocb} relative ad operazioni effettivamente +con delle strutture \struct{aiocb} relative ad operazioni effettivamente richieste, ma può contenere puntatori nulli, che saranno ignorati. In caso si siano specificati valori non validi l'effetto è indefinito. Un valore \val{NULL} per \param{timout} comporta l'assenza di timeout. -Lo standard POSIX.1b infine ha previsto pure una funzione, \func{lio\_listio}, +Lo standard POSIX.1b infine ha previsto pure una funzione, \funcd{lio\_listio}, che permette di effettuare la richiesta di una intera lista di operazioni di lettura o scrittura; il suo prototipo è: \begin{prototype}{aio.h} @@ -753,7 +753,7 @@ specifica \const{LIO\_NOWAIT} la funzione ritorna immediatamente dopo aver messo in coda tutte le richieste. In questo caso il chiamante può richiedere la notifica del completamento di tutte le richieste, impostando l'argomento \param{sig} in maniera analoga a come si fa per il campo \var{aio\_sigevent} -di \type{aiocb}. +di \struct{aiocb}. @@ -769,10 +769,10 @@ chiamate, ci sono casi in cui si vuole poter contare sulla atomicit operazioni. Per questo motivo BSD 4.2\footnote{Le due funzioni sono riprese da BSD4.4 ed - integrate anche dallo standard Unix 98; fino alle libc5 Linux usava + integrate anche dallo standard Unix 98. Fino alle libc5, Linux usava \type{size\_t} come tipo dell'argomento \param{count}, una scelta logica, che però è stata dismessa per restare aderenti allo standard.} ha introdotto -due nuove system call, \func{readv} e \func{writev}, che permettono di +due nuove system call, \funcd{readv} e \funcd{writev}, che permettono di effettuare con una sola chiamata una lettura o una scrittura su una serie di buffer (quello che viene chiamato \textsl{I/O vettorizzato}. I relativi prototipi sono: @@ -806,7 +806,7 @@ prototipi sono: usuali funzioni di lettura e scrittura eseguite su \param{fd}.} \end{functions} -Entrambe le funzioni usano una struttura \type{iovec}, definita in +Entrambe le funzioni usano una struttura \struct{iovec}, definita in \figref{fig:file_iovec}, che definisce dove i dati devono essere letti o scritti. Il primo campo, \var{iov\_base}, contiene l'indirizzo del buffer ed il secondo, \var{iov\_len}, la dimensione dello stesso. @@ -822,17 +822,17 @@ struct iovec { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{iovec}, usata dalle operazioni di I/O + \caption{La struttura \struct{iovec}, usata dalle operazioni di I/O vettorizzato.} \label{fig:file_iovec} \end{figure} I buffer da utilizzare sono indicati attraverso l'argomento \param{vector} che -è un vettore di strutture \var{iovec}, la cui lunghezza è specificata da +è un vettore di strutture \struct{iovec}, la cui lunghezza è specificata da \param{count}. Ciascuna struttura dovrà essere inizializzata per opportunamente per indicare i vari buffer da/verso i quali verrà eseguito il trasferimento dei dati. Essi verranno letti (o scritti) nell'ordine in cui li -si sono specificati nel vettore \var{vector}. +si sono specificati nel vettore \param{vector}. \subsection{File mappati in memoria} @@ -881,7 +881,7 @@ il cui solo limite memoria su cui possono esserne lette delle porzioni. L'interfaccia prevede varie funzioni per la gestione del \textit{memory mapped - I/O}, la prima di queste è \func{mmap}, che serve ad eseguire la mappatura + I/O}, la prima di queste è \funcd{mmap}, che serve ad eseguire la mappatura in memoria di un file; il suo prototipo è: \begin{functions} @@ -1042,13 +1042,14 @@ accesso. regione di cui si è richiesta la mappatura. A prima vista infatti si potrebbe ritenere che anch'essi debbano generare un segnale di violazione di accesso; questo però non tiene conto del fatto che, essendo basata sul meccanismo della -paginazione, la mappatura in memoria non può che essere eseguita su un -segmento di dimensioni rigorosamente multiple di quelle di una pagina, ed in -generale queste potranno non corrispondere alle dimensioni effettive del file -o della sezione che si vuole mappare. Il caso più comune è quello illustrato -in \figref{fig:file_mmap_boundary}, in cui la sezione di file non rientra nei -confini di una pagina: in tal caso verrà il file sarà mappato su un segmento -di memoria che si estende fino al bordo della pagina successiva. +paginazione\index{paginazione}, la mappatura in memoria non può che essere +eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una +pagina, ed in generale queste potranno non corrispondere alle dimensioni +effettive del file o della sezione che si vuole mappare. Il caso più comune è +quello illustrato in \figref{fig:file_mmap_boundary}, in cui la sezione di +file non rientra nei confini di una pagina: in tal caso verrà il file sarà +mappato su un segmento di memoria che si estende fino al bordo della pagina +successiva. \begin{figure}[htb] \centering @@ -1091,7 +1092,7 @@ biunivoca fra una sezione di un file ed una sezione di memoria. Questo comporta che ad esempio non è possibile mappare in memoria file descriptor relativi a pipe, socket e fifo, per i quali non ha senso parlare di \textsl{sezione}. Lo stesso vale anche per alcuni file di dispositivo, che non -dispongono della relativa operazione \var{mmap} (si ricordi quanto esposto in +dispongono della relativa operazione \func{mmap} (si ricordi quanto esposto in \secref{sec:file_vfs_work}). Si tenga presente però che esistono anche casi di dispositivi (un esempio è l'interfaccia al ponte PCI-VME del chip Universe) che sono utilizzabili solo con questa interfaccia. @@ -1134,7 +1135,7 @@ Per quanto appena visto, attraverso l'interfaccia standard, quando lo si è mappato in memoria, è invece possibile usare l'interfaccia standard per leggere un file mappato in memoria, purché si abbia una certa cura; infatti l'interfaccia dell'I/O mappato in -memoria mette a disposizione la funzione \func{msync} per sincronizzare il +memoria mette a disposizione la funzione \funcd{msync} per sincronizzare il contenuto della memoria mappata con il file su disco; il suo prototipo è: \begin{functions} \headdecl{unistd.h} @@ -1191,7 +1192,7 @@ le mappature dello stesso file, cos aggiornate ai nuovi valori. Una volta che si sono completate le operazioni di I/O si può eliminare la -mappatura della memoria usando la funzione \func{munmap}, il suo prototipo è: +mappatura della memoria usando la funzione \funcd{munmap}, il suo prototipo è: \begin{functions} \headdecl{unistd.h} \headdecl{sys/mman.h} @@ -1335,7 +1336,7 @@ lettura per un read lock e di scrittura per un write lock). La prima interfaccia per il file locking, quella derivata da BSD, permette di eseguire un blocco solo su un intero file; la funzione usata per richiedere e -rimuovere un \textit{file lock} è \func{flock}, ed il suo prototipo è: +rimuovere un \textit{file lock} è \funcd{flock}, ed il suo prototipo è: \begin{prototype}{sys/file.h}{int flock(int fd, int operation)} Applica o rimuove un \textit{file lock} sul file \param{fd}. @@ -1395,8 +1396,8 @@ perci mantenute a livello di inode\index{inode},\footnote{in particolare, come accennato in \figref{fig:file_flock_struct}, i \textit{file lock} sono mantenuti un una \textit{linked list}\index{linked list} di strutture - \var{file\_lock}. La lista è referenziata dall'indirizzo di partenza - mantenuto dal campo \var{i\_flock} della struttura \var{inode} (per le + \struct{file\_lock}. La lista è referenziata dall'indirizzo di partenza + mantenuto dal campo \var{i\_flock} della struttura \struct{inode} (per le definizioni esatte si faccia riferimento al file \file{fs.h} nei sorgenti del kernel). Un bit del campo \var{fl\_flags} di specifica se si tratta di un lock in semantica BSD (\const{FL\_FLOCK}) o POSIX (\const{FL\_POSIX}).} @@ -1413,15 +1414,15 @@ diversi che aprono lo stesso file. La richiesta di un file lock prevede una scansione della lista per determinare se l'acquisizione è possibile, ed in caso positivo l'aggiunta di un nuovo -elemento.\footnote{cioè una nuova struttura \var{file\_lock}.} Nel caso dei -lock creati con \func{flock} la semantica della funzione prevede che sia +elemento.\footnote{cioè una nuova struttura \struct{file\_lock}.} Nel caso +dei lock creati con \func{flock} la semantica della funzione prevede che sia \func{dup} che \func{fork} non creino ulteriori istanze di un file lock quanto piuttosto degli ulteriori riferimenti allo stesso. Questo viene realizzato dal kernel secondo lo schema di \figref{fig:file_flock_struct}, associando ad ogni nuovo \textit{file lock} un puntatore\footnote{il puntatore è mantenuto nel - campo \var{fl\_file} di \var{file\_lock}, e viene utilizzato solo per i lock - creati con la semantica BSD.} alla voce nella \textit{file table} da cui si -è richiesto il lock, che così ne identifica il titolare. + campo \var{fl\_file} di \struct{file\_lock}, e viene utilizzato solo per i + lock creati con la semantica BSD.} alla voce nella \textit{file table} da +cui si è richiesto il lock, che così ne identifica il titolare. Questa struttura prevede che, quando si richiede la rimozione di un file lock, il kernel acconsenta solo se la richiesta proviene da un file descriptor che @@ -1496,12 +1497,12 @@ Al contrario di quanto avviene con l'interfaccia basata su \func{flock} con \func{fcntl} è possibile bloccare anche delle singole sezioni di un file, fino al singolo byte. Inoltre la funzione permette di ottenere alcune informazioni relative agli eventuali lock preesistenti. Per poter fare tutto questo la -funzione utilizza come terzo argomento una apposita struttura \var{flock} (la -cui definizione è riportata in \figref{fig:struct_flock}) nella quale inserire -tutti i dati relativi ad un determinato lock. Si tenga presente poi che un -lock fa sempre riferimento ad una regione, per cui si potrà avere un conflitto -anche se c'è soltanto una sovrapposizione parziale con un'altra regione -bloccata. +funzione utilizza come terzo argomento una apposita struttura \struct{flock} +(la cui definizione è riportata in \figref{fig:struct_flock}) nella quale +inserire tutti i dati relativi ad un determinato lock. Si tenga presente poi +che un lock fa sempre riferimento ad una regione, per cui si potrà avere un +conflitto anche se c'è soltanto una sovrapposizione parziale con un'altra +regione bloccata. \begin{figure}[!bht] \footnotesize \centering @@ -1517,7 +1518,7 @@ struct flock { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{flock}, usata da \func{fcntl} per il file + \caption{La struttura \struct{flock}, usata da \func{fcntl} per il file locking.} \label{fig:struct_flock} \end{figure} @@ -1561,11 +1562,11 @@ il \acr{pid} del processo che detiene il lock. \const{F\_UNLCK} & Richiede l'eliminazione di un file lock.\\ \hline \end{tabular} - \caption{Valori possibili per il campo \var{l\_type} di \func{flock}.} + \caption{Valori possibili per il campo \var{l\_type} di \struct{flock}.} \label{tab:file_flock_type} \end{table} -Oltre a quanto richiesto tramite i campi di \var{flock}, l'operazione +Oltre a quanto richiesto tramite i campi di \struct{flock}, l'operazione effettivamente svolta dalla funzione è stabilita dal valore dall'argomento \param{cmd} che, come già riportato in \secref{sec:file_fcntl}, specifica l'azione da compiere; i valori relativi al file locking sono tre: @@ -1643,8 +1644,8 @@ esaminiamo pi strutture utilizzate è riportato in \figref{fig:file_posix_lock}; come si vede esso è molto simile all'analogo di \figref{fig:file_flock_struct}:\footnote{in questo caso nella figura si sono evidenziati solo i campi di - \var{file\_lock} significativi per la semantica POSIX, in particolare adesso - ciascuna struttura contiene, oltre al \acr{pid} del processo in + \struct{file\_lock} significativi per la semantica POSIX, in particolare + adesso ciascuna struttura contiene, oltre al \acr{pid} del processo in \var{fl\_pid}, la sezione di file che viene bloccata grazie ai campi \var{fl\_start} e \var{fl\_end}. La struttura è comunque la stessa, solo che in questo caso nel campo \var{fl\_flags} è impostato il bit @@ -1655,11 +1656,11 @@ il valore del \acr{pid} del processo. Quando si richiede un lock il kernel effettua una scansione di tutti i lock presenti sul file\footnote{scandisce cioè la linked list delle strutture - \var{file\_lock}, scartando automaticamente quelle per cui \var{fl\_flags} - non è \const{FL\_POSIX}, così che le due interfacce restano ben separate.} -per verificare se la regione richiesta non si sovrappone ad una già bloccata, -in caso affermativo decide in base al tipo di lock, in caso negativo il nuovo -lock viene comunque acquisito ed aggiunto alla lista. + \struct{file\_lock}, scartando automaticamente quelle per cui + \var{fl\_flags} non è \const{FL\_POSIX}, così che le due interfacce restano + ben separate.} per verificare se la regione richiesta non si sovrappone ad +una già bloccata, in caso affermativo decide in base al tipo di lock, in caso +negativo il nuovo lock viene comunque acquisito ed aggiunto alla lista. Nel caso di rimozione invece questa viene effettuata controllando che il \acr{pid} del processo richiedente corrisponda a quello contenuto nel lock. @@ -1967,7 +1968,7 @@ Abbiamo visto come l'interfaccia POSIX per il file locking sia molto pi potente e flessibile di quella di BSD, questo comporta anche una maggiore complessità per via delle varie opzioni da passare a \func{fcntl}. Per questo motivo è disponibile anche una interfaccia semplificata (ripresa da System V) -che utilizza la funzione \func{lockf}, il cui prototipo è: +che utilizza la funzione \funcd{lockf}, il cui prototipo è: \begin{prototype}{sys/file.h}{int lockf(int fd, int cmd, off\_t len)} Applica, controlla o rimuove un \textit{file lock} sul file \param{fd}. @@ -2007,7 +2008,7 @@ che specifica quale azione eseguire; i valori possibili sono riportati in con un OR aritmetico dei valori.\\ \hline \end{tabular} - \caption{Valori possibili per il campo \var{cmd} di \func{lockf}.} + \caption{Valori possibili per l'argomento \param{cmd} di \func{lockf}.} \label{tab:file_lockf_type} \end{table} diff --git a/filedir.tex b/filedir.tex index 3c564a6..2a634b9 100644 --- a/filedir.tex +++ b/filedir.tex @@ -27,52 +27,58 @@ dei file Come già accennato in \secref{sec:file_filesystem} in un sistema unix-like la gestione dei file ha delle caratteristiche specifiche che derivano -direttamente dall'architettura del sistema; in questa sezione esamineremo le -funzioni usate per manipolazione nel filesytem di file e directory, per la -creazione di link simbolici e diretti, per la gestione e la lettura delle -directory; il tutto mettendo in evidenza le conseguenze della struttura -standard della gestione dei file in un sistema unix-like, introdotta nel -capitolo precedente. +direttamente dall'architettura del sistema. + +In questa sezione esamineremo le funzioni usate per la manipolazione di file e +directory, per la creazione di link simbolici e diretti, per la gestione e la +lettura delle directory. + +In particolare ci soffermeremo sulle conseguenze che derivano +dall'architettura dei filesystem illustrata nel capitolo precedente per quanto +riguarda il comportamento delle varie funzioni. \subsection{Le funzioni \func{link} e \func{unlink}} \label{sec:file_link} Una caratteristica comune a diversi sistemi operativi è quella di poter creare -dei nomi fittizi (come gli alias del MacOS o i collegamenti di Windows) che -permettono di fare riferimento allo stesso file chiamandolo con nomi diversi -o accedendovi da directory diverse. +dei nomi fittizi (come gli alias del MacOS o i collegamenti di Windows o i +nomi logici del VMS) che permettono di fare riferimento allo stesso file +chiamandolo con nomi diversi o accedendovi da directory diverse. Questo è possibile anche in ambiente Unix, dove tali collegamenti sono -usualmente chiamati \textit{link}; ma data la struttura del sistema di -gestione dei file (ed in particolare quanto trattato in +usualmente chiamati \textit{link}; ma data l'architettura del sistema riguardo +la gestione dei file (ed in particolare quanto trattato in \secref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per fare questa operazione. Come spiegato in \secref{sec:file_filesystem} l'accesso al contenuto di un -file su disco avviene attraverso il suo inode\index{inode}, e il nome che si -trova in una directory è solo un'etichetta associata ad un puntatore a che fa -riferimento al suddetto inode. - -Questo significa che la realizzazione di un link è immediata in quanto uno -stesso file può avere tanti nomi diversi allo stesso tempo, dati da -altrettante diverse associazioni allo stesso inode\index{inode}; si noti poi -che nessuno di questi nomi viene ad assumere una particolare preferenza o -originalità rispetto agli altri. - -Per aggiungere un nome ad un inode\index{inode} 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: +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. + +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. + +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: \begin{prototype}{unistd.h} {int link(const char *oldpath, const char *newpath)} - Crea un nuovo collegamento diretto al file indicato da \var{oldpath} - dandogli nome \var{newpath}. + Crea un nuovo collegamento diretto al file indicato da \param{oldpath} + dandogli nome \param{newpath}. - \bodydesc{La funzione restituisce zero in caso di successo e -1 in - caso di errore. La variabile \var{errno} viene impostata - opportunamente, i principali codici di errore sono: + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore nel qual caso \var{errno} viene impostata ai valori: \begin{errlist} \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo stesso filesystem. @@ -90,9 +96,9 @@ seguenti: \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 \var{newpath} e -ad aumentare di uno il numero di riferimenti al file (riportato nel campo -\var{st\_nlink} della struttura \var{stat}, vedi \secref{sec:file_stat}) +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. @@ -106,7 +112,7 @@ La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo l'amministratore è in grado di creare un collegamento diretto ad un'altra directory: questo viene fatto perché con una tale operazione è possibile -creare dei circoli nel filesystem (vedi l'esempio mostrato in +creare dei \textit{loop} nel filesystem (vedi l'esempio mostrato in \secref{sec:file_symlink}, dove riprenderemo il discorso) che molti programmi non sono in grado di gestire e la cui rimozione diventerebbe estremamente complicata (in genere per questo tipo di errori occorre far girare il @@ -122,38 +128,45 @@ La rimozione di un file (o pi 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)} - 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. + + Cancella un file. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, nel qual caso il file non viene toccato. La variabile \var{errno} viene impostata secondo i seguenti codici di errore: \begin{errlist} - \item[\errcode{EISDIR}] \var{pathname} si riferisce ad una directory - (valore specifico ritornato da Linux che non consente l'uso di - \var{unlink} con le directory, e non conforme allo standard POSIX, che - prescrive invece l'uso di \errcode{EPERM} in caso l'operazione non sia - consentita o il processo non abbia privilegi sufficienti). - \item[\errcode{EROFS}] \var{pathname} è su un filesystem montato in sola + \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una directory. + \footnotemark + \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola lettura. - \item[\errcode{EISDIR}] \var{pathname} fa riferimento a una directory. + \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory. \end{errlist} ed inoltre: \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP}, \errval{EIO}.} \end{prototype} +\footnotetext{questo è un valore specifico ritornato da Linux che non consente + l'uso di \func{unlink} con le directory (vedi \secref{sec:file_remove}). Non + è conforme allo standard POSIX, che prescrive invece l'uso di + \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. + 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 -il diritto di esecuzione sulla directory che la contiene (torneremo in -dettaglio sui permessi e gli attributi in \secref{sec:file_access_control}), -se inoltre lo \textit{sticky} bit è impostato occorrerà anche essere -proprietari del file o proprietari della directory (o root, per cui nessuna -delle restrizioni è applicata). +scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e +il diritto di esecuzione sulla directory che la contiene (affronteremo in +dettaglio l'argomento dei permessi di file e directory in +\secref{sec:file_access_control}). Se inoltre lo \textit{sticky} bit (vedi +\secref{sec:file_sticky}) è impostato occorrerà anche essere proprietari del +file o proprietari della directory (o root, per cui nessuna delle restrizioni +è applicata). Una delle caratteristiche di queste funzioni è che la creazione/rimozione del nome dalla directory e l'incremento/decremento del numero di riferimenti @@ -162,11 +175,18 @@ nell'inode\index{inode} devono essere effettuati in maniera atomica (si veda operazioni. Per questo entrambe queste funzioni sono realizzate tramite una singola system call. -Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti +Si ricordi infine che un file non viene eliminato dal disco fintanto che tutti i riferimenti ad esso sono stati cancellati: solo quando il \textit{link - count} mantenuto nell'inode\index{inode} diventa zero lo spazio occupato -viene rimosso. A questo però si aggiunge un'altra condizione, e cioè che non -ci siano processi che abbiano detto file aperto. + count} mantenuto nell'inode\index{inode} diventa zero lo spazio occupato su +disco viene rimosso (si ricordi comunque che a questo si aggiunge sempre +un'ulteriore condizione,\footnote{come vedremo in + \secref{cha:file_unix_interface} il kernel mantiene anche una tabella dei + file aperti nei vari processi, che a sua volta contiene i riferimenti agli + inode ad essi relativi. Prima di procedere alla cancellazione dello spazio + occupato su disco dal contenuto di un file il kernel controlla anche questa + tabella, per verificare che anche in essa non ci sia più nessun riferimento + all'inode in questione.} e cioè che non ci siano processi che abbiano il +suddetto file aperto). Questa proprietà viene spesso usata per essere sicuri di non lasciare file temporanei su disco in caso di crash dei programmi; la tecnica è quella di @@ -184,49 +204,59 @@ 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}. 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 diretti). Per i file è identica a \func{unlink} e per le -directory è identica a \func{rmdir}: +funzione \func{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 +diretti). Per i file è identica a \func{unlink} e per le directory è identica +a \func{rmdir}; il suo prototipo è: \begin{prototype}{stdio.h}{int remove(const char *pathname)} - Cancella un nome dal filesystem. Usa \func{unlink} per i file e - \func{rmdir} per le directory. + Cancella un nome dal filesystem. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso il file non viene toccato. Per i codici di - errore vedi quanto riportato nelle descrizioni di \func{unlink} e - \func{rmdir}.} + errore, nel qual caso il file non viene toccato. + + I codici di errore riportati in \var{errno} sono quelli della chiamata + utilizzata, pertanto si può fare riferimento a quanto illustrato nelle + descrizioni di \func{unlink} e \func{rmdir}.} \end{prototype} +La funzione utilizza la funzione \func{unlink}\footnote{questo vale usando le + \acr{glibc}; nelle libc4 e nelle libc5 la funzione \func{remove} è un + semplice alias alla funzione \func{unlink} e quindi non può essere usata per + le directory.} per cancellare i file e la funzione \func{rmdir} per +cancellare le directory; si tenga presente che per alcune implementazioni del +protocollo NFS utilizzare questa funzione può comportare la scomparsa di file +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 - funzione è definita dallo standard ANSI C solo per i file, POSIX estende la - funzione anche alle directory.} il cui prototipo è: + 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 +è: \begin{prototype}{stdio.h} {int rename(const char *oldpath, const char *newpath)} - Rinomina \var{oldpath} in \var{newpath}, eseguendo se necessario lo - spostamento di un file fra directory diverse. Eventuali altri link diretti - allo stesso file non vengono influenzati. + Rinomina un file. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, nel qual caso il file non viene toccato. La variabile \var{errno} viene impostata secondo i seguenti codici di errore: \begin{errlist} - \item[\errcode{EISDIR}] \var{newpath} è una directory mentre \var{oldpath} - non è una directory. - \item[\errcode{EXDEV}] \var{oldpath} e \var{newpath} non sono sullo stesso - filesystem. - \item[\errcode{ENOTEMPTY}] \var{newpath} è una directory già esistente e non - vuota. - \item[\errcode{EBUSY}] o \var{oldpath} o \var{newpath} sono in uso da parte - di qualche processo (come directory di lavoro o come radice) o del sistema - (come mount point). - \item[\errcode{EINVAL}] \var{newpath} contiene un prefisso di \var{oldpath} o - più in generale si è cercato di creare una directory come sottodirectory - di se stessa. + \item[\errcode{EISDIR}] \param{newpath} è una directory mentre + \param{oldpath} non è una directory. + \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo + stesso filesystem. + \item[\errcode{ENOTEMPTY}] \param{newpath} è una directory già esistente e + non vuota. + \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da + parte di qualche processo (come directory di lavoro o come radice) o del + sistema (come mount point). + \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di + \param{oldpath} o più in generale si è cercato di creare una directory come + sottodirectory di se stessa. \item[\errcode{ENOTDIR}] Uno dei componenti dei pathname non è una directory - o \var{oldpath} è una directory e \var{newpath} esiste e non è una + o \param{oldpath} è una directory e \param{newpath} esiste e non è una directory. \end{errlist} ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK}, @@ -234,25 +264,29 @@ nello stesso filesystem) si usa invece la funzione \func{rename},\footnote{la \errval{ENOSPC}.} \end{prototype} +La funzione rinomina il file \param{oldpath} in \param{newpath}, eseguendo se +necessario lo spostamento di un file fra directory diverse. Eventuali altri +link diretti allo stesso file non vengono influenzati. + Il comportamento della funzione è diverso a seconda che si voglia rinominare -un file o una directory; se ci riferisce a un file allora \var{newpath}, se +un file o una directory; se ci riferisce a un file allora \param{newpath}, se esiste, non deve essere una directory (altrimenti si ha l'errore -\errcode{EISDIR}). Nel caso \var{newpath} indichi un file esistente questo +\errcode{EISDIR}). Nel caso \param{newpath} indichi un file esistente questo viene cancellato e rimpiazzato (atomicamente). -Se \var{oldpath} è una directory allora \var{newpath}, se esiste, deve essere -una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR} (se -non è una directory) o \errcode{ENOTEMPTY} (se non è vuota). Chiaramente -\var{newpath} non può contenere \var{oldpath} altrimenti si avrà un errore +Se \param{oldpath} è una directory allora \param{newpath}, se esiste, deve +essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR} +(se non è una directory) o \errcode{ENOTEMPTY} (se non è vuota). Chiaramente +\param{newpath} non può contenere \param{oldpath} altrimenti si avrà un errore \errcode{EINVAL}. -Se \var{oldpath} si riferisce a un link simbolico questo sarà rinominato; se -\var{newpath} è un link simbolico verrà cancellato come qualunque altro file. -Infine qualora \var{oldpath} e \var{newpath} siano due nomi dello stesso file -lo standard POSIX prevede che la funzione non dia errore, e non faccia nulla, -lasciando entrambi i nomi; Linux segue questo standard, anche se, come fatto -notare dal manuale delle \textit{glibc}, il comportamento più ragionevole -sarebbe quello di cancellare \var{oldpath}. +Se \param{oldpath} si riferisce a un link simbolico questo sarà rinominato; se +\param{newpath} è un link simbolico verrà cancellato come qualunque altro +file. Infine qualora \param{oldpath} e \param{newpath} siano due nomi dello +stesso file lo standard POSIX prevede che la funzione non dia errore, e non +faccia nulla, lasciando entrambi i nomi; Linux segue questo standard, anche +se, come fatto notare dal manuale delle \textit{glibc}, il comportamento più +ragionevole sarebbe quello di cancellare \param{oldpath}. Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di \func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non @@ -261,10 +295,10 @@ entrambi i nomi dello stesso file, o, in caso di sostituzione di un file esistente, non trovare quest'ultimo prima che la sostituzione sia stata eseguita. -In ogni caso se \var{newpath} esiste e l'operazione fallisce per un qualche +In ogni caso se \param{newpath} esiste e l'operazione fallisce per un qualche motivo (come un crash del kernel), \func{rename} garantisce di lasciare -presente un'istanza di \var{newpath}. Tuttavia nella sovrascrittura potrà -esistere una finestra in cui sia \var{oldpath} che \var{newpath} fanno +presente un'istanza di \param{newpath}. Tuttavia nella sovrascrittura potrà +esistere una finestra in cui sia \param{oldpath} che \param{newpath} fanno riferimento allo stesso file. @@ -372,11 +406,11 @@ 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)} - Legge il contenuto del link simbolico indicato da \var{path} nel buffer - \var{buff} di dimensione \var{size}. + Legge il contenuto del link simbolico indicato da \param{path} nel buffer + \param{buff} di dimensione \param{size}. \bodydesc{La funzione restituisce il numero di caratteri letti dentro - \var{buff} o -1 per un errore, nel qual caso la variabile + \param{buff} o -1 per un errore, nel qual caso la variabile \var{errno} assumerà i valori: \begin{errlist} \item[\errcode{EINVAL}] \param{path} non è un link simbolico o \param{size} @@ -390,7 +424,7 @@ la funzione \func{readlink}, il cui prototipo La funzione apre il link simbolico, ne legge il contenuto, lo scrive nel buffer, e lo richiude. Si tenga presente che la funzione non termina la stringa con un carattere nullo e la tronca alla dimensione specificata da -\var{size} per evitare di sovrascrivere oltre le dimensioni del buffer. +\param{size} per evitare di sovrascrivere oltre le dimensioni del buffer. \begin{figure}[htb] @@ -450,10 +484,7 @@ 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 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. + {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: @@ -477,32 +508,35 @@ accedere ai tipi usati da queste funzioni si deve includere il file \errval{EROFS}.} \end{prototype} -La funzione crea una nuova directory vuota (che contiene solo le due voci -standard \file{.} e \file{..}). I permessi di accesso (vedi la trattazione in -\secref{sec:file_access_control}) specificati da \var{mode} (i cui possibili -valori sono riportati in \tabref{tab:file_permission_const}) sono modificati -dalla maschera di creazione dei file (si veda \secref{sec:file_umask}). La -titolarità della nuova directory è impostata secondo quanto riportato in +La funzione crea una nuova directory vuota, che contiene cioè solo le due voci +standard \file{.} e \file{..}, con il nome indicato dall'argomento +\param{dirname}. Il nome può essere indicato sia come pathname assoluto che +relativo. + +I permessi di accesso alla directory (vedi \secref{sec:file_access_control}) +sono specificati da \param{mode}, i cui possibili valori sono riportati in +\tabref{tab:file_permission_const}; questi sono modificati dalla maschera di +creazione dei file (si veda \secref{sec:file_umask}). La titolarità della +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 è: \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. - + Cancella una directory. + \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[\errcode{EPERM}] Il filesystem non supporta la cancellazione di - directory, oppure la directory che contiene \var{dirname} ha lo sticky bit - impostato e l'userid effettivo del processo non corrisponde al + directory, oppure la directory che contiene \param{dirname} ha lo sticky + bit impostato e l'userid effettivo del processo non corrisponde al proprietario della directory. \item[\errcode{EACCES}] 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}. + \param{dirname}. \item[\errcode{EBUSY}] La directory specificata è la directory di lavoro o la radice di qualche processo. \item[\errcode{ENOTEMPTY}] La directory non è vuota. @@ -511,6 +545,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 modalità con cui avviene la cancellazione è analoga a quella di \func{unlink}: fintanto che il numero di link all'inode\index{inode} della directory non diventa nullo e nessun processo ha la directory aperta lo spazio @@ -533,14 +570,15 @@ vedremo in \capref{cha:socket_intro}). La manipolazione delle caratteristiche di questi file e la loro cancellazione può essere effettuata con le stesse funzioni che operano sui file regolari; ma quando li si devono creare sono necessarie delle funzioni apposite. La prima -di queste funzioni è \func{mknod}, il suo prototipo è: +di queste funzioni è \funcd{mknod}, il suo prototipo è: \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)} Crea un - inode, si usa per creare i file speciali. + \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} + + Crea un inode, si usa per creare i file speciali. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, nel qual caso \var{errno} assumerà i valori: @@ -548,8 +586,8 @@ di queste funzioni \item[\errcode{EPERM}] Non si hanno privilegi sufficienti a creare l'inode, o il filesystem su cui si è cercato di creare \func{pathname} non supporta l'operazione. - \item[\errcode{EINVAL}] Il valore di \var{mode} non indica un file, una fifo - o un dipositivo. + \item[\errcode{EINVAL}] Il valore di \param{mode} non indica un file, una + fifo o un dipositivo. \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico. \end{errlist} ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG}, @@ -585,11 +623,13 @@ creare l'inode\index{inode}. Per creare una fifo (un file speciale, su cui torneremo in dettaglio in \secref{sec:ipc_named_pipe}) lo standard POSIX specifica l'uso della funzione -\func{mkfifo}, il cui prototipo è: +\funcd{mkfifo}, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} - \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} Crea una fifo. + \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} + + Crea una fifo. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES}, @@ -606,21 +646,86 @@ Per creare una fifo (un file speciale, su cui torneremo in dettaglio in \label{sec:file_dir_read} 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 può scrivere direttamente -in una directory (onde evitare inconsistenze all'interno del filesystem), i +senso aprirle come fossero dei file di dati. Inoltre si + + 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 può scrivere direttamente il contenuto +di 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 di -\capref{cha:files_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 un'opportuna -struttura \var{struct dirent}. +\capref{cha:files_std_interface}); la funzione \funcd{opendir} apre uno di +questi stream, il suo prototipo è: +\begin{functions} + \headdecl{sys/types.h} \headdecl{dirent.h} + + \funcdecl{DIR * opendir(const char *name)} + + Apre un \textit{directory stream}. + + \bodydesc{La funzione restituisce un puntatore al \textit{directory stream} + in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno} + assumerà i valori \errval{EACCES}, \errval{EMFILE}, \errval{ENFILE}, + \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR}.} +\end{functions} + +La funzione apre un \textit{directory stream} per la directory indicata da +\param{name}, ritornando il puntatore allo stesso, e posizionandosi sulla +prima voce della directory. + +Dato che le directory sono comunque dei file, in alcuni casi può essere utile +conoscere il file descriptor sottostante un \textit{directory stream}, ad +esempio per utilizzarlo con la funzione \func{fchdir} per cambiare la +directory di lavoro (vedi \secref{sec:file_work_dir}) a quella relativa allo +stream che si è aperto. A questo scopo si può usare la funzione \funcd{dirfd}, +il cui prototipo è: +\begin{functions} + \headdecl{sys/types.h} \headdecl{dirent.h} + + \funcdecl{int dirfd(DIR * dir)} + + Restituisce il file descriptor associato ad un \textit{directory stream}. + + \bodydesc{La funzione restituisce il file descriptor (un valore positivo) in + caso di successo e -1 in caso di errore.} +\end{functions} + +La funzione\footnote{questa funzione è una estensione di BSD introdotta con + BSD 4.3-Reno; è presente in Linux con le libc5 (a partire dalla versione + 5.1.2) e con le \acr{glibc}.} restituisce il file descriptor associato al +\textit{directory stream} \param{dir}, essa è disponibile solo definendo +\macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}. + + + +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 un'opportuna struttura \struct{dirent} +definita in \figref{fig:file_dirent_struct}. + + +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} +struct dirent { + ino_t d_ino; + unsigned short int d_reclen; + unsigned char d_type; + char d_name[256]; /* We must not include limits.h! */ +}; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \structd{dirent} per la lettura delle informazioni dei + file.} + \label{fig:file_dirent_struct} +\end{figure} + -(NdA Il resto va scritto!!! É noioso e lo farò più avanti). \subsection{La directory di lavoro} @@ -644,16 +749,16 @@ 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)} 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}. + stringa puntata da \param{buffer}, che deve essere precedentemente allocata, + per una dimensione massima di \param{size}. - \bodydesc{La funzione restituisce il puntatore \var{buffer} se riesce, + \bodydesc{La funzione restituisce il puntatore \param{buffer} se riesce, \val{NULL} se fallisce, in quest'ultimo caso la variabile \var{errno} è impostata con i seguenti codici di errore: \begin{errlist} - \item[\errcode{EINVAL}] L'argomento \var{size} è zero e \var{buffer} non + \item[\errcode{EINVAL}] L'argomento \param{size} è zero e \param{buffer} non è nullo. - \item[\errcode{ERANGE}] L'argomento \var{size} è più piccolo della + \item[\errcode{ERANGE}] L'argomento \param{size} è più piccolo della lunghezza del pathname. \item[\errcode{EACCES}] Manca il permesso di lettura o di ricerca su uno dei componenti del pathname (cioè su una delle directory superiori alla @@ -663,10 +768,10 @@ apposita funzione di libreria, \func{getcwd}, il cui prototipo Il buffer deve essere sufficientemente lungo da poter contenere il pathname completo più lo zero di terminazione della stringa. Qualora esso ecceda le -dimensioni specificate con \var{size} la funzione restituisce un errore. Si -può anche specificare un puntatore nullo come \var{buffer},\footnote{questa è +dimensioni specificate con \param{size} la funzione restituisce un errore. Si +può anche specificare un puntatore nullo come \param{buffer},\footnote{questa è un'estensione allo standard POSIX.1, supportata da Linux.} nel qual caso la -stringa sarà allocata automaticamente per una dimensione pari a \var{size} +stringa sarà allocata automaticamente per una dimensione pari a \param{size} 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. @@ -909,25 +1014,26 @@ gestione del controllo di accesso, trattate in in \label{sec:file_stat} La lettura delle informazioni relative ai file è fatta attraverso la famiglia -delle funzioni \func{stat}; questa è la funzione che ad esempio usa il comando -\cmd{ls} per poter ottenere e mostrare tutti i dati dei files. I prototipi di -queste funzioni sono i seguenti: +delle funzioni \func{stat} (\funcd{stat}, \funcd{fstat} e \funcd{lstat}); +questa è la funzione che ad esempio usa il comando \cmd{ls} per poter ottenere +e mostrare tutti i dati dei files. I prototipi di queste funzioni sono i +seguenti: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} \headdecl{unistd.h} \funcdecl{int stat(const char *file\_name, struct stat *buf)} Legge le - informazione del file specificato da \var{file\_name} e le inserisce in - \var{buf}. + informazione del file specificato da \param{file\_name} e le inserisce in + \param{buf}. \funcdecl{int lstat(const char *file\_name, struct stat *buf)} Identica a - \func{stat} eccetto che se il \var{file\_name} è un link simbolico vengono + \func{stat} eccetto che se il \param{file\_name} è un link simbolico vengono lette le informazioni relativa ad esso e non al file a cui fa riferimento. \funcdecl{int fstat(int filedes, struct stat *buf)} Identica a \func{stat} eccetto che si usa con un file aperto, specificato tramite il suo file - descriptor \var{filedes}. + descriptor \param{filedes}. \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un errore, nel qual caso \var{errno} assumerà uno dei valori: \errval{EBADF}, @@ -937,7 +1043,7 @@ queste funzioni sono i seguenti: \noindent il loro comportamento è identico, solo che operano rispettivamente su un file, su un link simbolico e su un file descriptor. -La struttura \var{stat} usata da queste funzioni è definita nell'header +La struttura \struct{stat} usata da queste funzioni è definita nell'header \file{sys/stat.h} e in generale dipende dall'implementazione; la versione usata da Linux è mostrata in \figref{fig:file_stat_struct}, così come riportata dalla pagina di manuale di \func{stat} (in realtà la definizione @@ -967,8 +1073,8 @@ struct stat { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{stat} per la lettura delle informazioni dei - file} + \caption{La struttura \structd{stat} per la lettura delle informazioni dei + file.} \label{fig:file_stat_struct} \end{figure} @@ -1079,7 +1185,7 @@ poi si effettua il confronto con la combinazione di tipi scelta. \subsection{Le dimensioni dei file} \label{sec:file_file_size} -Il membro \var{st\_size} contiene la dimensione del file in byte (se si tratta +Il campo \var{st\_size} contiene la dimensione del file in byte (se si tratta di un file regolare, nel caso di un link simbolico la dimensione è quella del pathname che contiene, per le fifo è sempre nullo). @@ -1110,23 +1216,23 @@ presenti al di l Un file può sempre essere troncato a zero aprendolo con il flag \const{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra -dimensione si possono usare le due funzioni \func{truncate} e -\func{ftruncate}, i cui prototipi sono: +dimensione si possono usare le due funzioni \funcd{truncate} e +\funcd{ftruncate}, i cui prototipi sono: \begin{functions} \headdecl{unistd.h} \funcdecl{int truncate(const char *file\_name, off\_t - length)} Fa si che la dimensione del file \var{file\_name} sia troncata ad - un valore massimo specificato da \var{lenght}. + length)} Fa si che la dimensione del file \param{file\_name} sia troncata + ad un valore massimo specificato da \param{lenght}. \funcdecl{int ftruncate(int fd, off\_t length))} Identica a \func{truncate} eccetto che si usa con un file aperto, specificato tramite il suo file - descriptor \var{fd}. + descriptor \param{fd}. \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un errore, nel qual caso \var{errno} viene impostata opportunamente; per \func{ftruncate} si hanno i valori: \begin{errlist} - \item[\errcode{EBADF}] \var{fd} non è un file descriptor. - \item[\errcode{EINVAL}] \var{fd} è un riferimento ad un + \item[\errcode{EBADF}] \param{fd} non è un file descriptor. + \item[\errcode{EINVAL}] \param{fd} è un riferimento ad un socket\index{socket}, non a un file o non è aperto in scrittura. \end{errlist} per \func{truncate} si hanno: @@ -1152,8 +1258,8 @@ zeri (e in genere si ha la creazione di un \textit{hole} nel file). Il sistema mantiene per ciascun file tre tempi. Questi sono registrati nell'inode\index{inode} insieme agli altri attributi del file e possono essere letti tramite la funzione \func{stat}, che li restituisce attraverso tre campi -della struttura \var{stat} di \figref{fig:file_stat_struct}. Il significato di -detti tempi e dei relativi campi è riportato nello schema in +della struttura \struct{stat} di \figref{fig:file_stat_struct}. Il significato +di detti tempi e dei relativi campi è riportato nello schema in \tabref{tab:file_file_times}, dove è anche riportato un esempio delle funzioni che effettuano cambiamenti su di essi. @@ -1313,10 +1419,11 @@ di \param{times}. Se questa \item[\errcode{ENOENT}] \param{filename} non esiste. \end{errlist}} \end{prototype} - -La funzione prende come argomento \param{times} una struttura \var{utimebuf}, -la cui definizione è riportata in \figref{fig:struct_utimebuf}, con la quale -si possono specificare i nuovi valori che si vogliono impostare per tempi. + +La funzione prende come argomento \param{times} una struttura +\struct{utimebuf}, la cui definizione è riportata in +\figref{fig:struct_utimebuf}, con la quale si possono specificare i nuovi +valori che si vogliono impostare per tempi. \begin{figure}[!htb] \footnotesize \centering @@ -1329,8 +1436,8 @@ struct utimbuf { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{utimbuf}, usata da \func{utime} per modificare i - tempi dei file.} + \caption{La struttura \structd{utimbuf}, usata da \func{utime} per modificare + i tempi dei file.} \label{fig:struct_utimebuf} \end{figure} @@ -1371,12 +1478,12 @@ Ad ogni file Linux associa sempre l'utente che ne cosiddetto \textit{owner}) ed un gruppo di appartenenza, secondo il meccanismo degli identificatori di utente e gruppo (\acr{uid} e \acr{gid}). Questi valori sono accessibili da programma tramite la funzione \func{stat}, e sono -mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura \var{stat} -(si veda \secref{sec:file_stat}).\footnote{Questo è vero solo per filesystem - di tipo Unix, ad esempio non è vero per il filesystem vfat di Windows, che - non fornisce nessun supporto per l'accesso multiutente, e per il quale i - permessi vengono assegnati in maniera fissa con un opzione in fase di - montaggio.} +mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura +\struct{stat} (si veda \secref{sec:file_stat}).\footnote{Questo è vero solo + per filesystem di tipo Unix, ad esempio non è vero per il filesystem vfat di + Windows, che non fornisce nessun supporto per l'accesso multiutente, e per + il quale i permessi vengono assegnati in maniera fissa con un opzione in + fase di montaggio.} Il controllo di accesso ai file segue un modello abbastanza semplice che prevede tre permessi fondamentali strutturati su tre livelli di accesso. @@ -1418,13 +1525,13 @@ allocazione dei bit \centering \includegraphics[width=6cm]{img/fileperm} \caption{Lo schema dei bit utilizzati per specificare i permessi di un file - contenuti nel campo \var{st\_mode} di \var{fstat}.} + contenuti nel campo \var{st\_mode} di \struct{fstat}.} \label{fig:file_perm_bit} \end{figure} Anche i permessi, come tutte le altre informazioni pertinenti al file, sono memorizzati nell'inode\index{inode}; in particolare essi sono contenuti in -alcuni bit del campo \var{st\_mode} della struttura \func{stat} (si veda di +alcuni bit del campo \var{st\_mode} della struttura \struct{stat} (si veda di nuovo \figref{fig:file_stat_struct}). In genere ci si riferisce ai tre livelli dei privilegi usando le lettere @@ -1567,7 +1674,7 @@ tutti gli altri non vengono controllati. \label{sec:file_suid_sgid} Come si è accennato (in \secref{sec:file_perm_overview}) nei dodici bit del -campo \var{st\_mode} di \var{stat} che vengono usati per il controllo di +campo \var{st\_mode} di \struct{stat} che vengono usati per il controllo di accesso oltre ai bit dei permessi veri e propri, ci sono altri tre bit che vengono usati per indicare alcune proprietà speciali dei file. Due di questi sono i bit detti \acr{suid} (da \textit{set-user-ID bit}) e \acr{sgid} (da @@ -1744,7 +1851,7 @@ combinazione delle costanti numeriche riportate in \tabref{tab:file_access_mode_val} (attraverso un OR binario delle stesse). I primi tre valori implicano anche la verifica dell'esistenza del file, se si vuole verificare solo quest'ultima si può usare \const{F\_OK}, o anche -direttamente \func{stat}. Nel caso in cui \var{pathname} si riferisca ad un +direttamente \func{stat}. Nel caso in cui \param{pathname} si riferisca ad un link simbolico, questo viene seguito ed il controllo è fatto sul file a cui esso fa riferimento. @@ -1759,7 +1866,7 @@ contrario (o di errore) ritorna -1. \footnotesize \begin{tabular}{|c|l|} \hline - \textbf{\var{mode}} & \textbf{Significato} \\ + \textbf{\param{mode}} & \textbf{Significato} \\ \hline \hline \const{R\_OK} & verifica il permesso di lettura \\ @@ -1768,7 +1875,7 @@ contrario (o di errore) ritorna -1. \const{F\_OK} & verifica l'esistenza del file \\ \hline \end{tabular} - \caption{Valori possibile per il parametro \var{mode} della funzione + \caption{Valori possibile per l'argomento \param{mode} della funzione \func{access}.} \label{tab:file_access_mode_val} \end{table} @@ -1783,17 +1890,17 @@ permessi per accedere ad un certo file. \label{sec:file_chmod} Per cambiare i permessi di un file il sistema mette ad disposizione due -funzioni \func{chmod} e \func{fchmod}, che operano rispettivamente su un +funzioni \funcd{chmod} e \funcd{fchmod}, che operano rispettivamente su un filename e su un file descriptor, i loro prototipi sono: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} \funcdecl{int chmod(const char *path, mode\_t mode)} Cambia i permessi del - file indicato da \var{path} al valore indicato da \var{mode}. + file indicato da \param{path} al valore indicato da \param{mode}. \funcdecl{int fchmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa - il file descriptor \var{fd} per indicare il file. + il file descriptor \param{fd} per indicare il file. \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un errore, in caso di errore \var{errno} può assumere i valori: @@ -1817,7 +1924,7 @@ file. \footnotesize \begin{tabular}[c]{|c|c|l|} \hline - \textbf{\var{mode}} & \textbf{Valore} & \textbf{Significato} \\ + \textbf{\param{mode}} & \textbf{Valore} & \textbf{Significato} \\ \hline \hline \const{S\_ISUID} & 04000 & set user ID \\ @@ -1902,15 +2009,15 @@ funzione \func{umask}, il cui prototipo \begin{prototype}{stat.h} {mode\_t umask(mode\_t mask)} - Imposta la maschera dei permessi dei bit al valore specificato da \var{mask} - (di cui vengono presi solo i 9 bit meno significativi). +Imposta la maschera dei permessi dei bit al valore specificato da \param{mask} +(di cui vengono presi solo i 9 bit meno significativi). \bodydesc{La funzione ritorna il precedente valore della maschera. È una delle poche funzioni che non restituisce codici di errore.} \end{prototype} Questa maschera è una caratteristica di ogni processo\footnote{è infatti - contenuta nel campo \var{umask} di \var{fs\_struct}, vedi + contenuta nel campo \param{umask} di \struct{fs\_struct}, vedi \figref{fig:proc_task_struct}.} e viene utilizzata per impedire che alcuni permessi possano essere assegnati ai nuovi file in sede di creazione. I bit indicati nella maschera vengono infatti esclusi quando un nuovo file viene @@ -1937,7 +2044,8 @@ allora occorrer Come per i permessi, il sistema fornisce anche delle funzioni che permettano di cambiare utente e gruppo cui il file appartiene; le funzioni in questione -sono tre e i loro prototipi sono i seguenti: +sono tre: \funcd{chown}, \funcd{fchown} e \funcd{lchown}, ed i loro prototipi +sono: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} @@ -1947,7 +2055,7 @@ sono tre e i loro prototipi sono i seguenti: \funcdecl{int lchown(const char *path, uid\_t owner, gid\_t group)} Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori - specificati dalle variabili \var{owner} e \var{group}. + specificati dalle variabili \param{owner} e \param{group}. \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un errore, in caso di errore \var{errno} può assumere i valori: @@ -1976,7 +2084,7 @@ un link simbolico si deve usare la funzione \func{lchown}.\footnote{fino alla \func{chown} che seguisse i link simbolici.} La funzione \func{fchown} opera su un file aperto, essa è mutuata da BSD, ma non è nello standard POSIX. Un'altra estensione rispetto allo standard POSIX è che specificando -1 come -valore per \var{owner} e \var{group} i valori restano immutati. +valore per \param{owner} e \param{group} i valori restano immutati. Quando queste funzioni sono chiamate con successo da un processo senza i privilegi di root entrambi i bit \acr{suid} e \acr{sgid} vengono @@ -2097,7 +2205,7 @@ questa sezione. Come accennato in \secref{sec:proc_fork} ogni processo oltre ad una directory di lavoro corrente, ha anche una directory radice,\footnote{entrambe sono - contenute in due campi di \var{fs\_struct}, vedi + contenute in due campi di \struct{fs\_struct}, vedi \figref{fig:proc_task_struct}.} che è la directory che per il processo costituisce la radice dell'albero dei file e rispetto alla quale vengono risolti i pathname assoluti (si ricordi quanto detto in diff --git a/fileintro.tex b/fileintro.tex index e309ea9..342cd8d 100644 --- a/fileintro.tex +++ b/fileintro.tex @@ -409,7 +409,7 @@ 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 \code{register\_filesystem} passandole un'apposita struttura -(\var{file\_system\_type}) che contiene i dettagli per il riferimento +(\struct{file\_system\_type}) che contiene i dettagli per il riferimento all'implementazione del medesimo, che sarà aggiunta alla citata tabella. In questo modo quando viene effettuata la richiesta di montare un nuovo disco @@ -484,8 +484,8 @@ la \func{open} per aprire il file o la \func{stat} per leggere i dati dell'inode\index{inode} e passarli in user space. L'apertura di un file richiede comunque un'altra operazione, l'allocazione di -una struttura di tipo \var{file} in cui viene inserito un puntatore alla -\textit{dentry} e una struttura \var{f\_ops} che contiene i puntatori ai +una struttura di tipo \struct{file} in cui viene inserito un puntatore alla +\textit{dentry} e una struttura \struct{f\_ops} che contiene i puntatori ai metodi che implementano le operazioni disponibili sul file. In questo modo i processi in user space possono accedere alle operazioni attraverso detti metodi, che saranno diversi a seconda del tipo di file (o dispositivo) aperto @@ -528,8 +528,8 @@ operazioni previste dal kernel In questo modo per ciascun file diventano possibili una serie di operazioni (non è detto che tutte siano disponibili), che costituiscono l'interfaccia astratta del VFS. Qualora se ne voglia eseguire una, il kernel andrà ad -utilizzare l'opportuna routine dichiarata in \var{f\_ops} appropriata al tipo -di file in questione. +utilizzare l'opportuna routine dichiarata in \struct{f\_ops} appropriata al +tipo di file in questione. Pertanto è possibile scrivere allo stesso modo sulla porta seriale come su normale un file di dati; ovviamente certe operazioni (nel caso della seriale diff --git a/filestd.tex b/filestd.tex index 1dd23d9..aed8add 100644 --- a/filestd.tex +++ b/filestd.tex @@ -46,7 +46,7 @@ dimensioni del blocco di dati (il parametro \param{buf} di \func{read} e \func{write}) nell'efficienza nelle operazioni di I/O con i file descriptor, evidenziando come le prestazioni ottimali si ottengano a partire da dimensioni del buffer dei dati pari a quelle dei blocchi del filesystem (il valore dato -dal campo \var{st\_blksize} di \var{fstat}). +dal campo \var{st\_blksize} di \struct{stat}). Se il programmatore non si cura di effettuare le operazioni in blocchi di dimensioni adeguate, le prestazioni sono inferiori. La caratteristica @@ -236,7 +236,7 @@ Le funzioni che si possono usare per aprire uno stream sono solo tre: \val{NULL} in caso di errore, in tal caso \var{errno} assumerà il valore ricevuto dalla funzione sottostante di cui è fallita l'esecuzione. - Gli errori pertanto possono essere quelli di \code{malloc} per tutte + Gli errori pertanto possono essere quelli di \func{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}.} @@ -326,7 +326,7 @@ non viene duplicato e verr I nuovi file saranno creati secondo quanto visto in \secref{sec:file_ownership} ed avranno i permessi di accesso impostati al valore \code{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a -\var{0666}) modificato secondo il valore di \acr{umask} per il processo (si +\val{0666}) modificato secondo il valore di \acr{umask} per il processo (si veda \secref{sec:file_umask}). In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è diff --git a/fileunix.tex b/fileunix.tex index 5508c50..b4e7b57 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -57,11 +57,11 @@ ed un elenco dei file aperti nella \textit{file table}. La \textit{process table} è una tabella che contiene una voce per ciascun processo attivo nel sistema. In Linux ciascuna voce è costituita da una -struttura di tipo \var{task\_struct} nella quale sono raccolte tutte le +struttura di tipo \struct{task\_struct} nella quale sono raccolte tutte le informazioni relative al processo; fra queste informazioni c'è anche il -puntatore ad una ulteriore struttura di tipo \var{files\_struct}, in cui sono -contenute le informazioni relative ai file che il processo ha aperto, ed in -particolare: +puntatore ad una ulteriore struttura di tipo \struct{files\_struct}, in cui +sono contenute le informazioni relative ai file che il processo ha aperto, ed +in particolare: \begin{itemize*} \item i flag relativi ai file descriptor. \item il numero di file aperti. @@ -73,14 +73,14 @@ quest'ultima tabella. La \textit{file table} è una tabella che contiene una voce per ciascun file che è stato aperto nel sistema. In Linux è costituita da strutture di tipo -\var{file}; in ciascuna di esse sono tenute varie informazioni relative al +\struct{file}; in ciascuna di esse sono tenute varie informazioni relative al file, fra cui: \begin{itemize*} \item lo stato del file (nel campo \var{f\_flags}). \item il valore della posizione corrente (l'\textit{offset}) nel file (nel campo \var{f\_pos}). \item un puntatore all'inode\index{inode}\footnote{nel kernel 2.4.x si è in - realtà passati ad un puntatore ad una struttura \var{dentry} che punta a + realtà passati ad un puntatore ad una struttura \struct{dentry} che punta a sua volta all'inode\index{inode} passando per la nuova struttura del VFS.} del file. %\item un puntatore alla tabella delle funzioni \footnote{la struttura @@ -162,9 +162,10 @@ stesso inode\index{inode}). Nelle vecchie versioni di Unix (ed anche in Linux fino al kernel 2.0.x) il numero di file aperti era anche soggetto ad un limite massimo dato dalle dimensioni del vettore di puntatori con cui era realizzata la tabella dei file -descriptor dentro \var{file\_struct}; questo limite intrinseco nei kernel più -recenti non sussiste più, dato che si è passati da un vettore ad una lista, ma -restano i limiti imposti dall'amministratore (vedi \secref{sec:sys_limits}). +descriptor dentro \struct{file\_struct}; questo limite intrinseco nei kernel +più recenti non sussiste più, dato che si è passati da un vettore ad una +lista, ma restano i limiti imposti dall'amministratore (vedi +\secref{sec:sys_limits}). @@ -194,30 +195,30 @@ prototipo \headdecl{fcntl.h} \funcdecl{int open(const char *pathname, int flags)} \funcdecl{int open(const char *pathname, int flags, mode\_t mode)} - Apre il file indicato da \var{pathname} nella modalità indicata da - \var{flags}, e, nel caso il file sia creato, con gli eventuali permessi - specificati da \var{mode}. + Apre il file indicato da \param{pathname} nella modalità indicata da + \param{flags}, e, nel caso il file sia creato, con gli eventuali permessi + specificati da \param{mode}. \bodydesc{La funzione ritorna il file descriptor in caso di successo e -1 in caso di errore. In questo caso la variabile \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EEXIST}] \var{pathname} esiste e si è specificato + \item[\errcode{EEXIST}] \param{pathname} esiste e si è specificato \const{O\_CREAT} e \const{O\_EXCL}. - \item[\errcode{EISDIR}] \var{pathname} indica una directory e si è tentato + \item[\errcode{EISDIR}] \param{pathname} indica una directory e si è tentato l'accesso in scrittura. \item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e - \var{pathname} non è una directory. + \param{pathname} non è una directory. \item[\errcode{ENXIO}] si sono impostati \const{O\_NOBLOCK} o \const{O\_WRONLY} ed il file è una fifo che non viene letta da nessun - processo o \var{pathname} è un file di dispositivo ma il dispositivo è + processo o \param{pathname} è un file di dispositivo ma il dispositivo è assente. - \item[\errcode{ENODEV}] \var{pathname} si riferisce a un file di dispositivo - che non esiste. + \item[\errcode{ENODEV}] \param{pathname} si riferisce a un file di + dispositivo che non esiste. \item[\errcode{ETXTBSY}] si è cercato di accedere in scrittura all'immagine di un programma in esecuzione. \item[\errcode{ELOOP}] si sono incontrati troppi link simbolici nel risolvere - pathname o si è indicato \const{O\_NOFOLLOW} e \var{pathname} è un link + pathname o si è indicato \const{O\_NOFOLLOW} e \param{pathname} è un link simbolico. \end{errlist} ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOENT}, @@ -226,8 +227,8 @@ prototipo \end{functions} La funzione apre il file, usando il primo file descriptor libero, e crea -l'opportuna voce (cioè la struttura \var{file}) nella file table. Viene usato -sempre il file descriptor con il valore più basso. +l'opportuna voce (cioè la struttura \struct{file}) nella file table. Viene +usato sempre il file descriptor con il valore più basso. \begin{table}[!htb] \centering @@ -243,8 +244,8 @@ sempre il file descriptor con il valore pi \hline % modalità di apertura del file \hline \const{O\_CREAT} & se il file non esiste verrà creato, con le regole di - titolarità del file viste in \secref{sec:file_ownership}. Il parametro - \var{mode} deve essere specificato. \\ + titolarità del file viste in \secref{sec:file_ownership}. L'argomento + \param{mode} deve essere specificato. \\ \const{O\_EXCL} & usato in congiunzione con \const{O\_CREAT} fa sì che l'esistenza del file diventi un errore\protect\footnotemark\ che fa fallire \func{open} con \errcode{EEXIST}. \\ @@ -252,7 +253,7 @@ sempre il file descriptor con il valore pi valore specifica anche una modalità di operazione (vedi sotto), e comporta che \func{open} ritorni immediatamente (l'opzione ha senso solo per le fifo, torneremo questo in \secref{sec:ipc_named_pipe}). \\ - \const{O\_NOCTTY} & se \var{pathname} si riferisce ad un device di + \const{O\_NOCTTY} & se \param{pathname} si riferisce ad un device di terminale, questo non diventerà il terminale di controllo, anche se il processo non ne ha ancora uno (si veda \secref{sec:sess_ctrl_term}). \\ \const{O\_SHLOCK} & opzione di BSD, acquisisce uno shared lock (vedi @@ -263,11 +264,11 @@ sempre il file descriptor con il valore pi apertura consente la scrittura, allora la sua lunghezza verrà troncata a zero. Se il file è un terminale o una fifo il flag verrà ignorato, negli altri casi il comportamento non è specificato. \\ - \const{O\_NOFOLLOW} & se \var{pathname} è un link simbolico la chiamata + \const{O\_NOFOLLOW} & se \param{pathname} è un link simbolico la chiamata fallisce. Questa è un'estensione BSD aggiunta in Linux dal kernel 2.1.126. Nelle versioni precedenti i link simbolici sono sempre seguiti, e questa opzione è ignorata. \\ - \const{O\_DIRECTORY} & se \var{pathname} non è una directory la chiamata + \const{O\_DIRECTORY} & se \param{pathname} non è una directory la chiamata fallisce. Questo flag è specifico di Linux ed è stato introdotto con il kernel 2.1.126 per evitare dei \textit{DoS}\index{DoS}\protect\footnotemark\ quando @@ -352,7 +353,7 @@ processo. La funzione prevede diverse opzioni, che vengono specificate usando vari bit dell'argomento \param{flags}. Alcuni di questi bit vanno anche a costituire il flag di stato del file (o \textit{file status flag}), che è mantenuto nel -campo \var{f\_flags} della struttura \var{file} (al solito si veda lo schema +campo \var{f\_flags} della struttura \struct{file} (al solito si veda lo schema di \figref{fig:file_proc_file}). Essi sono divisi in tre categorie principali: \begin{itemize} @@ -389,7 +390,7 @@ questo motivo per creare un nuovo file c'era una system call apposita, \func{creat}, il cui 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 + Crea un nuovo file vuoto, con i permessi specificati da \param{mode}. È del 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 @@ -402,12 +403,12 @@ programmi. La funzione \func{close} permette di chiudere un file, in questo modo il file descriptor ritorna disponibile; il suo prototipo è: \begin{prototype}{unistd.h}{int close(int fd)} - Chiude il descrittore \var{fd}. + Chiude il descrittore \param{fd}. \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore, ed in questo caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EBADF}] \var{fd} non è un descrittore valido. + \item[\errcode{EBADF}] \param{fd} non è un descrittore valido. \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. \end{errlist} ed inoltre \errval{EIO}.} @@ -415,10 +416,10 @@ descriptor ritorna disponibile; il suo prototipo La chiusura di un file rilascia ogni blocco (il \textit{file locking}\index{file!locking} è trattato in \secref{sec:file_locking}) che il -processo poteva avere acquisito su di esso; se \var{fd} è l'ultimo riferimento -(di eventuali copie) ad un file aperto, tutte le risorse nella file table -vengono rilasciate. Infine se il file descriptor era l'ultimo riferimento ad -un file su disco quest'ultimo viene cancellato. +processo poteva avere acquisito su di esso; se \param{fd} è l'ultimo +riferimento (di eventuali copie) ad un file aperto, tutte le risorse nella +file table vengono rilasciate. Infine se il file descriptor era l'ultimo +riferimento ad un file su disco quest'ultimo viene cancellato. Si ricordi che quando un processo termina anche tutti i suoi file descriptor vengono chiusi, molti programmi sfruttano questa caratteristica e non usano @@ -446,7 +447,7 @@ di ripetere tre volte il comando prima di eseguire lo shutdown). Come già accennato in \secref{sec:file_fd} a ciascun file aperto è associata una \textsl{posizione corrente nel file} (il cosiddetto \textit{file offset}, -mantenuto nel campo \var{f\_pos} di \var{file}) espressa da un numero intero +mantenuto nel campo \var{f\_pos} di \struct{file}) espressa da un numero intero positivo come numero di byte dall'inizio del file. Tutte le operazioni di lettura e scrittura avvengono a partire da questa posizione che viene automaticamente spostata in avanti del numero di byte letti o scritti. @@ -492,7 +493,7 @@ Come accennato in \secref{sec:file_file_size} con \func{lseek} impostare la posizione corrente anche oltre la fine del file, e alla successiva scrittura il file sarà esteso. La chiamata non causa nessuna attività di input/output, si limita a modificare la posizione corrente nel -kernel (cioè \var{f\_pos} in \var{file}, vedi \figref{fig:file_proc_file}). +kernel (cioè \var{f\_pos} in \param{file}, vedi \figref{fig:file_proc_file}). Dato che la funzione ritorna la nuova posizione, usando il valore zero per \param{offset} si può riottenere la posizione corrente nel file chiamando la @@ -525,7 +526,8 @@ leggere i dati che contiene utilizzando la funzione \func{read}, il cui prototipo è: \begin{prototype}{unistd.h}{ssize\_t read(int fd, void * buf, size\_t count)} - Cerca di leggere \var{count} byte dal file \var{fd} al buffer \var{buf}. + Cerca di leggere \param{count} byte dal file \param{fd} al buffer + \param{buf}. \bodydesc{La funzione ritorna il numero di byte letti in caso di successo e -1 in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: @@ -537,12 +539,12 @@ prototipo \end{errlist} ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF}, \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori dipendenti dalla - natura dell'oggetto connesso a \var{fd}.} + natura dell'oggetto connesso a \param{fd}.} \end{prototype} -La funzione tenta di leggere \var{count} byte a partire dalla posizione +La funzione tenta di leggere \param{count} byte a partire dalla posizione corrente nel file. Dopo la lettura la posizione sul file è spostata -automaticamente in avanti del numero di byte letti. Se \var{count} è zero la +automaticamente in avanti del numero di byte letti. Se \param{count} è zero la funzione restituisce zero senza nessun altro risultato. Si deve sempre tener presente che non è detto che la funzione \func{read} @@ -601,8 +603,8 @@ definizione di un'altra funzione di lettura, \func{pread}, il cui prototipo \begin{prototype}{unistd.h} {ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)} -Cerca di leggere \var{count} byte dal file \var{fd}, a partire dalla posizione -\var{offset}, nel buffer \var{buf}. +Cerca di leggere \param{count} byte dal file \param{fd}, a partire dalla +posizione \param{offset}, nel buffer \param{buf}. \bodydesc{La funzione ritorna il numero di byte letti in caso di successo e -1 in caso di errore, nel qual caso \var{errno} assumerà i valori già visti per @@ -619,7 +621,7 @@ modificare la posizione corrente. posizione corrente sul file, ma permette di eseguire l'operazione atomicamente. Questo può essere importante quando la posizione sul file viene condivisa da processi diversi (vedi \secref{sec:file_sharing}). Il valore di -\var{offset} fa sempre riferimento all'inizio del file. +\param{offset} fa sempre riferimento all'inizio del file. \subsection{La funzione \func{write}} @@ -629,17 +631,17 @@ Una volta che un file scrivere su di esso utilizzando la funzione \func{write}, il cui prototipo è: \begin{prototype}{unistd.h}{ssize\_t write(int fd, void * buf, size\_t count)} - Scrive \var{count} byte dal buffer \var{buf} sul file \var{fd}. + Scrive \param{count} byte dal buffer \param{buf} sul file \param{fd}. \bodydesc{La funzione ritorna il numero di byte scritti in caso di successo e -1 in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EINVAL}] \var{fd} è connesso ad un oggetto che non consente la - scrittura. + \item[\errcode{EINVAL}] \param{fd} è connesso ad un oggetto che non consente + la scrittura. \item[\errcode{EFBIG}] si è cercato di scrivere oltre la dimensione massima consentita dal filesystem o il limite per le dimensioni dei file del processo o su una posizione oltre il massimo consentito. - \item[\errcode{EPIPE}] \var{fd} è connesso ad una pipe il cui altro capo è + \item[\errcode{EPIPE}] \param{fd} è connesso ad una pipe il cui altro capo è chiuso in lettura; in questo caso viene anche generato il segnale \const{SIGPIPE}, se questo viene gestito (o bloccato o ignorato) la funzione ritorna questo errore. @@ -650,11 +652,11 @@ scrivere su di esso utilizzando la funzione \func{write}, il cui prototipo \end{errlist} ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF}, \errval{ENOSPC}, \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori - dipendenti dalla natura dell'oggetto connesso a \var{fd}.} + dipendenti dalla natura dell'oggetto connesso a \param{fd}.} \end{prototype} -Come nel caso di \func{read} la funzione tenta di scrivere \var{count} byte a -partire dalla posizione corrente nel file e sposta automaticamente la +Come nel caso di \func{read} la funzione tenta di scrivere \param{count} byte +a partire dalla posizione corrente nel file e sposta automaticamente la posizione in avanti del numero di byte scritti. Se il file è aperto in modalità \const{O\_APPEND} i dati vengono sempre scritti alla fine del file. Lo standard POSIX richiede che i dati scritti siano immediatamente disponibili @@ -662,10 +664,10 @@ ad una \func{read} chiamata dopo che la \func{write} che li ha scritti ritornata; ma dati i meccanismi di caching non è detto che tutti i filesystem supportino questa capacità. -Se \var{count} è zero la funzione restituisce zero senza fare nient'altro. Per -i file ordinari il numero di byte scritti è sempre uguale a quello indicato -da \var{count}, a meno di un errore. Negli altri casi si ha lo stesso -comportamento di \func{read}. +Se \param{count} è zero la funzione restituisce zero senza fare nient'altro. +Per i file ordinari il numero di byte scritti è sempre uguale a quello +indicato da \param{count}, a meno di un errore. Negli altri casi si ha lo +stesso comportamento di \func{read}. Anche per \func{write} lo standard Unix98 definisce un'analoga \func{pwrite} per scrivere alla posizione indicata senza modificare la posizione corrente @@ -673,8 +675,8 @@ nel file, il suo prototipo \begin{prototype}{unistd.h} {ssize\_t pwrite(int fd, void * buf, size\_t count, off\_t offset)} -Cerca di scrivere sul file \var{fd}, a partire dalla posizione \var{offset}, -\var{count} byte dal buffer \var{buf}. +Cerca di scrivere sul file \param{fd}, a partire dalla posizione +\param{offset}, \param{count} byte dal buffer \param{buf}. \bodydesc{La funzione ritorna il numero di byte letti in caso di successo e -1 in caso di errore, nel qual caso \var{errno} assumerà i valori già visti per @@ -714,9 +716,9 @@ Il primo caso su disco; sulla base di quanto visto in \secref{sec:file_fd} avremo una situazione come quella illustrata in \figref{fig:file_mult_acc}: ciascun processo avrà una sua voce nella \textit{file table} referenziata da un -diverso file descriptor nella sua \var{file\_struct}. Entrambe le voci nella -\textit{file table} faranno però riferimento allo stesso inode\index{inode} su -disco. +diverso file descriptor nella sua \struct{file\_struct}. Entrambe le voci +nella \textit{file table} faranno però riferimento allo stesso +inode\index{inode} su disco. Questo significa che ciascun processo avrà la sua posizione corrente sul file, la sua modalità di accesso e versioni proprie di tutte le proprietà che @@ -734,9 +736,9 @@ stesso file, in particolare occorre tenere presente che: dimensione corrente del file letta dall'inode\index{inode}. Dopo la scrittura il file viene automaticamente esteso. \item l'effetto di \func{lseek} è solo quello di cambiare il campo - \var{f\_pos} nella struttura \var{file} della \textit{file table}, non c'è - nessuna operazione sul file su disco. Quando la si usa per porsi alla fine - del file la posizione viene impostata leggendo la dimensione corrente + \var{f\_pos} nella struttura \struct{file} della \textit{file table}, non + c'è nessuna operazione sul file su disco. Quando la si usa per porsi alla + fine del file la posizione viene impostata leggendo la dimensione corrente dall'inode\index{inode}. \end{itemize} @@ -753,7 +755,7 @@ caso dei file aperti che vengono ereditati dal processo figlio all'esecuzione di una \func{fork} (si ricordi quanto detto in \secref{sec:proc_fork}). La situazione è illustrata in \figref{fig:file_acc_child}; dato che il processo figlio riceve una copia dello spazio di indirizzi del padre, riceverà anche -una copia di \var{file\_struct} e relativa tabella dei file aperti. +una copia di \struct{file\_struct} e relativa tabella dei file aperti. In questo modo padre e figlio avranno gli stessi file descriptor che faranno riferimento alla stessa voce nella \textit{file table}, condividendo così la @@ -765,12 +767,12 @@ corrente nel file varier Si noti inoltre che anche i flag di stato del file (quelli impostati dall'argomento \param{flag} di \func{open}) essendo tenuti nella voce della \textit{file table}\footnote{per la precisione nel campo \var{f\_flags} di - \var{file}.}, vengono in questo caso condivisi. Ai file però sono associati -anche altri flag, dei quali l'unico usato al momento è \const{FD\_CLOEXEC}, -detti \textit{file descriptor flags}. Questi ultimi sono tenuti invece in -\var{file\_struct}, e perciò sono specifici di ciascun processo e non vengono -modificati dalle azioni degli altri anche in caso di condivisione della stessa -voce della \textit{file table}. + \struct{file}.}, vengono in questo caso condivisi. Ai file però sono +associati anche altri flag, dei quali l'unico usato al momento è +\const{FD\_CLOEXEC}, detti \textit{file descriptor flags}. Questi ultimi sono +tenuti invece in \struct{file\_struct}, e perciò sono specifici di ciascun +processo e non vengono modificati dalle azioni degli altri anche in caso di +condivisione della stessa voce della \textit{file table}. @@ -885,7 +887,7 @@ Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del file specificato, ed attendono fino alla conclusione delle operazioni; \func{fsync} forza anche la sincronizzazione dei metadati del file (che riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli -altri dati contenuti nell'inode\index{inode} che si leggono con \var{fstat} +altri dati contenuti nell'inode\index{inode} che si leggono con \func{fstat}, come i tempi del file). Si tenga presente che questo non comporta la sincronizzazione della @@ -921,10 +923,10 @@ La funzione ritorna, come \func{open}, il primo file descriptor libero. Il file descriptor è una copia esatta del precedente ed entrambi possono essere interscambiati nell'uso. Per capire meglio il funzionamento della funzione si può fare riferimento a \figref{fig:file_dup}: l'effetto della funzione è -semplicemente quello di copiare il valore nella struttura \var{file\_struct}, -cosicché anche il nuovo file descriptor fa riferimento alla stessa voce -nella \textit{file table}; per questo si dice che il nuovo file descriptor è -\textsl{duplicato}, da cui il nome della funzione. +semplicemente quello di copiare il valore nella struttura +\struct{file\_struct}, cosicché anche il nuovo file descriptor fa riferimento +alla stessa voce nella \textit{file table}; per questo si dice che il nuovo +file descriptor è \textsl{duplicato}, da cui il nome della funzione. \begin{figure}[htb] \centering \includegraphics[width=15cm]{img/filedup} @@ -1028,7 +1030,7 @@ un esempio per la duplicazione dei file descriptor, una lista dei possibili valori è riportata di seguito: \begin{basedescript}{\desclabelwidth{2.0cm}} \item[\const{F\_DUPFD}] trova il primo file descriptor disponibile di valore - maggiore o uguale ad \param{arg} e ne fa una copia di \var{fd}. In caso di + maggiore o uguale ad \param{arg} e ne fa una copia di \param{fd}. In caso di successo ritorna il nuovo file descriptor. Gli errori possibili sono \errcode{EINVAL} se \param{arg} è negativo o maggiore del massimo consentito o \errcode{EMFILE} se il processo ha già raggiunto il massimo numero di @@ -1039,7 +1041,7 @@ valori \const{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella esecuzione di una \func{exec} (vedi \secref{sec:proc_exec}). \item[\const{F\_GETFD}] ritorna il valore del \textit{file descriptor flag} di - \var{fd}, se \const{FD\_CLOEXEC} è impostato i file descriptor aperti + \param{fd}, se \const{FD\_CLOEXEC} è impostato i file descriptor aperti vengono chiusi attraverso una \func{exec} altrimenti (il comportamento predefinito) restano aperti. \item[\const{F\_GETFL}] ritorna il valore del \textit{file status flag}, @@ -1071,13 +1073,13 @@ valori nel controllo di sessione; a ciascuno di essi è associato un identificatore (un numero positivo analogo al \acr{pid}).} che è preposto alla ricezione dei segnali \const{SIGIO} e \const{SIGURG} per gli eventi - associati al file descriptor \var{fd}. Nel caso di un process group viene + associati al file descriptor \param{fd}. Nel caso di un process group viene restituito un valore negativo il cui valore assoluto corrisponde all'identificatore del process group. \item[\const{F\_SETOWN}] imposta, con il valore dell'argomento \param{arg}, l'identificatore del processo o del \textit{process group} che riceverà i segnali \const{SIGIO} e \const{SIGURG} per gli eventi associati al file - descriptor \var{fd}. Come per \const{F\_GETOWN}, per impostare un process + descriptor \param{fd}. Come per \const{F\_GETOWN}, per impostare un process group si deve usare per \param{arg} un valore negativo, il cui valore assoluto corrisponde all'identificatore del process group. \item[\const{F\_GETSIG}] restituisce il valore del segnale inviato quando ci @@ -1095,7 +1097,7 @@ valori \const{SA\_SIGINFO}, (vedi \secref{sec:sig_sigaction}), di rendere disponibili al manipolatore informazioni ulteriori informazioni riguardo il file che ha generato il segnale attraverso i valori restituiti in - \type{siginfo\_t} (come vedremo in + \struct{siginfo\_t} (come vedremo in \secref{sec:file_asyncronous_io}).\footnote{i due comandi \const{F\_SETSIG} e \const{F\_GETSIG} sono una estensione specifica di Linux.} \end{basedescript} diff --git a/ipc.tex b/ipc.tex index 4721013..e2052c8 100644 --- a/ipc.tex +++ b/ipc.tex @@ -869,7 +869,7 @@ sull'altro e viceversa. I parametri \param{domain}, \param{type} e \param{protocol} derivano dall'interfaccia dei socket\index{socket} (che è quella che fornisce il substrato per connettere i due descrittori), ma in questo caso i soli valori validi che possono essere specificati sono -rispettivamente \const{AF\_UNIX}, \const{SOCK\_STREAM} e \var{0}. +rispettivamente \const{AF\_UNIX}, \const{SOCK\_STREAM} e \val{0}. L'utilità di chiamare questa funzione per evitare due chiamate a \func{pipe} può sembrare limitata; in realtà l'utilizzo di questa funzione (e dei @@ -927,7 +927,7 @@ non si pone perciò il problema di come processi diversi possono accedere allo stesso oggetto. -Per risolvere il problema nella struttura \var{ipc\_perm} che il kernel +Per risolvere il problema nella struttura \struct{ipc\_perm} che il kernel associa a ciascun oggetto, viene mantenuto anche un campo apposito che contiene anche una \textsl{chiave}, identificata da una variabile del tipo primitivo \type{key\_t}, da specificare in fase di creazione dell'oggetto, e @@ -955,7 +955,8 @@ struct ipc_perm \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{ipc\_perm}, come definita in \file{sys/ipc.h}.} + \caption{La struttura \structd{ipc\_perm}, come definita in + \file{sys/ipc.h}.} \label{fig:ipc_ipc_perm} \end{figure} @@ -1017,7 +1018,7 @@ le chiavi che interessano. In ogni caso occorre sempre controllare, prima di creare un oggetto, che la chiave non sia già stata utilizzata. Se questo va bene in fase di creazione, le cose possono complicarsi per i programmi che devono solo accedere, in quanto, a parte gli eventuali controlli sugli altri -attributi di \var{ipc\_perm}, non esiste una modalità semplice per essere +attributi di \struct{ipc\_perm}, non esiste una modalità semplice per essere sicuri che l'oggetto associato ad una certa chiave sia stato effettivamente creato da chi ci si aspetta. @@ -1034,7 +1035,7 @@ effettuata una revisione completa nello standard POSIX.1b, che tratteremo in \label{sec:ipc_sysv_access_control} Oltre alle chiavi, abbiamo visto che ad ogni oggetto sono associate in -\var{ipc\_perm} ulteriori informazioni, come gli identificatori del creatore +\struct{ipc\_perm} ulteriori informazioni, come gli identificatori del creatore (nei campi \var{cuid} e \var{cgid}) e del proprietario (nei campi \var{uid} e \var{gid}) dello stesso, e un insieme di permessi (nel campo \var{mode}). In questo modo è possibile definire un controllo di accesso sugli oggetti di IPC, @@ -1056,7 +1057,7 @@ ed hanno lo stesso significato di quelli riportati in il proprietario, il suo gruppo e tutti gli altri. Quando l'oggetto viene creato i campi \var{cuid} e \var{uid} di -\var{ipc\_perm} ed i campi \var{cgid} e \var{gid} vengono settati +\struct{ipc\_perm} ed i campi \var{cgid} e \var{gid} vengono settati rispettivamente al valore dell'userid e del groupid effettivo del processo che ha chiamato la funzione, ma, mentre i campi \var{uid} e \var{gid} possono essere cambiati, i campi \var{cuid} e \var{cgid} restano sempre gli stessi. @@ -1098,7 +1099,7 @@ il valore di \var{umask} (si ricordi quanto esposto in \subsection{Gli identificatori ed il loro utilizzo} \label{sec:ipc_sysv_id_use} -L'unico campo di \var{ipc\_perm} del quale non abbiamo ancora parlato è +L'unico campo di \struct{ipc\_perm} del quale non abbiamo ancora parlato è \var{seq}, che in \figref{fig:ipc_ipc_perm} è qualificato con un criptico ``\textsl{numero di sequenza}'', ne parliamo adesso dato che esso è strettamente attinente alle modalità con cui il kernel assegna gli @@ -1121,7 +1122,7 @@ facciano in tempo ad accorgersi dell'avvenuto, e finiscano con l'interagire con gli oggetti del secondo, con conseguenze imprevedibili. Proprio per evitare questo tipo di situazioni il sistema usa il valore di -\var{req} per provvedere un meccanismo che porti gli identificatori ad +\var{seq} per provvedere un meccanismo che porti gli identificatori ad assumere tutti i valori possibili, rendendo molto più lungo il periodo in cui un identificatore può venire riutilizzato. @@ -1370,14 +1371,14 @@ struct msqid_ds { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{msgid\_ds}, associata a ciascuna coda di + \caption{La struttura \structd{msgid\_ds}, associata a ciascuna coda di messaggi.} \label{fig:ipc_msgid_ds} \end{figure} -A ciascuna coda è associata una struttura \var{msgid\_ds}, la cui definizione, -è riportata in \secref{fig:ipc_msgid_ds}. In questa struttura il kernel -mantiene le principali informazioni riguardo lo stato corrente della +A ciascuna coda è associata una struttura \struct{msgid\_ds}, la cui +definizione, è riportata in \secref{fig:ipc_msgid_ds}. In questa struttura il +kernel mantiene le principali informazioni riguardo lo stato corrente della coda.\footnote{come accennato questo vale fino ai kernel della serie 2.2.x, essa viene usata nei kernel della serie 2.4.x solo per compatibilità in quanto è quella restituita dalle funzioni dell'interfaccia. Si noti come ci @@ -1442,7 +1443,7 @@ prototipo } \end{functions} -La funzione permette di accedere ai valori della struttura \var{msqid\_ds}, +La funzione permette di accedere ai valori della struttura \struct{msqid\_ds}, mantenuta all'indirizzo \param{buf}, per la coda specificata dall'identificatore \param{msqid}. Il comportamento della funzione dipende dal valore dell'argomento \param{cmd}, che specifica il tipo di azione da @@ -1461,7 +1462,7 @@ eseguire; i valori possibili sono: \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario della coda, ed il limite massimo sulle dimensioni del totale dei messaggi in essa contenuti (\var{msg\_qbytes}). I valori devono essere passati in una - struttura \var{msqid\_ds} puntata da \param{buf}. Per modificare i valori + struttura \struct{msqid\_ds} puntata da \param{buf}. Per modificare i valori di \var{msg\_perm.mode}, \var{msg\_perm.uid} e \var{msg\_perm.gid} occorre essere il proprietario o il creatore della coda, oppure l'amministratore; lo stesso vale per \var{msg\_qbytes}, ma l'amministratore ha la facoltà di @@ -1502,7 +1503,7 @@ messaggio su una coda si utilizza la funzione \func{msgsnd}; il suo prototipo La funzione inserisce il messaggio sulla coda specificata da \param{msqid}; il messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso il l'argomento \param{msgp}. Quest'ultimo deve venire passato sempre come -puntatore ad una struttura \var{msgbuf} analoga a quella riportata in +puntatore ad una struttura \struct{msgbuf} analoga a quella riportata in \figref{fig:ipc_msbuf} che è quella che deve contenere effettivamente il messaggio. La dimensione massima per il testo di un messaggio non può comunque superare il limite \const{MSGMAX}. @@ -1541,17 +1542,17 @@ dovr \end{lstlisting} \end{minipage} \normalsize - \caption{Schema della struttura \var{msgbuf}, da utilizzare come argomento - per inviare/ricevere messaggi.} + \caption{Schema della struttura \structd{msgbuf}, da utilizzare come + argomento per inviare/ricevere messaggi.} \label{fig:ipc_msbuf} \end{figure} Per capire meglio il funzionamento della funzione riprendiamo in considerazione la struttura della coda illustrata in \figref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo messaggio -sarà aggiunto in fondo alla lista inserendo una nuova struttura \var{msg}, il -puntatore \var{msg\_last} di \var{msqid\_ds} verrà aggiornato, come pure il -puntatore al messaggio successivo per quello che era il precedente ultimo +sarà aggiunto in fondo alla lista inserendo una nuova struttura \struct{msg}, +il puntatore \var{msg\_last} di \struct{msqid\_ds} verrà aggiornato, come pure +il puntatore al messaggio successivo per quello che era il precedente ultimo messaggio; il valore di \var{mtype} verrà mantenuto in \var{msg\_type} ed il valore di \param{msgsz} in \var{msg\_ts}; il testo del messaggio sarà copiato all'indirizzo specificato da \var{msg\_spot}. @@ -1573,8 +1574,8 @@ una condizione di errore anche in due altri casi: quando la coda viene rimossa interrotta da un segnale (nel qual caso si ha un errore di \errcode{EINTR}). Una volta completato con successo l'invio del messaggio sulla coda, la -funzione aggiorna i dati mantenuti in \var{msqid\_ds}, in particolare vengono -modificati: +funzione aggiorna i dati mantenuti in \struct{msqid\_ds}, in particolare +vengono modificati: \begin{itemize*} \item Il valore di \var{msg\_lspid}, che viene impostato al \acr{pid} del processo chiamante. @@ -1659,8 +1660,8 @@ desiderato, oppure ritorna con errore qualora la coda sia rimossa (con un segnale (con \var{errno} impostata a \errcode{EINTR}). Una volta completata con successo l'estrazione del messaggio dalla coda, la -funzione aggiorna i dati mantenuti in \var{msqid\_ds}, in particolare vengono -modificati: +funzione aggiorna i dati mantenuti in \struct{msqid\_ds}, in particolare +vengono modificati: \begin{itemize*} \item Il valore di \var{msg\_lrpid}, che viene impostato al \acr{pid} del processo chiamante. @@ -1996,12 +1997,12 @@ struct semid_ds \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{semid\_ds}, associata a ciascun insieme di + \caption{La struttura \structd{semid\_ds}, associata a ciascun insieme di semafori.} \label{fig:ipc_semid_ds} \end{figure} -A ciascun insieme di semafori è associata una struttura \var{semid\_ds}, +A ciascun insieme di semafori è associata una struttura \struct{semid\_ds}, riportata in \figref{fig:ipc_semid_ds}.\footnote{non si sono riportati i campi ad uso interno del kernel, che vedremo in \figref{fig:ipc_sem_schema}, che dipendono dall'implementazione.} Come nel caso delle code di messaggi quando @@ -2021,8 +2022,8 @@ semaforo), per quanto riguarda gli altri campi invece: Ciascun semaforo dell'insieme è realizzato come una struttura di tipo -\var{sem} che ne contiene i dati essenziali, la sua definizione\footnote{si è - riportata la definizione originaria del kernel 1.0, che contiene la prima +\struct{sem} che ne contiene i dati essenziali, la sua definizione\footnote{si + è riportata la definizione originaria del kernel 1.0, che contiene la prima realizzazione del \textit{SysV IPC} in Linux. In realtà questa struttura ormai è ridotta ai soli due primi membri, e gli altri vengono calcolati dinamicamente. La si è utilizzata a scopo di esempio, perché indica tutti i @@ -2045,12 +2046,13 @@ struct sem { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{sem}, che contiene i dati di un singolo semaforo.} + \caption{La struttura \structd{sem}, che contiene i dati di un singolo + semaforo.} \label{fig:ipc_sem} \end{figure} I dati mantenuti nella struttura, ed elencati in \figref{fig:ipc_sem}, -indicano rispettivamente: +indicano rispettivamente: \begin{description*} \item[\var{semval}] il valore numerico del semaforo. \item[\var{sempid}] il \acr{pid} dell'ultimo processo che ha eseguito una @@ -2142,16 +2144,17 @@ union semun { \end{lstlisting} \end{minipage} \normalsize - \caption{La definizione dei possibili valori di una \var{union semun}, usata - come quarto argomento della funzione \func{semctl}.} + \caption{La definizione dei possibili valori di una \direct{union} + \structd{semun}, usata come quarto argomento della funzione + \func{semctl}.} \label{fig:ipc_semun} \end{figure} -Qualora la funzione operi con quattro argomenti \param{arg} è -un argomento generico, che conterrà un dato diverso a seconda dell'azione -richiesta; per unificare l'argomento esso deve essere passato come una -\var{union semun}, la cui definizione, con i possibili valori che può -assumere, è riportata in \figref{fig:ipc_semun}. +Qualora la funzione operi con quattro argomenti \param{arg} è un argomento +generico, che conterrà un dato diverso a seconda dell'azione richiesta; per +unificare l'argomento esso deve essere passato come una \struct{semun}, la cui +definizione, con i possibili valori che può assumere, è riportata in +\figref{fig:ipc_semun}. Come già accennato sia il comportamento della funzione che il numero di parametri con cui deve essere invocata, dipendono dal valore dell'argomento @@ -2160,9 +2163,9 @@ cio seguenti: \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} \item[\const{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiando il - contenuto della relativa struttura \var{semid\_ds} all'indirizzo specificato - con \var{arg.buf}. Occorre avere il permesso di lettura. L'argomento - \param{semnum} viene ignorato. + contenuto della relativa struttura \struct{semid\_ds} all'indirizzo + specificato con \var{arg.buf}. Occorre avere il permesso di lettura. + L'argomento \param{semnum} viene ignorato. \item[\const{IPC\_RMID}] Rimuove l'insieme di semafori e le relative strutture dati, con effetto immediato. Tutti i processi che erano stato di \textit{sleep} vengono svegliati, ritornando con un errore di @@ -2171,42 +2174,42 @@ seguenti: \param{semnum} viene ignorato. \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario dell'insieme. I valori devono essere passati in una struttura - \var{semid\_ds} puntata da \param{arg.buf} di cui saranno usati soltanto i + \struct{semid\_ds} puntata da \param{arg.buf} di cui saranno usati soltanto i campi \var{sem\_perm.uid}, \var{sem\_perm.gid} e i nove bit meno significativi di \var{sem\_perm.mode}. L'userid effettivo del processo deve corrispondere o al creatore o al proprietario dell'insieme, o all'amministratore. L'argomento \param{semnum} viene ignorato. \item[\const{GETALL}] Restituisce il valore corrente di ciascun semaforo - dell'insieme (corrispondente al campo \var{semval} di \var{sem}) nel vettore - indicato da \param{arg.array}. Occorre avere il permesso di lettura. + dell'insieme (corrispondente al campo \var{semval} di \struct{sem}) nel + vettore indicato da \param{arg.array}. Occorre avere il permesso di lettura. L'argomento \param{semnum} viene ignorato. \item[\const{GETNCNT}] Restituisce come valore di ritorno della funzione il numero di processi in attesa che il semaforo \param{semnum} dell'insieme \param{semid} venga incrementato (corrispondente al campo \var{semncnt} di - \var{sem}); va invocata con tre argomenti. Occorre avere il permesso di + \struct{sem}); va invocata con tre argomenti. Occorre avere il permesso di lettura. \item[\const{GETPID}] Restituisce come valore di ritorno della funzione il \acr{pid} dell'ultimo processo che ha compiuto una operazione sul semaforo \param{semnum} dell'insieme \param{semid} (corrispondente al campo - \var{sempid} di \var{sem}); va invocata con tre argomenti. Occorre avere il - permesso di lettura. + \var{sempid} di \struct{sem}); va invocata con tre argomenti. Occorre avere + il permesso di lettura. \item[\const{GETVAL}] Restituisce come valore di ritorno della funzione il il valore corrente del semaforo \param{semnum} dell'insieme \param{semid} - (corrispondente al campo \var{semval} di \var{sem}); va invocata con tre + (corrispondente al campo \var{semval} di \struct{sem}); va invocata con tre argomenti. Occorre avere il permesso di lettura. \item[\const{GETZCNT}] Restituisce come valore di ritorno della funzione il numero di processi in attesa che il valore del semaforo \param{semnum} dell'insieme \param{semid} diventi nullo (corrispondente al campo - \var{semncnt} di \var{sem}); va invocata con tre argomenti. Occorre avere + \var{semncnt} di \struct{sem}); va invocata con tre argomenti. Occorre avere il permesso di lettura. \item[\const{SETALL}] Inizializza il valore di tutti i semafori dell'insieme, - aggiornando il campo \var{sem\_ctime} di \var{semid\_ds}. I valori devono + aggiornando il campo \var{sem\_ctime} di \struct{semid\_ds}. I valori devono essere passati nel vettore indicato da \param{arg.array}. Si devono avere i privilegi di scrittura sul semaforo. L'argomento \param{semnum} viene ignorato. \item[\const{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato dall'argomento \param{arg.val}, aggiornando il campo \var{sem\_ctime} di - \var{semid\_ds}. Si devono avere i privilegi di scrittura sul semaforo. + \struct{semid\_ds}. Si devono avere i privilegi di scrittura sul semaforo. \end{basedescript} Quando si imposta il valore di un semaforo (sia che lo si faccia per tutto @@ -2237,7 +2240,7 @@ Il valore di ritorno della funzione in caso di successo dipende dall'operazione richiesta; per tutte le operazioni che richiedono quattro argomenti esso è sempre nullo, per le altre operazioni, elencate in \tabref{tab:ipc_semctl_returns} viene invece restituito il valore richiesto, -corrispondente al campo della struttura \var{sem} indicato nella seconda +corrispondente al campo della struttura \struct{sem} indicato nella seconda colonna della tabella. Le operazioni ordinarie sui semafori, come l'acquisizione o il rilascio degli @@ -2278,7 +2281,7 @@ un insieme. La funzione richiede come primo argomento l'identificatore \param{semid} dell'insieme su cui si vuole operare. Il numero di operazioni da effettuare viene specificato con l'argomento \param{nsop}, mentre il loro contenuto viene passato con un puntatore ad un vettore di strutture -\var{sembuf} nell'argomento \param{sops}. Le operazioni richieste vengono +\struct{sembuf} nell'argomento \param{sops}. Le operazioni richieste vengono effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante. \begin{figure}[!htb] @@ -2294,13 +2297,13 @@ struct sembuf \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{sembuf}, usata per le operazioni sui + \caption{La struttura \structd{sembuf}, usata per le operazioni sui semafori.} \label{fig:ipc_sembuf} \end{figure} Il contenuto di ciascuna operazione deve essere specificato attraverso una -opportuna struttura \var{sembuf} (la cui definizione è riportata in +opportuna struttura \struct{sembuf} (la cui definizione è riportata in \figref{fig:ipc_sembuf}) che il programma chiamante deve avere cura di allocare in un opportuno vettore. La struttura permette di indicare il semaforo su cui operare, il tipo di operazione, ed un flag di controllo. @@ -2374,17 +2377,17 @@ possibili: sull'insieme di semafori. \end{basedescript} -In caso di successo della funzione viene aggiornato di \var{sempid} per ogni -semaforo modificato al valore del \acr{pid} del processo chiamante; inoltre -vengono pure aggiornati al tempo corrente i campi \var{sem\_otime} e +In caso di successo della funzione viene aggiornato il campo \var{sempid} per +ogni semaforo modificato al valore del \acr{pid} del processo chiamante; +inoltre vengono pure aggiornati al tempo corrente i campi \var{sem\_otime} e \var{sem\_ctime}. Dato che, come già accennato in precedenza, in caso di uscita inaspettata i semafori possono restare occupati, abbiamo visto come \func{semop} permetta di attivare un meccanismo di ripristino attraverso l'uso del flag \const{SEM\_UNDO}. Il meccanismo è implementato tramite una apposita struttura -\var{sem\_undo}, associata ad ogni processo per ciascun semaforo che esso ha -modificato; all'uscita i semafori modificati vengono ripristinati, e le +\struct{sem\_undo}, associata ad ogni processo per ciascun semaforo che esso +ha modificato; all'uscita i semafori modificati vengono ripristinati, e le strutture disallocate. Per mantenere coerente il comportamento queste strutture non vengono ereditate attraverso una \func{fork} (altrimenti si avrebbe un doppio ripristino), mentre passano inalterate nell'esecuzione di @@ -2406,15 +2409,15 @@ a queste strutture restano per compatibilit \end{figure} Alla creazione di un nuovo insieme viene allocata una nuova strutture -\var{semid\_ds} ed il relativo vettore di strutture \var{sem}. Quando si +\struct{semid\_ds} ed il relativo vettore di strutture \struct{sem}. Quando si richiede una operazione viene anzitutto verificato che tutte le operazioni possono avere successo; se una di esse comporta il blocco del processo il -kernel crea una struttura \var{sem\_queue} che viene aggiunta in fondo alla +kernel crea una struttura \struct{sem\_queue} che viene aggiunta in fondo alla coda di attesa associata a ciascun insieme di semafori\footnote{che viene referenziata tramite i campi \var{sem\_pending} e \var{sem\_pending\_last} - di \var{semid\_ds}.}. Nella struttura viene memorizzato il riferimento alle -operazioni richieste (nel campo \var{sops}, che è un puntatore ad una -struttura \var{sembuf}) e al processo corrente (nel campo \var{sleeper}) poi + di \struct{semid\_ds}.}. Nella struttura viene memorizzato il riferimento +alle operazioni richieste (nel campo \var{sops}, che è un puntatore ad una +struttura \struct{sembuf}) e al processo corrente (nel campo \var{sleeper}) poi quest'ultimo viene messo stato di attesa e viene invocato lo scheduler\index{scheduler} per passare all'esecuzione di un altro processo. @@ -2422,14 +2425,14 @@ Se invece tutte le operazioni possono avere successo queste vengono eseguite immediatamente, dopo di che il kernel esegue una scansione della coda di attesa (a partire da \var{sem\_pending}) per verificare se qualcuna delle operazioni sospese in precedenza può essere eseguita, nel qual caso la -struttura \var{sem\_queue} viene rimossa e lo stato del processo associato +struttura \struct{sem\_queue} viene rimossa e lo stato del processo associato all'operazione (\var{sleeper}) viene riportato a \textit{running}; il tutto viene ripetuto fin quando non ci sono più operazioni eseguibili o si è svuotata la coda. Per gestire il meccanismo del ripristino tutte le volte che per un'operazione si è specificato il flag \const{SEM\_UNDO} viene mantenuta per ciascun insieme -di semafori una apposita struttura \var{sem\_undo} che contiene (nel vettore +di semafori una apposita struttura \struct{sem\_undo} che contiene (nel vettore puntato dal campo \var{semadj}) un valore di aggiustamento per ogni semaforo cui viene sommato l'opposto del valore usato per l'operazione. @@ -2439,7 +2442,7 @@ all'insieme di cui fa parte il semaforo, che viene usata per invalidare le strutture se questo viene cancellato o per azzerarle se si è eseguita una operazione con \func{semctl}; l'altra associata al processo che ha eseguito l'operazione;\footnote{attraverso il campo \var{semundo} di - \var{task\_struct}, come mostrato in \ref{fig:ipc_sem_schema}.} quando un + \struct{task\_struct}, come mostrato in \ref{fig:ipc_sem_schema}.} quando un processo termina, la lista ad esso associata viene scandita e le operazioni applicate al semaforo. @@ -2540,8 +2543,8 @@ assegnandogli i privilegi di lettura e scrittura per tutti. In caso di errore (\texttt{\small 9--11}) si ritorna subito il risultato di \func{semget}, altrimenti (\texttt{\small 12}) si inizializza il semaforo chiamando \func{semctl} con il comando \const{SETVAL}, utilizzando l'unione -\var{semunion} dichiarata ed avvalorata in precedenza (\texttt{\small 6}) ad 1 -per significare che risorsa è libera. In caso di errore (\texttt{\small +\struct{semunion} dichiarata ed avvalorata in precedenza (\texttt{\small 6}) +ad 1 per significare che risorsa è libera. In caso di errore (\texttt{\small 13--16}) si restituisce il valore di ritorno di \func{semctl}, altrimenti si ritorna l'identificatore del semaforo. @@ -2659,16 +2662,16 @@ struct shmid_ds { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{shmid\_ds}, associata a ciascun segmento di + \caption{La struttura \structd{shmid\_ds}, associata a ciascun segmento di memoria condivisa.} \label{fig:ipc_shmid_ds} \end{figure} A ciascun segmento di memoria condivisa è associata una struttura -\var{shmid\_ds}, riportata in \figref{fig:ipc_shmid_ds}. Come nel caso delle -code di messaggi quando si crea un nuovo segmento di memoria condivisa con -\func{shmget} questa struttura viene inizializzata, in particolare il campo -\var{shm\_perm} viene inizializzato come illustrato in +\struct{shmid\_ds}, riportata in \figref{fig:ipc_shmid_ds}. Come nel caso +delle code di messaggi quando si crea un nuovo segmento di memoria condivisa +con \func{shmget} questa struttura viene inizializzata, in particolare il +campo \var{shm\_perm} viene inizializzato come illustrato in \secref{sec:ipc_sysv_access_control}, e valgono le considerazioni ivi fatte relativamente ai permessi di accesso; per quanto riguarda gli altri campi invece: @@ -2765,7 +2768,7 @@ Il comportamento della funzione dipende dal valore del comando passato attraverso l'argomento \param{cmd}, i valori possibili sono i seguenti: \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} \item[\const{IPC\_STAT}] Legge le informazioni riguardo il segmento di memoria - condivisa nella struttura \var{shmid\_ds} puntata da \param{buf}. Occorre + condivisa nella struttura \struct{shmid\_ds} puntata da \param{buf}. Occorre avere il permesso di lettura sulla coda. \item[\const{IPC\_RMID}] Marca il segmento di memoria condivisa per la rimozione, questo verrà cancellato effettivamente solo quando l'ultimo @@ -2870,7 +2873,7 @@ lettura e scrittura (ed il processo deve aver questi permessi in sola scrittura. In caso di successo la funzione aggiorna anche i seguenti campi di -\var{shmid\_ds}: +\struct{shmid\_ds}: \begin{itemize*} \item il tempo \var{shm\_atime} dell'ultima operazione di aggancio viene impostato al tempo corrente. @@ -2911,7 +2914,7 @@ restituito dalla precedente chiamata a \func{shmat} con il quale era stato agganciato al processo. In caso di successo la funzione aggiorna anche i seguenti campi di -\var{shmid\_ds}: +\struct{shmid\_ds}: \begin{itemize*} \item il tempo \var{shm\_dtime} dell'ultima operazione di sganciamento viene impostato al tempo corrente. @@ -3185,10 +3188,10 @@ La prima funzione (\texttt{\small 1--22}) serve per acquisire il mutex. Anzitutto si apre (\texttt{\small 9--11}), creandolo se non esiste, il file specificato dall'argomento \param{pathname}. In caso di errore si ritorna immediatamente, altrimenti si prosegue impostando (\texttt{\small 12--16}) la -struttura \var{lock} in modo da poter acquisire un write lock sul file. Infine -si richiede (\texttt{\small 17--20}) il file lock (restituendo il codice di -ritorno di \func{fcntl} caso di errore). Se il file è libero il lock è -acquisito e la funzione ritorna immediatamente; altrimenti \func{fcntl} si +struttura \var{lock} in modo da poter acquisire un write lock sul file. +Infine si richiede (\texttt{\small 17--20}) il file lock (restituendo il +codice di ritorno di \func{fcntl} caso di errore). Se il file è libero il lock +è acquisito e la funzione ritorna immediatamente; altrimenti \func{fcntl} si bloccherà (si noti che la si è chiamata con \func{F\_SETLKW}) fino al rilascio del lock. diff --git a/macro.tex b/macro.tex index 301fb8e..18f67f6 100644 --- a/macro.tex +++ b/macro.tex @@ -112,6 +112,9 @@ \newcommand{\func}[1]{% \index{#1@{{\tt {#1}} (funzione)}}\texttt{#1}% } +\newcommand{\funcd}[1]{% +\index{#1@{{\tt {#1}} (funzione)}!definizione di}\texttt{#1}% +} \newcommand{\macro}[1]{% \index{#1@{{\tt {#1}} (macro)}}\texttt{#1}% } @@ -133,6 +136,12 @@ \newcommand{\type}[1]{% \index{#1@{{\tt {#1}} (tipo)}}\texttt{#1}% } % system type +\newcommand{\struct}[1]{% +\index{#1@{{\tt {#1}} (struttura dati)}}\texttt{#1}% +} % struttura dati +\newcommand{\structd}[1]{% +\index{#1@{{\tt {#1}} (struttura dati)}!definizione di}\texttt{#1}% +} % struttura dati \newcommand{\param}[1]{\texttt{#1}} % function parameter \newcommand{\acr}[1]{\textsl{#1}} % acrostic (for pid, suid, etc.) diff --git a/process.tex b/process.tex index 3069d29..d3e98e4 100644 --- a/process.tex +++ b/process.tex @@ -64,7 +64,7 @@ linea di comando, in sostanza un prototipo che va sempre bene \end{lstlisting} In realtà nei sistemi Unix esiste un'altro modo per definire la funzione -\func{main}, che prevede la presenza di un terzo parametro, \var{char +\func{main}, che prevede la presenza di un terzo parametro, \code{char *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{sec:proc_environ}) del programma; questa forma però non è prevista dallo standard POSIX.1 per cui se si vogliono scrivere programmi portabili è meglio evitarla. @@ -125,11 +125,10 @@ valori di tipo \ctyp{int} 0 e 1. \label{sec:proc_exit} Come accennato le funzioni usate per effettuare un'uscita ``normale'' da un -programma sono due, la prima è la funzione \func{exit} che è definita dallo +programma sono due, la prima è la funzione \funcd{exit}, che è definita dallo standard ANSI C ed il cui prototipo è: \begin{prototype}{stdlib.h}{void exit(int status)} - Causa la conclusione ordinaria del programma restituendo il valore - \var{status} al processo padre. + Causa la conclusione ordinaria del programma. \bodydesc{La funzione non ritorna. Il processo viene terminato.} \end{prototype} @@ -140,15 +139,14 @@ che sono state registrate con \func{atexit} e \func{on\_exit} (vedi \secref{sec:proc_atexit}), e chiude tutti gli stream effettuando il salvataggio dei dati sospesi (chiamando \func{fclose}, vedi \secref{sec:file_fopen}), infine passa il controllo al kernel chiamando -\func{\_exit} e passando \param{status} come stato di uscita. +\func{\_exit} e restituendo il valore di \param{status} come stato di uscita. -La system call \func{\_exit} restituisce direttamente il controllo al kernel, +La system call \funcd{\_exit} restituisce direttamente il controllo al kernel, concludendo immediatamente il processo; i dati sospesi nei buffer degli stream non vengono salvati e le eventuali funzioni registrate con \func{atexit} e \func{on\_exit} non vengono eseguite. Il prototipo della funzione è: \begin{prototype}{unistd.h}{void \_exit(int status)} - Causa la conclusione immediata del programma restituendo \param{status} al - processo padre come stato di uscita. + Causa la conclusione immediata del programma. \bodydesc{La funzione non ritorna. Il processo viene terminato.} \end{prototype} @@ -179,37 +177,37 @@ una funzione che effettui tali operazioni all'uscita dal programma. A questo scopo lo standard ANSI C prevede la possibilità di registrare un certo numero funzioni che verranno eseguite all'uscita dal programma (sia per la chiamata ad \func{exit} che per il ritorno di \func{main}). La prima funzione che si -può utilizzare a tal fine è: +può utilizzare a tal fine è \funcd{atexit} il cui prototipo è: \begin{prototype}{stdlib.h}{void atexit(void (*function)(void))} - Registra la funzione \param{function} per essere chiamata all'uscita dal - programma. + Registra la funzione \param{function} per la chiamata all'uscita dal + programma. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di fallimento, \var{errno} non viene modificata.} \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 \code{void - function(void)}). +\noindent la funzione richiede come argomento l'indirizzo di una opportuna +funzione di pulizia da chiamare all'uscita del programma, che non deve +prendere argomenti e non deve ritornare niente (deve essere essere cioè +definita come \code{void function(void)}). -Un'estensione di \func{atexit} è la funzione \func{on\_exit}, che le +Un'estensione di \func{atexit} è la funzione \funcd{on\_exit}, che le \acr{glibc} includono per compatibilità con SunOS, ma che non è detto sia definita su altri sistemi; il suo prototipo è: \begin{prototype}{stdlib.h} -{void on\_exit(void (*function)(int status, void *arg), void *arg)} - Registra la funzione \param{function} per essere chiamata all'uscita dal - programma. Tutte le funzioni registrate vengono chiamate in ordine inverso - rispetto a quello di registrazione. +{void on\_exit(void (*function)(int , void *), void *arg)} + Registra la funzione \param{function} per la chiamata all'uscita dal + programma. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di fallimento, \var{errno} non viene modificata.} \end{prototype} -In questo caso la funzione da chiamare prende due parametri, il primo dei -quali sarà inizializzato allo stato di uscita con cui è stata chiamata -\func{exit} ed il secondo al puntatore generico specificato come secondo -argomento nella chiamata di \func{on\_exit}. Così diventa possibile passare -dei dati alla funzione di chiusura. +In questo caso la funzione da chiamare all'uscita prende i due parametri +specificati nel prototipo, dovrà cioè essere definita come \code{void + function(int status, void *argp)}. Il primo argomento sarà inizializzato +allo stato di uscita con cui è stata chiamata \func{exit} ed il secondo al +puntatore \param{arg} passato come secondo argomento di \func{on\_exit}. Così +diventa possibile passare dei dati alla funzione di chiusura. Nella sequenza di chiusura tutte le funzioni registrate verranno chiamate in ordine inverso rispetto a quello di registrazione (ed una stessa funzione @@ -268,7 +266,7 @@ la cosiddetta \textsl{memoria virtuale}\index{memoria virtuale} che consiste nell'assegnare ad ogni processo uno spazio virtuale di indirizzamento lineare, in cui gli indirizzi vanno da zero ad un qualche valore massimo.\footnote{nel caso di Linux fino al kernel 2.2 detto massimo era, per macchine a 32bit, di - 2Gb, con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite + 2Gb. Con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite è stato esteso.} Come accennato in \capref{cha:intro_unix} questo spazio di indirizzi è @@ -318,8 +316,8 @@ a tempi molto pi Normalmente questo è il prezzo da pagare per avere un multitasking reale, ed in genere il sistema è molto efficiente in questo lavoro; quando però ci siano esigenze specifiche di prestazioni è possibile usare delle funzioni che -permettono di bloccare il meccanismo della paginazione e mantenere fisse delle -pagine in memoria (vedi \ref{sec:proc_mem_lock}). +permettono di bloccare il meccanismo della paginazione\index{paginazione} e +mantenere fisse delle pagine in memoria (vedi \ref{sec:proc_mem_lock}). \subsection{La struttura della memoria di un processo} @@ -458,31 +456,31 @@ attraverso dei puntatori. \label{sec:proc_mem_malloc} Le funzioni previste dallo standard ANSI C per la gestione della memoria sono -quattro: \func{malloc}, \func{calloc}, \func{realloc} e \func{free}, i loro -prototipi sono i seguenti: +quattro: \funcd{malloc}, \funcd{calloc}, \funcd{realloc} e \funcd{free}, i +loro prototipi sono i seguenti: \begin{functions} \headdecl{stdlib.h} \funcdecl{void *calloc(size\_t size)} - Alloca \var{size} byte nello heap. La memoria viene inizializzata a 0. + Alloca \param{size} byte nello heap. La memoria viene inizializzata a 0. La funzione restituisce il puntatore alla zona di memoria allocata in caso di successo e \val{NULL} in caso di fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}. \funcdecl{void *malloc(size\_t size)} - Alloca \var{size} byte nello heap. La memoria non viene inizializzata. + Alloca \param{size} byte nello heap. La memoria non viene inizializzata. La funzione restituisce il puntatore alla zona di memoria allocata in caso di successo e \val{NULL} in caso di fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}. \funcdecl{void *realloc(void *ptr, size\_t size)} - Cambia la dimensione del blocco allocato all'indirizzo \var{ptr} - portandola a \var{size}. + Cambia la dimensione del blocco allocato all'indirizzo \param{ptr} + portandola a \param{size}. La funzione restituisce il puntatore alla zona di memoria allocata in caso di successo e \val{NULL} in caso di fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}. \funcdecl{void free(void *ptr)} - Disalloca lo spazio di memoria puntato da \var{ptr}. + Disalloca lo spazio di memoria puntato da \param{ptr}. La funzione non ritorna nulla e non riporta errori. \end{functions} @@ -529,7 +527,7 @@ spazio aggiunto non viene inizializzato. Si deve sempre avere ben presente il fatto che il blocco di memoria restituito da \func{realloc} può non essere un'estensione di quello che gli si è passato in ingresso; per questo si dovrà \emph{sempre} eseguire la riassegnazione di -\var{ptr} al valore di ritorno della funzione, e reinizializzare o provvedere +\param{ptr} al valore di ritorno della funzione, e reinizializzare o provvedere ad un adeguato aggiornamento di tutti gli altri puntatori all'interno del blocco di dati ridimensionato. @@ -618,20 +616,22 @@ molto complesse riguardo l'allocazione della memoria. Una possibile alternativa all'uso di \func{malloc}, che non soffre dei problemi di \textit{memory leak} descritti in precedenza, è la funzione -\func{alloca}, che invece di allocare la memoria nello heap usa il segmento di -stack della funzione corrente. La sintassi è identica a quella di +\funcd{alloca}, che invece di allocare la memoria nello heap usa il segmento +di stack della funzione corrente. La sintassi è identica a quella di \func{malloc}, il suo prototipo è: \begin{prototype}{stdlib.h}{void *alloca(size\_t size)} - Alloca \var{size} byte nel segmento di stack della funzione chiamante. - La memoria non viene inizializzata. - - La funzione restituisce il puntatore alla zona di memoria allocata in caso - di successo e \val{NULL} in caso di fallimento, nel qual caso - \var{errno} assumerà il valore \errval{ENOMEM}. + Alloca \param{size} byte nello stack. + + \bodydesc{La funzione restituisce il puntatore alla zona di memoria allocata + in caso di successo e \val{NULL} in caso di fallimento, nel qual caso + \var{errno} assumerà il valore \errval{ENOMEM}.} \end{prototype} -\noindent ma in questo caso non è più necessario liberare la memoria (e quindi -non esiste un analogo della \func{free}) in quanto essa viene rilasciata -automaticamente al ritorno della funzione. + +La funzione alloca la quantità di memoria (non inizializzata) richiesta +dall'argomento \param{size} nel segmento di stack della funzione chiamante. +Con questa funzione non è più necessario liberare la memoria allocata (e +quindi non esiste un analogo della \func{free}) in quanto essa viene +rilasciata automaticamente al ritorno della funzione. Come è evidente questa funzione ha molti vantaggi, anzitutto permette di evitare alla radice i problemi di memory leak, dato che non serve più la @@ -670,33 +670,43 @@ cui torneremo in \secref{sec:proc_auto_var}. \subsection{Le funzioni \func{brk} e \func{sbrk}} \label{sec:proc_mem_sbrk} -L'uso di queste funzioni è necessario solo quando si voglia accedere alle -analoghe system call a cui fanno da interfaccia. I loro prototipi sono: -\begin{functions} - \headdecl{unistd.h} - \funcdecl{int brk(void *end\_data\_segment)} - Sposta la fine del segmento dei dati all'indirizzo specificato da - \var{end\_data\_segment}. +Queste due funzioni vengono utilizzate soltanto quando è necessario effettuare +direttamente la gestione della memoria associata allo spazio dati di un +processo, ad esempio qualora si debba implementare la propria versione delle +routine di allocazione della memoria viste in \secref{sec:proc_mem_malloc}. La +prima funzione è \funcd{brk}, ed il suo prototipo è: +\begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)} + Sposta la fine del segmento dei dati. - La funzione restituisce 0 in caso di successo e -1 in caso di - fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}. + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.} +\end{prototype} - \funcdecl{void *sbrk(ptrdiff\_t increment)} Incrementa lo spazio dati di un - programma di \var{increment}. Un valore zero restituisce l'attuale posizione - della fine del segmento dati. +La funzione è un'interfaccia diretta all'ominima system call ed imposta +l'indirizzo finale del segmento dati di un processo all'indirizzo specificato +da \param{end\_data\_segment}. Quest'ultimo deve essere un valore ragionevole, +ed inoltre la dimensione totale del segmento non deve comunque eccedere un +eventuale limite (si veda \secref{sec:sys_resource_limit}) imposto sulle +dimensioni massime dello spazio dati del processo. + +La seconda funzione per la manipolazione delle dimensioni del segmento +dati\footnote{in questo caso si tratta soltanto di una funzione di libreria, e + non di una sistem call.} è \funcd{sbrk}, ed il suo prototipo è: +\begin{prototype}{unistd.h}{void *sbrk(ptrdiff\_t increment)} + Incrementa la dimensione dello spazio dati. - La funzione restituisce il puntatore all'inizio della nuova zona di memoria - allocata in caso di successo e \val{NULL} in caso di fallimento, nel qual - caso \var{errno} assumerà il valore \errval{ENOMEM}. -\end{functions} -\noindent in genere si usa \func{sbrk} con un valore zero per ottenere -l'attuale posizione della fine del segmento dati. + \bodydesc{La funzione restituisce il puntatore all'inizio della nuova zona + di memoria allocata in caso di successo e \val{NULL} in caso di + fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.} +\end{prototype} +\noindent la funzione incrementa la dimensione lo spazio dati di un programma +di \param{increment} byte, restituendo il nuovo indirizzo finale dello stesso. +Un valore nullo permette di ottenere l'attuale posizione della fine del +segmento dati. Queste funzioni sono state deliberatamente escluse dallo standard POSIX.1 e per i programmi normali è sempre opportuno usare le funzioni di allocazione -standard descritte in precedenza, che sono costruite su di esse. L'uso di -queste funzioni è ristretto alle specifiche necessità di chi debba -implementare una sua versione delle routine di allocazione. +standard descritte in precedenza, che sono costruite su di esse. % \subsection{La personalizzazione delle funzioni di allocazione} @@ -717,12 +727,13 @@ trasparente, tutte le pagine che gli occorrono; esistono per particolari in cui non si vuole che questo meccanismo si attivi. In generale i motivi per cui si possono avere di queste necessità sono due: \begin{itemize} -\item \textsl{La velocità}. Il processo della paginazione è trasparente solo - se il programma in esecuzione non è sensibile al tempo che occorre a - riportare la pagina in memoria; per questo motivo processi critici che hanno - esigenze di tempo reale o tolleranze critiche nelle risposte (ad esempio - processi che trattano campionamenti sonori) possono non essere in grado di - sopportare le variazioni della velocità di accesso dovuta alla paginazione. +\item \textsl{La velocità}. Il processo della paginazione\index{paginazione} è + trasparente solo se il programma in esecuzione non è sensibile al tempo che + occorre a riportare la pagina in memoria; per questo motivo processi critici + che hanno esigenze di tempo reale o tolleranze critiche nelle risposte (ad + esempio processi che trattano campionamenti sonori) possono non essere in + grado di sopportare le variazioni della velocità di accesso dovuta alla + paginazione. In certi casi poi un programmatore può conoscere meglio dell'algoritmo di allocazione delle pagine le esigenze specifiche del suo programma e decidere @@ -733,23 +744,25 @@ motivi per cui si possono avere di queste necessit \item \textsl{La sicurezza}. Se si hanno password o chiavi segrete in chiaro in memoria queste possono essere portate su disco dal meccanismo della - paginazione. Questo rende più lungo il periodo di tempo in cui detti segreti - sono presenti in chiaro e più complessa la loro cancellazione (un processo - può cancellare la memoria su cui scrive le sue variabili, ma non può toccare - lo spazio disco su cui una pagina di memoria può essere stata salvata). Per - questo motivo di solito i programmi di crittografia richiedono il blocco di - alcune pagine di memoria. + paginazione\index{paginazione}. Questo rende più lungo il periodo di tempo + in cui detti segreti sono presenti in chiaro e più complessa la loro + cancellazione (un processo può cancellare la memoria su cui scrive le sue + variabili, ma non può toccare lo spazio disco su cui una pagina di memoria + può essere stata salvata). Per questo motivo di solito i programmi di + crittografia richiedono il blocco di alcune pagine di memoria. \end{itemize} -Il meccanismo che previene la paginazione di parte della memoria virtuale di -un processo è chiamato \textit{memory locking} (o \textsl{blocco della - memoria}). Il blocco è sempre associato alle pagine della memoria virtuale -del processo, e non al segmento reale di RAM su cui essa viene mantenuta. +Il meccanismo che previene la paginazione\index{paginazione} di parte della +memoria virtuale di un processo è chiamato \textit{memory locking} (o +\textsl{blocco della memoria}). Il blocco è sempre associato alle pagine della +memoria virtuale del processo, e non al segmento reale di RAM su cui essa +viene mantenuta. La regola è che se un segmento di RAM fa da supporto ad almeno una pagina -bloccata allora esso viene escluso dal meccanismo della paginazione. I blocchi -non si accumulano, se si blocca due volte la stessa pagina non è necessario -sbloccarla due volte, una pagina o è bloccata oppure no. +bloccata allora esso viene escluso dal meccanismo della +paginazione\index{paginazione}. I blocchi non si accumulano, se si blocca due +volte la stessa pagina non è necessario sbloccarla due volte, una pagina o è +bloccata oppure no. Il \textit{memory lock} persiste fintanto che il processo che detiene la memoria bloccata non la sblocca. Chiaramente la terminazione del processo @@ -775,18 +788,17 @@ standard POSIX.1 richiede che sia definita in \file{unistd.h} la macro \textit{memory locking} e la costante \const{PAGESIZE} in \file{limits.h} per indicare la dimensione di una pagina in byte. -Le funzioni per bloccare e sbloccare singole sezioni di memoria sono -\func{mlock} e \func{munlock}; i loro prototipi sono: +Le funzioni per bloccare e sbloccare la paginazione\index{paginazione} di +singole sezioni di memoria sono \funcd{mlock} e \funcd{munlock}; i loro +prototipi sono: \begin{functions} \headdecl{sys/mman.h} \funcdecl{int mlock(const void *addr, size\_t len)} - Blocca la paginazione per l'intervallo di memoria da \var{addr} per - \var{len} byte. Tutte le pagine che contengono una parte dell'intervallo - sono mantenute in RAM per tutta la durata del blocco. + Blocca la paginazione su un intervallo di memoria. \funcdecl{int munlock(const void *addr, size\_t len)} - Sblocca l'intervallo di memoria da \var{addr} per \var{len} byte. + Rimuove il blocco della paginazione su un intervallo di memoria. \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in @@ -796,16 +808,21 @@ Le funzioni per bloccare e sbloccare singole sezioni di memoria sono \item[\errcode{ENOMEM}] alcuni indirizzi dell'intervallo specificato non corrispondono allo spazio di indirizzi del processo o si è ecceduto il numero massimo consentito di pagine bloccate. - \item[\errcode{EINVAL}] \var{len} non è un valore positivo. + \item[\errcode{EINVAL}] \param{len} non è un valore positivo. \end{errlist} e, per \func{mlock}, anche \errval{EPERM} quando il processo non ha i privilegi richiesti per l'operazione.} \end{functions} -Altre due funzioni, \func{mlockall} e \func{munlockall}, consentono di -bloccare genericamente lo spazio di indirizzi di un processo. I prototipi di -queste funzioni sono: +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. +Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono poi di +bloccare genericamente la paginazione\index{paginazione} per l'intero spazio +di indirizzi di un processo. I prototipi di queste funzioni sono: \begin{functions} \headdecl{sys/mman.h} @@ -819,7 +836,7 @@ queste funzioni sono: e \func{munlock}.} \end{functions} -Il parametro \var{flags} di \func{mlockall} permette di controllarne il +L'argomento \param{flags} di \func{mlockall} permette di controllarne il comportamento; esso può essere specificato come l'OR aritmetico delle due costanti: \begin{basedescript}{\desclabelwidth{2.5cm}} @@ -857,7 +874,7 @@ che esse siano state effettivamente portate in memoria, ci si scrive sopra. Tutti i programmi hanno la possibilità di ricevere parametri e opzioni quando vengono lanciati. Il passaggio dei parametri è effettuato attraverso gli -argomenti \var{argc} e \var{argv} della funzione \func{main}, che vengono +argomenti \param{argc} e \param{argv} della funzione \func{main}, che vengono passati al programma dalla shell (o dal processo che esegue la \func{exec}, secondo le modalità che vedremo in \secref{sec:proc_exec}) quando questo viene messo in esecuzione. @@ -883,14 +900,14 @@ di ambiente \cmd{IFS}. \begin{figure}[htb] \centering \includegraphics[width=11cm]{img/argv_argc} - \caption{Esempio dei valori di \var{argv} e \var{argc} generati nella + \caption{Esempio dei valori di \param{argv} e \param{argc} generati nella scansione di una riga di comando.} \label{fig:proc_argv_argc} \end{figure} -Nella scansione viene costruito il vettore di puntatori \var{argv} inserendo +Nella scansione viene costruito il vettore di puntatori \param{argv} inserendo in successione il puntatore alla stringa costituente l'$n$-simo parametro; la -variabile \var{argc} viene inizializzata al numero di parametri trovati, in +variabile \param{argc} viene inizializzata al numero di parametri trovati, in questo modo il primo parametro è sempre il nome del programma; un esempio di questo meccanismo è mostrato in \figref{fig:proc_argv_argc}. @@ -900,8 +917,8 @@ questo meccanismo In generale un programma Unix riceve da linea di comando sia gli argomenti che le opzioni, queste ultime sono standardizzate per essere riconosciute come -tali: un elemento di \var{argv} che inizia con il carattere \texttt{'-'} e che -non sia un singolo \texttt{'-'} o un \texttt{'--'} viene considerato +tali: un elemento di \param{argv} che inizia con il carattere \texttt{'-'} e +che non sia un singolo \texttt{'-'} o un \texttt{'--'} viene considerato un'opzione. In genere le opzioni sono costituite da una lettera singola (preceduta dal carattere \cmd{'-'}) e possono avere o no un parametro associato; un comando tipico può essere quello mostrato in @@ -910,25 +927,25 @@ e la prima vuole un parametro mentre la seconda no (\cmd{questofile.txt} argomento del programma, non un parametro di \cmd{-m}). Per gestire le opzioni all'interno dei argomenti a linea di comando passati in -\var{argv} le librerie standard del C forniscono la funzione \func{getopt} +\param{argv} le librerie standard del C forniscono la funzione \funcd{getopt}, che ha il seguente prototipo: \begin{prototype}{unistd.h} {int getopt(int argc, char *const argv[], const char *optstring)} Esegue il parsing degli argomenti passati da linea di comando -riconoscendo le possibili opzioni segnalate con \var{optstring}. +riconoscendo le possibili opzioni segnalate con \param{optstring}. \bodydesc{Ritorna il carattere che segue l'opzione, \cmd{':'} se manca un parametro all'opzione, \cmd{'?'} se l'opzione è sconosciuta, e -1 se non esistono altre opzioni.} \end{prototype} -Questa funzione prende come argomenti le due variabili \var{argc} e \var{argv} -passate a \func{main} ed una stringa che indica quali sono le opzioni valide; -la funzione effettua la scansione della lista degli argomenti ricercando ogni -stringa che comincia con \cmd{-} e ritorna ogni volta che trova un'opzione -valida. +Questa funzione prende come argomenti le due variabili \param{argc} e +\param{argv} passate a \func{main} ed una stringa che indica quali sono le +opzioni valide; la funzione effettua la scansione della lista degli argomenti +ricercando ogni stringa che comincia con \cmd{-} e ritorna ogni volta che +trova un'opzione valida. -La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è +La stringa \param{optstring} indica quali sono le opzioni riconosciute ed è costituita da tutti i caratteri usati per identificare le singole opzioni, se l'opzione ha un parametro al carattere deve essere fatto seguire un segno di due punti \texttt{':'}; nel caso di \figref{fig:proc_argv_argc} ad esempio la @@ -937,11 +954,11 @@ stringa di opzioni avrebbe dovuto contenere \texttt{"r:m"}. La modalità di uso di \func{getopt} è pertanto quella di chiamare più volte la funzione all'interno di un ciclo, fintanto che essa non ritorna il valore -1 che indica che non ci sono più opzioni. Nel caso si incontri un'opzione non -dichiarata in \var{optstring} viene ritornato il carattere \texttt{'?'} +dichiarata in \param{optstring} viene ritornato il carattere \texttt{'?'} mentre se un opzione che lo richiede non è seguita da un parametro viene ritornato il carattere \texttt{':'}, infine se viene incontrato il valore \texttt{'--'} la scansione viene considerata conclusa, anche se vi sono altri -elementi di \var{argv} che cominciano con il carattere \texttt{'-'}. +elementi di \param{argv} che cominciano con il carattere \texttt{'-'}. \begin{figure}[htb] \footnotesize @@ -986,7 +1003,7 @@ carattere, in questo modo si possono eseguire azioni specifiche usando uno \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. + primo elemento di \param{argv} che non è un'opzione. \item \var{int opterr} previene, se posto a zero, la stampa di un messaggio di errore in caso di riconoscimento di opzioni non definite. \item \var{int optopt} contiene il carattere dell'opzione non riconosciuta. @@ -1005,21 +1022,21 @@ opzioni che prevedono un parametro si (il cui indirizzo è contenuto nella variabile \var{optarg}) avvalorando la relativa variabile (\texttt{\small 12-14}, \texttt{\small 15-17} e \texttt{\small 18-20}). Completato il ciclo troveremo in \var{optind} l'indice -in \var{argv[]} del primo degli argomenti rimanenti nella linea di comando. - -Normalmente \func{getopt} compie una permutazione degli elementi di \var{argv} -cosicché alla fine della scansione gli elementi che non sono opzioni sono -spostati in coda al vettore. Oltre a questa esistono altre due modalità di -gestire gli elementi di \var{argv}; se \var{optstring} inizia con il carattere -\texttt{'+'} (o è impostata la variabile di ambiente \val{POSIXLY\_CORRECT}) -la scansione viene fermata non appena si incontra un elemento che non è -un'opzione. L'ultima modalità, usata quando un programma può gestire la -mescolanza fra opzioni e argomenti, ma se li aspetta in un ordine definito, si -attiva quando \var{optstring} inizia con il carattere \texttt{'-'}. In questo -caso ogni elemento che non è un'opzione viene considerato comunque un'opzione -e associato ad un valore di ritorno pari ad 1, questo permette di identificare -gli elementi che non sono opzioni, ma non effettua il riordinamento del -vettore \var{argv}. +in \code{argv[]} del primo degli argomenti rimanenti nella linea di comando. + +Normalmente \func{getopt} compie una permutazione degli elementi di +\param{argv} cosicché alla fine della scansione gli elementi che non sono +opzioni sono spostati in coda al vettore. Oltre a questa esistono altre due +modalità di gestire gli elementi di \param{argv}; se \param{optstring} inizia +con il carattere \texttt{'+'} (o è impostata la variabile di ambiente +\macro{POSIXLY\_CORRECT}) la scansione viene fermata non appena si incontra un +elemento che non è un'opzione. L'ultima modalità, usata quando un programma +può gestire la mescolanza fra opzioni e argomenti, ma se li aspetta in un +ordine definito, si attiva quando \param{optstring} inizia con il carattere +\texttt{'-'}. In questo caso ogni elemento che non è un'opzione viene +considerato comunque un'opzione e associato ad un valore di ritorno pari ad 1, +questo permette di identificare gli elementi che non sono opzioni, ma non +effettua il riordinamento del vettore \param{argv}. \subsection{Opzioni in formato esteso} @@ -1043,8 +1060,8 @@ nella chiamata alla funzione \func{exec} quando questo viene lanciato. Come per la lista dei parametri anche questa lista è un array di puntatori a caratteri, ciascuno dei quali punta ad una stringa, terminata da un -\val{NULL}. A differenza di \var{argv[]} in questo caso non si ha una -lunghezza dell'array data da un equivalente di \var{argc}, ma la lista è +\val{NULL}. A differenza di \code{argv[]} in questo caso non si ha una +lunghezza dell'array data da un equivalente di \param{argc}, ma la lista è terminata da un puntatore nullo. L'indirizzo della lista delle variabili di ambiente è passato attraverso la @@ -1128,7 +1145,7 @@ controllare \cmd{man environ}. Lo standard ANSI C prevede l'esistenza di un ambiente, e pur non entrando nelle specifiche di come sono strutturati i contenuti, definisce la funzione -\func{getenv} che permette di ottenere i valori delle variabili di ambiente; +\funcd{getenv} che permette di ottenere i valori delle variabili di ambiente; il suo prototipo è: \begin{prototype}{stdlib.h}{char *getenv(const char *name)} Esamina l'ambiente del processo cercando una stringa che corrisponda a @@ -1172,7 +1189,7 @@ in \tabref{tab:proc_env_func}. 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, \func{putenv} e \func{setenv}, +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: \begin{functions} @@ -1187,7 +1204,7 @@ seguenti: \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 per un errore, che è sempre \errval{ENOMEM}.} \end{functions} -\noindent la terza, \func{unsetenv}, serve a cancellare una variabile di +\noindent la terza, \funcd{unsetenv}, serve a cancellare una variabile di ambiente; il suo prototipo è: \begin{functions} \headdecl{stdlib.h} @@ -1207,7 +1224,7 @@ variabile esista gi immutata se uguale a zero. La seconda funzione prende come parametro una stringa analoga quella -restituita da \func{getenv}, e sempre nella forma \var{NOME=valore}. Se la +restituita da \func{getenv}, e sempre nella forma \code{NOME=valore}. Se la variabile specificata non esiste la stringa sarà aggiunta all'ambiente, se invece esiste il suo valore sarà impostato a quello specificato da \param{string}. Si tenga presente che, seguendo lo standard SUSv2, le @@ -1296,7 +1313,7 @@ Come vedremo nei capitoli successivi, non sempre numero fisso di parametri per una funzione. Lo standard ISO C prevede nella sua sintassi la possibilità di definire delle \textit{variadic function} che abbiano un numero variabile di argomenti, attraverso l'uso della -\textit{ellipsis} \var{...} nella dichiarazione della funzione; ma non +\textit{ellipsis} \code{...} nella dichiarazione della funzione; ma non provvede a livello di linguaggio alcun meccanismo con cui dette funzioni possono accedere ai loro argomenti. @@ -1322,7 +1339,7 @@ il prototipo della funzione \func{execl} che vedremo in \end{lstlisting} in questo caso la funzione prende due parametri fissi ed un numero variabile di altri parametri (che verranno a costituire gli elementi successivi al primo -del vettore \var{argv} passato al nuovo processo). Lo standard ISO C richiede +del vettore \param{argv} passato al nuovo processo). Lo standard ISO C richiede inoltre che l'ultimo degli argomenti fissi sia di tipo \textit{self-promoting}\footnote{il linguaggio C prevede che quando si mescolano vari tipi di dati, alcuni di essi possano essere \textsl{promossi} @@ -1380,7 +1397,7 @@ In generale si possono avere pi ciascuno andrà inizializzato con \macro{va\_start} e letto con \macro{va\_arg} e ciascuno potrà scandire la lista degli argomenti per conto suo. -Dopo l'uso di \macro{va\_end} la variabile \var{ap} diventa indefinita e +Dopo l'uso di \macro{va\_end} la variabile \param{ap} diventa indefinita e successive chiamate a \macro{va\_arg} non funzioneranno. Si avranno risultati indefiniti anche chiamando \macro{va\_arg} specificando un tipo che non corrisponde a quello del parametro. @@ -1390,7 +1407,7 @@ corpo principale della funzione, il passo 2) invece pu in una subroutine passandole il puntatore alla lista di argomenti; in questo caso però si richiede che al ritorno della funzione il puntatore non venga più usato (lo standard richiederebbe la chiamata esplicita di \macro{va\_end}), -dato che il valore di \var{ap} risulterebbe indefinito. +dato che il valore di \param{ap} risulterebbe indefinito. Esistono dei casi in cui è necessario eseguire più volte la scansione dei parametri e poter memorizzare una posizione durante la stessa. La cosa più @@ -1496,7 +1513,7 @@ ciclo di lettura principale, scartando l'input come errato.\footnote{a meno 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 è -\func{setjmp}, il cui prototipo è: +\funcd{setjmp}, il cui prototipo è: \begin{functions} \headdecl{setjmp.h} \funcdecl{void setjmp(jmp\_buf env)} @@ -1522,7 +1539,7 @@ chiamato \func{setjmp} ritorna, nel qual caso l'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 \func{longjmp}; il suo +stabilito con \func{setjmp} si usa la funzione \funcd{longjmp}; il suo prototipo è: \begin{functions} \headdecl{setjmp.h} diff --git a/prochand.tex b/prochand.tex index f17fec4..7505cad 100644 --- a/prochand.tex +++ b/prochand.tex @@ -127,11 +127,11 @@ processi. Il kernel mantiene una tabella dei processi attivi, la cosiddetta \textit{process table}; per ciascun processo viene mantenuta una voce nella -tabella dei processi costituita da una struttura \type{task\_struct}, che +tabella dei processi costituita da una struttura \struct{task\_struct}, che contiene tutte le informazioni rilevanti per quel processo. Tutte le strutture usate a questo scopo sono dichiarate nell'header file \file{linux/sched.h}, ed uno schema semplificato, che riporta la struttura delle principali informazioni -contenute nella \type{task\_struct} (che in seguito incontreremo a più +contenute nella \struct{task\_struct} (che in seguito incontreremo a più riprese), è mostrato in \figref{fig:proc_task_struct}. \begin{figure}[htb] @@ -247,11 +247,18 @@ sempre il \acr{pid} uguale a uno. Tutti i processi inoltre memorizzano anche il \acr{pid} del genitore da cui sono stati creati, questo viene chiamato in genere \acr{ppid} (da \textit{parent process id}). Questi due identificativi possono essere -ottenuti da programma usando le funzioni: +ottenuti usando le due funzioni \funcd{getpid} e \funcd{getppid}, i cui +prototipi sono: \begin{functions} - \headdecl{sys/types.h} \headdecl{unistd.h} \funcdecl{pid\_t getpid(void)} - Restituisce il \acr{pid} del processo corrente. \funcdecl{pid\_t - getppid(void)} Restituisce il \acr{pid} del padre del processo corrente. + \headdecl{sys/types.h} + \headdecl{unistd.h} + \funcdecl{pid\_t getpid(void)} + + Restituisce il \acr{pid} del processo corrente. + + \funcdecl{pid\_t getppid(void)} + + Restituisce il \acr{pid} del padre del processo corrente. \bodydesc{Entrambe le funzioni non riportano condizioni di errore.} \end{functions} @@ -285,7 +292,7 @@ affrontato in dettaglio in \secref{sec:proc_perms}. \subsection{La funzione \func{fork}} \label{sec:proc_fork} -La funzione \func{fork} è la funzione fondamentale della gestione dei +La funzione \funcd{fork} è la funzione fondamentale della gestione dei processi: come si è detto l'unico modo di creare un nuovo processo è attraverso l'uso di questa funzione, essa quindi riveste un ruolo centrale tutte le volte che si devono scrivere programmi che usano il multitasking. Il @@ -644,7 +651,7 @@ le differenze fra padre e figlio dopo la \func{fork} invece sono: \item il \acr{pid} (\textit{process id}). \item il \acr{ppid} (\textit{parent process id}), quello del figlio viene impostato al \acr{pid} del padre. -\item i valori dei tempi di esecuzione della struttura \var{tms} (vedi +\item i valori dei tempi di esecuzione della struttura \struct{tms} (vedi \secref{sec:sys_cpu_times}) che nel figlio sono posti a zero. \item i \textit{lock} sui file (vedi \secref{sec:file_locking}), che non vengono ereditati dal figlio. @@ -672,7 +679,7 @@ venne introdotta in BSD per migliorare le prestazioni. Dato che Linux supporta il \textit{copy on write}\index{copy on write} la perdita di prestazioni è assolutamente trascurabile, e l'uso di questa -funzione (che resta un caso speciale della funzione \func{clone}), è +funzione (che resta un caso speciale della system call \func{\_\_clone}), è deprecato; per questo eviteremo di trattarla ulteriormente. @@ -856,7 +863,7 @@ principale attende le richieste che vengono poi soddisfatte da una serie di processi figli. Si è già sottolineato al paragrafo precedente come in questo caso diventi necessario gestire esplicitamente la conclusione dei figli onde evitare di riempire di \textit{zombie}\index{zombie} la tabella dei processi; -le funzioni deputate a questo compito sono sostanzialmente due, \func{wait} e +le funzioni deputate a questo compito sono sostanzialmente due, \funcd{wait} e \func{waitpid}. La prima, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} @@ -879,10 +886,10 @@ immediatamente, se pi più volte se si vuole recuperare lo stato di terminazione di tutti quanti. Al ritorno della funzione lo stato di terminazione del figlio viene salvato -nella variabile puntata da \var{status} e tutte le risorse del kernel relative -al processo (vedi \secref{sec:proc_termination}) vengono rilasciate. Nel caso -un processo abbia più figli il valore di ritorno (il \acr{pid} del figlio) -permette di identificare qual'è quello che è uscito. +nella variabile puntata da \param{status} e tutte le risorse del kernel +relative al processo (vedi \secref{sec:proc_termination}) vengono rilasciate. +Nel caso un processo abbia più figli il valore di ritorno (il \acr{pid} del +figlio) permette di identificare qual'è quello che è uscito. Questa funzione ha il difetto di essere poco flessibile, in quanto ritorna all'uscita di un qualunque processo figlio. Nelle occasioni in cui è @@ -891,9 +898,9 @@ predisporre un meccanismo che tenga conto dei processi gi provvedere a ripetere la chiamata alla funzione nel caso il processo cercato sia ancora attivo. -Per questo motivo lo standard POSIX.1 ha introdotto la funzione \func{waitpid} -che effettua lo stesso servizio, ma dispone di una serie di funzionalità più -ampie, legate anche al controllo di sessione (si veda +Per questo motivo lo standard POSIX.1 ha introdotto la funzione +\funcd{waitpid} che effettua lo stesso servizio, ma dispone di una serie di +funzionalità più ampie, legate anche al controllo di sessione (si veda \secref{sec:sess_job_control}). Dato che è possibile ottenere lo stesso comportamento di \func{wait} si consiglia di utilizzare sempre questa funzione, il cui prototipo è: @@ -931,16 +938,16 @@ secondo lo specchietto riportato in \tabref{tab:proc_waidpid_pid}. \hline $<-1$& -- & attende per un figlio il cui \textit{process group} (vedi \secref{sec:sess_proc_group}) è uguale al - valore assoluto di \var{pid}. \\ + valore assoluto di \param{pid}. \\ $-1$ & \const{WAIT\_ANY} & attende per un figlio qualsiasi, usata in questa maniera è equivalente a \func{wait}.\\ $0$ & \const{WAIT\_MYPGRP} & attende per un figlio il cui \textit{process group} è uguale a quello del processo chiamante. \\ $>0$ & -- &attende per un figlio il cui \acr{pid} è uguale al - valore di \var{pid}.\\ + valore di \param{pid}.\\ \hline \end{tabular} - \caption{Significato dei valori del parametro \var{pid} della funzione + \caption{Significato dei valori dell'argomento \param{pid} della funzione \func{waitpid}.} \label{tab:proc_waidpid_pid} \end{table} @@ -1032,7 +1039,7 @@ Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per analizzare lo stato di uscita. Esse sono definite sempre in \file{} ed elencate in \tabref{tab:proc_status_macro} (si tenga presente che queste macro prendono come parametro la variabile di tipo -\ctyp{int} puntata da \var{status}). +\ctyp{int} puntata da \param{status}). Si tenga conto che nel caso di conclusione anomala il valore restituito da \val{WTERMSIG} può essere confrontato con le costanti definite in @@ -1065,7 +1072,7 @@ queste funzioni, che diventano accessibili definendo la costante ormai deprecata in favore di \func{wait4}. \end{functions} \noindent -la struttura \type{rusage} è definita in \file{sys/resource.h}, e viene +la struttura \struct{rusage} è definita in \file{sys/resource.h}, e viene utilizzata anche dalla funzione \func{getrusage} (vedi \secref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un processo; la sua definizione è riportata in \figref{fig:sys_rusage_struct}. @@ -1117,8 +1124,8 @@ famiglia di funzioni) che possono essere usate per questo compito, in realt \end{prototype} La funzione \func{exec} esegue il file o lo script indicato da -\var{filename}, passandogli la lista di argomenti indicata da \var{argv} -e come ambiente la lista di stringhe indicata da \var{envp}; entrambe le +\param{filename}, passandogli la lista di argomenti indicata da \param{argv} +e come ambiente la lista di stringhe indicata da \param{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 @@ -1149,7 +1156,7 @@ Per capire meglio le differenze fra le funzioni della famiglia si pu riferimento allo specchietto riportato in \tabref{tab:proc_exec_scheme}. La prima differenza riguarda le modalità di passaggio dei parametri che poi andranno a costituire gli argomenti a linea di comando (cioè i valori di -\var{argv} e \var{argc} visti dalla funzione \func{main} del programma +\param{argv} e \param{argc} visti dalla funzione \func{main} del programma chiamato). Queste modalità sono due e sono riassunte dagli mnemonici \code{v} e \code{l} @@ -1197,7 +1204,7 @@ per indicare il nome del file che contiene il programma che verr La seconda differenza fra le funzioni riguarda le modalità con cui 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 +specificare il comando da eseguire; quando il parametro \param{file} non contiene una \file{/} esso viene considerato come un nome di programma, e viene eseguita automaticamente una ricerca fra i file presenti nella lista di directory specificate dalla variabile di ambiente \var{PATH}. Il file che @@ -1209,7 +1216,7 @@ non viene trovato nessun altro file viene finalmente restituito \errcode{EACCES}. Le altre quattro funzioni si limitano invece a cercare di eseguire il file -indicato dal parametro \var{path}, che viene interpretato come il +indicato dall'argomento \param{path}, che viene interpretato come il \textit{pathname} del programma. \begin{figure}[htb] @@ -1507,7 +1514,7 @@ eventuali \textsl{groupid supplementari} non vengono modificati. L'effetto della chiamata è diverso a seconda dei privilegi del processo; se l'\textsl{userid effettivo} è zero (cioè è quello dell'amministratore di sistema) allora tutti gli identificatori (\textit{real}, \textit{effective} e -\textit{saved}) vengono impostati al valore specificato da \var{uid}, +\textit{saved}) vengono impostati al valore specificato da \param{uid}, altrimenti viene impostato solo l'\textsl{userid effettivo}, e soltanto se il valore specificato corrisponde o all'\textsl{userid reale} o all'\textsl{userid salvato}. Negli altri casi viene segnalato un errore (con @@ -1589,11 +1596,11 @@ loro \textit{effective} e \textit{real}. I loro prototipi sono: \funcdecl{int setreuid(uid\_t ruid, uid\_t euid)} Imposta l'\textsl{userid reale} e l'\textsl{userid effettivo} del processo corrente ai valori -specificati da \var{ruid} e \var{euid}. +specificati da \param{ruid} e \param{euid}. \funcdecl{int setregid(gid\_t rgid, gid\_t egid)} Imposta il \textsl{groupid reale} ed il \textsl{groupid effettivo} del processo corrente ai valori -specificati da \var{rgid} e \var{egid}. +specificati da \param{rgid} e \param{egid}. \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento: l'unico errore possibile è \errval{EPERM}.} @@ -1642,10 +1649,10 @@ identificatori del gruppo \textit{effective}; i loro prototipi sono: \headdecl{sys/types.h} \funcdecl{int seteuid(uid\_t uid)} Imposta l'userid effettivo del processo -corrente a \var{uid}. +corrente a \param{uid}. \funcdecl{int setegid(gid\_t gid)} Imposta il groupid effettivo del processo -corrente a \var{gid}. +corrente a \param{gid}. \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento: l'unico errore è \errval{EPERM}.} @@ -1670,13 +1677,14 @@ e permettono un completo controllo su tutti gli identificatori (\textit{real}, \headdecl{sys/types.h} \funcdecl{int setresuid(uid\_t ruid, uid\_t euid, uid\_t suid)} Imposta -l'userid reale, l'userid effettivo e l'userid salvato del processo corrente -ai valori specificati rispettivamente da \var{ruid}, \var{euid} e \var{suid}. +l'userid reale, l'userid effettivo e l'userid salvato del processo corrente ai +valori specificati rispettivamente da \param{ruid}, \param{euid} e +\param{suid}. \funcdecl{int setresgid(gid\_t rgid, gid\_t egid, gid\_t sgid)} Imposta il groupid reale, il groupid effettivo ed il groupid salvato del processo -corrente ai valori specificati rispettivamente da \var{rgid}, \var{egid} e -\var{sgid}. +corrente ai valori specificati rispettivamente da \param{rgid}, \param{egid} e +\param{sgid}. \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento: l'unico errore è \errval{EPERM}.} @@ -1745,10 +1753,10 @@ usate se si intendono scrivere programmi portabili; i loro prototipi sono: \headdecl{sys/fsuid.h} \funcdecl{int setfsuid(uid\_t fsuid)} Imposta l'userid di filesystem del -processo corrente a \var{fsuid}. +processo corrente a \param{fsuid}. \funcdecl{int setfsgid(gid\_t fsgid)} Imposta il groupid di filesystem del -processo corrente a \var{fsgid}. +processo corrente a \param{fsgid}. \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento: l'unico errore possibile è \errval{EPERM}.} @@ -2006,10 +2014,10 @@ assegnata una \textit{time-slice}, cio una fetta) per il quale esso deve essere eseguito. Il valore della \textit{time-slice} è controllato dalla cosiddetta \textit{nice} (o \textit{niceness}) del processo. Essa è contenuta nel campo \var{nice} di -\var{task\_struct}; tutti i processi vengono creati con lo stesso valore, ed -essa specifica il valore della durata iniziale della \textit{time-slice} che -viene assegnato ad un altro campo della struttura (\var{counter}) quando il -processo viene eseguito per la prima volta e diminuito progressivamente ad +\struct{task\_struct}; tutti i processi vengono creati con lo stesso valore, +ed essa specifica il valore della durata iniziale della \textit{time-slice} +che viene assegnato ad un altro campo della struttura (\var{counter}) quando +il processo viene eseguito per la prima volta e diminuito progressivamente ad ogni interruzione del timer. Quando lo scheduler\index{scheduler} viene eseguito scandisce la coda dei @@ -2189,13 +2197,13 @@ 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}. - - \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: + + \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: \begin{errlist} \item[\errcode{ESRCH}] il processo \param{pid} non esiste. - \item[\errcode{EINVAL}] il valore di \param{policy} non esiste o il relativo - valore di \param{p} non è valido. + \item[\errcode{EINVAL}] il valore di \param{policy} non esiste o il + relativo valore di \param{p} non è valido. \item[\errcode{EPERM}] il processo non ha i privilegi per attivare la politica richiesta (vale solo per \const{SCHED\_FIFO} e \const{SCHED\_RR}). @@ -2229,12 +2237,12 @@ la politica di scheduling corrente. \label{tab:proc_sched_policy} \end{table} -Il valore della priorità è passato attraverso la struttura \var{sched\_param} -(riportata in \figref{fig:sig_sched_param}), il cui solo campo attualmente -definito è \var{sched\_priority}, che nel caso delle priorità assolute deve -essere specificato nell'intervallo fra un valore massimo ed uno minimo, che -nel caso sono rispettivamente 1 e 99 (il valore zero è legale, ma indica i -processi normali). +Il valore della priorità è passato attraverso la struttura +\struct{sched\_param} (riportata in \figref{fig:sig_sched_param}), il cui solo +campo attualmente definito è \var{sched\_priority}, che nel caso delle +priorità assolute deve essere specificato nell'intervallo fra un valore +massimo ed uno minimo, che nel caso sono rispettivamente 1 e 99 (il valore +zero è legale, ma indica i processi normali). \begin{figure}[!htb] \footnotesize \centering @@ -2246,7 +2254,7 @@ struct sched_param { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{sched\_param}.} + \caption{La struttura \structd{sched\_param}.} \label{fig:sig_sched_param} \end{figure} @@ -2355,7 +2363,7 @@ il suo prototipo \end{prototype} La funzione restituisce il valore dell'intervallo di tempo usato per la -politica \textit{round robin} in una struttura \var{timespec}, (la cui +politica \textit{round robin} in una struttura \struct{timespec}, (la cui definizione si può trovare in \figref{fig:sys_timeval_struct}). diff --git a/session.tex b/session.tex index 6ab9508..ee8b2d8 100644 --- a/session.tex +++ b/session.tex @@ -115,7 +115,7 @@ processi vengono raggruppati in \textit{process group} e \textit{sessioni}; per far questo vengono utilizzati due ulteriori identificatori (oltre quelli visti in \secref{sec:proc_pid}) che il kernel associa a ciascun processo:\footnote{in Linux questi identificatori sono mantenuti nei campi - \var{pgrp} e \var{session} della struttura \var{task\_struct} definita in + \var{pgrp} e \var{session} della struttura \struct{task\_struct} definita in \file{sched.h}.} l'identificatore del \textit{process group} e l'identificatore della \textsl{sessione}, che vengono indicati rispettivamente con le sigle \acr{pgid} e \acr{sid}, e sono mantenuti in variabili di tipo @@ -221,10 +221,11 @@ Inoltre la funzione pu dei suoi figli, ed in quest'ultimo caso ha successo soltanto se questo non ha ancora eseguito una \func{exec}.\footnote{questa caratteristica è implementata dal kernel che mantiene allo scopo un altro campo, \var{did\_exec}, in - \var{task\_struct}.} Specificando un valore nullo per \param{pid} si indica -il processo corrente, mentre specificando un valore nullo per \param{pgid} si -imposta il \textit{process group} al valore del \acr{pid} del processo -selezionato; pertanto \func{setpgrp} è equivalente a \code{setpgid(0, 0)}. + \struct{task\_struct}.} Specificando un valore nullo per \param{pid} si +indica il processo corrente, mentre specificando un valore nullo per +\param{pgid} si imposta il \textit{process group} al valore del \acr{pid} del +processo selezionato; pertanto \func{setpgrp} è equivalente a \code{setpgid(0, + 0)}. Di norma questa funzione viene usata dalla shell quando si usano delle pipeline, per mettere nello stesso process group tutti i programmi lanciati su @@ -253,10 +254,10 @@ valore del suo \acr{pid}, creando cos \textit{process group} di cui esso diventa leader (come per i \textit{process group} un processo si dice leader di sessione\footnote{in Linux la proprietà è mantenuta in maniera indipendente con un apposito campo \var{leader} in - \var{task\_struct}.} se il suo \acr{sid} è uguale al suo \acr{pid}) ed unico -componente. Inoltre la funzione distacca il processo da ogni terminale di -controllo (torneremo sull'argomento in \secref{sec:sess_ctrl_term}) cui fosse -in precedenza associato. + \struct{task\_struct}.} se il suo \acr{sid} è uguale al suo \acr{pid}) ed +unico componente. Inoltre la funzione distacca il processo da ogni terminale +di controllo (torneremo sull'argomento in \secref{sec:sess_ctrl_term}) cui +fosse in precedenza associato. La funzione ha successo soltanto se il processo non è già leader di un \textit{process group}, per cui per usarla di norma si esegue una \func{fork} @@ -292,8 +293,8 @@ associato un terminale di controllo; in Linux questo viene realizzato mantenendo fra gli attributi di ciascun processo anche qual'è il suo terminale di controllo. \footnote{Lo standard POSIX.1 non specifica nulla riguardo l'implementazione; in Linux anch'esso viene mantenuto nella solita struttura - \var{task\_struct}, nel campo \var{tty}.} In generale ogni processo eredita -dal padre, insieme al \acr{pgid} e al \acr{sid} anche il terminale di + \struct{task\_struct}, nel campo \var{tty}.} In generale ogni processo +eredita dal padre, insieme al \acr{pgid} e al \acr{sid} anche il terminale di controllo (vedi \secref{sec:proc_fork}). In questo modo tutti processi originati dallo stesso leader di sessione mantengono lo stesso terminale di controllo. @@ -1076,12 +1077,12 @@ univocamente il terminale (ad esempio potrebbe essere \file{/dev/tty}), inoltre non è detto che il processo possa effettivamente aprire il terminale. I vari attributi vengono mantenuti per ciascun terminale in una struttura -\var{termios}, (la cui definizione è riportata in \figref{fig:term_termios}), -usata dalle varie funzioni dell'interfaccia. In \figref{fig:term_termios} si -sono riportati tutti i campi della definizione usata in Linux; di questi solo -i primi cinque sono previsti dallo standard POSIX.1, ma le varie -implementazioni ne aggiungono degli altri per mantenere ulteriori -informazioni.\footnote{la definizione della struttura si trova in +\struct{termios}, (la cui definizione è riportata in +\figref{fig:term_termios}), usata dalle varie funzioni dell'interfaccia. In +\figref{fig:term_termios} si sono riportati tutti i campi della definizione +usata in Linux; di questi solo i primi cinque sono previsti dallo standard +POSIX.1, ma le varie implementazioni ne aggiungono degli altri per mantenere +ulteriori informazioni.\footnote{la definizione della struttura si trova in \file{bits/termios.h}, da non includere mai direttamente, Linux, seguendo l'esempio di BSD, aggiunge i due campi \var{c\_ispeed} e \var{c\_ospeed} per mantenere le velocità delle linee seriali, ed un campo ulteriore, @@ -1104,7 +1105,7 @@ struct termios { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{termios}, che identifica le proprietà di un + \caption{La struttura \structd{termios}, che identifica le proprietà di un terminale.} \label{fig:term_termios} \end{figure} @@ -1336,13 +1337,13 @@ valore. \const{CBAUD} & Maschera dei bit (4+1) usati per impostare della velocità della linea (il \textit{baud rate}) in ingresso. In Linux non è implementato in quanto viene - usato un apposito campo di \var{termios}.\\ + usato un apposito campo di \struct{termios}.\\ \const{CBAUDEX}& Bit aggiuntivo per l'impostazione della velocità della linea, per le stesse motivazioni del precedente non è implementato in Linux.\\ \const{CIBAUD} & Maschera dei bit della velocità della linea in ingresso. Analogo a \const{CBAUD}, anch'esso in Linux è - mantenuto in un apposito campo di \var{termios}. \\ + mantenuto in un apposito campo di \struct{termios}. \\ \const{CRTSCTS}& Abilita il controllo di flusso hardware sulla seriale, attraverso l'utilizzo delle dei due fili di RTS e CTS.\\ \hline @@ -1370,7 +1371,7 @@ standard POSIX non specifica nulla riguardo l'implementazione, ma solo delle funzioni di lettura e scrittura) che mantengono le velocità delle linee seriali all'interno dei flag; come accennato in Linux questo viene fatto (seguendo l'esempio di BSD) attraverso due campi aggiuntivi, \var{c\_ispeed} e -\var{c\_ospeed}, nella struttura \var{termios} (mostrati in +\var{c\_ospeed}, nella struttura \struct{termios} (mostrati in \figref{fig:term_termios}). \begin{table}[b!ht] @@ -1467,10 +1468,10 @@ avviene solo in modo canonico, pertanto questi flag non hanno significato se non è impostato \const{ICANON}. Oltre ai vari flag per gestire le varie caratteristiche dei terminali, -\var{termios} contiene pure il campo \var{c\_cc} che viene usato per impostare -i caratteri speciali associati alle varie funzioni di controllo. Il numero di -questi caratteri speciali è indicato dalla costante \const{NCCS}, POSIX ne -specifica almeno 11, ma molte implementazioni ne definiscono molti +\struct{termios} contiene pure il campo \var{c\_cc} che viene usato per +impostare i caratteri speciali associati alle varie funzioni di controllo. Il +numero di questi caratteri speciali è indicato dalla costante \const{NCCS}, +POSIX ne specifica almeno 11, ma molte implementazioni ne definiscono molti altri.\footnote{in Linux il valore della costante è 32, anche se i caratteri effettivamente definiti sono solo 17.} @@ -1540,7 +1541,7 @@ altri.\footnote{in Linux il valore della costante \hline \end{tabular} \caption{Valori dei caratteri di controllo mantenuti nel campo \var{c\_cc} - della struttura \var{termios}.} + della struttura \struct{termios}.} \label{tab:sess_termios_cc} \end{table} @@ -1569,8 +1570,8 @@ vengono interpretati e non sono passati sulla coda di ingresso. Per leggere ed scrivere tutte le impostazioni dei terminali lo standard POSIX prevede due funzioni, \func{tcgetattr} e \func{tcsetattr}; entrambe utilizzano -come argomento un puntatore ad struttura \var{termios} che sarà quella in cui -andranno immagazzinate le impostazioni, il loro prototipo è: +come argomento un puntatore ad struttura \struct{termios} che sarà quella in +cui andranno immagazzinate le impostazioni, il loro prototipo è: \begin{functions} \headdecl{unistd.h} \headdecl{termios.h} @@ -1733,11 +1734,11 @@ negato. Al contrario di tutte le altre caratteristiche dei terminali, che possono essere impostate esplicitamente utilizzando gli opportuni campi di -\var{termios}, per le velocità della linea (il cosiddetto \textit{baud rate}) -non è prevista una implementazione standardizzata, per cui anche se in Linux -sono mantenute in due campi dedicati nella struttura, questi non devono essere -acceduti direttamente ma solo attraverso le apposite funzioni di interfaccia -provviste da POSIX.1. +\struct{termios}, per le velocità della linea (il cosiddetto \textit{baud + rate}) non è prevista una implementazione standardizzata, per cui anche se +in Linux sono mantenute in due campi dedicati nella struttura, questi non +devono essere acceduti direttamente ma solo attraverso le apposite funzioni di +interfaccia provviste da POSIX.1. Lo standard prevede due funzioni per scrivere la velocità delle linee seriali, \func{cfsetispeed} per la velocità della linea di ingresso e @@ -1758,9 +1759,9 @@ sono: \end{functions} Si noti che le funzioni si limitano a scrivere opportunamente il valore della -velocità prescelta \var{speed} all'interno della struttura puntata da -\var{termios\_p}; per effettuare l'impostazione effettiva occorrerà poi -chiamare \func{tcsetattr}. +velocità prescelta \param{speed} all'interno della struttura puntata da +\param{termios\_p}; per effettuare l'impostazione effettiva occorrerà poi +chiamare \func{tcsetattr}. Si tenga presente che per le linee seriali solo alcuni valori di velocità sono validi; questi possono essere specificati direttamente (le \acr{glibc} @@ -1792,8 +1793,8 @@ l'effetto sar di output. Analogamente a quanto avviene per l'impostazione, le velocità possono essere -lette da una struttura \var{termios} utilizzando altre due funzioni, -\func{cfgetispeed} e \func{cfgetospeed}, i cui prototipi sono: +lette da una struttura \struct{termios} utilizzando altre due funzioni, +\funcd{cfgetispeed} e \funcd{cfgetospeed}, i cui prototipi sono: \begin{functions} \headdecl{unistd.h} \headdecl{termios.h} diff --git a/signal.tex b/signal.tex index 755f19c..d287ef2 100644 --- a/signal.tex +++ b/signal.tex @@ -143,7 +143,7 @@ moderno) il gestore una volta installato resta attivo e non si hanno tutti i problemi precedenti. In questa semantica i segnali vengono \textsl{generati} dal kernel per un processo all'occorrenza dell'evento che causa il segnale. In genere questo viene fatto dal kernel impostando l'apposito -campo della \var{task\_struct} del processo nella process table (si veda +campo della \struct{task\_struct} del processo nella process table (si veda \figref{fig:proc_task_struct}). Si dice che il segnale viene \textsl{consegnato} al processo (dall'inglese @@ -152,7 +152,7 @@ per tutto il tempo che passa fra la generazione del segnale e la sua consegna esso è detto \textsl{pendente} (o \textit{pending}). In genere questa procedura viene effettuata dallo scheduler\index{scheduler} quando, riprendendo l'esecuzione del processo in questione, verifica la presenza del -segnale nella \var{task\_struct} e mette in esecuzione il gestore. +segnale nella \struct{task\_struct} e mette in esecuzione il gestore. In questa semantica un processo ha la possibilità di bloccare la consegna dei segnali, in questo caso, se l'azione per il suddetto segnale non è quella di @@ -215,7 +215,7 @@ internamente o esternamente al processo. Come accennato quando un segnale viene generato, se la sua azione predefinita non è quella di essere ignorato, il kernel prende nota del fatto nella -\var{task\_struct} del processo; si dice così che il segnale diventa +\struct{task\_struct} del processo; si dice così che il segnale diventa \textsl{pendente} (o \textit{pending}), e rimane tale fino al momento in cui verrà notificato al processo (o verrà specificata come azione quella di ignorarlo). @@ -720,7 +720,7 @@ GNU, accessibile avendo definito \macro{\_GNU\_SOURCE}, ed 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}. + \param{signum}. \end{prototype} \noindent dato che la stringa è allocata staticamente non se ne deve modificare il contenuto, che resta valido solo fino alla successiva chiamata @@ -1134,14 +1134,14 @@ illustrati in precedenza usare; i possibili valori sono riportati in \label{tab:sig_setitimer_values} \end{table} -Il valore della struttura specificata \param{value} viene usato per impostare il -timer, se il puntatore \param{ovalue} non è nullo il precedente valore viene -salvato qui. I valori dei timer devono essere indicati attraverso una -struttura \type{itimerval}, definita in \figref{fig:file_stat_struct}. +Il valore della struttura specificata \param{value} viene usato per impostare +il timer, se il puntatore \param{ovalue} non è nullo il precedente valore +viene salvato qui. I valori dei timer devono essere indicati attraverso una +struttura \struct{itimerval}, definita in \figref{fig:file_stat_struct}. La struttura è composta da due membri, il primo, \var{it\_interval} definisce il periodo del timer; il secondo, \var{it\_value} il tempo mancante alla -scadenza. Entrambi esprimono i tempi tramite una struttura \var{timeval} che +scadenza. Entrambi esprimono i tempi tramite una struttura \struct{timeval} che permette una precisione fino al microsecondo. Ciascun timer decrementa il valore di \var{it\_value} fino a zero, poi invia @@ -1161,8 +1161,8 @@ struct itimerval \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{itimerval}, che definisce i valori dei timer di - sistema.} + \caption{La struttura \structd{itimerval}, che definisce i valori dei timer + di sistema.} \label{fig:sig_itimerval} \end{figure} @@ -1348,7 +1348,7 @@ Lo standard richiede che la funzione sia implementata in maniera del tutto indipendente da \func{alarm}\footnote{nel caso di Linux questo è fatto utilizzando direttamente il timer del kernel.} e sia utilizzabile senza interferenze con l'uso di \const{SIGALRM}. La funzione prende come parametri -delle strutture di tipo \var{timespec}, la cui definizione è riportata in +delle strutture di tipo \struct{timespec}, la cui definizione è riportata in \figref{fig:sys_timeval_struct}, che permettono di specificare un tempo con una precisione (teorica) fino al nanosecondo. @@ -1775,10 +1775,10 @@ corrente viene restituito indietro. Questo permette (specificando \param{act} nullo e \param{oldact} non nullo) di superare uno dei limiti di \func{signal}, che non consente di ottenere l'azione corrente senza installarne una nuova. -Entrambi i puntatori fanno riferimento alla struttura \var{sigaction}, tramite -la quale si specificano tutte le caratteristiche dell'azione associata ad un -segnale. Anch'essa è descritta dallo standard POSIX.1 ed in Linux è definita -secondo quanto riportato in \figref{fig:sig_sigaction}. Il campo +Entrambi i puntatori fanno riferimento alla struttura \struct{sigaction}, +tramite la quale si specificano tutte le caratteristiche dell'azione associata +ad un segnale. Anch'essa è descritta dallo standard POSIX.1 ed in Linux è +definita secondo quanto riportato in \figref{fig:sig_sigaction}. Il campo \var{sa\_restorer}, non previsto dallo standard, è obsoleto e non deve essere più usato. @@ -1797,7 +1797,7 @@ struct sigaction \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{sigaction}.} + \caption{La struttura \structd{sigaction}.} \label{fig:sig_sigaction} \end{figure} @@ -1853,7 +1853,7 @@ in \tabref{tab:sig_sa_flag}. \secref{sec:sig_specific_features}).\\ \hline \end{tabular} - \caption{Valori del campo \var{sa\_flag} della struttura \var{sigaction}.} + \caption{Valori del campo \var{sa\_flag} della struttura \struct{sigaction}.} \label{tab:sig_sa_flag} \end{table} @@ -1862,7 +1862,7 @@ permette\footnote{La possibilit stata aggiunta nei kernel della serie 2.1.x con l'introduzione dei segnali real-time (vedi \secref{sec:sig_real_time}). In precedenza era possibile ottenere alcune informazioni addizionali usando \var{sa\_handler} con un - secondo parametro addizionale di tipo \var{struct sigcontext}, che adesso è + secondo parametro addizionale di tipo \var{sigcontext}, che adesso è deprecato.} di utilizzare due forme diverse di gestore, da specificare, a seconda dell'uso o meno del flag \const{SA\_SIGINFO}, rispettivamente attraverso i campi \var{sa\_sigaction} o \var{sa\_handler}, @@ -1870,7 +1870,7 @@ rispettivamente attraverso i campi \var{sa\_sigaction} o \var{sa\_handler}, questi vengono addirittura definiti come \ctyp{union}): la prima è quella classica usata anche con \func{signal}, la seconda permette invece di usare un gestore in grado di ricevere informazioni più dettagliate dal sistema, -attraverso la struttura \type{siginfo\_t}, riportata in +attraverso la struttura \struct{siginfo\_t}, riportata in \figref{fig:sig_siginfo_t}. \begin{figure}[!htb] @@ -1896,7 +1896,7 @@ siginfo_t { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{siginfo\_t}.} + \caption{La struttura \structd{siginfo\_t}.} \label{fig:sig_siginfo_t} \end{figure} @@ -1935,9 +1935,9 @@ dati urgenti su un socket\index{socket}. Benché sia possibile usare nello stesso programma sia \func{sigaction} che \func{signal} occorre molta attenzione, in quanto le due funzioni possono interagire in maniera anomala. Infatti l'azione specificata con -\var{sigaction} contiene un maggior numero di informazioni rispetto al -semplice indirizzo del gestore restituito da \func{signal}. Per questo -motivo se si usa quest'ultima per installare un gestore sostituendone uno +\struct{sigaction} contiene un maggior numero di informazioni rispetto al +semplice indirizzo del gestore restituito da \func{signal}. Per questo motivo +se si usa quest'ultima per installare un gestore sostituendone uno precedentemente installato con \func{sigaction}, non sarà possibile effettuare un ripristino corretto dello stesso. @@ -2009,12 +2009,12 @@ permettono si bloccare temporaneamente (o di eliminare completamente, impostando \const{SIG\_IGN} come azione) la consegna dei segnali ad un processo. Questo è fatto specificando la cosiddetta \textsl{maschera dei segnali} (o \textit{signal mask}) del processo\footnote{nel caso di Linux - essa è mantenuta dal campo \var{blocked} della \var{task\_struct} del + essa è mantenuta dal campo \var{blocked} della \struct{task\_struct} del processo.} cioè l'insieme dei segnali la cui consegna è bloccata. Abbiamo accennato in \secref{sec:proc_fork} che la \textit{signal mask} viene ereditata dal padre alla creazione di un processo figlio, e abbiamo visto al paragrafo precedente che essa può essere modificata, durante l'esecuzione di -un gestore, attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}. +un gestore, attraverso l'uso dal campo \var{sa\_mask} di \struct{sigaction}. Uno dei problemi evidenziatisi con l'esempio di \secref{fig:sig_event_wrong} è che in molti casi è necessario proteggere delle sezioni di codice (nel caso in @@ -2279,11 +2279,11 @@ typedef struct { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{stack\_t}.} + \caption{La struttura \structd{stack\_t}.} \label{fig:sig_stack_t} \end{figure} -Il campo \var{ss\_sp} di \var{stack\_t} indica l'indirizzo base dello stack, +Il campo \var{ss\_sp} di \struct{stack\_t} indica l'indirizzo base dello stack, mentre \var{ss\_size} ne indica la dimensione; il campo \var{ss\_flags} invece indica lo stato dello stack. Nell'indicare un nuovo stack occorre inizializzare \var{ss\_sp} e \var{ss\_size} rispettivamente al puntatore e @@ -2400,7 +2400,7 @@ vengono chiamati \textsl{segnali real-time}, in particolare: con un numero minore, che pertanto hanno una priorità maggiore. \item è stata introdotta la possibilità di restituire dei dati al gestore, attraverso l'uso di un campo apposito nella struttura - \type{siginfo\_t} accessibile tramite gestori di tipo + \struct{siginfo\_t} accessibile tramite gestori di tipo \var{sa\_sigaction}. \end{itemize*} @@ -2423,9 +2423,9 @@ real-time. Si tenga presente che questi nuovi segnali non sono associati a nessun evento sepcifico (a meno di non utilizzarli, come vedremo in \secref{sec:file_asyncronous_io}, per l'I/O asincrono) e devono essere inviati -esplicitamente. Tutti i segnali real-time restituiscono al gestore, oltre -ai campi \var{si\_pid} e \var{si\_uid} di \type{siginfo\_t} una struttura -\type{sigval} (riportata in \figref{fig:sig_sigval}) in cui può essere +esplicitamente. Tutti i segnali real-time restituiscono al gestore, oltre ai +campi \var{si\_pid} e \var{si\_uid} di \struct{siginfo\_t} una struttura +\struct{sigval} (riportata in \figref{fig:sig_sigval}) in cui può essere restituito al processo un valore o un indirizzo, che costituisce il meccanismo con cui il segnale è in grado di inviare una ulteriore informazione al processo. @@ -2441,15 +2441,15 @@ union sigval { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \type{sigval}, usata dai segnali real time per + \caption{La struttura \structd{sigval}, usata dai segnali real time per restituire dati al gestore.} \label{fig:sig_sigval} \end{figure} A causa di queste loro caratteristiche, la funzione \func{kill} non è adatta ad inviare un segnale real time, in quanto non è in grado di fornire alcun -valore per \var{sigval}; per questo motivo lo standard ha previsto una nuova -funzione, \func{sigqueue}, il cui prototipo è: +valore per \struct{sigval}; per questo motivo lo standard ha previsto una +nuova funzione, \func{sigqueue}, il cui prototipo è: \begin{prototype}{signal.h} {int sigqueue(pid\_t pid, int signo, const union sigval value)} @@ -2476,17 +2476,17 @@ stessi; un valore nullo di \func{signo} permette di verificare le condizioni di errore senza inviare nessun segnale. Se il segnale è bloccato la funzione ritorna immediatamente, se si è -installato un gestore con \const{SA\_SIGINFO} e ci sono risorse -disponibili, vale a dire che c'è posto nella coda\footnote{la profondità della - coda è indicata dalla costante \const{SIGQUEUE\_MAX}, una della tante - costanti di sistema definite dallo standard POSIX, che non abbiamo riportato +installato un gestore con \const{SA\_SIGINFO} e ci sono risorse disponibili, +vale a dire che c'è posto nella coda\footnote{la profondità della coda è + indicata dalla costante \const{SIGQUEUE\_MAX}, una della tante costanti di + sistema definite dallo standard POSIX, che non abbiamo riportato esplicitamente in \secref{sec:sys_limits}. Il suo valore minimo secondo lo standard, \const{\_POSIX\_SIGQUEUE\_MAX}, è pari a 32.}, esso viene inserito e diventa pendente; una volta consegnato riporterà nel campo \var{si\_code} di -\var{siginfo} il valore \const{SI\_QUEUE} e il campo \var{si\_value} riceverà -quanto inviato con \param{value}. Se invece si è installato un gestore -nella forma classica il segnale sarà generato, ma tutte le caratteristiche -tipiche dei segnali real-time (priorità e coda) saranno perse. +\struct{siginfo} il valore \const{SI\_QUEUE} e il campo \var{si\_value} +riceverà quanto inviato con \param{value}. Se invece si è installato un +gestore nella forma classica il segnale sarà generato, ma tutte le +caratteristiche tipiche dei segnali real-time (priorità e coda) saranno perse. Lo standard POSIX.1b definisce inoltre delle nuove funzioni che permettono di gestire l'attesa di segnali specifici su una coda, esse servono in particolar diff --git a/socket.tex b/socket.tex index 4b875cc..e024bd7 100644 --- a/socket.tex +++ b/socket.tex @@ -318,7 +318,7 @@ nelle varie famiglie di protocolli; questo pone il problema di come passare questi puntatori, il C ANSI risolve questo problema coi i puntatori generici (i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla definizione dello standard ANSI, e per questo nel 1982 fu scelto di definire una struttura -generica per gli indirizzi dei socket, \type{sockaddr}, che si è riportata in +generica per gli indirizzi dei socket, \struct{sockaddr}, che si è riportata in \figref{fig:sock_sa_gen_struct}. \begin{figure}[!htb] @@ -331,7 +331,8 @@ struct sockaddr { }; \end{lstlisting} \end{minipage} - \caption{La struttura generica degli indirizzi dei socket \type{sockaddr}} + \caption{La struttura generica degli indirizzi dei socket + \structd{sockaddr}.} \label{fig:sock_sa_gen_struct} \end{figure} @@ -378,7 +379,7 @@ include in cui sono definiti; la struttura \end{table} In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro -aggiuntivo \var{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi +aggiuntivo \code{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi libri). Questo campo non verrebbe usato direttamente dal programmatore e non è richiesto dallo standard POSIX.1g, in Linux pertanto non esiste. Il campo \type{sa\_family\_t} era storicamente un \ctyp{unsigned short}. @@ -397,7 +398,7 @@ l'uso di questa struttura. I socket di tipo \const{PF\_INET} vengono usati per la comunicazione attraverso internet; la struttura per gli indirizzi per un socket internet -(IPv4) è definita come \type{sockaddr\_in} nell'header file +(IPv4) è definita come \struct{sockaddr\_in} nell'header file \file{netinet/in.h} e secondo le pagine di manuale ha la forma mostrata in \figref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g. @@ -417,7 +418,7 @@ struct in_addr { \end{lstlisting} \end{minipage} \caption{La struttura degli indirizzi dei socket internet (IPv4) - \type{sockaddr\_in}.} + \structd{sockaddr\_in}.} \label{fig:sock_sa_ipv4_struct} \end{figure} @@ -437,7 +438,7 @@ possono usare la funzione \func{bind} su queste porte. Il membro \var{sin\_addr} contiene l'indirizzo internet dell'altro capo della comunicazione, e viene acceduto sia come struttura (un resto di una -implementazione precedente in cui questa era una \texttt{union} usata per +implementazione precedente in cui questa era una \direct{union} usata per accedere alle diverse classi di indirizzi) che come intero. Infine è da sottolineare che sia gli indirizzi che i numeri di porta devono @@ -474,7 +475,7 @@ struct in6_addr { \end{lstlisting} \end{minipage} \caption{La struttura degli indirizzi dei socket IPv6 - \type{sockaddr\_in6}.} + \structd{sockaddr\_in6}.} \label{fig:sock_sa_ipv6_struct} \end{figure} @@ -490,7 +491,7 @@ Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, infine il campo \var{sin6\_scope\_id} è un campo introdotto con il kernel 2.4 per gestire alcune operazioni riguardanti il multicasting. -Si noti che questa struttura è più grande di una \var{sockaddr} generica, +Si noti che questa struttura è più grande di una \struct{sockaddr} generica, quindi occorre stare attenti a non avere fatto assunzioni riguardo alla possibilità di contenere i dati nelle dimensioni di quest'ultima. @@ -518,7 +519,7 @@ struct sockaddr_un { \end{lstlisting} \end{minipage} \caption{La struttura degli indirizzi dei socket locali - \var{sockaddr\_un}.} + \structd{sockaddr\_un}.} \label{fig:sock_sa_local_struct} \end{figure} @@ -612,19 +613,19 @@ funzioni sono: \begin{functions} \headdecl{netinet/in.h} \funcdecl{unsigned long int htonl(unsigned long int hostlong)} - Converte l'intero a 32 bit \var{hostlong} dal formato della macchina a + Converte l'intero a 32 bit \param{hostlong} dal formato della macchina a quello della rete. \funcdecl{unsigned short int htons(unsigned short int hostshort)} - Converte l'intero a 16 bit \var{hostshort} dal formato della macchina a + Converte l'intero a 16 bit \param{hostshort} dal formato della macchina a quello della rete. \funcdecl{unsigned long int ntonl(unsigned long int netlong)} - Converte l'intero a 32 bit \var{netlong} dal formato della rete a quello + Converte l'intero a 32 bit \param{netlong} dal formato della rete a quello della macchina. \funcdecl{unsigned sort int ntons(unsigned short int netshort)} - Converte l'intero a 16 bit \var{netshort} dal formato della rete a quello + Converte l'intero a 16 bit \param{netshort} dal formato della rete a quello della macchina. \bodydesc{Tutte le funzioni restituiscono il valore convertito, e non hanno @@ -685,11 +686,11 @@ di \func{inet\_aton}. La funzione \func{inet\_aton} converte la stringa puntata da \param{src} nell'indirizzo binario che viene memorizzato nell'opportuna struttura -\var{in\_addr} (si veda \secref{fig:sock_sa_ipv4_struct}) situata +\struct{in\_addr} (si veda \secref{fig:sock_sa_ipv4_struct}) situata all'indirizzo dato dall'argomento \param{dest} (è espressa in questa forma in modo da poterla usare direttamente con il puntatore usato per passare la struttura degli indirizzi). La funzione restituesce 0 in caso di successo e 1 -in caso di fallimento. Se usata con \var{dest} inizializzato a \val{NULL} +in caso di fallimento. Se usata con \param{dest} inizializzato a \val{NULL} effettua la validazione dell'indirizzo. L'ultima funzione, \func{inet\_ntoa}, converte il valore a 32 bit @@ -726,7 +727,7 @@ prototipi delle suddette funzioni sono i seguenti: Converte l'indirizzo espresso tramite una stringa nel valore numerico. - \bodydesc{La funzione restituisce un valore negativo se \var{af} specifica + \bodydesc{La funzione restituisce un valore negativo se \param{af} specifica una famiglia di indirizzi non valida, con \var{errno} che assume il valore \errcode{EAFNOSUPPORT}, un valore nullo se \param{src} non rappresenta un indirizzo valido, ed un valore positivo in caso di successo.} @@ -734,9 +735,9 @@ prototipi delle suddette funzioni sono i seguenti: La funzione converte la stringa indicata tramite \param{src} nel valore numerico dell'indirizzo IP del tipo specificato da \param{af} che viene -memorizzato all'indirizzo puntato da \var{addr\_ptr}, la funzione restituisce +memorizzato all'indirizzo puntato da \param{addr\_ptr}, la funzione restituisce un valore positivo in caso di successo, e zero se la stringa non rappresenta -un indirizzo valido, e negativo se \var{af} specifica una famiglia di +un indirizzo valido, e negativo se \param{af} specifica una famiglia di indirizzi non valida. @@ -749,24 +750,24 @@ indirizzi non valida. qual caso \var{errno} assume i valor: \begin{errlist} \item[\errcode{ENOSPC}] le dimensioni della stringa con la conversione - dell'indirizzo eccedono la lunghezza specificata da \var{len}. - \item[\errcode{ENOAFSUPPORT}] la famiglia di indirizzi \var{af} non è una - valida. + dell'indirizzo eccedono la lunghezza specificata da \param{len}. + \item[\errcode{ENOAFSUPPORT}] la famiglia di indirizzi \param{af} non è + una valida. \end{errlist}} \end{prototype} -La funzione converte la struttura dell'indirizzo puntata da \var{addr\_ptr} in -una stringa che viene copiata nel buffer puntato dall'indirizzo \var{dest}; -questo deve essere preallocato dall'utente e la lunghezza deve essere almeno -\const{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e \const{INET6\_ADDRSTRLEN} -per indirizzi IPv6; la lunghezza del buffer deve comunque venire specificata -attraverso il parametro \var{len}. +La funzione converte la struttura dell'indirizzo puntata da \param{addr\_ptr} +in una stringa che viene copiata nel buffer puntato dall'indirizzo +\param{dest}; questo deve essere preallocato dall'utente e la lunghezza deve +essere almeno \const{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e +\const{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve +comunque venire specificata attraverso il parametro \param{len}. Gli indirizzi vengono convertiti da/alle rispettive strutture di indirizzo -(\var{struct in\_addr} per IPv4, e \var{struct in6\_addr} per IPv6), che -devono essere precedentemente allocate e passate attraverso il puntatore -\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere -nullo e deve essere allocato precedentemente. +(una struttura \struct{in\_addr} per IPv4, e una struttura \struct{in6\_addr} +per IPv6), che devono essere precedentemente allocate e passate attraverso il +puntatore \param{addr\_ptr}; l'argomento \param{dest} di \func{inet\_ntop} non +può essere nullo e deve essere allocato precedentemente. Il formato usato per gli indirizzi in formato di presentazione è la notazione \textit{dotted decimal} per IPv4 e quello descritto in @@ -872,7 +873,7 @@ ssize_t SockWrite(int fd, const void *buf, size_t count) return (count); } \end{lstlisting} - \caption{Funzione \func{SockWrite}, scrive \var{count} byte su un socket } + \caption{Funzione \func{SockWrite}, scrive \var{count} byte su un socket.} \label{fig:sock_SockWrite_code} \end{figure} @@ -978,7 +979,7 @@ socket in tutte le chiamate successive. Nel caso la chiamata fallisca si stampa un errore con la relativa routine e si esce. Il passo seguente (\texttt{\small 19--27}) è quello di costruire un'apposita -struttura \type{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed +struttura \struct{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed il numero della porta del servizio. Il primo passo è inizializzare tutto a zero, per poi inserire il tipo di protocollo e la porta (usando per quest'ultima la funzione \func{htons} per convertire il formato dell'intero @@ -1096,7 +1097,7 @@ necessarie in seguito (\texttt{\small 1--18}), come nel caso precedente si sono omesse le parti relative al trattamento delle opzioni da riga di comando. La creazione del socket (\texttt{\small 22--26}) è analoga al caso precedente, -come pure l'inizializzazione della struttura \type{sockaddr\_in}, anche in +come pure l'inizializzazione della struttura \struct{sockaddr\_in}, anche in questo caso si usa la porta standard del servizio daytime, ma come indirizzo IP si il valore predefinito \const{INET\_ANY} che corrisponde ad un indirizzo generico (\texttt{\small 27--31}). diff --git a/system.tex b/system.tex index ec2f1b6..69d6036 100644 --- a/system.tex +++ b/system.tex @@ -535,21 +535,21 @@ struct utsname { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{utsname}.} + \caption{La struttura \structd{utsname}.} \label{fig:sys_utsname} \end{figure} In generale si tenga presente che le dimensioni delle stringe di una -\var{utsname} non è specificata, e che esse sono sempre terminate con -\val{null}; il manuale delle \acr{glibc} indica due diverse dimensioni, +\struct{utsname} non è specificata, e che esse sono sempre terminate con NUL; +il manuale delle \acr{glibc} indica due diverse dimensioni, \const{\_UTSNAME\_LENGTH} per i campi standard e \const{\_UTSNAME\_DOMAIN\_LENGTH} per quello specifico per il nome di dominio; altri sistemi usano nomi diversi come \const{SYS\_NMLN} o \const{\_SYS\_NMLN} o \const{UTSLEN} che possono avere valori diversi.\footnote{Nel caso di Linux -\func{uname} corrisponde in realtà a 3 system call diverse, le prime due usano -rispettivamente delle lunghezze delle stringhe di 9 e 65 byte; la terza usa -anch'essa 65 byte, ma restituisce anche l'ultimo campo, \var{domainname}, con -una lunghezza di 257 byte.} + \func{uname} corrisponde in realtà a 3 system call diverse, le prime due + usano rispettivamente delle lunghezze delle stringhe di 9 e 65 byte; la + terza usa anch'essa 65 byte, ma restituisce anche l'ultimo campo, + \var{domainname}, con una lunghezza di 257 byte.} \section{Opzioni e configurazione del sistema} @@ -886,12 +886,12 @@ informazioni riguardo al filesystem su cui si trova un certo file, sono Queste funzioni permettono di ottenere una serie di informazioni generali riguardo al filesystem su cui si trova il file specificato; queste vengono -restituite una struttura \param{buf} di tipo \type{statfs} definita come in -\figref{fig:sys_statfs}, ed i campi che sono indefiniti per il filesystem in -esame sono impostati a zero. I valori del campo \var{f\_type} sono definiti -per i vari filesystem nei relativi file di header dei sorgenti del kernel da -costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in genere è il -nome del filesystem stesso. +restituite all'indirizzo \param{buf} di una struttura \struct{statfs} definita +come in \figref{fig:sys_statfs}, ed i campi che sono indefiniti per il +filesystem in esame sono impostati a zero. I valori del campo \var{f\_type} +sono definiti per i vari filesystem nei relativi file di header dei sorgenti +del kernel da costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in +genere è il nome del filesystem stesso. \begin{figure}[!htb] \footnotesize \centering @@ -912,18 +912,18 @@ struct statfs { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{statfs}.} + \caption{La struttura \structd{statfs}.} \label{fig:sys_statfs} \end{figure} Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due -file \file{/etc/fstab} ed \file{/etc/mtab}, che convenzionalmente sono usati in -quasi tutti i sistemi unix-like per mantenere rispettivamente le informazioni -riguardo ai filesystem da montare e a quelli correntemente montati. Le -funzioni servono a leggere il contenuto di questi file in opportune strutture -\var{struct fstab} e \var{struct mntent}, e, per \file{/etc/mtab} per inserire -e rimuovere le voci presenti nel file. +file \file{/etc/fstab} ed \file{/etc/mtab}, che convenzionalmente sono usati +in quasi tutti i sistemi unix-like per mantenere rispettivamente le +informazioni riguardo ai filesystem da montare e a quelli correntemente +montati. Le funzioni servono a leggere il contenuto di questi file in +opportune strutture \struct{fstab} e \struct{mntent}, e, per \file{/etc/mtab} +per inserire e rimuovere le voci presenti nel file. In generale si dovrebbero usare queste funzioni (in particolare quelle relative a \file{/etc/mtab}), quando si debba scrivere un programma che @@ -975,7 +975,7 @@ Le due funzioni forniscono le informazioni memorizzate nel database degli utenti (che nelle versioni più recenti possono essere ottenute attraverso PAM) relative all'utente specificato attraverso il suo \acr{uid} o il nome di login. Entrambe le funzioni restituiscono un puntatore ad una struttura di -tipo \type{passwd} la cui definizione (anch'essa eseguita in \file{pwd.h}) è +tipo \struct{passwd} la cui definizione (anch'essa eseguita in \file{pwd.h}) è riportata in \figref{fig:sys_passwd_struct}, dove è pure brevemente illustrato il significato dei vari campi. @@ -996,8 +996,8 @@ struct passwd { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{passwd} contenente le informazioni relative ad un - utente del sistema.} + \caption{La struttura \structd{passwd} contenente le informazioni relative ad + un utente del sistema.} \label{fig:sys_passwd_struct} \end{figure} @@ -1026,15 +1026,15 @@ essere rientranti, per cui ne esistono anche due versioni alternative In questo caso l'uso è molto più complesso, in quanto bisogna prima allocare la memoria necessaria a contenere le informazioni. In particolare i valori -della struttura \var{passwd} saranno restituiti all'indirizzo \param{password} -mentre la memoria allocata all'indirizzo \param{buffer}, per un massimo di -\param{buflen} byte, sarà utilizzata per contenere le stringhe puntate dai -campi di \param{password}. Infine all'indirizzo puntato da \param{result} -viene restituito il puntatore ai dati ottenuti, cioè \param{buffer} nel caso -l'utente esista, o \val{null} altrimenti. Qualora i dati non possano essere -contenuti nei byte specificati da \param{buflen}, la funzione fallirà -restituendo \errcode{ERANGE} (e \param{result} sarà comunque impostato a -\val{null}). +della struttura \struct{passwd} saranno restituiti all'indirizzo +\param{password} mentre la memoria allocata all'indirizzo \param{buffer}, per +un massimo di \param{buflen} byte, sarà utilizzata per contenere le stringhe +puntate dai campi di \param{password}. Infine all'indirizzo puntato da +\param{result} viene restituito il puntatore ai dati ottenuti, cioè +\param{buffer} nel caso l'utente esista, o \val{null} altrimenti. Qualora i +dati non possano essere contenuti nei byte specificati da \param{buflen}, la +funzione fallirà restituendo \errcode{ERANGE} (e \param{result} sarà comunque +impostato a \val{null}). Del tutto analoghe alle precedenti sono le funzioni \func{getgrnam} e \func{getgrgid} (e le relative analoghe rientranti con la stessa estensione @@ -1063,7 +1063,8 @@ loro prototipi sono: Il comportamento di tutte queste funzioni è assolutamente identico alle precedenti che leggono le informazioni sugli utenti, l'unica differenza è che in questo caso le informazioni vengono restituite in una struttura di tipo -\type{group}, la cui definizione è riportata in \figref{fig:sys_group_struct}. +\struct{group}, la cui definizione è riportata in +\figref{fig:sys_group_struct}. \begin{figure}[!htb] \footnotesize @@ -1079,8 +1080,8 @@ struct group { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{group} contenente le informazioni relative ad un - gruppo del sistema.} + \caption{La struttura \structd{group} contenente le informazioni relative ad + un gruppo del sistema.} \label{fig:sys_group_struct} \end{figure} @@ -1223,12 +1224,12 @@ una voce con le funzioni \func{getutent}, \func{getutid}, \func{getutline} e \funcdecl{struct utmp *pututline(struct utmp *ut)} Scrive una voce nel database. - - \bodydesc{Le funzioni ritornano il puntatore ad una struttura \var{utmp} in - caso di successo e \val{null} in caso di errore.} + + \bodydesc{Le funzioni ritornano il puntatore ad una struttura \struct{utmp} + in caso di successo e \val{NULL} in caso di errore.} \end{functions} -Tutte queste funzioni fanno riferimento ad una struttura di tipo \var{utmp}, +Tutte queste funzioni fanno riferimento ad una struttura di tipo \struct{utmp}, la cui definizione in Linux è riportata in \secref{fig:sys_utmp_struct}. Le prime tre funzioni servono per leggere una voce dal database; \func{getutent} legge semplicemente la prima voce disponibile; le altre due permettono di @@ -1257,8 +1258,8 @@ struct utmp \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{utmp} contenente le informazioni di una voce del - database di \textit{accounting}.} + \caption{La struttura \structd{utmp} contenente le informazioni di una voce + del database di \textit{accounting}.} \label{fig:sys_utmp_struct} \end{figure} @@ -1342,13 +1343,13 @@ prototipi sono: \funcdecl{void logwtmp(const char *line, const char *name, const char *host)} Aggiunge nel database di accounting una voce con i valori specificati. - - \bodydesc{Le funzioni ritornano il puntatore ad una struttura \var{utmp} in - caso di successo e \val{null} in caso di errore.} + + \bodydesc{Le funzioni ritornano il puntatore ad una struttura \struct{utmp} + in caso di successo e \val{NULL} in caso di errore.} \end{functions} La prima funzione permette l'aggiunta di una voce a \file{wmtp} specificando -direttamente una struttura \type{utmp}, mentre la seconda utilizza gli +direttamente una struttura \struct{utmp}, mentre la seconda utilizza gli argomenti \param{line}, \param{name} e \param{host} per costruire la voce che poi aggiunge chiamando \func{updwtmp}. @@ -1369,7 +1370,7 @@ permettono di imporre a ciascuno di essi vincoli e limiti di utilizzo. Come abbiamo accennato in \secref{sec:proc_wait4} le informazioni riguardo l'utilizzo delle risorse da parte di un processo è mantenuto in una struttura -di tipo \code{struct }\type{rusage}, la cui definizione (che si trova in +di tipo \struct{rusage}, la cui definizione (che si trova in \file{sys/resource.h}) è riportata in \figref{fig:sys_rusage_struct}. \begin{figure}[!htb] @@ -1398,7 +1399,7 @@ struct rusage { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{rusage} per la lettura delle informazioni dei + \caption{La struttura \structd{rusage} per la lettura delle informazioni dei delle risorse usate da un processo.} \label{fig:sys_rusage_struct} \end{figure} @@ -1420,8 +1421,8 @@ memoria per essere inserito nello swap. In genere includere esplicitamente \file{} non è più necessario, ma aumenta la portabilità, e serve comunque quando, come nella maggior parte -dei casi, si debba accedere ai campi di \var{rusage} relativi ai tempi di -utilizzo del processore, che sono definiti come \code{struct }\type{timeval}. +dei casi, si debba accedere ai campi di \struct{rusage} relativi ai tempi di +utilizzo del processore, che sono definiti come strutture \struct{timeval}. Questa è la stessa struttura utilizzata da \func{wait4} per ricavare la @@ -1463,7 +1464,7 @@ In generale il primo viene chiamato un limite \textsl{soffice} (o \textit{soft limit}) dato che il suo valore può essere aumentato, mentre il secondo è detto \textsl{duro} (o \textit{hard limit}), in quanto un processo normale non può modificarne il valore. Il valore di questi limiti è mantenuto in una -struttura \var{rlimit}, la cui definizione è riportata in +struttura \struct{rlimit}, la cui definizione è riportata in \figref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a limite corrente e massimo. @@ -1479,7 +1480,7 @@ struct rlimit { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{rlimit} per impostare i limiti di utilizzo + \caption{La struttura \structd{rlimit} per impostare i limiti di utilizzo delle risorse usate da un processo.} \label{fig:sys_rlimit_struct} \end{figure} @@ -1514,7 +1515,7 @@ prototipi sono: Entrambe le funzioni permettono di specificare su quale risorsa si vuole operare attraverso \param{resource}, i cui possibili valori sono elencati in -\secref{tab:sys_rlimit_values}, e utilizzano una struttura \var{rlimit} per +\secref{tab:sys_rlimit_values}, e utilizzano una struttura \struct{rlimit} per specificarne i valori. \begin{table}[htb] @@ -1788,7 +1789,7 @@ possono essere letti attraverso la funzione \func{times}, il cui prototipo \end{prototype} La funzione restituisce i valori di process time del processo corrente in una -struttura di tipo \var{tms}, la cui definizione è riportata in +struttura di tipo \struct{tms}, la cui definizione è riportata in \secref{fig:sys_tms_struct}. La struttura prevede quattro campi; i primi due, \var{tms\_utime} e \var{tms\_stime}, sono l'\textit{user time} ed il \textit{system time} del processo, così come definiti in @@ -1808,7 +1809,7 @@ struct tms { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{tms} dei tempi di processore associati a un + \caption{La struttura \structd{tms} dei tempi di processore associati a un processo.} \label{fig:sys_tms_struct} \end{figure} @@ -1886,8 +1887,8 @@ sono: \errval{EPERM}.} \end{functions} -Queste funzioni utilizzano una struttura di tipo \var{timeval}, la cui -definizione, insieme a quella della analoga \var{timespec}, è riportata in +Queste funzioni utilizzano una struttura di tipo \struct{timeval}, la cui +definizione, insieme a quella della analoga \struct{timespec}, è riportata in \figref{fig:sys_timeval_struct}. Le \acr{glibc} infatti forniscono queste due rappresentazioni alternative del \textit{calendar time} che rispetto a \type{time\_t} consentono rispettivamente precisioni del microsecondo e del @@ -1911,7 +1912,7 @@ struct timespec { \end{lstlisting} \end{minipage} \normalsize - \caption{Le strutture \var{timeval} e \var{timespec} usate per una + \caption{Le strutture \structd{timeval} e \structd{timespec} usate per una rappresentazione ad alta risoluzione del \textit{calendar time}.} \label{fig:sys_timeval_struct} \end{figure} @@ -1920,8 +1921,8 @@ Come nel caso di \func{stime} anche \func{settimeofday} (e qualunque funzione vada a modificare l'orologio di sistema, come quelle che tratteremo in seguito) può essere utilizzata solo da un processo coi privilegi di amministratore. Il secondo parametro di entrambe le funzioni è una struttura -\var{timezone}, che storicamente veniva utilizzata per specificare appunto la -\textit{time zone}, cioè l'insieme del fuso orario e delle convenzioni per +\struct{timezone}, che storicamente veniva utilizzata per specificare appunto +la \textit{time zone}, cioè l'insieme del fuso orario e delle convenzioni per l'ora legale che permettevano il passaggio dal tempo universale all'ora locale. Questo parametro è obsoleto e in Linux non è mai stato utilizzato e non è supportato né dalle vecchie \textsl{libc5}, né dalle \textsl{glibc}: @@ -1964,11 +1965,11 @@ modificare anche la velocit assumerà i valori \errval{EFAULT}, \errval{EINVAL} ed \errval{EPERM}.} \end{prototype} -La funzione richiede una struttura di tipo \var{timex}, la cui definizione, +La funzione richiede una struttura di tipo \struct{timex}, la cui definizione, così come effettuata in \file{sys/timex.h}, è riportata in \figref{fig:sys_timex_struct}. L'azione della funzione dipende dal valore del campo \var{mode}, che specifica quale parametro dell'orologio di sistema, -specificato in un opportuno campo di \var{timex}, deve essere impostato. Un +specificato in un opportuno campo di \struct{timex}, deve essere impostato. Un valore nullo serve per leggere i parametri correnti; i valori diversi da zero devono essere specificati come OR binario delle costanti riportate in \secref{tab:sys_timex_mode}. @@ -2001,7 +2002,8 @@ struct timex { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{timex} per il controllo dell'orologio di sistema.} + \caption{La struttura \structd{timex} per il controllo dell'orologio di + sistema.} \label{fig:sys_timex_struct} \end{figure} @@ -2012,7 +2014,7 @@ anche un suo omonimo \func{ntp\_adjtime}. La trattazione completa di questa funzione necessita di una lettura approfondita del meccanismo descritto nell'RFC~1305, ci limitiamo a descrivere in \tabref{tab:sys_timex_mode} i principali valori utilizzabili per il campo \var{mode}, un elenco più -dettagliato del significato dei vari campi della struttura \var{timex} può +dettagliato del significato dei vari campi della struttura \struct{timex} può essere ritrovato in \cite{glibc}. \begin{table}[htb] @@ -2027,33 +2029,33 @@ essere ritrovato in \cite{glibc}. reale e l'orologio di sistema, che deve essere indicata in microsecondi nel campo \var{offset} di - \var{timex}.\\ + \struct{timex}.\\ \const{ADJ\_FREQUENCY} & 0x0002 & Imposta la differenze in frequenza fra il tempo reale e l'orologio di sistema, che deve essere indicata in parti per milione nel campo - \var{frequency} di \var{timex}.\\ + \var{frequency} di \struct{timex}.\\ \const{ADJ\_MAXERROR} & 0x0004 & Imposta il valore massimo dell'errore sul tempo, espresso in microsecondi nel campo \var{maxerror} di - \var{timex}.\\ + \struct{timex}.\\ \const{ADJ\_ESTERROR} & 0x0008 & Imposta la stima dell'errore sul tempo, espresso in microsecondi nel campo \var{esterror} di - \var{timex}.\\ + \struct{timex}.\\ \const{ADJ\_STATUS} & 0x0010 & Imposta alcuni valori di stato interni usati dal sistema nella gestione dell'orologio specificati nel campo - \var{status} di \var{timex}.\\ + \var{status} di \struct{timex}.\\ \const{ADJ\_TIMECONST} & 0x0020 & Imposta la larghezza di banda del PLL implementato dal kernel, specificato nel campo - \var{constant} di \var{timex}.\\ + \var{constant} di \struct{timex}.\\ \const{ADJ\_TICK} & 0x4000 & Imposta il valore dei tick del timer in microsecondi, espresso nel campo - \var{tick} di \var{timex}.\\ + \var{tick} di \struct{timex}.\\ \const{ADJ\_OFFSET\_SINGLESHOT}&0x8001&Imposta uno spostamento una tantum dell'orologio secondo il valore del campo \var{offset} simulando il @@ -2061,7 +2063,7 @@ essere ritrovato in \cite{glibc}. \hline \end{tabular} \caption{Costanti per l'assegnazione del valore del campo \var{mode} della - struttura \var{timex}.} + struttura \struct{timex}.} \label{tab:sys_timex_mode} \end{table} @@ -2129,12 +2131,12 @@ struct tm { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{tm} per una rappresentazione del tempo in termini - di ora, minuti, secondi, ecc.} + \caption{La struttura \structd{tm} per una rappresentazione del tempo in + termini di ora, minuti, secondi, ecc.} \label{fig:sys_tm_struct} \end{figure} -Questo viene effettuato attraverso una opportuna struttura \var{tm}, la cui +Questo viene effettuato attraverso una opportuna struttura \struct{tm}, la cui definizione è riportata in \figref{fig:sys_tm_struct}, ed è in genere questa struttura che si utilizza quando si deve specificare un tempo a partire dai dati naturali (ora e data), dato che essa consente anche di trattare la @@ -2189,7 +2191,7 @@ l'utente deve specificare il buffer su cui la stringa deve essere copiata (deve essere di almeno 26 caratteri). Le altre tre funzioni, \func{gmtime}, \func{localtime} e \func{mktime} servono -per convertire il tempo dal formato \type{time\_t} a quello di \var{tm} e +per convertire il tempo dal formato \type{time\_t} a quello di \struct{tm} e viceversa; \func{gmtime} effettua la conversione usando il tempo coordinato universale (UTC), cioè l'ora di Greenwich; mentre \func{localtime} usa l'ora locale; \func{mktime} esegue la conversione inversa. @@ -2206,7 +2208,7 @@ locale, compresa l'eventuale ora legale. Questo viene fatto attraverso le tre variabili globali mostrate in \figref{fig:sys_tzname}, cui si accede quando si include \file{time.h}. Queste variabili vengono impostate quando si chiama una delle precedenti funzioni di conversione, oppure invocando direttamente la -funzione \func{tzset}, il cui prototipo è: +funzione \funcd{tzset}, il cui prototipo è: \begin{prototype}{sys/timex.h} {void tzset(void)} @@ -2354,7 +2356,7 @@ normale. I valori che può assumere \var{errno} sono riportati in \capref{cha:errors}, nell'header \file{errno.h} sono anche definiti i nomi simbolici per le costanti numeriche che identificano i vari errori; essi iniziano tutti per -\var{E} e si possono considerare come nomi riservati. In seguito faremo +\val{E} e si possono considerare come nomi riservati. In seguito faremo sempre riferimento a tali valori, quando descriveremo i possibili errori restituiti dalle funzioni. Il programma di esempio \cmd{errcode} stampa il codice relativo ad un valore numerico con l'opzione \cmd{-l}. @@ -2430,13 +2432,13 @@ automatizzata sullo standard error (vedi \secref{sec:file_std_descr}) \func{perror}, il cui prototipo è: \begin{prototype}{stdio.h}{void perror(const char *message)} Stampa il messaggio di errore relativo al valore corrente di \var{errno} - sullo standard error; preceduto dalla stringa \var{message}. + sullo standard error; preceduto dalla stringa \param{message}. \end{prototype} I messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati in \capref{cha:errors}), e, usando il valore corrente di \var{errno}, si riferiscono all'ultimo errore avvenuto. La stringa specificata con -\var{message} viene stampato prime del messaggio d'errore, seguita dai due +\param{message} viene stampato prime del messaggio d'errore, seguita dai due punti e da uno spazio, il messaggio è terminato con un a capo. Il messaggio può essere riportato anche usando altre variabili globali