\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:
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:
\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)}
\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
\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
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,
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
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
\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
\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
\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
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
\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
\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
\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
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}
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
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 è:
\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
\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
\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.
(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},
\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
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}).
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
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.
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 è
\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}
\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
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}
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)}
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}
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}
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}
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}
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}.
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:
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.
\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}
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}
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
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.
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}
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}
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}.
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}).}
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
\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
\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}
\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:
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
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.
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}.
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}
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.
\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.
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
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
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
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},
\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
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.
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}
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]
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:
\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.
\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
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:
\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},
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},
\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}
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
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.
\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},
\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
\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}
\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).
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:
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.
\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
\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}
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.
\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
\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
\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.
\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 \\
\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}
\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:
\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 \\
\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
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}
\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:
\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
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
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
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
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
\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
\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}.}
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'è
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.
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
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}).
\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},
\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
\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}. \\
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
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
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}
\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
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}.}
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
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.
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
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:
\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}
\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
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}}
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.
\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
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
\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
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
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}
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
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}.
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
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}
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
\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},
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
\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}
\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
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
\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}
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.
\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,
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.
\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
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.
\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
}
\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
\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
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}.
\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}.
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.
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.
\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
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
\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
\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
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
\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
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
\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]
\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.
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
\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.
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.
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.
(\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.
\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:
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
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.
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.
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.
\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}%
}
\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.)
\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.
\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}
\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}
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
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 è
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}
\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}
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.
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
\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}
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
\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
\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
\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}
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}}
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.
\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}.
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
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
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
\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.
(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}
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
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
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}
\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}
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
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.
\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}
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.
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ù
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)}
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}
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]
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}
\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
\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.
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.
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}
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 è
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 è:
\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}
analizzare lo stato di uscita. Esse sono definite sempre in
\file{<sys/wait.h>} 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
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}.
\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
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}
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
\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]
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
\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}.}
\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}.}
\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}.}
\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}.}
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
\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}).
\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
\end{lstlisting}
\end{minipage}
\normalsize
- \caption{La struttura \var{sched\_param}.}
+ \caption{La struttura \structd{sched\_param}.}
\label{fig:sig_sched_param}
\end{figure}
\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}).
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
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
\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}
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.
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,
\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}
\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
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]
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.}
\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}
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}
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
\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}
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}
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
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
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).
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
\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
\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}
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.
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.
\end{lstlisting}
\end{minipage}
\normalsize
- \caption{La struttura \var{sigaction}.}
+ \caption{La struttura \structd{sigaction}.}
\label{fig:sig_sigaction}
\end{figure}
\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}
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},
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]
\end{lstlisting}
\end{minipage}
\normalsize
- \caption{La struttura \type{siginfo\_t}.}
+ \caption{La struttura \structd{siginfo\_t}.}
\label{fig:sig_siginfo_t}
\end{figure}
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.
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
\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
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*}
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.
\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)}
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
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]
};
\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}
\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}.
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.
\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}
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
\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}
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.
\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}
\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
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
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.}
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.
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
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}
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
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}).
\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}
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
\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
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.
\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}
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
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
\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}
\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
\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}
\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}.
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]
\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}
In genere includere esplicitamente \file{<sys/time.h>} 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
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.
\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}
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]
\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
\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}
\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
\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}
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}:
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}.
\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}
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]
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
\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}
\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
(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.
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)}
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}.
\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