Altro accorpamento di sezioni e risistemazione dei riferimenti,
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 5 Feb 2012 17:47:35 +0000 (17:47 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 5 Feb 2012 17:47:35 +0000 (17:47 +0000)
Completato tutto fino a dupN.

fileadv.tex
fileio.tex
img/filedup.dia
img/filemultacc.dia
img/fileshar.dia
ipc.tex
prochand.tex
tcpsock.tex

index 1de6aeb86eac23b1e881d49ddeeabf3c5100a196..a4ca6e28ae80d4cd30656cb521cd36fa588be2c8 100644 (file)
@@ -26,12 +26,12 @@ controllo più dettagliato delle modalità di I/O.
 
 \itindbeg{file~locking}
 
 
 \itindbeg{file~locking}
 
-In sez.~\ref{sec:file_sharing} abbiamo preso in esame le modalità in cui un
-sistema unix-like gestisce la condivisione dei file da parte di processi
-diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti
-in \itindex{append~mode} \textit{append mode}, quando più processi scrivono
-contemporaneamente sullo stesso file non è possibile determinare la sequenza
-in cui essi opereranno.
+In sez.~\ref{sec:file_shared_access} abbiamo preso in esame le modalità in cui
+un sistema unix-like gestisce l'accesso concorrente ai file da parte di
+processi diversi. In quell'occasione si è visto come, con l'eccezione dei file
+aperti in \itindex{append~mode} \textit{append mode}, quando più processi
+scrivono contemporaneamente sullo stesso file non è possibile determinare la
+sequenza in cui essi opereranno.
 
 Questo causa la possibilità di una \itindex{race~condition} \textit{race
   condition}; in generale le situazioni più comuni sono due: l'interazione fra
 
 Questo causa la possibilità di una \itindex{race~condition} \textit{race
   condition}; in generale le situazioni più comuni sono due: l'interazione fra
@@ -260,8 +260,8 @@ Questa struttura prevede che, quando si richiede la rimozione di un
 file descriptor che fa riferimento ad una voce nella \itindex{file~table}
 \textit{file table} corrispondente a quella registrata nel blocco.  Allora se
 ricordiamo quanto visto in sez.~\ref{sec:file_dup} e
 file descriptor che fa riferimento ad una voce nella \itindex{file~table}
 \textit{file table} corrispondente a quella registrata nel blocco.  Allora se
 ricordiamo quanto visto in sez.~\ref{sec:file_dup} e
-sez.~\ref{sec:file_sharing}, e cioè che i file descriptor duplicati e quelli
-ereditati in un processo figlio puntano sempre alla stessa voce nella
+sez.~\ref{sec:file_shared_access}, e cioè che i file descriptor duplicati e
+quelli ereditati in un processo figlio puntano sempre alla stessa voce nella
 \itindex{file~table} \textit{file table}, si può capire immediatamente quali
 sono le conseguenze nei confronti delle funzioni \func{dup} e \func{fork}.
 
 \itindex{file~table} \textit{file table}, si può capire immediatamente quali
 sono le conseguenze nei confronti delle funzioni \func{dup} e \func{fork}.
 
index 481d210f17324b3e8729761824a10a8262bf0c14..d631d4060f4b5613a5e58304b79084a6fbcbbcaa 100644 (file)
@@ -294,7 +294,7 @@ nuovo file questo diventerà il nuovo \itindex{standard~input} \textit{standard
 Al momento dell'apertura il nuovo file descriptor non è condiviso con nessun
 altro processo (torneremo sul significato della condivisione dei file
 descriptor, che in genere si ottiene dopo una \func{fork}, in
 Al momento dell'apertura il nuovo file descriptor non è condiviso con nessun
 altro processo (torneremo sul significato della condivisione dei file
 descriptor, che in genere si ottiene dopo una \func{fork}, in
-sez.~\ref{sec:file_sharing}) ed è impostato, come accennato in
+sez.~\ref{sec:file_shared_access}) ed è impostato, come accennato in
 sez.~\ref{sec:proc_exec}, per restare aperto attraverso una
 \func{exec}. Inoltre la posizione sul file, il cosiddetto \textit{offset}, è
 impostata all'inizio del file. Una volta aperto un file si potrà operare su di
 sez.~\ref{sec:proc_exec}, per restare aperto attraverso una
 \func{exec}. Inoltre la posizione sul file, il cosiddetto \textit{offset}, è
 impostata all'inizio del file. Una volta aperto un file si potrà operare su di
@@ -699,8 +699,8 @@ La funzione chiude il file descriptor \param{fd}. La chiusura rilascia ogni
 eventuale blocco (il \textit{file locking} \itindex{file~locking} è trattato
 in sez.~\ref{sec:file_locking}) che il processo poteva avere acquisito su di
 esso. Se \param{fd} è l'ultimo riferimento (di eventuali copie, vedi
 eventuale blocco (il \textit{file locking} \itindex{file~locking} è trattato
 in sez.~\ref{sec:file_locking}) che il processo poteva avere acquisito su di
 esso. Se \param{fd} è l'ultimo riferimento (di eventuali copie, vedi
-sez.~\ref{sec:file_sharing} e \ref{sec:file_dup}) ad un file aperto, tutte le
-risorse nella \itindex{file~table} \textit{file table} vengono
+sez.~\ref{sec:file_shared_access} e \ref{sec:file_dup}) ad un file aperto,
+tutte le risorse nella \itindex{file~table} \textit{file table} vengono
 rilasciate. Infine se il file descriptor era l'ultimo riferimento ad un file
 su disco quest'ultimo viene cancellato.
 
 rilasciate. Infine se il file descriptor era l'ultimo riferimento ad un file
 su disco quest'ultimo viene cancellato.
 
@@ -818,7 +818,7 @@ la successiva scrittura avvenga alla fine del file, infatti se questo è stato
 aperto anche da un altro processo che vi ha scritto, la fine del file può
 essersi spostata, ma noi scriveremo alla posizione impostata in precedenza
 (questa è una potenziale sorgente di \itindex{race~condition} \textit{race
 aperto anche da un altro processo che vi ha scritto, la fine del file può
 essersi spostata, ma noi scriveremo alla posizione impostata in precedenza
 (questa è una potenziale sorgente di \itindex{race~condition} \textit{race
-  condition}, vedi sez.~\ref{sec:file_atomic}).
+  condition}, vedi sez.~\ref{sec:file_shared_access}).
 
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
 questo caso la funzione ritorna l'errore \errcode{ESPIPE}. Questo, oltre che
 
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
 questo caso la funzione ritorna l'errore \errcode{ESPIPE}. Questo, oltre che
@@ -1024,7 +1024,7 @@ L'uso di \func{pread} è equivalente all'esecuzione di una \func{read} seguita
 da una \func{lseek} che riporti al valore precedente la 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
 da una \func{lseek} che riporti al valore precedente la 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 sez.~\ref{sec:file_sharing}).  Il valore di
