%% fileio.tex (merge fileunix.tex - filestd.tex)
%%
-%% Copyright (C) 2000-2014 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2015 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",
in fase di apertura del file, deve
invece essere attivato successivamente con
\func{fcntl}.\\
- \const{O\_CLOEXEC}& Attiva la modalità di \itindex{close-on-exec}
- \textit{close-on-exec} (vedi
+ \const{O\_CLOEXEC}& Attiva la modalità di \textit{close-on-exec} (vedi
sez.~\ref{sec:proc_exec}) sul file. Il flag è
previsto dallo standard POSIX.1-2008, ed è stato
introdotto con il kernel 2.6.23 per evitare una
operazioni di lettura e scrittura avvengono a partire da questa posizione che
viene automaticamente spostata in avanti del numero di byte letti o scritti.
-In genere, a meno di non avere richiesto la modalità \itindex{append~mode} di
-\textit{append} con \const{O\_APPEND}, questa posizione viene impostata a zero
-all'apertura del file. È possibile impostarla ad un valore qualsiasi con la
-funzione di sistema \funcd{lseek}, il cui prototipo è:
+In genere, a meno di non avere richiesto la modalità di \textit{append} con
+\const{O\_APPEND}, questa posizione viene impostata a zero all'apertura del
+file. È possibile impostarla ad un valore qualsiasi con la funzione di sistema
+\funcd{lseek}, il cui prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
\item[\errcode{EINVAL}] \param{whence} non è un valore valido.
\item[\errcode{EOVERFLOW}] \param{offset} non può essere rappresentato nel
tipo \type{off\_t}.
- \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo.
+ \item[\errcode{ESPIPE}] \param{fd} è una \textit{pipe}, un socket o una
+ \textit{fifo}.
\end{errlist}
ed inoltre \errval{EBADF} nel suo significato generico.}
\end{funcproto}
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
- condition}, vedi sez.~\ref{sec:file_shared_access}).
+(questa è una potenziale sorgente di \textit{race 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
un errore ma restituiscono un valore indefinito.
\itindbeg{sparse~file}
+\index{file!\textit{hole}|(}
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. In tal caso alla successiva scrittura il file sarà esteso a
partire da detta posizione, con la creazione di quello che viene chiamato
-\index{file!\textit{hole}} ``\textsl{buco}'' (in gergo \textit{hole}) nel
-file. Il nome deriva dal fatto 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
-corrisponde ad una allocazione effettiva di spazio su disco, che sarebbe
-inutile dato che quella zona è effettivamente vuota.
+``\textsl{buco}'' (in gergo \textit{hole}) nel file. Il nome deriva dal fatto
+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 corrisponde ad una allocazione effettiva di
+spazio su disco, che sarebbe inutile dato che quella zona è effettivamente
+vuota.
Questa è una delle caratteristiche specifiche della gestione dei file di un
sistema unix-like e si dice che il file in questione è uno \textit{sparse
A partire dal kernel 3.1, riprendendo una interfaccia adottata su Solaris,
sono state aggiunti due nuovi valori per l'argomento \param{whence}, riportati
nella seconda sezione di tab.~\ref{tab:lseek_whence_values}, che consentono di
-riconoscere la presenza di \index{file!\textit{hole}} \textit{hole}
-all'interno dei file ad uso di quelle applicazioni (come i programmi di
-backup) che possono salvare spazio disco nella copia degli \textit{sparse
- file}. Una applicazione può così determinare la presenza di un
-\index{file!\textit{hole}} \textit{hole} usando \const{SEEK\_HOLE} all'inizio
-del file e determinare poi l'inizio della successiva sezione di dati usando
+riconoscere la presenza di \textit{hole} all'interno dei file ad uso di quelle
+applicazioni (come i programmi di backup) che possono salvare spazio disco
+nella copia degli \textit{sparse file}. Una applicazione può così determinare
+la presenza di un \textit{hole} usando \const{SEEK\_HOLE} all'inizio del file
+e determinare poi l'inizio della successiva sezione di dati usando
\const{SEEK\_DATA}. Per compatibilità con i filesystem che non supportano
questa funzionalità è previsto comunque che in tal caso \const{SEEK\_HOLE}
riporti sempre la fine del file e \const{SEEK\_DATA} il valore
di \param{offset}.
Inoltre la decisione di come riportare (o di non riportare) la presenza di un
-\index{file!\textit{hole}} buco in un file è lasciata all'implementazione del
+buco in un file è lasciata all'implementazione del
filesystem, dato che esistono vari motivi per cui una sezione di un file può
non contenere dati ed essere riportata come tale (ad esempio può essere stata
preallocata con \func{fallocate}, vedi sez.~\ref{sec:file_fadvise}) oltre a
disco di un file, per il quale esiste una specifica operazione di controllo
(vedi sez.~\ref{sec:file_fcntl_ioctl}).
+\index{file!\textit{hole}|)}
\subsection{Le funzioni per la lettura di un file}
Con i \textsl{file regolari} questa è l'unica situazione in cui si può avere
un numero di byte letti inferiore a quello richiesto, ma questo non è vero
-quando si legge da un terminale, da una fifo o da una pipe. In tal caso
-infatti, se non ci sono dati in ingresso, la \func{read} si blocca (a meno di
-non aver selezionato la modalità non bloccante, vedi
-sez.~\ref{sec:file_noblocking}) e ritorna solo quando ne arrivano; se il numero
-di byte richiesti eccede quelli disponibili la funzione ritorna comunque, ma
-con un numero di byte inferiore a quelli richiesti.
+quando si legge da un terminale, da una \textit{fifo} o da una
+\textit{pipe}. In tal caso infatti, se non ci sono dati in ingresso, la
+\func{read} si blocca (a meno di non aver selezionato la modalità non
+bloccante, vedi sez.~\ref{sec:file_noblocking}) e ritorna solo quando ne
+arrivano; se il numero di byte richiesti eccede quelli disponibili la funzione
+ritorna comunque, ma con un numero di byte inferiore a quelli richiesti.
Lo stesso comportamento avviene caso di lettura dalla rete (cioè su un socket,
come vedremo in sez.~\ref{sec:sock_io_behav}), o per la lettura da certi file
potuto scrivere qualsiasi dato.
\item[\errcode{EINVAL}] \param{fd} è connesso ad un oggetto che non consente
la scrittura o si è usato \const{O\_DIRECT} ed il buffer non è allineato.
- \item[\errcode{EPIPE}] \param{fd} è connesso ad una pipe il cui altro capo è
- chiuso in lettura; in questo caso viene anche generato il segnale
- \signal{SIGPIPE}, se questo viene gestito (o bloccato o ignorato) la
- funzione ritorna questo errore.
+ \item[\errcode{EPIPE}] \param{fd} è connesso ad una \textit{pipe} il cui
+ altro capo è chiuso in lettura; in questo caso viene anche generato il
+ segnale \signal{SIGPIPE}, se questo viene gestito (o bloccato o ignorato)
+ la funzione ritorna questo errore.
\end{errlist}
ed inoltre \errval{EBADF}, \errval{EFAULT}, \errval{EIO}, \errval{EISDIR},
\errval{ENOSPC} nel loro significato generico.}
Come nel caso di \func{read} la funzione tenta di scrivere \param{count} byte
a partire dalla posizione corrente nel file e sposta automaticamente la
posizione in avanti del numero di byte scritti. Se il file è aperto in
-modalità \itindex{append~mode} \const{O\_APPEND} i dati vengono sempre scritti
+modalità \textit{append} con \const{O\_APPEND} i dati vengono sempre scritti
alla fine del file. Lo standard POSIX richiede che i dati scritti siano
immediatamente disponibili ad una \func{read} chiamata dopo che la
\func{write} che li ha scritti è ritornata; ma dati i meccanismi di caching
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_ioctl}), questo verrà cancellato nel file descriptor
-restituito come copia.
+descriptor, se questo ha il flag di \textit{close-on-exec} attivo (vedi
+sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl_ioctl}), 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
+\textit{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).
+sez.~\ref{sec:ipc_pipe_use}, quando tratteremo le \textit{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
\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}.
+flag di \textit{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}
% inserita nello stesso standard e da usare con openat, vedi
% http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
+% TODO: manca prototipo e motivazione di execveat, vedi
+% http://man7.org/linux/man-pages/man2/execveat.2.html
\subsection{Le operazioni di controllo}
\label{sec:file_fcntl_ioctl}
o \errcode{EMFILE} se il processo ha già raggiunto il massimo numero di
descrittori consentito.
+\itindbeg{close-on-exec}
+
\item[\const{F\_DUPFD\_CLOEXEC}] ha lo stesso effetto di \const{F\_DUPFD}, ma
- in più attiva il flag di \itindex{close-on-exec} \textit{close-on-exec} sul
- file descriptor duplicato, in modo da evitare una successiva chiamata con
+ in più attiva il flag di \textit{close-on-exec} sul file descriptor
+ duplicato, in modo da evitare una successiva chiamata con
\const{F\_SETFD}. La funzionalità è stata introdotta con il kernel 2.6.24 ed
è prevista nello standard POSIX.1-2008 (si deve perciò definire
\macro{\_POSIX\_C\_SOURCE} ad un valore adeguato secondo quanto visto in
flags} di \param{fd} in caso di successo o $-1$ in caso di errore, il
terzo argomento viene ignorato. Non sono previsti errori diversi da
\errval{EBADF}. Al momento l'unico flag usato è quello di
- \itindex{close-on-exec} \textit{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 sez.~\ref{sec:proc_exec}). Un valore
- nullo significa pertanto che il flag non è impostato.
+ \textit{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 sez.~\ref{sec:proc_exec}). Un valore nullo significa
+ pertanto che il flag non è impostato.
\item[\const{F\_SETFD}] imposta il valore dei \textit{file descriptor flags}
al valore specificato con \param{arg}, ritorna un valore nullo in caso di
successo e $-1$ in caso di errore. Non sono previsti errori diversi da
\errval{EBADF}. Dato che l'unico flag attualmente usato è quello di
- \itindex{close-on-exec} \textit{close-on-exec}, identificato dalla costante
- \const{FD\_CLOEXEC}, tutti gli altri bit di \param{arg}, anche se impostati,
- vengono ignorati.\footnote{questo almeno è quanto avviene fino al kernel
- 3.2, come si può evincere dal codice della funzione \texttt{do\_fcntl} nel
- file \texttt{fs/fcntl.c} dei sorgenti del kernel.}
+ \textit{close-on-exec}, identificato dalla costante \const{FD\_CLOEXEC},
+ tutti gli altri bit di \param{arg}, anche se impostati, vengono
+ ignorati.\footnote{questo almeno è quanto avviene fino al kernel 3.2, come
+ si può evincere dal codice della funzione \texttt{do\_fcntl} nel file
+ \texttt{fs/fcntl.c} dei sorgenti del kernel.}
+\itindend{close-on-exec}
\item[\const{F\_GETFL}] ritorna il valore dei \textit{file status flags} di
\param{fd} in caso di successo o $-1$ in caso di errore, il terzo argomento
sufficiente per creare il \textit{file lease}, \errcode{EACCES} se non si è
il proprietario del file e non si hanno i privilegi di
amministratore.\footnote{per la precisione occorre la capacità
- \itindex{capabilities} \const{CAP\_LEASE}.}
+ \const{CAP\_LEASE}.}
Il supporto il supporto per i \textit{file lease}, che consente ad un
processo che detiene un \textit{lease} su un file di riceve una notifica
del buffer associato alla \textit{pipe} \param{fd} (vedi
sez.~\ref{sec:ipc_pipes}) o $-1$ in caso di errore, il terzo argomento viene
ignorato. Non sono previsti errori diversi da \errval{EBADF}, che viene
- restituito anche se il file descriptor non è una pipe. Il comando è
+ restituito anche se il file descriptor non è una \textit{pipe}. Il comando è
specifico di Linux, è disponibile solo a partire dal kernel 2.6.35, ed è
utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
inferiore, il valore specificato viene in genere arrotondato per eccesso al
valore ritenuto più opportuno dal sistema, pertanto una volta eseguita la
modifica è opportuno rileggere la nuova dimensione con
- \const{F\_GETPIPE\_SZ}. I processi non privilegiati\footnote{{per la
- precisione occorre la capacità \itindex{capabilities}
- \const{CAP\_SYS\_RESOURCE}.}} non possono impostare un valore valore
- superiore a quello indicato da \sysctlfile{fs/pipe-size-max}. Il comando è
- specifico di Linux, è disponibile solo a partire dal kernel 2.6.35, ed è
- utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
+ \const{F\_GETPIPE\_SZ}. I processi non privilegiati\footnote{per la
+ precisione occorre la capacità \const{CAP\_SYS\_RESOURCE}.} non possono
+ impostare un valore valore superiore a quello indicato da
+ \sysctlfile{fs/pipe-size-max}. Il comando è specifico di Linux, è
+ disponibile solo a partire dal kernel 2.6.35, ed è utilizzabile solo se si è
+ definita la macro \macro{\_GNU\_SOURCE}.
\end{basedescript}
prime, per cui, come illustrato in \cite{LinDevDri}, eventuali operazioni
specifiche che usino lo stesso valore verrebbero ignorate:
\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\const{FIOCLEX}] imposta il flag di \itindex{close-on-exec}
- \textit{close-on-exec} sul file, in questo caso, essendo usata come
- operazione logica, \func{ioctl} non richiede un terzo argomento, il cui
- eventuale valore viene ignorato.
-\item[\const{FIONCLEX}] cancella il flag di \itindex{close-on-exec}
- \textit{close-on-exec} sul file, in questo caso, essendo usata come
- operazione logica, \func{ioctl} non richiede un terzo argomento, il cui
- eventuale valore viene ignorato.
+\item[\const{FIOCLEX}] imposta il flag di \textit{close-on-exec} sul file, in
+ questo caso, essendo usata come operazione logica, \func{ioctl} non richiede
+ un terzo argomento, il cui eventuale valore viene ignorato.
+\item[\const{FIONCLEX}] cancella il flag di \textit{close-on-exec} sul file,
+ in questo caso, essendo usata come operazione logica, \func{ioctl} non
+ richiede un terzo argomento, il cui eventuale valore viene ignorato.
\item[\const{FIOASYNC}] abilita o disabilita la modalità di I/O asincrono sul
file (vedi sez.~\ref{sec:signal_driven_io}); il terzo argomento
deve essere un puntatore ad un intero (cioè di tipo \texttt{const int *})
su una stringa, in genere l'uso di \func{sprintf} è sconsigliato in quanto è
possibile, se non si ha la sicurezza assoluta sulle dimensioni del risultato
della stampa, eccedere le dimensioni di \param{str}, con conseguente
-sovrascrittura di altre variabili e possibili \itindex{buffer~overflow}
-\textit{buffer overflow}. Per questo motivo si consiglia l'uso
-dell'alternativa \funcd{snprintf}, il cui prototipo è:
+sovrascrittura di altre variabili e possibili \textit{buffer overflow}. Per
+questo motivo si consiglia l'uso dell'alternativa \funcd{snprintf}, il cui
+prototipo è:
\begin{funcproto}{
\fhead{stdio.h}
\func{vsprintf}.}
\end{funcproto}
-\noindent in modo da evitare possibili \itindex{buffer~overflow} buffer
-overflow.
+\noindent in modo da evitare possibili \textit{buffer overflow}.
Per eliminare alla radice questi problemi, la \acr{glibc} supporta una