From 68e54409d759e7043e45198cd4ce3fc31010fb48 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sat, 20 Oct 2018 02:55:54 +0200 Subject: [PATCH] Altra documentazione O_PATH. --- fileio.tex | 153 ++++++++++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 71 deletions(-) diff --git a/fileio.tex b/fileio.tex index dad46a0..acbedc2 100644 --- a/fileio.tex +++ b/fileio.tex @@ -319,15 +319,15 @@ 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. -\itindbeg{file~status~flag} +\itindbeg{file~status~flags} 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 (i cosiddetti \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}). +cosiddetti \textit{file status flags} (i \textsl{flag di stato} del file), 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 @@ -388,7 +388,7 @@ sinonimo di \const{O\_RDONLY} e \constd{O\_WRITE} come sinonimo di system}''; pur essendo equivalenti alle definizioni classiche non è comunque il caso di utilizzarle.} -\itindend{file~status~flag} +\itindend{file~status~flags} Il secondo gruppo di flag è quello delle \textsl{modalità di apertura},\footnote{la pagina di manuale di \func{open} parla di @@ -450,18 +450,7 @@ sez.~\ref{sec:file_fcntl_ioctl}). la chiamata fallisce. Questa è un'estensione BSD aggiunta in Linux a partire dal kernel 2.1.126, ed utilizzabile soltanto se si è definita - la macro \macro{\_GNU\_SOURCE}.\\ - \const{O\_PATH} & Ottiene un file descriptor io cui uso è limitato - all'indicare una posizione sul filesystem o - eseguire operazioni che operano solo a livello del - file descriptor (e non di accesso al contenuto del - file). Introdotto con il kernel 2.6.39, è specifico - di Linux.\\ - \const{O\_TMPFILE} & Consente di creare un file temporaneo anonimo, non - visibile con un pathname sul filesystem, ma - leggibile e scrivibile all'iterno del processo. - Introdotto con il kernel 3.11, è specifico di - Linux.\\ + la macro \macro{\_GNU\_SOURCE}.\\ \constd{O\_TRUNC} & Se usato su un file di dati aperto in scrittura, ne tronca la lunghezza a zero; con un terminale o una \textit{fifo} viene ignorato, negli altri casi @@ -480,8 +469,8 @@ sez.~\ref{sec:file_fcntl_ioctl}). 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 \constd{O\_SHLOCK}, che aprirebbe il file con uno \textit{shared lock} e - \constd{O\_EXLOCK} che lo aprirebbe con un \textit{exclusive lock} (vedi + flag \constd{O\_SHLOCK}, che aprirebbe il file con uno \textit{shared lock} + e \constd{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 @@ -498,9 +487,14 @@ nome univoco ed usando la funzione \func{link} per creare il file di lock, (vedi sez.~\ref{sec:ipc_file_lock}). Se si usa \const{O\_EXCL} senza \const{O\_CREAT} il comportamento è -indefinito, escluso il caso in cui viene usato con uno dei due nuovi flag -\const{O\_PATH} o \const{O\_TMPFILE} su cui torneremo a breve. Nella -creazione di un file con \const{O\_CREAT} occorre sempre specificare +indefinito, escluso il caso in cui viene usato con \const{O\_TMPFILE} su cui +torneremo più avanti; un'altra eccezione è quello in cui lo si usa da solo su +un file di dispositivo, in quel caso se questo è in uso (ad esempio se è +relativo ad un filesystem che si è montato) si avrà un errore di +\errval{EBUSY}, e pertanto può essere usato in questa modalità per rilevare lo +stato del dispositivo. + +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 in seguito potrebbero non consentire lettura o scrittura, quando il file viene aperto @@ -511,44 +505,6 @@ 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}. -Dei flag illustrati in tab.~\ref{tab:open_time_flag} due, specifici di Linux -ed introdotti solo con i kernel più recenti, meritano un approfondimento. Il -primo di questi è \constd{O\_PATH}, che viene usato per limitare l'uso del -file descriptor restituito da \func{open} o all'identificazione di una -posizione sul filesystem (ad uso delle \textit{at-functions} che tratteremo in -sez.~\ref{sec:file_openat}) o a operazioni che riguardano solo il file -descriptor; in sostanza lo si potrà utilizzare solo per: - -\begin{itemize*} -\item chiudere il file con \func{close}; -\item cambiare directory di lavoro con \func{fchdir} se il file descriptor fa - riferimento a una directory (dal kernel 3.5); -\item ottenere le informazioni relative al file con \func{fstat} (dal kernel - 3.6) o al filesystem con \func{fstatfs} (dal kernel 3.12); -\item usare le funzioni che duplicano il file descriptor (vedi - sez.~\ref{sec:file_dup}); -\item usare il file descriptor come indicatore della directory di partenza con - una delle \textit{at-functions} (vedi sez.~\ref{sec:file_openat}); -\item passare il file descriptor ad un altro processo usando un socket - \const{PF\_UNIX} (vedi sez.~\ref{sec:unix_socket}) - -\end{itemize*} - -In realtà infatti usando \constd{O\_PATH} il file non viene effettivamente -aperto, per cui ogni tentativo di usare il file descriptor così ottenuto con -funzioni che operano effettivamente sul file (come ad esempio \func{read}, -\func{write}, \func{fchown}, \func{fchmod}, \func{ioctl}, ecc.) fallirano con -un errore di \errval{EBADF} come se questo non fosse un file descriptor -valido. - - - -% TODO: aggiungere O_TMPFILE per la creazione di file temporanei senza che -% questi appaiano sul filesystem, introdotto con il 3.11, vedi: -% https://lwn.net/Articles/556512/, http://kernelnewbies.org/Linux_3.11 -% https://lwn.net/Articles/558598/ http://lwn.net/Articles/619146/ - - \begin{table}[!htb] \centering \footnotesize @@ -562,7 +518,7 @@ valido. 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 + supportata e viene emulata, per questo possono verificarsi \textit{race condition} con una sovrapposizione dei dati se più di un processo scrive allo stesso tempo.\\ @@ -620,6 +576,12 @@ valido. come vedremo in sez.~\ref{sec:file_read} il ritorno di un valore nullo da parte di \func{read} ha il significato di una \textit{end-of-file}.\\ + \const{O\_PATH} & Ottiene un file descriptor io cui uso è limitato + all'indicare una posizione sul filesystem o + eseguire operazioni che operano solo a livello del + file descriptor (e non di accesso al contenuto del + file). Introdotto con il kernel 2.6.39, è specifico + di Linux.\\ \constd{O\_SYNC} & Apre il file per l'input/output sincrono. Ogni scrittura si bloccherà fino alla conferma dell'arrivo di tutti i dati e di tutti i metadati @@ -630,6 +592,11 @@ valido. dell'arrivo degli stessi e della parte di metadati ad essi relativa sull'hardware sottostante (in questo significato solo dal kernel 2.6.33).\\ + \const{O\_TMPFILE} & Consente di creare un file temporaneo anonimo, non + visibile con un pathname sul filesystem, ma + leggibile e scrivibile all'iterno del processo. + Introdotto con il kernel 3.11, è specifico di + Linux.\\ \hline \end{tabular} \caption{Le costanti che identificano le \textit{modalità di operazione} di @@ -640,20 +607,20 @@ valido. 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 venire riletti in un secondo tempo con \func{fcntl}, inoltre alcuni -di essi possono anche essere modificati tramite questa funzione, con -conseguente effetto sulle caratteristiche operative che controllano (torneremo -sull'argomento in sez.~\ref{sec:file_fcntl_ioctl}). +eseguite sul file o le modalità in cui lo si potrà utilizzare. 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 \textit{file status flags}. Il loro valore viene impostato alla +chiamata di \func{open}, ma possono venire riletti in un secondo tempo con +\func{fcntl}, inoltre alcuni di essi possono anche essere modificati tramite +questa funzione, con conseguente effetto sulle caratteristiche operative che +controllano (torneremo sull'argomento in sez.~\ref{sec:file_fcntl_ioctl}). Il flag \const{O\_ASYNC} (che, per compatibilità con BSD, si può indicare anche con la costante \constd{FASYNC}) è definito come possibile valore per \func{open}, ma per un bug dell'implementazione,\footnote{segnalato come - ancora presente nella pagina di manuale almeno fino al Settembre 2011.} non + ancora presente nella pagina di manuale, almeno fino al novembre 2018.} non solo non attiva il comportamento citato, ma se usato richiede di essere esplicitamente disattivato prima di essere attivato in maniera effettiva con l'uso di \func{fcntl}. Per questo motivo, non essendovi nessuna necessità @@ -723,6 +690,50 @@ torni a corrispondere al valore di \const{O\_DSYNC}. % NOTE: per 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/ +Il flag \constd{O\_PATH}, introdotto con il kernel 2.6.39, viene usato per +limitare l'uso del file descriptor restituito da \func{open} o +all'identificazione di una posizione sul filesystem (ad uso delle +\textit{at-functions} che tratteremo in sez.~\ref{sec:file_openat}) o alle +operazioni che riguardano il file descriptor in quanto tale, senza consentire +operazioni sul file; in sostanza se si apre un file con \const{O\_PATH} si +potrà soltanto: + +\begin{itemize*} +\item usare il file descriptor come indicatore della directory di partenza con + una delle \textit{at-functions} (vedi sez.~\ref{sec:file_openat}); +\item cambiare directory di lavoro con \func{fchdir} se il file descriptor fa + riferimento a una directory (dal kernel 3.5); +\item usare le funzioni che duplicano il file descriptor (vedi + sez.~\ref{sec:file_dup}); +\item passare il file descriptor ad un altro processo usando un socket + \const{PF\_UNIX} (vedi sez.~\ref{sec:unix_socket}) +\item ottenere le informazioni relative al file con \func{fstat} (dal kernel + 3.6) o al filesystem con \func{fstatfs} (dal kernel 3.12); +\item ottenere il valore dei \textit{file descriptor flags} (fra cui comparirà + anche lo stesso \const{O\_PATH}) o impostare o leggere i \textit{file status + flags} con \func{fcntl} (rispettivamente con le operazioni + \const{F\_GETFL}, \const{F\_SETFD} e \const{F\_GETFD}, vedi + sez.~\ref{sec:file_fcntl_ioctl}). +\item chiudere il file con \func{close}; +\end{itemize*} + +In realtà usando \const{O\_PATH} il file non viene effettivamente aperto per +cui ogni tentativo di usare il file descriptor così ottenuto con funzioni che +operano effettivamente sul file (come ad esempio \func{read}, \func{write}, +\func{fchown}, \func{fchmod}, \func{ioctl}, ecc.) fallirano con un errore di +\errval{EBADF}, come se questo non fosse un file descriptor valido. + +Se si usa \const{O\_PATH} tutti gli altri flag eccettuati \const{O\_CLOEXEC}, +\const{O\_DIRECTORY} e \const{O\_NOFOLLOW} verranno ignorati. + +% TODO: aggiungere O_TMPFILE per la creazione di file temporanei senza che +% questi appaiano sul filesystem, introdotto con il 3.11, vedi: +% https://lwn.net/Articles/556512/, http://kernelnewbies.org/Linux_3.11 +% https://lwn.net/Articles/558598/ http://lwn.net/Articles/619146/ + + + + 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 questo motivo per creare un nuovo file c'era una \textit{system call} -- 2.30.2