+(vedi sez.~\ref{sec:file_shared_access}).  Il valore di
 \param{offset} fa sempre riferimento all'inizio del file.
 
 La funzione \func{pread} è disponibile anche in Linux, però diventa
 \param{offset} fa sempre riferimento all'inizio del file.
 
 La funzione \func{pread} è disponibile anche in Linux, però diventa
@@ -1115,14 +1115,15 @@ permettono di eseguire alcune operazioni avanzate con i file (il grosso
 dell'argomento sarà comunque affrontato in cap.~\ref{cha:file_advanced}).
 
 
 dell'argomento sarà comunque affrontato in cap.~\ref{cha:file_advanced}).
 
 
-\subsection{La condivisione dei files}
-\label{sec:file_sharing}
+\subsection{La gestione dell'accesso concorrente ai files}
+\label{sec:file_shared_access}
 
 In sez.~\ref{sec:file_fd} abbiamo descritto brevemente l'architettura
 dell'interfaccia con i file da parte di un processo, mostrando in
 fig.~\ref{fig:file_proc_file} le principali strutture usate dal kernel;
 esamineremo ora in dettaglio le conseguenze che questa architettura ha nei
 
 In sez.~\ref{sec:file_fd} abbiamo descritto brevemente l'architettura
 dell'interfaccia con i file da parte di un processo, mostrando in
 fig.~\ref{fig:file_proc_file} le principali strutture usate dal kernel;
 esamineremo ora in dettaglio le conseguenze che questa architettura ha nei
-confronti dell'accesso allo stesso file da parte di processi diversi.
+confronti dell'accesso concorrente allo stesso file da parte di processi
+diversi.
 
 \begin{figure}[!htb]
   \centering
 
 \begin{figure}[!htb]
   \centering
@@ -1147,20 +1148,20 @@ vengono mantenute nella sua voce della \itindex{file~table} \textit{file
 azione simultanea sullo stesso file, in particolare occorre tenere presente
 che:
 \begin{itemize}
 azione simultanea sullo stesso file, in particolare occorre tenere presente
 che:
 \begin{itemize}
-\item ciascun processo può scrivere indipendentemente; dopo ciascuna
-  \func{write} la posizione corrente sarà cambiata solo nel processo. Se la
-  scrittura eccede la dimensione corrente del file questo verrà esteso
-  automaticamente con l'aggiornamento del campo \var{i\_size} \itindex{inode}
-  nell'\textit{inode}.
+\item ciascun processo può scrivere indipendentemente, dopo ciascuna
+  \func{write} la posizione corrente sarà cambiata solo nel processo
+  scrivente. Se la scrittura eccede la dimensione corrente del file questo
+  verrà esteso automaticamente con l'aggiornamento del campo \var{i\_size}
+  della struttura \kstruct{inode}.
 \item se un file è in modalità \itindex{append~mode} \const{O\_APPEND} tutte
   le volte che viene effettuata una scrittura la posizione corrente viene
 \item se un file è in modalità \itindex{append~mode} \const{O\_APPEND} tutte
   le volte che viene effettuata una scrittura la posizione corrente viene
-  prima impostata alla dimensione corrente del file letta \itindex{inode}
-  dall'\textit{inode}. Dopo la scrittura il file viene automaticamente esteso.
+  prima impostata alla dimensione corrente del file letta dalla struttura
+  \kstruct{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 \kstruct{file} della \itindex{file~table}
   \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
 \item l'effetto di \func{lseek} è solo quello di cambiare il campo
   \var{f\_pos} nella struttura \kstruct{file} della \itindex{file~table}
   \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 \itindex{inode} dall'\textit{inode}.
+  dimensione corrente dalla struttura \kstruct{inode}.
 \end{itemize}
 
 \begin{figure}[!htb]
 \end{itemize}
 
 \begin{figure}[!htb]
@@ -1171,175 +1172,89 @@ che:
 \end{figure}
 
 Il secondo caso è quello in cui due file descriptor di due processi diversi
 \end{figure}
 
 Il secondo caso è quello in cui due file descriptor di due processi diversi
-puntino alla stessa voce nella \itindex{file~table} \textit{file table};
-questo è ad esempio il caso dei file aperti che vengono ereditati dal processo
+puntino alla stessa voce nella \itindex{file~table} \textit{file table}.
+Questo è ad esempio il caso dei file aperti che vengono ereditati dal processo
 figlio all'esecuzione di una \func{fork} (si ricordi quanto detto in
 sez.~\ref{sec:proc_fork}). La situazione è illustrata in
 fig.~\ref{fig:file_acc_child}; dato che il processo figlio riceve una copia
 dello spazio di indirizzi del padre, riceverà anche una copia di
 figlio all'esecuzione di una \func{fork} (si ricordi quanto detto in
 sez.~\ref{sec:proc_fork}). La situazione è illustrata in
 fig.~\ref{fig:file_acc_child}; dato che il processo figlio riceve una copia
 dello spazio di indirizzi del padre, riceverà anche una copia di
-\kstruct{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
-posizione corrente sul file. Questo ha le conseguenze descritte a suo tempo in
-sez.~\ref{sec:proc_fork}: in caso di scrittura contemporanea la posizione
-corrente nel file varierà per entrambi i processi (in quanto verrà modificato
-\var{f\_pos} che è lo stesso per entrambi).
-
-Si noti inoltre che anche i \itindex{file~status~flag} flag di stato del file
-(quelli impostati dall'argomento \param{flag} di \func{open}) essendo tenuti
-nella voce della \textit{file table}, vengono in questo caso condivisi. Ai
-file però sono associati anche altri flag, dei quali l'unico usato al momento
-è \const{FD\_CLOEXEC}, detti \itindex{file~descriptor~flags} \textit{file
-  descriptor flags}. Questi ultimi sono tenuti invece in
-\kstruct{file\_struct}, e perciò sono specifici di ciascun processo e non
+\kstruct{file\_struct} e della relativa tabella dei file aperti.
+
+Questo significa che il figlio avrà gli stessi file aperti del padre, in
+quanto la sua \kstruct{file\_struct}, pur essendo allocata in maniera
+indipendente, contiene gli stessi valori di quella del padre e quindi i suoi
+file descriptor faranno riferimento alla stessa voce nella
+\itindex{file~table} \textit{file table}, condividendo così la posizione
+corrente sul file. Questo ha le conseguenze descritte a suo tempo in
+sez.~\ref{sec:proc_fork}: in caso di scrittura o lettura da parte di uno dei
+due processi, la posizione corrente nel file varierà per entrambi, in quanto
+verrà modificato il campo \var{f\_pos} della struttura \kstruct{file}, che è
+la stessa per entrambi. Questo consente una sorta di
+``\textsl{sincronizzazione}'' automatica della posizione sul file fra padre e
+figlio che occorre tenere presente.
+
+Si noti inoltre che in questo caso anche i \itindex{file~status~flag} flag di
+stato del file, essendo mantenuti nella struttura \kstruct{file} della
+\textit{file table}, vengono condivisi, per cui una modifica degli stessi con
+\func{fcntl} (vedi sez.~\ref{sec:file_fcntl}) si applicherebbe a tutti
+processi che condividono la voce nella \itindex{file~table} \textit{file
+  table}. Ai file però sono associati anche altri flag, dei quali l'unico
+usato al momento è \const{FD\_CLOEXEC}, detti \itindex{file~descriptor~flags}
+\textit{file descriptor flags}; questi invece sono mantenuti in
+\kstruct{file\_struct}, e perciò sono locali per ciascun processo e non
 vengono modificati dalle azioni degli altri anche in caso di condivisione
 vengono modificati dalle azioni degli altri anche in caso di condivisione
-della stessa voce della \textit{file table}.
-
-
-
-\subsection{Operazioni atomiche con i file}
-\label{sec:file_atomic}
-
-Come si è visto in un sistema unix-like è sempre possibile per più processi
-accedere in contemporanea allo stesso file, e che le operazioni di lettura e
-scrittura possono essere fatte da ogni processo in maniera autonoma in base
-ad una posizione corrente nel file che è locale a ciascuno di essi.
-
-Se dal punto di vista della lettura dei dati questo non comporta nessun
-problema, quando si andrà a scrivere le operazioni potranno mescolarsi in
-maniera imprevedibile.  Il sistema però fornisce in alcuni casi la possibilità
-di eseguire alcune operazioni di scrittura in maniera coordinata anche senza
-utilizzare meccanismi di sincronizzazione più complessi (come il
-\itindex{file~locking} \textit{file locking}, che esamineremo in
-sez.~\ref{sec:file_locking}).
+della stessa voce della \itindex{file~table} \textit{file table}.
+
+Si tenga presente dunque che in un sistema unix-like è sempre possibile per
+più processi accedere in contemporanea allo stesso file e che non esistono, a
+differenza di altri sistemi operativi, dei meccanismi di blocco o di
+restrizione dell'accesso impliciti se più processi vogliono accedere allo
+stesso file. Questo significa che le operazioni di lettura e scrittura vengono
+sempre fatte da ogni processo in maniera autonoma, utilizzando una posizione
+corrente nel file che normalmente (a meno di non trovarsi nella situazione di
+fig.~\ref{fig:file_acc_child}) è locale a ciascuno di essi.
+
+Dal punto di vista della lettura dei dati questo comporta la possibilità di
+poter leggere dati non coerenti in caso di scrittura contemporanea da parte di
+un altro processo. Dal punto di vista della scrittura invece si potranno avere
+sovrapposizioni imprevedibili quando due processi scrivono nella stessa
+sezione di file, dato che ciascuno lo farà in maniera indipendente.  Il
+sistema però fornisce in alcuni casi la possibilità di eseguire alcune
+operazioni di scrittura in maniera coordinata anche senza utilizzare dei
+meccanismi di sincronizzazione espliciti come il \itindex{file~locking}
+\textit{file locking}, che esamineremo in sez.~\ref{sec:file_locking}.
 
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in sez.~\ref{sec:file_lseek} impostare la posizione alla
 fine del file e poi scrivere può condurre ad una \itindex{race~condition}
 
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in sez.~\ref{sec:file_lseek} impostare la posizione alla
 fine del file e poi scrivere può condurre ad una \itindex{race~condition}
-\textit{race condition}: infatti può succedere che un secondo processo scriva
-alla fine del file fra la \func{lseek} e la \func{write}; in questo caso, come
-abbiamo appena visto, il file sarà esteso, ma il nostro primo processo avrà
-ancora la posizione corrente impostata con la \func{lseek} che non corrisponde
-più alla fine del file, e la successiva \func{write} sovrascriverà i dati del
-secondo processo.
-
-Il problema è che usare due \textit{system call} in successione non è
-un'operazione atomica; il problema è stato risolto introducendo la modalità
-\itindex{append~mode} \const{O\_APPEND}. In questo caso infatti, come abbiamo
-descritto in precedenza, è il kernel che aggiorna automaticamente la posizione
-alla fine del file prima di effettuare la scrittura, e poi estende il file.
-Tutto questo avviene all'interno di una singola \textit{system call} (la
-\func{write}) che non essendo interrompibile da un altro processo costituisce
-un'operazione atomica.
-
-Un altro caso tipico in cui è necessaria l'atomicità è quello in cui si vuole
-creare un \textsl{file di lock} \index{file!di lock}, bloccandosi se il file
-esiste. In questo caso la sequenza logica porterebbe a verificare prima
-l'esistenza del file con una \func{stat} per poi crearlo con una \func{creat};
-di nuovo avremmo la possibilità di una \itindex{race~condition} \textit{race
-  condition} da parte di un altro processo che crea lo stesso file fra il
-controllo e la creazione.
-
-Per questo motivo sono stati introdotti per \func{open} i due flag
-\const{O\_CREAT} e \const{O\_EXCL}. In questo modo l'operazione di controllo
-dell'esistenza del file (con relativa uscita dalla funzione con un errore) e
-creazione in caso di assenza, diventa atomica essendo svolta tutta all'interno
-di una singola \textit{system call} (per i dettagli sull'uso di questa
-caratteristica si veda sez.~\ref{sec:ipc_file_lock}).
-
-
-\subsection{Le funzioni \func{sync} e \func{fsync}}
-\label{sec:file_sync}
-
-% TODO, aggiungere syncfs, introdotta con il 2.6.39
-
-Come accennato in sez.~\ref{sec:file_open_close} tutte le operazioni di
-scrittura sono in genere bufferizzate dal kernel, che provvede ad effettuarle
-in maniera asincrona (ad esempio accorpando gli accessi alla stessa zona del
-disco) in un secondo tempo rispetto al momento della esecuzione della
-\func{write}.
-
-Per questo motivo, quando è necessaria una sincronizzazione dei dati, il
-sistema mette a disposizione delle funzioni che provvedono a forzare lo
-scarico dei dati dai buffer del kernel.\footnote{come già accennato neanche
-  questo dà la garanzia assoluta che i dati siano integri dopo la chiamata,
-  l'hardware dei dischi è in genere dotato di un suo meccanismo interno di
-  ottimizzazione per l'accesso al disco che può ritardare ulteriormente la
-  scrittura effettiva.} La prima di queste funzioni è \funcd{sync} il cui
-prototipo è:
-
-\begin{funcproto}{
-\fhead{unistd.h}
-\fdecl{int sync(void)}
-\fdesc{Sincronizza il buffer della cache dei file col disco.} 
-}
-
-{La funzione ritorna sempre $0$ ed ha sempre successo.}  
-\end{funcproto}
-
-\noindent  i vari standard prevedono che la funzione si limiti a far partire
-le operazioni, ritornando immediatamente; in Linux (dal kernel 1.3.20) invece
-la funzione aspetta la conclusione delle operazioni di sincronizzazione del
-kernel.
-
-La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
-esplicitamente lo scarico dei dati su disco, o dal demone di sistema
-\cmd{update} che esegue lo scarico dei dati ad intervalli di tempo fissi: il
-valore tradizionale, usato da BSD, per l'update dei dati è ogni 30 secondi, ma
-in Linux il valore utilizzato è di 5 secondi; con le nuove versioni\footnote{a
-  partire dal kernel 2.2.8} poi, è il kernel che si occupa direttamente di
-tutto quanto attraverso il demone interno \cmd{bdflush}, il cui comportamento
-può essere controllato attraverso il file \sysctlfile{vm/bdflush} (per
-il significato dei valori si può leggere la documentazione allegata al kernel
-in \file{Documentation/sysctl/vm.txt}).
-
-Quando si vogliono scaricare soltanto i dati di un file (ad esempio essere
-sicuri che i dati di un database sono stati registrati su disco) si possono
-usare le due funzioni \funcd{fsync} e \funcd{fdatasync}, i cui prototipi sono:
-
-\begin{funcproto}{
-\fhead{unistd.h}
-\fdecl{int fsync(int fd)}
-\fdesc{Sincronizza dati e metadati di un file.} 
-\fdecl{int fdatasync(int fd)}
-\fdesc{Sincronizza i dati di un file.} 
-}
-
-{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-  caso \var{errno} assumerà uno dei valori: 
-  \begin{errlist}
-  \item[\errcode{EINVAL}] \param{fd} è un \index{file!speciali} file speciale
-    che non supporta la sincronizzazione.
-  \end{errlist}
-  ed inoltre \errval{EBADF}, \errval{EROFS} e \errval{EIO} nel loro
-  significato generico.}
-\end{funcproto}
-
-Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
-file specificato, ed attendono fino alla conclusione delle operazioni;
-\func{fsync} forza anche la sincronizzazione dei meta-dati del file (che
-riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli
-altri dati contenuti \itindex{inode} nell'\textit{inode} che si leggono con
-\func{fstat}, come i tempi del file).
-
-Si tenga presente che questo non comporta la sincronizzazione della
-directory che contiene il file (e scrittura della relativa voce su
-disco) che deve essere effettuata esplicitamente.\footnote{in realtà per
-  il filesystem \acr{ext2}, quando lo si monta con l'opzione \cmd{sync},
-  il kernel provvede anche alla sincronizzazione automatica delle voci
-  delle directory.}
-
-
-\subsection{Le funzioni \func{dup} e \func{dup2}}
+\textit{race condition}l infatti può succedere che un secondo processo scriva
+alla fine del file fra la \func{lseek} e la \func{write}. In questo caso, come
+abbiamo appena visto, il file sarà esteso, ma il primo processo, che avrà la
+posizione corrente che aveva impostato con la \func{lseek} che non corrisponde
+più alla fine del file, e la sua successiva \func{write} sovrascriverà i dati
+del secondo processo.
+
+Il problema deriva dal fatto che usare due \textit{system call} in successione
+non è mai un'operazione atomica dato che il kernel può interrompere
+l'esecuzione del processo fra le due. Nel caso specifico il problema è stato
+risolto introducendo la modalità di scrittura \itindex{append~mode} in
+\textit{append}, attivabile con il flag \const{O\_APPEND}. In questo caso
+infatti, come abbiamo illustrato in sez.~\ref{sec:file_open_close}, è il
+kernel che aggiorna automaticamente la posizione alla fine del file prima di
+effettuare la scrittura, e poi estende il file.  Tutto questo avviene
+all'interno di una singola \textit{system call}, la \func{write}, che non
+essendo interrompibile da un altro processo realizza un'operazione atomica.
+
+
+\subsection{La duplicazione dei file descriptor}
 \label{sec:file_dup}
 
 \label{sec:file_dup}
 
-Abbiamo già visto in sez.~\ref{sec:file_sharing} come un processo figlio
+Abbiamo già visto in sez.~\ref{sec:file_shared_access} come un processo figlio
 condivida gli stessi file descriptor del padre; è possibile però ottenere un
 comportamento analogo all'interno di uno stesso processo \textit{duplicando}
 condivida gli stessi file descriptor del padre; è possibile però ottenere un
 comportamento analogo all'interno di uno stesso processo \textit{duplicando}
-un file descriptor. Per far questo si usa la funzione \funcd{dup} il cui
-prototipo è:
+un file descriptor. Per far questo si usa la funzione di sistema \funcd{dup},
+il cui prototipo è:
 
 \begin{funcproto}{
 \fhead{unistd.h}
 
 \begin{funcproto}{
 \fhead{unistd.h}
@@ -1360,11 +1275,12 @@ prototipo è:
 La funzione ritorna, come \func{open}, il primo file descriptor libero. Il
 file descriptor è una copia esatta del precedente ed entrambi possono essere
 interscambiati nell'uso. Per capire meglio il funzionamento della funzione si
 La funzione ritorna, come \func{open}, il primo file descriptor libero. Il
 file descriptor è una copia esatta del precedente ed entrambi possono essere
 interscambiati nell'uso. Per capire meglio il funzionamento della funzione si
-può fare riferimento a fig.~\ref{fig:file_dup}: l'effetto della funzione è
-semplicemente quello di copiare il valore nella struttura
-\kstruct{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.
+può fare riferimento a fig.~\ref{fig:file_dup}. L'effetto della funzione è
+semplicemente quello di copiare il valore di un certo file descriptor in
+un altro all'interno della struttura \kstruct{file\_struct}, cosicché anche
+questo faccia riferimento alla stessa voce nella \textit{file table}. Per
+questo motivo si dice che il nuovo file descriptor è ``\textsl{duplicato}'',
+da cui il nome della funzione.
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=12cm]{img/filedup}
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=12cm]{img/filedup}
@@ -1373,30 +1289,47 @@ file descriptor è \textsl{duplicato}, da cui il nome della funzione.
 \end{figure}
 
 Si noti che per quanto illustrato in fig.~\ref{fig:file_dup} i file descriptor
 \end{figure}
 
 Si noti che per quanto illustrato in fig.~\ref{fig:file_dup} i file descriptor
-duplicati condivideranno eventuali lock, \textit{file status flag}, e
-posizione corrente. Se ad esempio si esegue una \func{lseek} per modificare la
-posizione su uno dei due file descriptor, essa risulterà modificata anche
-sull'altro (dato che quello che viene modificato è lo stesso campo nella voce
-della \textit{file table} a cui entrambi fanno riferimento). L'unica
-differenza fra due file descriptor duplicati è che ciascuno avrà il suo
-\textit{file descriptor flag}; a questo proposito va specificato che nel caso
-di \func{dup} il flag di \textit{close-on-exec} \itindex{close-on-exec} (vedi
-sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl}) viene sempre cancellato
-nella copia.
-
-L'uso principale di questa funzione è per la redirezione dell'input e
-dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec};
-diventa così possibile associare un file (o una pipe) allo standard input o
-allo standard output (torneremo sull'argomento in sez.~\ref{sec:ipc_pipe_use},
-quando tratteremo le pipe). Per fare questo in genere occorre prima chiudere
-il file che si vuole sostituire, cosicché il suo file descriptor possa esser
-restituito alla chiamata di \func{dup}, come primo file descriptor
-disponibile.
-
-Dato che questa è l'operazione più comune, è prevista una diversa versione
-della funzione, \funcd{dup2}, che permette di specificare esplicitamente
-qual è il valore di file descriptor che si vuole avere come duplicato; il suo
-prototipo è:
+duplicati condivideranno eventuali lock (vedi sez.~\ref{sec:file_locking}),
+\itindex{file~status~flag} i flag di stato, e la posizione corrente sul
+file. Se ad esempio si esegue una \func{lseek} per modificare la posizione su
+uno dei due file descriptor, essa risulterà modificata anche sull'altro, dato
+che quello che viene modificato è lo stesso campo nella voce della
+\textit{file table} a cui entrambi fanno riferimento. 
+
+L'unica differenza fra due file descriptor duplicati è che ciascuno avrà un
+suo \textit{file descriptor flag} indipendente. A questo proposito deve essere
+tenuto presente che nel caso in cui si usi \func{dup} per duplicare un file
+descriptor, se questo ha il flag di \textit{close-on-exec}
+\itindex{close-on-exec} attivo (vedi sez.~\ref{sec:proc_exec} e
+sez.~\ref{sec:file_fcntl}), questo verrà cancellato nel file descriptor
+restituito come copia.
+
+L'uso principale di questa funzione è nella shell per la redirezione dei file
+standard di tab.~\ref{tab:file_std_files} fra l'esecuzione di una \func{fork}
+e la successiva \func{exec}. Diventa così possibile associare un file (o una
+pipe) allo \itindex{standard~input} \textit{standard input} o allo
+\itindex{standard~output} \textit{standard output} (vedremo un esempio in
+sez.~\ref{sec:ipc_pipe_use}, quando tratteremo le pipe). 
+
+Ci si può chiedere perché non sia in questo caso sufficiente chiudere il file
+standard che si vuole redirigere e poi aprire direttamente con \func{open} il
+file vi si vuole far corrispondere, invece di duplicare un file descriptor che
+si è già aperto. La risposta sta nel fatto che il file che si vuole redirigere
+non è detto sia un file regolare, ma potrebbe essere, come accennato, anche
+una fifo o un socket, oppure potrebbe essere un file associato ad un file
+descriptor che si è ereditato già aperto (ad esempio attraverso un'altra
+\func{exec}) da un processo antenato del padre, del quale non si conosce il
+nome. Operando direttamente con i file descriptor \func{dup} consente di
+ignorare le origini del file descriptor che si duplica e funziona in maniera
+generica indipendentemente dall'oggetto a cui questo fa riferimento.
+
+Per ottenere la redirezione occorre pertanto disporre del file descriptor
+associato al file che si vuole usare e chiudere il file descriptor che si
+vuole sostituire, cosicché esso possa esser restituito alla successiva
+chiamata di \func{dup} come primo file descriptor disponibile.  Dato che
+questa è l'operazione più comune, è prevista un'altra funzione di sistema,
+\funcd{dup2}, che permette di specificare esplicitamente qual è il numero di
+file descriptor che si vuole ottenere come duplicato; il suo prototipo è:
 
 \begin{funcproto}{
 \fhead{unistd.h}
 
 \begin{funcproto}{
 \fhead{unistd.h}
@@ -1409,31 +1342,173 @@ prototipo è:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{oldfd} non è un file aperto o \param{newfd} ha
     un valore fuori dall'intervallo consentito per i file descriptor.
   \begin{errlist}
   \item[\errcode{EBADF}] \param{oldfd} non è un file aperto o \param{newfd} ha
     un valore fuori dall'intervallo consentito per i file descriptor.
+  \item[\errcode{EBUSY}] si è rilevata la possibilità di una
+    \itindex{race~condition} \textit{race condition}.
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
   \item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
     descriptor aperti.
   \end{errlist}
 }  
 \end{funcproto}
 
   \item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
     descriptor aperti.
   \end{errlist}
 }  
 \end{funcproto}
 
-
-\noindent e qualora il file descriptor \param{newfd} sia già aperto (come
-avviene ad esempio nel caso della duplicazione di uno dei file standard) esso
-sarà prima chiuso e poi duplicato (così che il file duplicato sarà connesso
-allo stesso valore per il file descriptor).
+La funzione duplica il file descriptor \param{oldfd} su un altro file
+descriptor di valore \param{newfd}. Qualora il file descriptor \param{newfd}
+sia già aperto, come avviene ad esempio nel caso della duplicazione di uno dei
+file standard di tab.~\ref{tab:file_std_files}, esso sarà prima chiuso e poi
+duplicato. Se \param{newfd} è uguale a \param{oldfd} la funzione non fa nulla
+e si limita a restituire \param{newfd}.
+
+L'uso di \func{dup2} ha vari vantaggi rispetto alla combinazione di
+\func{close} e \func{dup}; anzitutto se \param{oldfd} è uguale \param{newfd}
+questo verrebbe chiuso e \func{dup} fallirebbe, ma soprattutto l'operazione è
+atomica e consente di evitare una \itindex{race~condition} \textit{race
+  condition} in cui dopo la chiusura del file si potrebbe avere la ricezione
+di un segnale il cui gestore (vedi sez.~\ref{sec:sig_signal_handler}) potrebbe
+a sua volta aprire un file, per cui alla fine \func{dup} restituirebbe un file
+descriptor diverso da quello voluto.
+
+Con Linux inoltre la funzione prevede la possibilità di restituire l'errore
+\errcode{EBUSY}, che non è previsto dallo standard, quando viene rilevata la
+possibilità di una \itindex{race~condition} \textit{race condition} interna in
+cui si cerca di duplicare un file descriptor che è stato allocato ma per il
+quale non sono state completate le operazioni di apertura.\footnote{la
+  condizione è abbastanza peculiare e non attinente al tipo di utilizzo
+  indicato, quanto piuttosto ad un eventuale tentativo di duplicare file
+  descriptor non ancora aperti, la condizione di errore non è prevista dallo
+  standard, ma in condizioni simili FreeBSD risponde con un errore di
+  \errval{EBADF}, mentre OpenBSD elimina la possibilità di una \textit{race
+    condition} al costo di una perdita di prestazioni.} In tal caso occorre
+ritentare l'operazione.
 
 La duplicazione dei file descriptor può essere effettuata anche usando la
 funzione di controllo dei file \func{fcntl} (che esamineremo in
 sez.~\ref{sec:file_fcntl}) con il parametro \const{F\_DUPFD}.  L'operazione ha
 la sintassi \code{fcntl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per
 
 La duplicazione dei file descriptor può essere effettuata anche usando la
 funzione di controllo dei file \func{fcntl} (che esamineremo in
 sez.~\ref{sec:file_fcntl}) con il parametro \const{F\_DUPFD}.  L'operazione ha
 la sintassi \code{fcntl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per
-\param{newfd} diventa equivalente a \func{dup}. 
+\param{newfd} diventa equivalente a \func{dup}.  La sola differenza fra le due
+funzioni (a parte la sintassi ed i diversi codici di errore) è che \func{dup2}
+chiude il file descriptor \param{newfd} se questo è già aperto, garantendo che
+la duplicazione sia effettuata esattamente su di esso, invece \func{fcntl}
+restituisce il primo file descriptor libero di valore uguale o maggiore
+di \param{newfd}, per cui se \param{newfd} è aperto la duplicazione avverrà su
+un altro file descriptor.
+
+Su Linux inoltre è presente una terza funzione di sistema non
+standard,\footnote{la funzione è stata introdotta con il kernel 2.6.27 e resa
+  disponibile con la \acr{glibc} 2.9.} \funcd{dup3}, che consente di duplicare
+un file descriptor reimpostandone i flag, per usarla occorre definire la macro
+\macro{\_GNU\_SOURCE} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int dup3(int oldfd, int newfd, int flags)}
+\fdesc{Duplica un file descriptor su un altro.} 
+}
+
+{La funzione ritorna il nuovo file descriptor in caso di successo e $-1$ per
+  un errore, nel qual caso \var{errno} assumerà gli stessi valori di
+  \func{dup2} più \errcode{EINVAL} qualora \param{flags} contenga un valore
+  non valido o \param{newfd} sia uguale a \param{oldfd}.
+}  
+\end{funcproto}
+
+La funzione è identica a \func{dup2} ma prevede la possibilità di mantenere il
+flag di \textit{close-on-exec} \itindex{close-on-exec} sul nuovo
+file descriptor specificando \const{O\_CLOEXEC} in \param{flags} (che è l'unico
+flag usabile in questo caso). Inoltre rileva esplicitamente la possibile
+coincidenza fra \param{newfd} e \param{oldfd}, fallendo con un errore di
+\errval{EINVAL}.
+
+
+\subsection{Le funzioni di sincronizzazione dei dati}
+\label{sec:file_sync}
+
+Come accennato in sez.~\ref{sec:file_open_close} tutte le operazioni di
+scrittura sono in genere bufferizzate dal kernel, che provvede ad effettuarle
+in maniera asincrona, ad esempio accorpando gli accessi alla stessa zona del
+disco, in un secondo tempo rispetto al momento della esecuzione della
+\func{write}.
 
 
-La sola differenza fra le due funzioni\footnote{a parte la sintassi ed i
-  diversi codici di errore.} è che \func{dup2} chiude il file descriptor
-\param{newfd} se questo è già aperto, garantendo che la duplicazione sia
-effettuata esattamente su di esso, invece \func{fcntl} restituisce il primo
-file descriptor libero di valore uguale o maggiore di \param{newfd} (e se
-\param{newfd} è aperto la duplicazione avverrà su un altro file descriptor).
+Per questo motivo quando è necessaria una sincronizzazione dei dati il sistema
+mette a disposizione delle funzioni che provvedono a forzare lo scarico dei
+dati dai buffer del kernel.  La prima di queste funzioni di sistema è
+\funcd{sync}, il cui prototipo è:\footnote{questo è il prototipo usato a
+  partire dalla \acr{glibc} 2.2.2 seguendo gli standard, in precedenza la
+  funzione era definita come \code{int sync(void)} e ritornava sempre $0$.}
 
 
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{void sync(void)}
+\fdesc{Sincronizza il buffer della cache dei file col disco.} 
+}
+
+{La funzione non ritorna nulla e non prevede condizioni di errore.}  
+\end{funcproto}
+
+I vari standard prevedono che la funzione si limiti a far partire le
+operazioni, ritornando immediatamente; con Linux fin dal kernel 1.3.20 invece
+la funzione aspetta la conclusione delle operazioni di sincronizzazione. Si
+tenga presente comunque che questo non dà la garanzia assoluta che i dati
+siano integri dopo la chiamata, l'hardware dei dischi è in genere dotato di un
+suo meccanismo interno di bufferizzazione che può ritardare ulteriormente la
+scrittura effettiva.
+
+La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
+esplicitamente lo scarico dei dati su disco, un tempo era invocata da un
+apposito demone di sistema (in genere chiamato \cmd{update}) che eseguiva lo
+scarico dei dati ad intervalli di tempo fissi, ad esempio il valore
+tradizionale usato da BSD era di 30 secondi, mentre su Linux il valore
+utilizzato è di 5 secondi. 
+
+Con le nuove versioni del kernel le operazioni di scarico periodico dei dati
+su disco vengono gestite direttamente dal sistema della memoria virtuale,
+attraverso opportuni \textit{task} interni al kernel il cui comportamento può
+essere controllato attraverso il file \sysctlfile{vm/bdflush}. Per il
+significato dei valori si può leggere la documentazione allegata ai sorgenti
+del kernel nel file \file{Documentation/sysctl/vm.txt}. Si tenga presente che
+la funzione di sistema \funcm{bdflush} che un tempo veniva usata per queste
+impostazioni è deprecata e causa semplicemente la stampa di un messaggio nei
+log del kernel, pertanto non la prenderemo in esame.
+
+Quando si vogliono scaricare soltanto i dati di un singolo file (ad esempio
+essere sicuri che i dati di un database sono stati registrati su disco) si
+possono usare le due funzioni di sistema \funcd{fsync} e \funcd{fdatasync}, i
+cui prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int fsync(int fd)}
+\fdesc{Sincronizza dati e metadati di un file.} 
+\fdecl{int fdatasync(int fd)}
+\fdesc{Sincronizza i dati di un file.} 
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+  \item[\errcode{EINVAL}] \param{fd} è un \index{file!speciali} file speciale
+    che non supporta la sincronizzazione.
+  \end{errlist}
+  ed inoltre \errval{EBADF}, \errval{EROFS} e \errval{EIO} nel loro
+  significato generico.}
+\end{funcproto}
+
+Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
+file specificato, ed attendono fino alla conclusione delle operazioni;
+\func{fsync} forza anche la sincronizzazione dei meta-dati del file (che
+riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli
+altri dati contenuti \itindex{inode} nell'\textit{inode} che si leggono con
+\func{fstat}, come i tempi del file).
+
+Si tenga presente che questo non comporta la sincronizzazione della
+directory che contiene il file (e scrittura della relativa voce su
+disco) che deve essere effettuata esplicitamente.\footnote{in realtà per
+  il filesystem \acr{ext2}, quando lo si monta con l'opzione \cmd{sync},
+  il kernel provvede anche alla sincronizzazione automatica delle voci
+  delle directory.}
+
+
+
+% TODO, aggiungere syncfs, introdotta con il 2.6.39
 
 
 \subsection{Le funzioni \func{openat}, \func{mkdirat} e affini}
 
 
 \subsection{Le funzioni \func{openat}, \func{mkdirat} e affini}
