%% License".
%%
-\chapter{La gestione dei contenuti dei file}
+\chapter{La gestione dell'I/O su file}
\label{cha:file_IO_interface}
sez.~\ref{sec:proc_hierarchy} come il kernel mantenga un elenco di tutti
processi nella cosiddetta \itindex{process~table} \textit{process table}. Lo
stesso, come accennato in sez.~\ref{sec:file_vfs_work}, vale anche per tutti i
-file che sono stati aperti, il cui elenco viene mantenuto nella cosiddetta
+file aperti, il cui elenco viene mantenuto nella cosiddetta
\itindex{file~table} \textit{file table}.
La \itindex{process~table} \textit{process table} è una tabella che contiene
una voce per ciascun processo attivo nel sistema. Ciascuna voce è costituita
-da una struttura di tipo \kstruct{task\_struct} nella quale sono raccolte
-tutte le informazioni relative al processo, fra queste informazioni c'è anche
-il puntatore ad una ulteriore struttura di tipo
+dal puntatore a una struttura di tipo \kstruct{task\_struct} nella quale sono
+raccolte tutte le informazioni relative al processo, fra queste informazioni
+c'è anche il puntatore ad una ulteriore struttura di tipo
\kstruct{files\_struct},\footnote{la definizione corrente di questa struttura
si trova nel file \texttt{include/linux/fdtable.h} dei sorgenti del kernel,
quella mostrata in fig.~\ref{fig:file_proc_file} è una versione pesantemente
- semplificata.} in cui sono contenute le informazioni relative ai file che il
-processo ha aperto.
+ semplificata.} che contiene le informazioni relative ai file che il processo
+ha aperto.
-La \itindex{file~table} \textit{file table} è invece una tabella che contiene
-una voce per ciascun file che è stato aperto nel sistema. Come accennato in
+La \itindex{file~table} \textit{file table} è una tabella che contiene una
+voce per ciascun file che è stato aperto nel sistema. Come accennato in
sez.~\ref{sec:file_vfs_work} per ogni file aperto viene allocata una struttura
\kstruct{file} e la \textit{file table} è costituita da un elenco di puntatori
-a ciascuna di queste strutture, che come illustrato in
-fig.~\ref{fig:kstruct_file}, contengono le informazioni necessario per la
-gestione dei contenuti del file, fra cui:
+a ciascuna di queste strutture, che, come illustrato in
+fig.~\ref{fig:kstruct_file}, contengono le informazioni necessarie per la
+gestione dei file, ed in particolare:
\begin{itemize*}
-\item lo stato del file nel campo \var{f\_flags}.
+\item il flag di stato \itindex{file~status~flag} del file nel campo
+ \var{f\_flags}.
\item la posizione corrente nel file, il cosiddetto \textit{offset}, nel campo
\var{f\_pos}.
\item un puntatore alla struttura \kstruct{inode} che identifica
\begin{figure}[!htb]
\centering
- \includegraphics[width=13cm]{img/procfile}
+ \includegraphics[width=12cm]{img/procfile}
\caption{Schema della architettura dell'accesso ai file attraverso
l'interfaccia dei \textit{file descriptor}.}
\label{fig:file_proc_file}
vengono assegnati in successione tutte le volte che si apre un nuovo file,
posto che non ne sia stato chiuso nessuno in precedenza.
-In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
+In tutti i sistemi unix-like esiste poi una convenzione generale per cui ogni
processo viene lanciato dalla shell con almeno tre file aperti. Questi, per
quanto appena detto, avranno come \itindex{file~descriptor} \textit{file
descriptor} i valori 0, 1 e 2. Benché questa sia soltanto una convenzione,
essa è seguita dalla gran parte delle applicazioni, e non aderirvi potrebbe
portare a gravi problemi di interoperabilità.
-Il primo file è sempre associato al cosiddetto \textit{standard input}; è cioè
-il file da cui un processo si aspetta di ricevere i dati in ingresso. Il
-secondo file è il cosiddetto \textit{standard output}, cioè quello su cui ci
-si aspetta debbano essere inviati i dati in uscita. Il terzo è lo
-\textit{standard error}, su cui viene inviata l'uscita relativa agli errori.
-Nel caso della shell tutti questi file sono associati al terminale di
-controllo, e corrispondono quindi alla lettura della tastiera per l'ingresso e
-alla scrittura sul terminale per l'uscita. Lo standard POSIX.1 provvede, al
-posto dei valori numerici, tre costanti simboliche, definite in
-tab.~\ref{tab:file_std_files}.
+Il primo file è sempre associato al cosiddetto \itindex{standard~input}
+\textit{standard input}, è cioè il file da cui un processo si aspetta di dover
+leggere i dati in ingresso. Il secondo file è il cosiddetto
+\itindex{standard~output} \textit{standard output}, cioè quello su cui ci si
+aspetta di dover scrivere i dati in uscita. Il terzo è lo
+\itindex{standard~error} \textit{standard error}, su cui vengono scritti i
+dati relativi agli errori. Nel caso della shell tutti questi file sono
+associati al terminale di controllo, e corrispondono quindi alla lettura della
+tastiera per l'ingresso e alla scrittura sul terminale per l'uscita. Lo
+standard POSIX.1 provvede, al posto dei valori numerici, tre costanti
+simboliche, definite in tab.~\ref{tab:file_std_files}.
\begin{table}[htb]
\centering
In fig.~\ref{fig:file_proc_file} si è rappresentata una situazione diversa
rispetto a quella usuale della shell, in cui tutti e tre questi file fanno
riferimento al terminale su cui si opera. Nell'esempio invece viene illustrata
-la situazione di un programma in cui lo \textit{standard input} è associato ad
-un certo file mentre lo \textit{standard output} e lo \textit{standard error}
-sono entrambi associati ad un altro file.
-
-Si noti come questi ultimi, pur utilizzando strutture \kstruct{file} diverse,
-essendo il file che è stato aperto lo stesso, fanno a loro volta riferimento
-allo stesso \itindex{inode} \textit{inode}. Questo è quello che avviene
-normalmente quando si apre più volte lo stesso file.
+la situazione di un programma in cui lo \itindex{standard~input}
+\textit{standard input} è associato ad un file mentre lo
+\itindex{standard~output} \textit{standard output} e lo
+\itindex{standard~error} \textit{standard error} sono associati ad un altro
+file. Si noti poi come per questi ultimi le strutture \kstruct{file} nella
+\itindex{file~table} \textit{file table}, pur essendo distinte, fanno
+riferimento allo stesso \itindex{inode} \textit{inode}, dato che il file che è
+stato aperto lo stesso. Questo è quello che avviene normalmente quando si apre
+più volte lo stesso file.
Si ritrova quindi anche con le voci della \itindex{file~table} \textit{file
table} una situazione analoga di quella delle voci di una directory, con la
\subsection{Apertura e creazione di un file}
\label{sec:file_open}
-La funzione di sistema \funcd{open} è la funzione fondamentale
-dell'interfaccia di gestione dei file su Unix, ed è quella che dato un
-\textit{pathname} consente di ottenere un file descriptor ``\textsl{aprendo}''
-il file corrispondente,\footnote{è questa funzione che alloca la struttura
- \kstruct{file}, la inserisce nella \itindex{file~table} \textit{file table}
- e crea il riferimento nella \kstruct{files\_struct} del processo.} il suo
-prototipo è:
+La funzione di sistema \funcd{open} è la principale funzione dell'interfaccia
+di gestione dei file, quella che dato un \textit{pathname} consente di
+ottenere un file descriptor ``\textsl{aprendo}'' il file
+corrispondente,\footnote{è \func{open} che alloca \kstruct{file}, la inserisce
+ nella \itindex{file~table} \textit{file table} e crea il riferimento nella
+ \kstruct{files\_struct} del processo.} il suo prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{EEXIST}] \param{pathname} esiste e si è specificato
- \const{O\_CREAT} e \const{O\_EXCL}.
+ \const{O\_CREAT} e \const{O\_EXCL}.
+ \item[\errcode{EINTR}] la funzione era bloccata ed è stata interrotta da un
+ segnale (vedi sez.~\ref{sec:sig_gen_beha}).
\item[\errcode{EISDIR}] \param{pathname} indica una directory e si è tentato
- l'accesso in scrittura.
+ l'accesso in scrittura o in lettura/scrittura.
+ \item[\errcode{EFBIG}] il file è troppo grande per essere aperto (lo
+ standard richiederebbe \errval{EOVERFLOW}).
+ \item[\errcode{ELOOP}] si sono incontrati troppi collegamenti simbolici nel
+ risolvere \param{pathname} o si è indicato \const{O\_NOFOLLOW} e
+ \param{pathname} è un collegamento simbolico.
+ \item[\errcode{ENODEV}] \param{pathname} si riferisce a un file di
+ dispositivo che non esiste.
+ \item[\errcode{ENOENT}] \param{pathname} non esiste e non si è richiesto
+ \const{O\_CREAT}, o non esiste un suo componente.
\item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e
\param{pathname} non è una directory.
\item[\errcode{ENXIO}] si sono impostati \const{O\_NOBLOCK} o
\const{O\_WRONLY} ed il file è una fifo che non viene letta da nessun
processo o \param{pathname} è un file di dispositivo ma il dispositivo è
assente.
- \item[\errcode{ENODEV}] \param{pathname} si riferisce a un file di
- dispositivo che non esiste.
+ \item[\errcode{EPERM}] si è specificato \const{O\_NOATIME} e non si è né
+ amministratori né proprietari del file.
\item[\errcode{ETXTBSY}] si è cercato di accedere in scrittura all'immagine
di un programma in esecuzione.
- \item[\errcode{ELOOP}] si sono incontrati troppi link simbolici nel
- risolvere il \textit{pathname} o si è indicato \const{O\_NOFOLLOW} e
- \param{pathname} è un link simbolico.
+ \item[\errcode{EWOULDBLOCK}] la funzione si sarebbe bloccata ma si è
+ richiesto \const{O\_NOBLOCK}.
\end{errlist}
- ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOENT},
- \errval{EROFS}, \errval{EFAULT}, \errval{ENOSPC}, \errval{ENOMEM},
- \errval{EMFILE} e \errval{ENFILE} nel loro significato generico.}
+ ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EMFILE},
+ \errval{ENAMETOOLONG}, \errval{ENFILE}, \errval{ENOMEM}, \errval{ENOSPC},
+ \errval{EROFS}, nel loro significato generico.}
\end{funcproto}
La funzione apre il file indicato da \param{pathname} nella modalità indicata da
\param{flags}. Essa può essere invocata in due modi diversi, specificando
opzionalmente un terzo argomento \param{mode}. Qualora il file non esista e
venga creato, questo argomento consente di indicare quali permessi dovranno
-essergli assegnati. La funzione restituisce il primo file descriptor libero.
-
-Quest'ultima caratteristica permette di prevedere sempre 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 visti in tab.~\ref{tab:file_std_files}. Se ad esempio si chiude lo
-standard input e si apre subito dopo un nuovo file questo diventerà il nuovo
-standard input (avrà cioè il file descriptor 0).
+essergli assegnati. I valori possibili sono gli stessi già visti in
+sez.~\ref{sec:file_perm_overview} e possono essere specificati come OR binario
+delle costanti descritte in tab.~\ref{tab:file_bit_perm}. Questi permessi sono
+comunque filtrati dal valore della \itindex{umask} \textit{umask} (vedi
+sez.~\ref{sec:file_perm_management}) del processo.
+
+La funzione restituisce sempre il primo file descriptor libero, e questa
+caratteristica permette di prevedere qual è il valore del file descriptor che
+si otterrà al ritorno di \func{open}, e viene spesso usata dalle applicazioni
+per sostituire i file corrispondenti ai file standard visti in
+tab.~\ref{tab:file_std_files}. Se ad esempio si chiude lo
+\itindex{standard~input} \textit{standard input} e si apre subito dopo un
+nuovo file questo diventerà il nuovo \itindex{standard~input} \textit{standard
+ input} (avrà cioè il file descriptor 0).
Al momento dell'apertura il nuovo file descriptor non è condiviso con nessun
-altro processo (torneremo sulla condivisione dei file, in genere accessibile
-dopo una \func{fork}, in sez.~\ref{sec:file_sharing}) ed è impostato per
-restare aperto attraverso una \func{exec} (come accennato in
-sez.~\ref{sec:proc_exec}). L'\textit{offset} è impostato all'inizio del file.
+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: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
+esso direttamente tramite il file descriptor, e quanto avviene al
+\textit{pathname} con cui lo si è aperto sarà del tutto ininfluente.
+
+Il comportamento della funzione e le diverse modalità con cui può essere
+aperto il file vengono controllati dall'argomento \param{flags} il cui valore
+deve essere indicato come maschera binaria in cui ciascun bit ha un
+significato specifico. Alcuni di questi bit vanno anche a costituire i
+cosiddetti \textsl{flag di stato} del file (o \itindex{file~status~flag}
+\textit{file status flags}), che vengono mantenuti nel campo \var{f\_flags}
+della struttura \kstruct{file} che abbiamo riportato anche in
+fig.~\ref{fig:file_proc_file}).
+
+Ciascun flag viene identificato da una apposita costante, ed il valore
+di \param{flags} deve essere specificato come OR aritmetico di queste
+costanti. I vari bit che si possono usare come componenti di \param{flags}
+sono divisi in tre gruppi principali. Il primo gruppo è quello dei cosiddetti
+flag delle \textsl{modalità di accesso} (o \textit{access mode flags}), che
+specificano che tipo di accesso si effettuerà sul file, fra lettura, scrittura
+e lettura/scrittura. Questa modalità deve essere indicata usando una delle
+costanti di tab.~\ref{tab:open_access_mode_flag}.
-L'argomento opzionale \param{mode} indica i permessi con cui il file viene
-creato ed i valori possibili sono gli stessi già visti in
-sez.~\ref{sec:file_perm_overview} e possono essere specificati come OR binario
-delle costanti descritte in tab.~\ref{tab:file_bit_perm}. Questi permessi sono
-filtrati dal valore di \itindex{umask} \textit{umask} (vedi
-sez.~\ref{sec:file_perm_management}) per il processo.
-
-La funzione prevede diverse opzioni, che vengono specificate usando vari bit
-dell'argomento \param{flags}. Alcuni di questi bit vanno anche a costituire
-il cosiddetto flag di stato del file (o \textit{file status flag}), che è
-mantenuto nel campo \var{f\_flags} della struttura \kstruct{file} (al solito
-si veda lo schema di fig.~\ref{fig:file_proc_file}). Essi sono divisi in tre
-categorie principali:
-\begin{itemize*}
-\item \textsl{i bit delle modalità di accesso}: specificano con quale modalità
- si accederà al file: i valori possibili sono lettura, scrittura o
- lettura/scrittura. Uno di questi bit deve essere sempre specificato quando
- si apre un file. Vengono impostati alla chiamata da \func{open}, e possono
- essere riletti con \func{fcntl} (fanno parte del \textit{file status flag}),
- ma non possono essere modificati.
-\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{O\_RDONLY}] Apre il file in sola lettura, le \acr{glibc}
- definiscono anche \const{O\_READ} come sinonimo.
-\item[\const{O\_WRONLY}] Apre il file in sola scrittura, le \acr{glibc}
- definiscono anche \const{O\_WRITE} come sinonimo.
-\item[\const{O\_RDWR}] Apre il file sia in lettura che in scrittura.
-\end{basedescript}
-\item \textsl{i bit delle modalità di operazione}: permettono di specificare
- alcune caratteristiche del comportamento delle future operazioni sul file
- (come \func{read} o \func{write}). Anch'essi fan parte del \textit{file
- status flag}. Il loro valore è impostato alla chiamata di \func{open}, ma
- possono essere riletti e modificati (insieme alle caratteristiche operative
- che controllano) con una \func{fcntl}.
-\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
-
-\item[\const{O\_CREAT}] Se il file non esiste verrà creato, con le regole di
- titolarità del file viste in sez.~\ref{sec:file_ownership_management}. Con
- questa opzione l'argomento \param{mode} deve essere specificato.
-
-\item[\const{O\_EXCL}] Usato in congiunzione con \const{O\_CREAT} fa sì che la
- precedente esistenza del file diventi un errore\footnote{la pagina di
- manuale di \func{open} segnala che questa opzione è difettosa su NFS, e
- che i programmi che la usano per stabilire un \index{file!di lock}
- \textsl{file di lock} possono incorrere in una \itindex{race~condition}
- \textit{race condition}. Si consiglia come alternativa di usare un file
- con un nome univoco e la funzione \func{link} per verificarne l'esistenza
- (vedi sez.~\ref{sec:ipc_file_lock}).} che fa fallire \func{open} con
- \errcode{EEXIST}.
-
-\item[\const{O\_NONBLOCK}] Apre il file in modalità non bloccante, e comporta
- che \func{open} ritorni immediatamente anche quando dovrebbe bloccarsi
- (l'opzione ha senso solo per le fifo, vedi sez.~\ref{sec:ipc_named_pipe}).
-
-\item[\const{O\_NOCTTY}] Se \param{pathname} si riferisce ad un dispositivo di
- terminale, questo non diventerà il terminale di controllo, anche se il
- processo non ne ha ancora uno (si veda sez.~\ref{sec:sess_ctrl_term}).
-
-\item[\const{O\_SHLOCK}] Apre il file con uno shared lock (vedi
- sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux.
-
-\item[\const{O\_EXLOCK}] Apre il file con un lock esclusivo (vedi
- sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux.
-
-\item[\const{O\_TRUNC}] Se usato su un file di dati aperto in scrittura, ne
- tronca la lunghezza a zero; con un terminale o una fifo viene ignorato,
- negli altri casi il comportamento non è specificato.
-
-\item[\const{O\_NOFOLLOW}] Se \param{pathname} è un link simbolico la chiamata
- fallisce. Questa è un'estensione BSD aggiunta in Linux dal kernel
- 2.1.126. Nelle versioni precedenti i link simbolici sono sempre seguiti, e
- questa opzione è ignorata.
-
-\item[\const{O\_DIRECTORY}] Se \param{pathname} non è una directory la
- chiamata fallisce. Questo flag è specifico di Linux ed è stato introdotto
- con il kernel 2.1.126 per evitare dei \itindex{Denial~of~Service~(DoS)}
- \textit{DoS}\footnote{acronimo di \itindex{Denial~of~Service~(DoS)}
- \textit{Denial of Service}, si chiamano così attacchi miranti ad impedire
- un servizio causando una qualche forma di carico eccessivo per il sistema,
- che resta bloccato nelle risposte all'attacco.} quando \func{opendir}
- viene chiamata su una fifo o su un dispositivo associato ad una unità a
- nastri, non deve dispositivo a nastri; non deve essere utilizzato
- al di fuori dell'implementazione di \func{opendir}.
-
-\item[\const{O\_LARGEFILE}] Nel caso di sistemi a 32 bit che supportano file
- di grandi dimensioni consente di aprire file le cui dimensioni non possono
- essere rappresentate da numeri a 31 bit.
-\end{basedescript}
-\item \textsl{i bit delle modalità di apertura}: permettono di specificare
- alcune delle caratteristiche del comportamento di \func{open} quando viene
- eseguita. Hanno effetto solo al momento della chiamata della funzione e non
- sono memorizzati né possono essere riletti.
-\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
-
-\item[\const{O\_APPEND}] Il file viene aperto in \itindex{append~mode}
- \textit{append mode}. Prima di ciascuna scrittura la posizione corrente
- viene sempre impostata alla fine del file. Con NFS si può avere una
- corruzione del file se più di un processo scrive allo stesso
- tempo.\footnote{il problema è che NFS non supporta la scrittura in
- \itindex{append~mode} \textit{append}, ed il kernel deve simularla, ma
- questo comporta la possibilità di una \itindex{race~condition}
- \textit{race condition}, vedi sez.~\ref{sec:file_atomic}.}
-
-\item[\const{O\_NONBLOCK}] Il file viene aperto in modalità non bloccante per
- le operazioni di I/O (che tratteremo in sez.~\ref{sec:file_noblocking}):
- questo significa il fallimento di \func{read} in assenza di dati da leggere
- e quello di \func{write} in caso di impossibilità di scrivere
- immediatamente. Questa modalità ha senso solo per le fifo e per alcuni file
- di dispositivo.
-
-\item[\const{O\_NDELAY}] In Linux è sinonimo di
- \const{O\_NONBLOCK}.\footnote{l'opzione origina da SVr4, dove però causava
- il ritorno da una \func{read} con un valore nullo e non con un errore,
- questo introduce un'ambiguità, dato che come vedremo in
- sez.~\ref{sec:file_read} il ritorno di zero da parte di \func{read} ha il
- significato di una \textit{end-of-file}.}
-
-\item[\const{O\_ASYNC}] Apre il file per l'I/O in modalità asincrona (vedi
- sez.~\ref{sec:file_asyncronous_io}). Quando è impostato viene generato il
- segnale \signal{SIGIO} tutte le volte che sono disponibili dati in input sul
- file.
-
-\item[\const{O\_SYNC}] Apre il file per l'input/output sincrono: ogni
- \func{write} bloccherà fino al completamento della scrittura di tutti i dati
- sull'hardware sottostante.
-
-\item[\const{O\_FSYNC}] Sinonimo di \const{O\_SYNC}, usato da BSD.
-
-\item[\const{O\_DSYNC}] Variante di I/O sincrono definita da POSIX; presente
- dal kernel 2.1.130 come sinonimo di \const{O\_SYNC}.
-
-\item[\const{O\_RSYNC}] Variante analoga alla precedente, trattata allo stesso
- modo.
-
-\item[\const{O\_NOATIME}] Blocca l'aggiornamento dei tempi di accesso dei file
- (vedi sez.~\ref{sec:file_file_times}). Per molti filesystem questa
- funzionalità non è disponibile per il singolo file ma come opzione generale
- da specificare in fase di montaggio.
-
-\item[\const{O\_DIRECT}] Esegue l'I/O direttamente dai buffer in user space in
- maniera sincrona, in modo da scavalcare i meccanismi di caching del
- kernel. In genere questo peggiora le prestazioni tranne quando le
- applicazioni ottimizzano il proprio caching.\footnote{l'opzione è stata
- introdotta dalla SGI in IRIX, e serve sostanzialmente a permettere ad
- alcuni programmi (in genere database) la gestione diretta della
- bufferizzazione dell'I/O in quanto essi sono in grado di ottimizzarla al
- meglio per le loro prestazioni; l'opzione è presente anche in FreeBSD,
- senza limiti di allineamento dei buffer. In Linux è stata introdotta con
- il kernel 2.4.10, le versioni precedenti la ignorano.} Per i kernel della
- serie 2.4 si deve garantire che i buffer in user space siano allineati alle
- dimensioni dei blocchi del filesystem; per il kernel 2.6 basta che siano
- allineati a multipli di 512 byte.
-
-\item[\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}).\footnote{introdotto con il kernel 2.6.23, per evitare
- una \itindex{race~condition} \textit{race condition} che si può verificare
- con i \itindex{thread} \textit{thread}, fra l'apertura del file e
- l'impostazione della suddetta modalità con \func{fcntl}.}
-\end{basedescript}
-\end{itemize*}
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Flag} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{O\_RDONLY} & Apre il file in sola lettura.\\
+ \const{O\_WRONLY} & Apre il file in sola scrittura.\\
+ \const{O\_RDWR} & Apre il file sia in lettura che in scrittura.\\
+ \hline
+ \end{tabular}
+ \caption{Le tre costanti che identificano le modalità di accesso
+ nell'apertura di un file.}
+ \label{tab:open_access_mode_flag}
+\end{table}
+A differenza di tutti gli altri flag che vedremo in seguito, in questo caso
+non si ha a che fare con singoli bit separati dell'argomento \param{flags}, ma
+con un numero composto da due bit. Questo significa ad esempio che la
+combinazione \code{\const{O\_RDONLY}|\const{O\_WRONLY}} non è affatto
+equivalente a \const{O\_WRONLY}, e non deve essere usata.\footnote{in realtà
+ su Linux, dove i valori per le tre costanti di
+ tab.~\ref{tab:open_access_mode_flag} sono rispettivamente $0$, $1$ e $2$, il
+ valore $3$ viene usato con un significato speciale ed assolutamente fuori
+ standard, disponibile solo per i file di dispositivo e solo per alcuni
+ driver, in cui si richiede la verifica della capacità di accesso in lettura
+ e scrittura ma viene restituito un file descriptor che non può essere letto
+ o scritto, ma solo usato con una \func{ioctl} (vedi
+ sez.~\ref{sec:file_ioctl}).}
+
+La modalità di accesso deve sempre essere specificata quando si apre un file,
+il valore indicato in \param{flags} viene salvato nei
+\itindex{file~status~flag} \textit{file status flags}, e può essere riletto
+con \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}), il relativo valore può
+essere poi ottenuto un AND aritmetico della maschera binaria
+\const{O\_ACCMODE}, ma non può essere modificato. Nella \acr{glibc} sono
+definite inoltre \const{O\_READ} come sinonimo di \const{O\_RDONLY} e
+\const{O\_WRITE} come sinonimo di \const{O\_WRONLY}.\footnote{si tratta di
+ definizioni completamente fuori standard, attinenti insieme a
+ \const{O\_EXEC}, che permetterebbe l'apertura di un file per l'esecuzione,
+ ad un non meglio precisato ``\textit{GNU system}''; pur essendo equivalenti
+ alle definizioni classiche non è comunque il caso di utilizzarle.}
+
+Il secondo gruppo di flag è quello delle \textsl{modalità di
+ apertura},\footnote{la pagina di manuale di \func{open} parla di
+ \textit{file creation flags}, ma alcuni di questi flag non hanno nulla a che
+ fare con la creazione dei file, mentre il manuale dalla \acr{glibc} parla di
+ più correttamente di \textit{open-time flags}, dato che si tratta di flag il
+ cui significato ha senso solo al momento dell'apertura del file.} che
+permettono di specificare alcune delle caratteristiche del comportamento di
+\func{open} nel momento in viene eseguita per aprire un file. Questi flag
+hanno effetto solo nella chiamata della funzione, non sono memorizzati fra i
+\itindex{file~status~flag} \textit{file status flags} e non possono essere
+riletti da \func{fcntl} (vedi sez.~\ref{sec:file_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/
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10 cm}|}
+ \hline
+ \textbf{Flag} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{O\_CREAT} & Se il file non esiste verrà creato, con le regole
+ di titolarità del file viste in
+ sez.~\ref{sec:file_ownership_management}. Se si
+ imposta questo flag l'argomento \param{mode} deve
+ essere sempre specificato.\\
+ \const{O\_DIRECTORY}& Se \param{pathname} non è una directory la
+ chiamata fallisce. Questo flag, introdotto con il
+ kernel 2.1.126, è specifico di Linux e
+ serve ad evitare dei possibili
+ \itindex{Denial~of~Service~(DoS)}
+ \textit{DoS}\footnotemark quando \func{opendir}
+ viene chiamata su una fifo o su un dispositivo
+ associato ad una unità a nastri. Non viene
+ usato al di fuori dell'implementazione di
+ \func{opendir}, ed è utilizzabile soltanto se si è
+ definata la macro \macro{\_GNU\_SOURCE}.\\
+ \const{O\_EXCL} & Deve essere usato in congiunzione con
+ \const{O\_CREAT} ed in tal caso impone che il file
+ indicato da \param{pathname} non sia già esistente
+ (altrimenti causa il fallimento della chiamata con
+ un errore di \errcode{EEXIST}).\\
+ \const{O\_LARGEFILE}& Viene usato sui sistemi a 32 bit per richiedere
+ l'apertura di file molto grandi, la cui
+ dimensione non è rappresentabile con la versione a
+ 32 bit del tipo \type{off\_t}, utilizzando
+ l'interfaccia alternativa abilitata con la
+ macro \macro{\_LARGEFILE64\_SOURCE}. Come
+ illustrato in sez.~\ref{sec:intro_gcc_glibc_std} è
+ sempre preferibile usare la conversione automatica
+ delle funzioni che si attiva assegnando a $64$ la
+ macro \macro{\_FILE\_OFFSET\_BITS} e non usare mai
+ questo flag.\\
+ \const{O\_NOCTTY} & Se \param{pathname} si riferisce ad un dispositivo
+ di terminale, questo non diventerà il terminale di
+ controllo, anche se il processo non ne ha ancora
+ uno (si veda sez.~\ref{sec:sess_ctrl_term}).\\
+ \const{O\_NOFOLLOW} & Se \param{pathname} è un collegamento simbolico
+ la chiamata fallisce. Questa è un'estensione BSD
+ aggiunta in Linux a partire dal kernel
+ 2.1.126 ed utilizzabile soltanto se si è definata
+ la macro \macro{\_GNU\_SOURCE}.\\
+ \const{O\_TRUNC} & Se usato su un file di dati aperto in scrittura,
+ ne tronca la lunghezza a zero; con un terminale o
+ una fifo viene ignorato, negli altri casi il
+ comportamento non è specificato.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano le \textit{modalità di apertura} di
+ un file.}
+ \label{tab:open_time_flag}
+\end{table}
+
+\footnotetext{acronimo di \itindex{Denial~of~Service~(DoS)} \textit{Denial of
+ Service}, si chiamano così attacchi miranti ad impedire un servizio
+ causando una qualche forma di carico eccessivo per il sistema, che resta
+ bloccato nelle risposte all'attacco.}
+
+Si è riportato in tab.~\ref{tab:open_time_flag} l'elenco dei flag delle
+\textsl{modalità di apertura}.\footnote{la \acr{glibc} definisce anche i due
+ flag \const{O\_SHLOCK}, che aprirebbe il file con uno \textit{shared lock} e
+ \const{O\_EXLOCK} che lo aprirebbe con un \textit{exclusive lock} (vedi
+ sez.~\ref{sec:file_locking}, si tratta di opzioni specifiche di BSD, che non
+ esistono con Linux.} Uno di questi, \const{O\_EXCL}, ha senso solo se usato
+in combinazione a \const{O\_CREAT} quando si vuole creare un nuovo file per
+assicurarsi che questo non esista di già, e lo si usa spesso per creare i
+cosiddetti \index{file!di lock} ``\textsl{file di lock}'' (vedi
+sez.~\ref{sec:ipc_file_lock}). Si tenga presente che questa opzione è
+supportata su NFS solo a partire da NFSv3 e con il kernel 2.6, nelle versioni
+precedenti la funzionalità viene emulata controllando prima l'esistenza del
+file per cui usarla per creare \index{file!di lock} un file di lock potrebbe
+dar luogo a una \itindex{race~condition} \textit{race condition}.\footnote{un
+ file potrebbe venir creato fra il controllo la successiva apertura
+ \const{O\_CREAT}, la cosa si può risolvere comunque creando un file con un
+ nome univoco ed usando la funzione \func{link} per creare il \index{file!di
+ lock} file di lock, (vedi sez.~\ref{sec:ipc_file_lock}).}
+
+Se si usa \const{O\_EXCL} senza \const{O\_CREAT} il comportamento è
+indefinito. Nella creazione di un file con \const{O\_CREAT} occorre sempre
+specificare l'argomento di \param{mode}, che altrimenti è ignorato. Si tenga
+presente che indipendentemente dai permessi che si possono assegnare, che
+potrebbero non consentire in seguito lettura o scrittura, quando il file viene
+aperto l'accesso viene garantito secondo quanto richiesto con i flag di
+tab.~\ref{tab:open_access_mode_flag}. Quando viene creato un nuovo file
+\const{O\_CREAT} con tutti e tre i tempi del file di
+tab.~\ref{tab:file_file_times} vengono impostati al tempo corrente. Se invece
+si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il
+\textit{modification time} e lo \textit{status change time}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10 cm}|}
+ \hline
+ \textbf{Flag} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{O\_APPEND} & Il file viene aperto in \itindex{append~mode}
+ \textit{append mode}. La posizione sul file (vedi
+ sez.~\ref{sec:file_lseek}) viene sempre mantenuta
+ sulla sua coda, per cui quanto si scrive
+ viene sempre aggiunto al contenuto precedente. Con
+ NFS questa funzionalità non è supportata
+ e viene emulata, per questo possono verificarsi
+ \itindex{race~condition} \textit{race
+ condition} con una sovrapposizione dei dati se
+ più di un processo scrive allo stesso tempo. \\
+ \const{O\_ASYNC} & Apre il file per l'I/O in modalità asincrona (vedi
+ sez.~\ref{sec:file_asyncronous_io}). Quando è
+ impostato viene generato il segnale \signal{SIGIO}
+ tutte le volte che il file è pronto per le
+ operazioni di lettura o scrittura. Questo flag si
+ può usare solo terminali, pseudoterminali e socket
+ e, a partire dal kernel 2.6, anche sulle fifo.\\
+ \const{O\_CLOEXEC}& Attiva la modalità di \itindex{close-on-exec}
+ \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
+ \itindex{race~condition} \textit{race condition}
+ che si potrebbe verificare con i \textit{thread}
+ fra l'apertura del file e l'impostazione della
+ suddetta modalità con \func{fcntl} (vedi
+ sez.~\ref{sec:file_fcntl}).\\
+ \const{O\_DIRECT} & Esegue l'I/O direttamente dalla memoria in
+ \textit{user space} in maniera sincrona, in modo da
+ scavalcare i meccanismi di bufferizzazione del
+ kernel. Introdotto con il kernel 2.4.10 ed
+ utilizzabile soltanto se si è definita la
+ macro \macro{\_GNU\_SOURCE}.\\
+ \const{O\_NOATIME} & Blocca l'aggiornamento dei tempi di accesso dei
+ file (vedi sez.~\ref{sec:file_file_times}). Per
+ molti filesystem questa funzionalità non è
+ disponibile per il singolo file ma come opzione
+ generale da specificare in fase di montaggio.\\
+ \const{O\_NONBLOCK}& Apre il file in \textsl{modalità non bloccante} per
+ le operazioni di I/O (vedi
+ sez.~\ref{sec:file_noblocking}). Questo significa
+ il fallimento delle successive operazioni di
+ lettura o scrittura qualora il file non sia pronto
+ per la loro esecuzione immediata, invece del
+ blocco delle stesse in attesa di una successiva
+ possibilità di esecuzione come avviene
+ normalmente. Questa modalità ha senso solo per le
+ fifo, vedi sez.~\ref{sec:ipc_named_pipe}), o quando
+ si vuole aprire un file di dispositivo per eseguire
+ una \func{ioctl} (vedi
+ sez.~\ref{sec:file_ioctl}).\\
+ \const{O\_NDELAY} & In Linux è un sinonimo di \const{O\_NONBLOCK}, ma
+ origina da SVr4, dove però causava il ritorno da
+ una \func{read} con un valore nullo e non con un
+ errore, questo introduce un'ambiguità, dato che
+ come vedremo in sez.~\ref{sec:file_read} il ritorno
+ di un valore nulla da parte di \func{read} ha
+ il significato di una \textit{end-of-file}.\\
+ \const{O\_SYNC} & Apre il file per l'input/output sincrono. Ogni
+ scrittura di dati si bloccherà fino alla conferma
+ dell'arrivo di tutti i dati sull'hardware
+ sottostante.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano le \textit{modalità di operazione} di
+ un file.}
+ \label{tab:open_operation_flag}
+\end{table}
+
+
+Il terzo gruppo è quello dei flag delle \textsl{modalità di operazione},
+riportati in tab.~\ref{tab:open_operation_flag}, che permettono di specificare
+varie caratteristiche del comportamento delle operazioni di I/O che verranno
+eseguite sul file. Tutti questi, tranne \const{O\_CLOEXEC}, che viene
+mantenuto per ogni singolo file descriptor, vengono salvati nel campo
+\var{f\_flags} della struttura \kstruct{file} insieme al valore della
+\textsl{modalità di accesso} andando far parte dei cosiddetti \textit{file
+ status flags}. Il loro valore viene impostato alla chiamata di \func{open},
+ma possono essere riletti ed in alcuni anche modificati, con conseguente
+effetto sulle caratteristiche operative che controllano, con \func{fcntl}
+(vedi sez.~\ref{sec:file_fcntl}).
+Il flag \const{O\_DIRECT} non è previsto da nessuno standard, anche se è
+presente in alcuni kernel unix-like.\footnote{il flag è stato introdotto dalla
+ SGI in IRIX, ma è presente senza limiti di allineamento dei buffer anche in
+ FreeBSD.} Per i kernel della serie 2.4 si deve garantire che i buffer in
+\textit{user space} da cui si effettua il trasferimento diretto dei dati siano
+allineati alle dimensioni dei blocchi del filesystem. Con il kernel 2.6 in
+genere basta che siano allineati a multipli di 512 byte, ma le restrizioni
+possono variare a seconda del filesystem, ed inoltre su alcuni filesystem può
+non essere supportato nel qual caso si avrà un errore di \errval{EINVAL}.
-In tab.~\ref{tab:file_open_flags} sono riportate, ordinate e divise fra loro
-secondo le tre modalità appena elencate, le costanti mnemoniche associate a
-ciascuno di questi bit. Dette costanti possono essere combinate fra loro con
-un OR aritmetico per costruire il valore (in forma di maschera binaria)
-dell'argomento \param{flags} da passare alla \func{open}. I due flag
-\const{O\_NOFOLLOW} e \const{O\_DIRECTORY} sono estensioni specifiche di
-Linux, e deve essere definita la macro \macro{\_GNU\_SOURCE} per poterli
-usare.
+Lo scopo di \const{O\_DIRECT} è consentire un completo controllo sulla
+bufferizzazione dei propri dati per quelle applicazioni (in genere database)
+che hanno esigenze specifiche che non vengono soddisfatte nella maniera più
+efficiente dalla politica generica utilizzata dal kernel. In genere l'uso di
+questo flag peggiora le prestazioni tranne quando le applicazioni sono in
+grado di ottimizzare la propria bufferizzazione in maniera adeguata. Se lo si
+usa si deve avere cura di non mescolare questo tipo di accesso con quello
+ordinario, in quante le esigenze di mantenere coerenti i dati porterebbero ad
+un peggioramento delle prestazioni. Lo stesso dicasi per l'interazione con
+eventuale mappatura in memoria del file (vedi sez.~\ref{sec:file_memory_map}).
+
+Si tenga presente infine che anche se l'uso di \const{O\_DIRECT} comporta
+sostanzialmente una scrittura sincrona dei dati dei buffer in \textit{user
+ space}, questo non è completamente equivalente all'uso di \const{O\_SYNC}
+che garantisce anche sulla scrittura sincrona dei metadati. Per questo in
+genere è opportuno se si usa \const{O\_DIRECT} è opportuno richiedere anche
+\const{O\_SYNC}.
+
+Si tenga presente infine che la implementazione di \const{O\_SYNC} di Linux
+differisce da quanto previsto dallo standard POSIX.1 che prevede oltre a
+questo, che dovrebbe indicare la sincronizzazione dei dati e dei metadati,
+altri due flag \const{O\_DSYNC} e \const{O\_RSYNC}.
+
+
+ diversi
+
+ \const{O\_FSYNC} Sinonimo di \const{O\_SYNC}, usato da BSD.
+
+ \const{O\_DSYNC} Variante di I/O sincrono definita da POSIX; presente
+ dal kernel 2.1.130 come sinonimo di
+ \const{O\_SYNC}.
+
+
+ \const{O\_RSYNC} & Variante analoga alla precedente, trattata allo
+ stesso modo.
+
+
+
+
+
+
+%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/
Nelle prime versioni di Unix i valori di \param{flag} specificabili per
\func{open} erano solo quelli relativi alle modalità di accesso del file. Per
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 flag di stato del file (quelli impostati
-dall'argomento \param{flag} di \func{open}) essendo tenuti nella voce della
-\textit{file table}\footnote{per la precisione nel campo \var{f\_flags} di
- \kstruct{file}.}, vengono in questo caso condivisi. Ai file però sono
-associati anche altri flag, dei quali l'unico usato al momento è
-\const{FD\_CLOEXEC}, detti \textit{file descriptor flags}. Questi ultimi sono
-tenuti invece in \kstruct{file\_struct}, e perciò sono specifici di ciascun
-processo e non vengono modificati dalle azioni degli altri anche in caso di
-condivisione della stessa voce della \textit{file table}.
+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}\footnote{per la precisione nel campo
+ \var{f\_flags} di \kstruct{file}, vedi fig.~\ref{fig:kstruct_file}.},
+vengono in questo caso condivisi. Ai file però sono associati anche altri
+flag, dei quali l'unico usato al momento è \const{FD\_CLOEXEC}, detti
+\index{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 vengono modificati dalle azioni degli altri anche in
+caso di condivisione della stessa voce della \textit{file table}.
Per tutte le funzioni che lo prevedono, a parte \func{unlinkat} e
\funcd{faccessat}, l'ulteriore argomento è stato introdotto solo per fornire
un meccanismo con cui modificarne il comportamento nel caso si stia operando
-su un link simbolico, così da poter scegliere se far agire la funzione
+su un collegamento simbolico, così da poter scegliere se far agire la funzione
direttamente sullo stesso o sul file da esso referenziato. Dato che in certi
casi esso può fornire ulteriori indicazioni per modificare il comportamento
delle funzioni, \param{flags} deve comunque essere passato come maschera
\end{functions}
In questo caso il valore di \param{flags} stabilisce il comportamento della
-funzione quando la si applica ad un link simbolico, e l'unico valore
+funzione quando la si applica ad un collegamento simbolico, e l'unico valore
utilizzabile è \const{AT\_SYMLINK\_NOFOLLOW}\footnote{in \headfile{fcntl.h} è
definito anche \const{AT\_SYMLINK\_FOLLOW}, che richiede di dereferenziare i
- link simbolici, essendo questo però il comportamento adottato per un valore
- nullo di \param{flags} questo valore non viene mai usato.} che se impostato
-indica alla funzione di non eseguire la dereferenziazione di un eventuale link
-simbolico, facendo comportare \func{fchownat} come \func{lchown} invece che
-come \func{chown}.
+ collegamenti simbolici, essendo questo però il comportamento adottato per un
+ valore nullo di \param{flags} questo valore non viene mai usato.} che se
+impostato indica alla funzione di non eseguire la dereferenziazione di un
+eventuale collegamento simbolico, facendo comportare \func{fchownat} come
+\func{lchown} invece che come \func{chown}.
Come accennato fra tutte quelle marcate in tab.~\ref{tab:file_atfunc_corr}
solo due funzioni possono usare l'argomento \param{flags} con valori diversi
dei permessi usando l'\ids{UID} effettivo invece di quello reale (il
comportamento di default, che riprende quello di \func{access}).
\item[\const{AT\_SYMLINK\_NOFOLLOW}] se impostato \funcd{faccessat} non esegue
- la dereferenziazione dei link simbolici, effettuando il controllo dei
- permessi direttamente sugli stessi.
+ la dereferenziazione dei collegamenti simbolici, effettuando il controllo
+ dei permessi direttamente sugli stessi.
\end{basedescript}
La seconda eccezione è \func{unlinkat}, in questo caso l'ulteriore