X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=3a9d1c0ba63e5a10f116f159ec9fa3ff549feab6;hp=ea5484a93225cdf11f0f770e98474ea489320ad2;hb=b81723c64c1d63b89cd3cec12f2fcccc4a756967;hpb=1fe3be8e307c2190bf91e531478d39a6d3d51911 diff --git a/fileunix.tex b/fileunix.tex index ea5484a..3a9d1c0 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -1,6 +1,6 @@ %% fileunix.tex %% -%% Copyright (C) 2000-2009 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2010 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", @@ -523,8 +523,10 @@ file. 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} @@ -546,14 +548,12 @@ seguenti valori\footnote{per compatibilit 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 @@ -568,15 +568,67 @@ per i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che 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. - -\subsection{La funzione \func{read}} +\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} - Una volta che un file è stato aperto (con il permesso in lettura) si possono leggere i dati che contiene utilizzando la funzione \funcd{read}, il cui prototipo è: @@ -689,7 +741,7 @@ dichiarazioni \file{unistd.h}. -\subsection{La funzione \func{write}} +\subsection{Le funzioni \func{write} e \func{pwrite}} \label{sec:file_write} Una volta che un file è stato aperto (con il permesso in scrittura) si può