@@ -1775,19 +1850,15 @@ per \var{cmd} è riportata di seguito:
   (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
   (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
-  tab.~\ref{tab:file_open_flags}).
-% TODO toglire riferimeto a tabella flag e mettere altro
-
+  bit impostati da \func{open} all'apertura del file che vengono memorizzati,
+  quelli riportati in tab.~\ref{tab:open_access_mode_flag} e
+  tab.~\ref{tab:open_operation_flag}).
 \item[\const{F\_SETFL}] imposta il \textit{file status flag} al valore
   specificato da \param{arg}, ritorna un valore nullo in caso di successo o
 \item[\const{F\_SETFL}] imposta il \textit{file status flag} al valore
   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 tab.~\ref{tab:file_open_flags}.\footnote{la pagina di
-    manuale riporta come impostabili solo \const{O\_APPEND},
-    \const{O\_NONBLOCK} e \const{O\_ASYNC}.}
-% TODO toglire riferimeto a tabella flag e mettere altro
-
+  $-1$ in caso di errore. Possono essere impostati solo i bit riportati in
+  tab.~\ref{tab:open_operation_flag}.\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;
   ritorna un valore nullo in caso di successo o $-1$ in caso di errore.  Questa
 \item[\const{F\_GETLK}] richiede un controllo sul file lock specificato da
   \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
