+2004-01-13 Simone Piccardi <piccardi@anarres.truelite.it>
+
+ * intro.tex: Varie correzioni di ortografia e sintassi da parte di
+ Massimo Fidanza.
+
2003-12-31 Simone Piccardi <piccardi@anarres.truelite.it>
* tcpsock.tex: Corretto su segnalazione di Enzo.
I/O.
-\subsection{La problematica dell'\textit{I/O multiplexing} e l'uso
- dell'\textsl{I/O non-bloccante}}
+\subsection{La problematica dell'\textit{I/O multiplexing}}
\label{sec:file_noblocking}
Abbiamo visto in \secref{sec:sig_gen_beha}, affrontando la suddivisione fra
-\textit{fast} e \textit{slow} system call, che in certi casi le funzioni di
-I/O possono bloccarsi indefinitamente.\footnote{si ricordi però che questo può
- accadere solo per le pipe, i socket\index{socket} ed alcuni file di
- dispositivo\index{file!di dispositivo}; sui file normali le funzioni di
- lettura e scrittura ritornano sempre subito.} Ad esempio le operazioni di
-lettura possono bloccarsi quando non ci sono dati disponibili sul descrittore
-su cui si sta operando.
+\textit{fast} e \textit{slow} system call,\index{system call lente} che in
+certi casi le funzioni di I/O possono bloccarsi indefinitamente.\footnote{si
+ ricordi però che questo può accadere solo per le pipe, i
+ socket\index{socket} ed alcuni file di dispositivo\index{file!di
+ dispositivo}; sui file normali le funzioni di lettura e scrittura
+ ritornano sempre subito.} Ad esempio le operazioni di lettura possono
+bloccarsi quando non ci sono dati disponibili sul descrittore su cui si sta
+operando.
Questo comportamento causa uno dei problemi più comuni che ci si trova ad
affrontare nelle operazioni di I/O, che si verifica quando si deve operare con
può fare conto sul fatto che all'arrivo di un segnale essa verrebbe interrotta
e si potrebbero eseguire di conseguenza le operazioni relative al segnale e
alla gestione dati con un ciclo del tipo:
-\includecodesnip{listati/select_race.c}
-qui però emerge una race condition, perché se il segnale arriva prima della
+\includecodesnip{listati/select_race.c} qui però emerge una race
+condition,\index{race condition} perché se il segnale arriva prima della
chiamata a \func{select}, questa non verrà interrotta, e la ricezione del
segnale non sarà rilevata.
presente in Linux, e non hanno nulla a che fare con i file \textit{stream}
delle librerie standard del C.} è da questi che derivano i nomi di alcune
costanti, in quanto per essi sono definite tre classi di dati:
-\textsl{normali}, \textit{prioritari} ed \textit{urgenti}.} In Linux la
+\textsl{normali}, \textit{prioritari} ed \textit{urgenti}. In Linux la
distinzione ha senso solo per i dati \textit{out-of-band} dei socket (vedi
\secref{sec:TCP_urgent_data}), ma su questo e su come \func{poll} reagisce
alle varie condizioni dei socket torneremo in \secref{sec:TCP_serv_poll}, dove
%da fare
-\section{Altre modalità e funzioni di I/O avanzato}
-\label{sec:file_advanced_io}
+\section{L'accesso \textsl{asincrono} ai file}
+\label{sec:file_asyncronous_access}
Benché l'\textit{I/O multiplexing} sia stata la prima, e sia tutt'ora una fra
-le più diffuse modalità di gestire l'I/O in situazioni complesse che
-coivolgono molti file, esistono altre modalità di gestione delle stesse
-problematiche, oltre che differenti interfacce per la gestione di altre
-problematiche avanzate riguardanti l'I/O su file, tratteremo tutto ciò in
-questa sezione.
-
+le più diffuse modalità di gestire l'I/O in situazioni complesse in cui si
+debba operare su più file contemporaneamente, esistono altre modalità di
+gestione delle stesse problematiche. In particolare sono importanti in questo
+contesto le modalità di accesso ai file eseguibili in maniera
+\textsl{asincrona}, senza cioè che un processo debba bloccarsi, ed utilizzi
+invece un meccanismo di notifica asincrono, come un segnale, per rilevare la
+possibilità di eseguire le operazioni volute.
-\subsection{L'apertura asincrona dei file}
-\label{sec:file_asyncronous_open}
-Una modalità alternativa all'uso dell'\textit{I/O multiplexing} per gestione
-dell'I/O simultaneo su molti file, è costituita dal cosiddetto \textsl{I/O
- asincrono}. Il concetto base dell'\textsl{I/O asincrono} è che le funzioni
-di I/O non attendono il completamento delle operazioni prima di ritornare,
-così che il processo non viene bloccato. In questo modo diventa ad esempio
-possibile effettuare una richiesta preventiva di dati, in modo da poter
-effettuare in contemporanea le operazioni di calcolo e quelle di I/O.
+\subsection{Operazioni asincrone sui file}
+\label{sec:file_asyncronous_operation}
Abbiamo accennato in \secref{sec:file_open} che è possibile, attraverso l'uso
del flag \const{O\_ASYNC},\footnote{l'uso del flag di \const{O\_ASYNC} e dei
l'uso di \func{fcntl} con il comando \const{F\_SETFL} (vedi
\secref{sec:file_fcntl}).
-In realtà in questo caso non si tratta di I/O asincrono vero e proprio (che
-vedremo in \secref{sec:file_asyncronous_io}), quanto di un meccanismo
-asincrono di notifica delle variazione dello stato del file descriptor; quello
-che succede è che il sistema genera un segnale (normalmente \const{SIGIO}, ma
-è possibile usarne altri) tutte le volte che diventa possibile leggere o
-scrivere dal file descriptor che si è posto in questa modalità. Si può inoltre
-selezionare, con il comando \const{F\_SETOWN} di \func{fcntl}, quale processo
-(o gruppo di processi) riceverà il segnale. Se pertanto si effettuano le
-operazioni in risposta alla ricezione del segnale non ci sarà più la necessità
-di restare bloccati in attesa della disponibilità di accesso ai file.
+In realtà in questo caso non si tratta di eseguire delle operazioni di lettura
+o scrittura del file in modo asincrono (tratteremo questo, che più
+propriamente è detto \textsl{I/O asincrono} in
+\secref{sec:file_asyncronous_io}), quanto di un meccanismo asincrono di
+notifica delle variazione dello stato del file descriptor aperto in questo
+modo.
+
+Quello che succede è che il sistema genera un segnale (normalmente
+\const{SIGIO}, ma è possibile usarne altri con il comando \const{F\_SETSIG} di
+\func{fcntl}) tutte le volte che diventa possibile leggere o scrivere dal file
+descriptor che si è posto in questa modalità. Si può inoltre selezionare, con
+il comando \const{F\_SETOWN} di \func{fcntl}, quale processo (o gruppo di
+processi) riceverà il segnale. Se pertanto si effettuano le operazioni in
+risposta alla ricezione del segnale non ci sarà più la necessità di restare
+bloccati in attesa della disponibilità di accesso ai file.
In questo modo si può evitare l'uso delle funzioni \func{poll} o \func{select}
che, quando vengono usate con un numero molto grande di file descriptor, non
percentuale) sono diventati attivi.
Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
-presenta notevoli problemi, dato che non è possibile determinare, quando sono
-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 \struct{siginfo\_t}, utilizzando la forma estesa
-\var{sa\_sigaction} del gestore (si riveda quanto illustrato in
+presenta notevoli problemi, dato che non è possibile determinare, quando i
+file descriptor sono più di uno, qual'è quello responsabile dell'emissione del
+segnale; inoltre dato che i segnali normali non si accumulano, in presenza di
+più file descriptor attivi contemporaneamente, più segnali emessi nello stesso
+tempo verrebbero notificati una volta sola. Linux però supporta le estensioni
+POSIX.1b dei segnali real-time, che possono accumularsi e che permettono di
+riconoscere il file descriptor facendo ricorso alle informazioni aggiuntive
+restituite attraverso la struttura \struct{siginfo\_t}, utilizzando la forma
+estesa \var{sa\_sigaction} del gestore (si riveda quanto illustrato in
\secref{sec:sig_sigaction}).
Per far questo però occorre utilizzare le funzionalità dei segnali real-time
(vedi \secref{sec:sig_real_time}) impostando esplicitamente con il comando
\const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
I/O asincrono (il segnale predefinito è \const{SIGIO}). In questo caso il
-gestore tutte le volte che riceverà \const{SI\_SIGIO} come valore del
+gestore, tutte le volte che riceverà \const{SI\_SIGIO} come valore del
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
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 \const{SIGIO}, su cui si accumuleranno tutti i segnali
-in eccesso, e si dovrà determinare al solito modo quali sono i file diventati
+in eccesso, e si dovrà determinare con un ciclo quali sono i file diventati
attivi.
+
\subsection{L'interfaccia POSIX per l'I/O asincrono}
\label{sec:file_asyncronous_io}
+Una modalità alternativa all'uso dell'\textit{I/O multiplexing} per gestione
+dell'I/O simultaneo su molti file è costituita dal cosiddetto \textsl{I/O
+ asincrono}. Il concetto base dell'\textsl{I/O asincrono} è che le funzioni
+di I/O non attendono il completamento delle operazioni prima di ritornare,
+così che il processo non viene bloccato. In questo modo diventa ad esempio
+possibile effettuare una richiesta preventiva di dati, in modo da poter
+effettuare in contemporanea le operazioni di calcolo e quelle di I/O.
+
Benché la modalità di apertura asincrona di un file possa risultare utile in
varie occasioni (in particolar modo con i socket\index{socket} e gli altri
-file per i quali le funzioni di I/O sono system call lente), essa è comunque
-limitata alla notifica della disponibilità del file descriptor per le
-operazioni di I/O, e non ad uno svolgimento asincrono delle medesime. Lo
-standard POSIX.1b definisce anche una interfaccia apposita per l'I/O
-asincrono, che prevede un insieme di funzioni dedicate, completamente separate
-rispetto a quelle usate normalmente.
+file per i quali le funzioni di I/O sono \index{system call lente}system call
+lente), essa è comunque limitata alla notifica della disponibilità del file
+descriptor per le operazioni di I/O, e non ad uno svolgimento asincrono delle
+medesime. Lo standard POSIX.1b definisce una interfaccia apposita per l'I/O
+asincrono vero e proprio, che prevede un insieme di funzioni dedicate per la
+lettura e la scrittura dei file, completamente separate rispetto a quelle
+usate normalmente.
In generale questa interfaccia è completamente astratta e può essere
implementata sia direttamente nel kernel, che in user space attraverso l'uso
di \struct{aiocb}.
+\section{Altre modalità di I/O avanzato}
+\label{sec:file_advanced_io}
+
+Oltre alle precedenti modalità di \textit{I/O multiplexing} e \textsl{I/O
+ asincrono}, esistono altre funzioni che implementano delle modalità di
+accesso ai file più evolute rispetto alle normali funzioni di lettura e
+scrittura che abbiamo esaminato in \secref{sec:file_base_func}. In questa
+sezione allora prenderemo in esame le interfacce per l'\textsl{I/O
+ vettorizzato} e per l'\textsl{I/O mappato in memoria}.
+
\subsection{I/O vettorizzato}
\label{sec:file_multiple_io}
illustrato in \figref{fig:file_mmap_layout}, una sezione del file viene
riportata direttamente nello spazio degli indirizzi del programma. Tutte le
operazioni su questa zona verranno riportate indietro sul file dal meccanismo
-della memoria virtuale che trasferirà il contenuto di quel segmento sul file
-invece che nella swap, per cui si può parlare tanto di file mappato in
-memoria, quanto di memoria mappata su file.
+della memoria virtuale\index{memoria virtuale} che trasferirà il contenuto di
+quel segmento sul file invece che nella swap, per cui si può parlare tanto di
+file mappato in memoria, quanto di memoria mappata su file.
\begin{figure}[htb]
\centering
istante.
Infatti, dato che l'accesso è fatto direttamente attraverso la memoria
-virtuale, la sezione di memoria mappata su cui si opera sarà a sua volta letta
-o scritta sul file una pagina alla volta e solo per le parti effettivamente
-usate, il tutto in maniera completamente trasparente al processo; l'accesso
-alle pagine non ancora caricate avverrà allo stesso modo con cui vengono
-caricate in memoria le pagine che sono state salvate sullo swap. Infine in
-situazioni in cui la memoria è scarsa, le pagine che mappano un file vengono
-salvate automaticamente, così come le pagine dei programmi vengono scritte
-sulla swap; questo consente di accedere ai file su dimensioni il cui solo
-limite è quello dello spazio di indirizzi disponibile, e non della memoria su
-cui possono esserne lette delle porzioni.
+virtuale,\index{memoria virtuale} la sezione di memoria mappata su cui si
+opera sarà a sua volta letta o scritta sul file una pagina alla volta e solo
+per le parti effettivamente usate, il tutto in maniera completamente
+trasparente al processo; l'accesso alle pagine non ancora caricate avverrà
+allo stesso modo con cui vengono caricate in memoria le pagine che sono state
+salvate sullo swap. Infine in situazioni in cui la memoria è scarsa, le
+pagine che mappano un file vengono salvate automaticamente, così come le
+pagine dei programmi vengono scritte sulla swap; questo consente di accedere
+ai file su dimensioni il cui solo limite è quello dello spazio di indirizzi
+disponibile, e non della 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 è \funcd{mmap}, che serve ad eseguire la mappatura
Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
piuttosto complessi, essi si possono comprendere solo tenendo presente che
tutto quanto è comunque basato sul basato sul meccanismo della memoria
-virtuale. Questo comporta allora una serie di conseguenze. La più ovvia è che
-se si cerca di scrivere su una zona mappata in sola lettura si avrà
-l'emissione di un segnale di violazione di accesso (\const{SIGSEGV}), dato che
-i permessi sul segmento di memoria relativo non consentono questo tipo di
-accesso.
+virtuale.\index{memoria virtuale} Questo comporta allora una serie di
+conseguenze. La più ovvia è che se si cerca di scrivere su una zona mappata in
+sola lettura si avrà l'emissione di un segnale di violazione di accesso
+(\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non
+consentono questo tipo di accesso.
\begin{figure}[!htb]
\centering
descriptor, che non riguardano la normale lettura e scrittura di dati, ma la
gestione sia delle loro proprietà, che di tutta una serie di ulteriori
funzionalità che il kernel può mettere a disposizione.\footnote{ad esempio si
- gestiscono con questa funzione l'I/O asincrono (vedi
- \secref{sec:file_asyncronous_io}) e il file locking\index{file!locking}
- (vedi \secref{sec:file_locking}).}
+ gestiscono con questa funzione varie modalità di I/O asincrono (vedi
+ \secref{sec:file_asyncronous_operation}) e il file
+ locking\index{file!locking} (vedi \secref{sec:file_locking}).}
-Per queste operazioni di manipolazione e di controllo su proprietà e
-caratteristiche un file descriptor, viene usata la funzione \funcd{fcntl}, il
-cui prototipo è:
+Per queste operazioni di manipolazione e di controllo delle varie proprietà e
+caratteristiche di un file descriptor, viene usata la funzione \funcd{fcntl},
+il cui prototipo è:
\begin{functions}
\headdecl{unistd.h}
\headdecl{fcntl.h}
\end{errlist}}
\end{functions}
-Il comportamento di questa funzione è determinato dal valore del comando
-\param{cmd} che le viene fornito; in \secref{sec:file_dup} abbiamo incontrato
-un esempio per la duplicazione dei file descriptor, una lista dei possibili
-valori è riportata di seguito:
+
+Il primo argomento della funzione è sempre il numero di file descriptor
+\var{fd} su cui si vuole operare. Il comportamento di questa funzione, il
+numero e il tipo degli argomenti, il valore di ritorno e gli eventuali errori
+sono determinati dal valore dell'argomento \param{cmd} che in sostanza
+corrisponde all'esecuzione di un determinato \textsl{comando}; in
+\secref{sec:file_dup} abbiamo incontrato un esempio dell'uso di \func{fcntl}
+per la duplicazione dei file descriptor, una lista di tutti i possibili valori
+per \var{cmd} è 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 \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
- descrittori consentito.
+ maggiore o uguale ad \param{arg} e ne fa una copia di \param{fd}. Ritorna il
+ nuovo file descriptor in caso di successo e -1 in caso di errore. 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 descrittori consentito.
\item[\const{F\_SETFD}] imposta il valore del \textit{file descriptor flag} al
valore specificato con \param{arg}. Al momento l'unico bit usato è quello di
\textit{close-on-exec}\index{close-on-exec}, identificato dalla costante
\const{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella
- esecuzione di una \func{exec} (vedi \secref{sec:proc_exec}).
+ esecuzione di una \func{exec} (vedi \secref{sec:proc_exec}). Ritorna un
+ valore nullo in caso di successo e -1 in caso di errore.
\item[\const{F\_GETFD}] ritorna il valore del \textit{file descriptor flag} di
- \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},
- permette cioè di rileggere quei bit impostati da \func{open} all'apertura del
- file che vengono memorizzati (quelli riportati nella prima e terza sezione
- di \tabref{tab:file_open_flags}).
+ \param{fd} o -1 in caso di errore; 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} in
+ caso di successo o -1 in caso di errore; permette cioè di rileggere quei bit
+ impostati da \func{open} all'apertura del file che vengono memorizzati
+ (quelli riportati nella prima e terza sezione di
+ \tabref{tab:file_open_flags}).
\item[\const{F\_SETFL}] imposta il \textit{file status flag} al valore
- specificato da \param{arg}, possono essere impostati solo i bit riportati
- nella terza sezione di \tabref{tab:file_open_flags}.\footnote{la pagina di
- manuale riporta come impostabili solo \const{O\_APPEND},
- \const{O\_NONBLOCK} e \const{O\_ASYNC}.}
+ specificato da \param{arg}, ritorna un valore nullo in caso di successo o -1
+ in caso di errore. Possono essere impostati solo i bit riportati nella terza
+ sezione di \tabref{tab:file_open_flags}.\footnote{la pagina di manuale
+ riporta come impostabili solo \const{O\_APPEND}, \const{O\_NONBLOCK} e
+ \const{O\_ASYNC}.}
\item[\const{F\_GETLK}] richiede un controllo sul file lock specificato da
- \param{lock}, sovrascrivendo la struttura da esso puntata con il risultato
- (questa funzionalità è trattata in dettaglio in
- \secref{sec:file_posix_lock}).
+ \param{lock}, sovrascrivendo la struttura da esso puntata con il risultato,
+ ritorna un valore nullo in caso di successo o -1 in caso di errore. Questa
+ funzionalità è trattata in dettaglio in \secref{sec:file_posix_lock}.
\item[\const{F\_SETLK}] richiede o rilascia un file lock a seconda di quanto
specificato nella struttura puntata da \param{lock}. Se il lock è tenuto da
qualcun'altro ritorna immediatamente restituendo -1 e imposta \var{errno} a
- \errcode{EACCES} o \errcode{EAGAIN} (questa funzionalità è trattata in
- dettaglio in \secref{sec:file_posix_lock}).
+ \errcode{EACCES} o \errcode{EAGAIN}, in caso di successo ritorna un valore
+ nullo. Questa funzionalità è trattata in dettaglio in
+ \secref{sec:file_posix_lock}.
\item[\const{F\_SETLKW}] identica a \const{F\_SETLK} eccetto per il fatto che
la funzione non ritorna subito ma attende che il blocco sia rilasciato. Se
l'attesa viene interrotta da un segnale la funzione restituisce -1 e imposta
- \var{errno} a \errcode{EINTR} (questa funzionalità è trattata in dettaglio in
- \secref{sec:file_posix_lock}).
+ \var{errno} a \errcode{EINTR}, in caso di successo ritorna un valore nullo.
+ Questa funzionalità è trattata in dettaglio in \secref{sec:file_posix_lock}.
\item[\const{F\_GETOWN}] restituisce il \acr{pid} del processo o
l'identificatore del process group\footnote{i \texttt{process group} sono
- (vedi \secref{sec:sess_proc_group}) sono raggruppamenti di processi usati
- 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 \param{fd}. Nel caso di un process group viene
- restituito un valore negativo il cui valore assoluto corrisponde
- all'identificatore del process group.
+ (vedi \secref{sec:sess_proc_group}) raggruppamenti di processi usati 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 \param{fd}. Nel caso di un process group viene restituito un
+ valore negativo il cui valore assoluto corrisponde all'identificatore del
+ process group. In caso di errore viene restituito -1.
\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 \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.
+ descriptor \param{fd}, ritorna un valore nullo in caso di successo o -1 in
+ caso di errore. Come per \const{F\_GETOWN}, per impostare un
+ \textit{process group} si deve usare per \param{arg} un valore negativo, il
+ cui valore assoluto corrisponde all'identificatore del \textit{process
+ group}.
\item[\const{F\_GETSIG}] restituisce il valore del segnale inviato quando ci
sono dati disponibili in ingresso su un file descriptor aperto ed impostato
per l'I/O asincrono (si veda \secref{sec:file_asyncronous_io}). Il valore 0
indica il valore predefinito (che è \const{SIGIO}), un valore diverso da
zero indica il segnale richiesto, (che può essere anche lo stesso
- \const{SIGIO}).
+ \const{SIGIO}). In caso di errore ritorna -1.
\item[\const{F\_SETSIG}] imposta il segnale da inviare quando diventa
- possibile effettuare I/O sul file descriptor in caso di I/O asincrono. Il
+ possibile effettuare I/O sul file descriptor in caso di I/O asincrono,
+ ritorna un valore nullo in caso di successo o -1 in caso di errore. Il
valore zero indica di usare il segnale predefinito, \const{SIGIO}. Un altro
- valore (compreso lo stesso \const{SIGIO}) specifica il segnale voluto; l'uso
- di un valore diverso da zero permette inoltre, se si è installato il
- gestore del segnale come \var{sa\_sigaction} usando
+ valore diverso da zero (compreso lo stesso \const{SIGIO}) specifica il
+ segnale voluto; l'uso di un valore diverso da zero permette inoltre, se si è
+ installato il gestore del segnale come \var{sa\_sigaction} usando
\const{SA\_SIGINFO}, (vedi \secref{sec:sig_sigaction}), di rendere
- disponibili al gestore informazioni ulteriori informazioni riguardo il
- file che ha generato il segnale attraverso i valori restituiti 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.}
+ disponibili al gestore informazioni ulteriori riguardo il file che ha
+ generato il segnale attraverso i valori restituiti 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.}
+\item[\const{F\_SETLEASE}] imposta o rimuove un \textit{file
+ lease}\footnote{questa è una nuova funzionalità, specifica di Linux, e
+ presente solo a partire dai kernel della serie 2.4.x, in cui il processo
+ che detiene un \textit{lease} su un file riceve una notifica qualora un
+ altro processo cerca di eseguire una \func{open} o una \func{truncate} su
+ di esso.} sul file descriptor \var{fd} a seconda del valore del terzo
+ argomento, che in questo caso è un \ctyp{int}, ritorna un valore nullo in
+ caso di successo o -1 in caso di errore. Questa funzionalità avanzata è
+ trattata in dettaglio in \secref{sec:file_asyncronous_operation}.
+\item[\const{F\_GETLEASE}] restituisce il tipo di \textit{file lease} che il
+ processo detiene nei confronti del file descriptor \var{fd} o -1 in caso di
+ errore. Con questo comando il terzo argomento può essere omesso. Questa
+ funzionalità avanzata è trattata in dettaglio in
+ \secref{sec:file_asyncronous_operation}.
+\item[\const{F\_NOTIFY}] attiva un meccanismo di notifica per cui viene
+ riportata al processo chiamante, tramite il segnale \const{SIGIO} (o altro
+ segnale specificato con \const{F\_SETSIG}) ogni modifica eseguita o
+ direttamente sulla directory cui \var{fd} fa riferimento, o su uno dei file
+ in essa contenuti; ritorna un valore nullo in caso di successo o -1 in caso
+ di errore. Questa funzionalità avanzata, disponibile dai kernel della serie
+ 2.4.x, è trattata in dettaglio in \secref{sec:file_asyncronous_operation}.
\end{basedescript}
La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per
-poter essere affrontate in dettaglio a questo punto; saranno riprese più
-avanti quando affronteremo le problematiche ad esse relative (in particolare
-le tematiche relative all'I/O asincrono sono trattate in maniera esaustiva in
-\secref{sec:file_asyncronous_io} mentre quelle relative al \textit{file
+poter essere affrontate in tutti i loro aspetti a questo punto; saranno
+pertanto riprese più avanti quando affronteremo le problematiche ad esse
+relative. In particolare le tematiche relative all'I/O asincrono e ai vari
+meccanismi di notifica saranno trattate in maniera esaustiva in
+\secref{sec:file_asyncronous_operation} mentre quelle relative al \textit{file
locking}\index{file!locking} saranno esaminate in
\secref{sec:file_locking}).
+
Si tenga presente infine che quando si usa la funzione per determinare le
modalità di accesso con cui è stato aperto il file (attraverso l'uso del
comando \const{F\_GETFL}) è necessario estrarre i bit corrispondenti nel
dal progetto GNU. Le \textit{libc5} oggi sono, tranne casi particolari,
completamente soppiantate dalle \acr{glibc}, le \textit{uClib} pur non
essendo complete come le \acr{glibc}, restano invece molto diffuse nel mondo
- embedded per le loro di dimensioni ridotte (e soprattutto la possibilità di
+ embedded per le loro dimensioni ridotte (e soprattutto la possibilità di
togliere le parti non necessarie), e pertanto costituiscono un valido
rimpiazzo delle \acr{glibc} in tutti quei sistemi specializzati che
richiedono una minima occupazione di memoria.} si dovrebbe usare il nome
dall'acronimo \acr{gid}, e sono quelli che vengono usati dal kernel per
identificare l'utente.
-In questo modo il sistema è in grado di tenere traccia per ogni processo
-dell'utente a cui appartiene ed impedire ad altri utenti di interferire con
-esso. Inoltre con questo sistema viene anche garantita una forma base di
-sicurezza interna in quanto anche l'accesso ai file (vedi
+In questo modo il sistema è in grado di tenere traccia dell'utente a cui
+appartiene ciascun processo ed impedire ad altri utenti di interferire con
+quest'ultimo. Inoltre con questo sistema viene anche garantita una forma base
+di sicurezza interna in quanto anche l'accesso ai file (vedi
\secref{sec:file_access_control}) è regolato da questo meccanismo di
identificazione.
Si tenga presente inoltre che nuove specifiche e proposte di standardizzazione
si aggiungono continuamente, mentre le versioni precedenti vengono riviste;
-talvolta poi i riferimenti cambiamo nome, per cui anche solo seguire le
+talvolta poi i riferimenti cambiano nome, per cui anche solo seguire le
denominazioni usate diventa particolarmente faticoso; una pagina dove si
possono recuperare varie (e di norma piuttosto intricate) informazioni è:
\href{http://www.pasc.org/standing/sd11.html}
compatibilità prima di quelle normali.
\item[\macro{\_SVID\_SOURCE}] definendo questa macro si attivano le
funzionalità derivate da SVID. Esse comprendono anche quelle definite negli
- standard ISO C, POSIX.1, POSIX.2, and X/Open.
+ standard ISO C, POSIX.1, POSIX.2, e X/Open.
\item[\macro{\_XOPEN\_SOURCE}] definendo questa macro si attivano le
funzionalità descritte nella \textit{X/Open Portability Guide}. Anche queste
sono un sovrainsieme di quelle definite in POSIX.1 e POSIX.2 ed in effetti
all'utente, avere la possibilità di effettuare automaticamente la chiamata ad
una funzione che effettui tali operazioni all'uscita dal programma. A questo
scopo lo standard ANSI C prevede la possibilità di registrare un certo numero
-funzioni che verranno eseguite all'uscita dal programma (sia per la chiamata
-ad \func{exit} che per il ritorno di \func{main}). La prima funzione che si
-può utilizzare a tal fine è \funcd{atexit} il cui prototipo è:
+di 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 è \funcd{atexit} il cui prototipo è:
\begin{prototype}{stdlib.h}{void atexit(void (*function)(void))}
Registra la funzione \param{function} per la chiamata all'uscita dal
programma.
\end{prototype}
\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)}).
+prendere argomenti e non deve ritornare niente (deve essere cioè definita come
+\code{void function(void)}).
Un'estensione di \func{atexit} è la funzione \funcd{on\_exit}, che le
\acr{glibc} includono per compatibilità con SunOS, ma che non è detto sia
normale pensare di poter effettuare questa operazione.
In generale però possono esistere anche realizzazioni diverse, per questo
-motivo \macro{va\_list} è definito come \textsl{tipo opaco}\index{tipo opaco}
+motivo \macro{va\_list} è definito come \textsl{tipo opaco}\index{tipo!opaco}
e non può essere assegnato direttamente ad un'altra variabile dello stesso
tipo. Per risolvere questo problema lo standard ISO C99\footnote{alcuni
sistemi che non hanno questa macro provvedono al suo posto
\func{longjmp}, ma quelli delle variabili automatiche (o di quelle dichiarate
\direct{register}\footnote{la direttiva \direct{register} del compilatore
chiede che la variabile dichiarata tale sia mantenuta, nei limiti del
- possibile, all'interno di un registro del processore. Questa direttiva
- origina dai primi compilatori, quando stava al programmatore scrivere codice
- ottimizzato, riservando esplicitamente alle variabili più usate l'uso dei
- registri del processore. Oggi questa direttiva oggi è in disuso dato che
- tutti i compilatori sono normalmente in grado di valutare con maggior
- efficacia degli stessi programmatori quando sia il caso di eseguire questa
- ottimizzazione.}) sono in genere indeterminati.
+ possibile, all'interno di un registro del processore. Questa direttiva è
+ originaria dell'epoca dai primi compilatori, quando stava al programmatore
+ scrivere codice ottimizzato, riservando esplicitamente alle variabili più
+ usate l'uso dei registri del processore. Oggi questa direttiva è in disuso
+ dato che tutti i compilatori sono normalmente in grado di valutare con
+ maggior efficacia degli stessi programmatori quando sia il caso di eseguire
+ questa ottimizzazione.}) sono in genere indeterminati.
Quello che succede infatti è che i valori delle variabili che sono tenute in
memoria manterranno il valore avuto al momento della chiamata di
Quello che succede è che quando lo standard output del padre viene rediretto,
lo stesso avviene anche per tutti i figli; la funzione \func{fork} infatti ha
-la caratteristica di duplicare (allo stesso modo in cui lo fa la funzione
-\func{dup}, trattata in \secref{sec:file_dup}) nei figli tutti i file
-descriptor aperti nel padre, il che comporta che padre e figli condividono le
+la caratteristica di duplicare nei figli tutti i file descriptor aperti nel
+padre (allo stesso modo in cui lo fa la funzione \func{dup}, trattata in
+\secref{sec:file_dup}), il che comporta che padre e figli condividono le
stesse voci della \textit{file table} (per la spiegazione di questi termini si
-veda \secref{sec:file_sharing}) e fra cui c'è anche la posizione corrente nel
+veda \secref{sec:file_sharing}) fra cui c'è anche la posizione corrente nel
file.
In questo modo se un processo scrive sul file aggiornerà la posizione corrente
successiva pressione di \texttt{C-c} o \texttt{C-y}.
Per quanto riguarda il comportamento di tutte le altre system call si danno
-sostanzialmente due casi, a seconda che esse siano \textsl{lente}
-(\textit{slow}) o \textsl{veloci} (\textit{fast}). La gran parte di esse
-appartiene a quest'ultima categoria, che non è influenzata dall'arrivo di un
-segnale. Esse sono dette \textsl{veloci} in quanto la loro esecuzione è
-sostanzialmente immediata; la risposta al segnale viene sempre data dopo che
-la system call è stata completata, in quanto attendere per eseguire un
-gestore non comporta nessun inconveniente.
+sostanzialmente due casi, a seconda che esse siano\index{system call lente}
+\textsl{lente} (\textit{slow}) o \textsl{veloci} (\textit{fast}). La gran
+parte di esse appartiene a quest'ultima categoria, che non è influenzata
+dall'arrivo di un segnale. Esse sono dette \textsl{veloci} in quanto la loro
+esecuzione è sostanzialmente immediata; la risposta al segnale viene sempre
+data dopo che la system call è stata completata, in quanto attendere per
+eseguire un gestore non comporta nessun inconveniente.
In alcuni casi però alcune system call (che per questo motivo vengono chiamate
\textsl{lente}) possono bloccarsi indefinitamente. In questo caso non si può
\const{SA\_RESTART} & Riavvia automaticamente le \textit{slow system
call} quando vengono interrotte dal suddetto
segnale; riproduce cioè il comportamento standard
- di BSD.\\
+ di BSD.\index{system call lente}\\
\const{SA\_NOMASK} & Evita che il segnale corrente sia bloccato durante
l'esecuzione del gestore.\\
\const{SA\_NODEFER} & Sinonimo di \const{SA\_NOMASK}.\\
interrotta dall'arrivo di \const{SIGCHLD}, è quella ad \func{accept}, che è
l'unica funzione che può mettere il processo padre in stato di sleep nel
periodo in cui un figlio può terminare; si noti infatti come le altre
-\textit{slow system call}\footnote{si ricordi la distinzione fatta in
- \secref{sec:sig_gen_beha}.} o sono chiamate prima di entrare nel ciclo
-principale, quando ancora non esistono processi figli, o sono chiamate dai
-figli stessi e non risentono di \const{SIGCHLD}.
+\index{system call lente} \textit{slow system call}\footnote{si ricordi la
+ distinzione fatta in \secref{sec:sig_gen_beha}.} o sono chiamate prima di
+entrare nel ciclo principale, quando ancora non esistono processi figli, o
+sono chiamate dai figli stessi e non risentono di \const{SIGCHLD}.
Per questo l'unica modifica sostanziale nel ciclo principale (\texttt{\small
23--42}), rispetto precedente versione di \figref{fig:TCP_ServEcho_first}, è