Altra documentazione O_PATH.
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 20 Oct 2018 00:55:54 +0000 (02:55 +0200)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 20 Oct 2018 00:55:54 +0000 (02:55 +0200)
fileio.tex

index dad46a0d2fdbb8b93cff327250d47c2319b1dfd5..acbedc27d3b7796663f76093366286280f7d25b3 100644 (file)
@@ -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}
+  \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}