@@ -2119,8 +2190,9 @@ A parte i dettagli legati alla gestione delle operazioni di lettura e
 scrittura (sia per quel che riguarda la bufferizzazione, che le
 formattazioni), i \textit{file stream} restano del tutto equivalenti ai file
 descriptor (sui quali sono basati), ed in particolare continua a valere quanto
 scrittura (sia per quel che riguarda la bufferizzazione, che le
 formattazioni), i \textit{file stream} restano del tutto equivalenti ai file
 descriptor (sui quali sono basati), ed in particolare continua a valere quanto
-visto in sez.~\ref{sec:file_sharing} a proposito dell'accesso condiviso ed in
-sez.~\ref{sec:file_access_control} per il controllo di accesso.
+visto in sez.~\ref{sec:file_shared_access} a proposito dell'accesso
+concorrente ed in sez.~\ref{sec:file_access_control} per il controllo di
+accesso.
 
 \itindend{file~stream}
 
 
 \itindend{file~stream}
 
@@ -3867,12 +3939,6 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o
 % LocalWords:  locking fsetlocking type  Virtual operation dentry unistd sys AT
 % LocalWords:  modification hole functions FSETSIG pathname EEXIST CREAT EINTR
 % LocalWords:  EISDIR EFBIG EOVERFLOW ELOOP NOFOLLOW ENODEV ENOENT ENOTDIR fork
 % LocalWords:  locking fsetlocking type  Virtual operation dentry unistd sys AT
 % LocalWords:  modification hole functions FSETSIG pathname EEXIST CREAT EINTR
 % LocalWords:  EISDIR EFBIG EOVERFLOW ELOOP NOFOLLOW ENODEV ENOENT ENOTDIR fork
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End: 
-% LocalWords:  ENXIO  NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK EACCES% LocalWords:  EFAULT
 % LocalWords:  EMFILE ENAMETOOLONG ENFILE ENOMEM ENOSPC EROFS exec access RDWR
 % LocalWords:  RDONLY ioctl AND ACCMODE creation Denial Service DoS opendir NFS
 % LocalWords:  SOURCE LARGEFILE BITS NOCTTY TRUNC SHLOCK shared EXLOCK race SGI
 % LocalWords:  EMFILE ENAMETOOLONG ENFILE ENOMEM ENOSPC EROFS exec access RDWR
 % LocalWords:  RDONLY ioctl AND ACCMODE creation Denial Service DoS opendir NFS
 % LocalWords:  SOURCE LARGEFILE BITS NOCTTY TRUNC SHLOCK shared EXLOCK race SGI
