%% fileunix.tex
%%
-%% Copyright (C) 2000-2009 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2011 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
alle dimensioni dei blocchi del filesystem; per il
kernel 2.6 basta che siano allineati a multipli di 512
byte.\\
- \const{O\_CLOEXEC} & Attiva la modalità di \textit{close-on-exec} (vedi
+ \const{O\_CLOEXEC} & Attiva la modalità di \itindex{close-on-exec}
+ \textit{close-on-exec} (vedi
sez.~\ref{sec:file_sharing} e
\ref{sec:file_fcntl}).\footnotemark\\
\hline
\itindex{thread} \textit{thread}, fra l'apertura del file e l'impostazione
della suddetta modalità con \func{fcntl}.}
+%TODO trattare le differenze fra O_DSYNC, O_SYNC e O_RSYNC introdotte nella
+% nello sviluppo del kernel 2.6.33, vedi http://lwn.net/Articles/350219/
+
Questa caratteristica permette di prevedere qual è il valore del file
descriptor che si otterrà al ritorno di \func{open}, e viene talvolta usata da
alcune applicazioni per sostituire i file corrispondenti ai file standard
successo e $-1$ in caso di errore nel qual caso \var{errno} assumerà uno
dei valori:
\begin{errlist}
- \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo.
+ \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo.
\item[\errcode{EINVAL}] \param{whence} non è un valore valido.
+ \item[\errcode{EOVERFLOW}] \param{offset} non può essere rappresentato nel
+ tipo \type{off\_t}.
\end{errlist}
ed inoltre \errval{EBADF}.}
\end{functions}
per ottenere la nuova posizione corrente.
\end{basedescript}
-Come accennato in sez.~\ref{sec:file_file_size} con \func{lseek} è possibile
-impostare la posizione corrente anche oltre la fine del file, e alla
-successiva scrittura il file sarà esteso. La chiamata non causa nessun accesso
-al file, si limita a modificare la posizione corrente (cioè il valore
-\var{f\_pos} in \param{file}, vedi fig.~\ref{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 funzione con
-\code{lseek(fd, 0, SEEK\_CUR)}.
+Si tenga presente che la chiamata a \func{lseek} non causa nessun accesso al
+file, si limita a modificare la posizione corrente (cioè il valore
+\var{f\_pos} in \param{file}, vedi fig.~\ref{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 funzione con \code{lseek(fd, 0, SEEK\_CUR)}.
Si tenga presente inoltre che usare \const{SEEK\_END} non assicura affatto che
la successiva scrittura avvenga alla fine del file, infatti se questo è stato
non supportano questa funzione, come ad esempio per i file di
terminale.\footnote{altri sistemi, usando \const{SEEK\_SET}, in questo caso
ritornano il numero di caratteri che vi sono stati scritti.} Lo standard
-POSIX però non specifica niente in proposito. Infine alcuni file speciali, ad
+POSIX però non specifica niente in proposito. Inoltre alcuni file speciali, ad
esempio \file{/dev/null}, non causano un errore ma restituiscono un valore
indefinito.
+\itindbeg{sparse~file}
+
+Infine si tenga presente che, come accennato in sez.~\ref{sec:file_file_size},
+con \func{lseek} è possibile impostare una posizione anche oltre la corrente
+fine del file; ed in tal caso alla successiva scrittura il file sarà esteso a
+partire da detta posizione. In questo caso si ha quella che viene chiamata la
+creazione di un \index{file!\textit{hole}} \textsl{buco} nel file, accade cioè
+che nonostante la dimensione del file sia cresciuta in seguito alla scrittura
+effettuata, lo spazio vuoto fra la precedente fine del file ed la nuova parte
+scritta dopo lo spostamento, non corrisponda ad una allocazione effettiva di
+spazio su disco, che sarebbe inutile dato che quella zona è effettivamente
+vuota.
+
+Questa è una delle caratteristiche spcifiche della gestione dei file di un
+sistema unix-like, ed in questo caso si ha appunto quello che in gergo si
+chiama un \index{file!\textit{hole}} \textit{hole} nel file e si dice che il
+file in questione è uno \textit{sparse file}. In sostanza, se si ricorda la
+struttura di un filesystem illustrata in fig.~\ref{fig:file_filesys_detail},
+quello che accade è che nell'\textit{inode} del file viene segnata
+l'allocazione di un blocco di dati a partire dalla nuova posizione, ma non
+viene allocato nulla per le posizioni intermedie; in caso di lettura
+sequenziale del contenuto del file il kernel si accorgerà della presenza del
+buco, e restituirà degli zeri come contenuto di quella parte del file.
+
+Questa funzionalità comporta una delle caratteristiche della gestione dei file
+su Unix che spesso genera più confusione in chi non la conosce, per cui
+sommando le dimensioni dei file si può ottenere, se si hanno molti
+\textit{sparse file}, un totale anche maggiore della capacità del proprio
+disco e comunque maggiore della dimensione che riporta un comando come
+\cmd{du}, che calcola lo spazio disco occupato in base al numero dei blocchi
+effettivamente allocati per il file.
+
+Questo avviene proprio perché in un sistema unix-like la dimensione di un file
+è una caratteristica del tutto indipendente dalla quantità di spazio disco
+effettivamente allocato, e viene registrata sull'\textit{inode} come le altre
+proprietà del file. La dimensione viene aggiornata automaticamente quando si
+estende un file scrivendoci, e viene riportata dal campo \var{st\_size} di una
+struttura \struct{stat} quando si effettua chiamata ad una delle funzioni
+\texttt{*stat} viste in sez.~\ref{sec:file_stat}.
+
+Questo comporta che in generale, fintanto che lo si è scritto sequenzialmente,
+la dimensione di un file sarà più o meno corrispondente alla quantità di
+spazio disco da esso occupato, ma esistono dei casi, come questo in cui ci si
+sposta in una posizione oltre la fine corrente del file, o come quello
+accennato in in sez.~\ref{sec:file_file_size} in cui si estende la dimensione
+di un file con una \func{truncate}, in cui in sostanza di modifica il valore
+della dimensione di \var{st\_size} senza allocare spazio su disco. Questo
+consente di creare inizialmente file di dimensioni anche molto grandi, senza
+dover occupare da subito dello spazio disco che in realtà sarebbe
+inutilizzato.
+
+\itindend{sparse~file}
+
\subsection{Le funzioni \func{read} e \func{pread}}
\label{sec:file_read}
\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_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
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
+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.