@@ -3890,4 +3956,12 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o
 % LocalWords:  sigaction SIGINFO siginfo SETLEASE lease GETLEASE NOTIFY request
 % LocalWords:  everything framebuffer ENOTTY argp CDROM lsattr chattr magic
 % LocalWords:  number FIOCLEX FIONCLEX FIOASYNC FIONBIO FIOSETOWN FIOGETOWN
 % LocalWords:  sigaction SIGINFO siginfo SETLEASE lease GETLEASE NOTIFY request
 % LocalWords:  everything framebuffer ENOTTY argp CDROM lsattr chattr magic
 % LocalWords:  number FIOCLEX FIONCLEX FIOASYNC FIONBIO FIOSETOWN FIOGETOWN
-% LocalWords:  FIONREAD epoll FIOQSIZE side effects SAFE BYCALLER QUERY
+% LocalWords:  FIONREAD epoll FIOQSIZE side effects SAFE BYCALLER QUERY EACCES
+% LocalWords:  EBUSY OpenBSD
+% LocalWords:  ENXIO  NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK
+% LocalWords:  EFAULT
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: 
index 14771736bb47757c734a092e6a9c69b15f3ca072..7230f1a05040d61542534bde191e2cd7bd84beda 100644 (file)
Binary files a/img/filedup.dia and b/img/filedup.dia differ
index 5393ff1af27681f77df448c0038b3a613d777679..25911095b6ec3b8194bfa91f19a8b0499420c106 100644 (file)
Binary files a/img/filemultacc.dia and b/img/filemultacc.dia differ
index 077ceb01c4b0919a5a403b8ed2f364e1ed4704a9..01d2f4ad6ba661b0a4fe8ba4622e214448fbaf92 100644 (file)
Binary files a/img/fileshar.dia and b/img/fileshar.dia differ
diff --git a/ipc.tex b/ipc.tex
index 59c7f833eeb5fb0d0905ed7d249bca27bfddb326..1d085684f79bb80d538b6d9ea37875f3a46202ac 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -82,7 +82,7 @@ indicano la direzione del flusso dei dati.
 \end{figure}
 
 Chiaramente creare una pipe all'interno di un singolo processo non serve a
 \end{figure}
 
 Chiaramente creare una pipe all'interno di un singolo processo non serve a
-niente; se però ricordiamo quanto esposto in sez.~\ref{sec:file_sharing}
+niente; se però ricordiamo quanto esposto in sez.~\ref{sec:file_shared_access}
 riguardo al comportamento dei file descriptor nei processi figli, è immediato
 capire come una pipe possa diventare un meccanismo di intercomunicazione. Un
 processo figlio infatti condivide gli stessi file descriptor del padre,
 riguardo al comportamento dei file descriptor nei processi figli, è immediato
 capire come una pipe possa diventare un meccanismo di intercomunicazione. Un
 processo figlio infatti condivide gli stessi file descriptor del padre,
index 182ad5f29263bbc507b3a6c5aa88855cb8a22245..fa6e1d50969b63087422d86a5b12a7a3865e21e7 100644 (file)
@@ -549,10 +549,10 @@ ultimo) troveremo anche l'output completo del padre.
 L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file,
 valido anche per l'esempio precedente, ma meno evidente: il fatto cioè che non
 solo processi diversi possono scrivere in contemporanea sullo stesso file
 L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file,
 valido anche per l'esempio precedente, ma meno evidente: il fatto cioè che non
 solo processi diversi possono scrivere in contemporanea sullo stesso file
-(l'argomento della condivisione dei file è trattato in dettaglio in
-sez.~\ref{sec:file_sharing}), ma anche che, a differenza di quanto avviene per
-le variabili in memoria, la posizione corrente sul file è condivisa fra il
-padre e tutti i processi figli. 
+(l'argomento dell'accesso concorrente ai file è trattato in dettaglio in
+sez.~\ref{sec:file_shared_access}), ma anche che, a differenza di quanto
+avviene per le variabili in memoria, la posizione corrente sul file è
+condivisa fra il padre e tutti i processi figli.
 
 Quello che succede è che quando lo \textit{standard output}\footnote{si chiama
   così il file su cui un programma scrive i suoi dati in uscita, tratteremo
 
 Quello che succede è che quando lo \textit{standard output}\footnote{si chiama
   così il file su cui un programma scrive i suoi dati in uscita, tratteremo
@@ -563,8 +563,9 @@ processi figli tutti i \textit{file descriptor} (vedi sez.~\ref{sec:file_fd})
 dei file aperti nel processo padre (allo stesso modo in cui lo fa la funzione
 \func{dup}, trattata in sez.~\ref{sec:file_dup}), il che comporta che padre e
 figli condividono le stesse voci della \itindex{file~table} \textit{file
 dei file aperti nel processo padre (allo stesso modo in cui lo fa la funzione
 \func{dup}, trattata in sez.~\ref{sec:file_dup}), il che comporta che padre e
 figli condividono le stesse voci della \itindex{file~table} \textit{file
-  table} (tratteremo in dettagli questi termini in
-sez.~\ref{sec:file_sharing}) fra cui c'è anche la posizione corrente nel file.
+  table} (tratteremo in dettaglio questi termini in
+sez.~\ref{sec:file_shared_access}) fra cui c'è anche la posizione corrente nel
+file.
 
 In questo modo se un processo scrive su un file aggiornerà la posizione
 corrente sulla \itindex{file~table} \textit{file table}, e tutti gli altri
 
 In questo modo se un processo scrive su un file aggiornerà la posizione
 corrente sulla \itindex{file~table} \textit{file table}, e tutti gli altri
@@ -4148,11 +4149,11 @@ Nel caso dell'interazione fra processi la situazione è molto più semplice, ed
 occorre preoccuparsi della atomicità delle operazioni solo quando si ha a che
 fare con meccanismi di intercomunicazione (che esamineremo in dettaglio in
 cap.~\ref{cha:IPC}) o nelle operazioni con i file (vedremo alcuni esempi in
 occorre preoccuparsi della atomicità delle operazioni solo quando si ha a che
 fare con meccanismi di intercomunicazione (che esamineremo in dettaglio in
 cap.~\ref{cha:IPC}) o nelle operazioni con i file (vedremo alcuni esempi in
-sez.~\ref{sec:file_atomic}). In questi casi in genere l'uso delle appropriate
-funzioni di libreria per compiere le operazioni necessarie è garanzia
-sufficiente di atomicità in quanto le \textit{system call} con cui esse sono
-realizzate non possono essere interrotte (o subire interferenze pericolose) da
-altri processi.
+sez.~\ref{sec:file_shared_access}). In questi casi in genere l'uso delle
+appropriate funzioni di libreria per compiere le operazioni necessarie è
+garanzia sufficiente di atomicità in quanto le \textit{system call} con cui
+esse sono realizzate non possono essere interrotte (o subire interferenze
+pericolose) da altri processi.
 
 Nel caso dei segnali invece la situazione è molto più delicata, in quanto lo
 stesso processo, e pure alcune \textit{system call}, possono essere interrotti
 
 Nel caso dei segnali invece la situazione è molto più delicata, in quanto lo
 stesso processo, e pure alcune \textit{system call}, possono essere interrotti
index fb63b0b7ee85f78ca2a12907062c648eb8383557..4c60c0a7fe5e6b97299063780373ced4e606a378 100644 (file)
@@ -1241,9 +1241,9 @@ Come per tutti i file descriptor anche per i socket viene mantenuto un numero
 di riferimenti, per cui se più di un processo ha lo stesso socket aperto
 l'emissione del FIN e la sequenza di chiusura di TCP non viene innescata
 fintanto che il numero di riferimenti non si annulla, questo si applica, come
 di riferimenti, per cui se più di un processo ha lo stesso socket aperto
 l'emissione del FIN e la sequenza di chiusura di TCP non viene innescata
 fintanto che il numero di riferimenti non si annulla, questo si applica, come
-visto in sez.~\ref{sec:file_sharing}, sia ai file descriptor duplicati che a
-quelli ereditati dagli eventuali processi figli, ed è il comportamento che ci
-si aspetta in una qualunque applicazione client/server.
+visto in sez.~\ref{sec:file_shared_access}, sia ai file descriptor duplicati
+che a quelli ereditati dagli eventuali processi figli, ed è il comportamento
+che ci si aspetta in una qualunque applicazione client/server.
 
 Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura
 descritta in sez.~\ref{sec:TCP_conn_term}, si può invece usare la funzione
 
 Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura
 descritta in sez.~\ref{sec:TCP_conn_term}, si può invece usare la funzione