\chapter{La gestione dell'I/O su file}
\label{cha:file_IO_interface}
-Esamineremo in questo capitol le due interfacce di programmazione che
+Esamineremo in questo capitolo le due interfacce di programmazione che
consentono di gestire i dati mantenuti nei file. Cominceremo con quella nativa
del sistema, detta dei \textit{file descriptor}, che viene fornita
direttamente dalle \textit{system call} e che non prevede funzionalità evolute
\itindend{file~descriptor}
-Benché questa sia soltanto una convenzione, essa è seguita dalla gran parte
-delle applicazioni, e non aderirvi potrebbe portare a problemi di
+Benché questa sia alla fine soltanto una convenzione, essa è seguita dalla
+totalità delle applicazioni, e non aderirvi potrebbe portare a problemi di
interoperabilità. 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
\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 o in lettura/scrittura.
- \item[\errcode{EFBIG}] il file è troppo grande per essere aperto (lo
- standard richiederebbe \errval{EOVERFLOW}).
+ \item[\errcode{EINVAL}] si è usato \const{O\_CREAT} indicando un pathname
+ con caratteri non supportati dal filesystem sottostante o si è richiesto
+ \const{O\_TMPFILE} senza indicare \const{O\_WRONLY} o \const{O\_RDWR} o si
+ è usato \const{O\_DIRECT} per un filesystem che non lo supporta.
+ \item[\errcode{EISDIR}] \param{pathname} indica una directory e o si è
+ tentato un accesso che prevede la scrittura o si è usato
+ \const{O\_TMPFILE} con accesso che prevede la scrittura ma il kernel non
+ supporta la funzionalità.
+ \item[\errcode{EFBIG}] il file è troppo grande per essere aperto, in genere
+ dovuto al fatto che si è compilata una applicazione a 32 bit senza
+ abilitare il supporto per le dimensioni a 64 bit; questo è il valore
+ restituito fino al kernel 2.6.23, coi successivi viene restituito
+ \errcode{EOVERFLOW} come richiesto da POSIX.1.
\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.
+ \param{pathname} è un collegamento simbolico (e non si è usato
+ \const{O\_PATH}).
\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.
+ \const{O\_CREAT}, o non esiste un suo componente, o si riferisce ad una
+ directory inesistente, si è usato \const{O\_TMPFILE} con accesso che
+ prevede la scrittura ma il kernel non supporta la funzionalità.
\item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e
\param{pathname} non è una directory.
\item[\errcode{ENXIO}] si sono impostati \const{O\_NONBLOCK} o
\item[\errcode{EWOULDBLOCK}] la funzione si sarebbe bloccata ma si è
richiesto \const{O\_NONBLOCK}.
\end{errlist}
- ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EMFILE},
+ ed inoltre \errval{EACCES}, \errval{EDQUOT}, \errval{EFAULT}, \errval{EMFILE},
\errval{ENAMETOOLONG}, \errval{ENFILE}, \errval{ENOMEM}, \errval{ENOSPC},
\errval{EROFS}, nel loro significato generico.}
\end{funcproto}
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. I valori possibili sono gli stessi già visti in
+essergli assegnati.\footnote{questo è possibile solo se si è usato in
+ \param{flags} uno fra \const{O\_CREATE} e \const{O\_TMPFILE}, in tutti gli
+ altri casi sarà ignorato.} 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 \textit{umask} (vedi
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
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
\textbf{Flag} & \textbf{Significato} \\
\hline
\hline
- \constd{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.\\
- \constd{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 \textit{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 è
- definita la macro \macro{\_GNU\_SOURCE}.\\
- \constd{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}).\\
- \constd{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.\\
- \constd{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}).\\
+ \constd{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.\\
+ \constd{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 \textit{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 è
+ definita la macro \macro{\_GNU\_SOURCE}.\\
+ \constd{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}).\\
+ \constd{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.\\
+ \constd{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}).\\
\constd{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 è definita
- 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 il
- comportamento non è specificato.\\
+ la macro \macro{\_GNU\_SOURCE}.\\
+ \const{O\_TMPFILE} & Consente di creare un file temporaneo anonimo, non
+ visibile con un pathname sul filesystem, ma
+ leggibile e scrivibile all'interno del processo.
+ Introdotto con il kernel 3.11, è specifico di
+ Linux.\\
+ \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
+ il comportamento non è specificato.\\
\hline
\end{tabular}
\caption{Le costanti che identificano le \textit{modalità di apertura} di
\label{tab:open_time_flag}
\end{table}
-
-% 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/
-
\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
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
- sez.~\ref{sec:file_locking}, si tratta di opzioni specifiche di BSD, che non
+ 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
assicurarsi che questo non esista di già, e lo si usa spesso per creare i
-cosiddetti ``\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 un file di
-lock potrebbe dar luogo a una \textit{race condition}.\footnote{un file
- potrebbe venir creato fra il controllo la successiva apertura con
- \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 file di lock,
- (vedi sez.~\ref{sec:ipc_file_lock}).}
+cosiddetti ``\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 un
+file di lock potrebbe dar luogo a una \textit{race condition}, in tal caso
+infatti un file potrebbe venir creato fra il controllo la successiva apertura
+con \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 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 in
-seguito potrebbero non consentire lettura o scrittura, quando il file viene
-aperto l'accesso viene garantito secondo quanto richiesto con i flag di
+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
+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}.
+Il flag \constd{O\_TMPFILE}, introdotto con il kernel
+3.11,\footnote{inizialmente solo su alcuni filesystem (i vari \acr{extN},
+ \acr{Minix}, \acr{UDF}, \acr{shmem}) poi progressivamente esteso ad altri
+ (\acr{XFS} con il 3.15, \acr{Btrfs} e \acr{F2FS} con il 3.16, \acr{ubifs}
+ con il 4.9).} consente di aprire un file temporaneo senza che questo venga
+associato ad un nome e compaia nel filesystem. In questo caso la funzione
+restituirà un file descriptor da poter utilizzare per leggere e scrivere dati,
+ma il contenuto dell'argomento \param{path} verrà usato solamente per
+determinare, in base alla directory su cui si verrebbe a trovare il
+\textit{pathname} indicato, il filesystem all'interno del quale deve essere
+allocato l'\textit{inode} e lo spazio disco usato dal file
+descriptor. L'\textit{inode} resterà anonimo e l'unico riferimento esistente
+sarà quello contenuto nella \textit{file table} del processo che ha chiamato
+\func{open}.
+
+Lo scopo principale del flag è quello fornire una modalità atomica, semplice e
+sicura per applicare la tecnica della creazione di un file temporaneo seguita
+dalla sua immediata cancellazione con \func{unlink} per non lasciare rimasugli
+sul filesystem, di cui è parlato in sez.~\ref{sec:link_symlink_rename}.
+Inoltre, dato che il file non compare nel filesystem, si evitano alla radice
+tutti gli eventuali problemi di \textit{race condition} o \textit{symlink
+ attack} e non ci si deve neanche preoccupare di ottenere un opportuno nome
+univoco con l'uso delle funzioni di sez.~\ref{sec:file_temp_file}.
+
+Una volta aperto il file vi si potrà leggere o scrivere a seconda che siano
+utilizzati \const{O\_RDWR} o \const{O\_WRONLY}, mentre l'uso di
+\func{O\_RDONLY} non è consentito, non avendo molto senso ottenere un file
+descriptor da cui non si potrà comunque mai leggere nulla. L'unico altro flag
+che può essere utilizzato insieme a \const{O\_TMPFILE} è \const{O\_EXCL}, che
+in questo caso assume però un significato diverso da quello ordinario, dato
+che in questo caso non avrebbe senso fallire se il file non esiste, dato che
+questo è sempre vero.
+
+L'uso di \const{O\_EXCL} attiene all'altro possibile impiego di
+\const{O\_TMPFILE} oltre a quello della creazione sicura di un file temporaneo
+come sostituto di \func{tmpfile}: la possibilità di creare un eventuale
+contenuto iniziale ed impostare permessi, proprietario e attributi estesi con
+\func{fchmod}, \func{fchown} e \func{fsetxattr} operando sul file descriptor,
+senza possibilità di \textit{race condition} ed interferenze esterne, per poi
+far apparire il tutto sul filesystem in un secondo tempo utilizzando
+\func{linkat} sul file descriptor (torneremo su questo in
+sez.~\ref{sec:file_openat}) per dargli un nome. Questa operazione però non
+sarà possibile se si è usato \const{O\_EXCL}, che in questo caso viene ad
+assumere il significato di escludere la possibilità di far esistere il file
+anche in un secondo tempo.
+
+% NOTE: per O_TMPFILE vedi: http://kernelnewbies.org/Linux_3.11
+% https://lwn.net/Articles/558598/ http://lwn.net/Articles/619146/
+
+
\begin{table}[!htb]
\centering
\footnotesize
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.\\
tutte le volte che il file è pronto per le
operazioni di lettura o scrittura. Questo flag si
può usare solo terminali, pseudo-terminali e socket
- e, a partire dal kernel 2.6, anche sulle \textit{fifo}. Per
- un bug dell'implementazione non è opportuno usarlo
- in fase di apertura del file, deve
- invece essere attivato successivamente con
+ e, a partire dal kernel 2.6, anche sulle
+ \textit{fifo}. Per un bug dell'implementazione non
+ è opportuno usarlo in fase di apertura del file,
+ deve invece essere attivato successivamente con
\func{fcntl}.\\
\constd{O\_CLOEXEC}& Attiva la modalità di \textit{close-on-exec} (vedi
sez.~\ref{sec:proc_exec}) sul file. Il flag è
l'impostazione della suddetta modalità con
\func{fcntl} (vedi
sez.~\ref{sec:file_fcntl_ioctl}).\\
- \constd{O\_DIRECT} & Esegue l'I/O direttamente dalla memoria in
+ \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
montaggio. Introdotto con il kernel 2.6.8 ed
utilizzabile soltanto se si è definita la
macro \macro{\_GNU\_SOURCE}.\\
- \constd{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
- \textit{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_fcntl_ioctl}).\\
+ \constd{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
+ \textit{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_fcntl_ioctl}).\\
\constd{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
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
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à
attivarlo in un secondo tempo con \func{fcntl} (vedi
sez.~\ref{sec:file_fcntl_ioctl}).
-Il flag \const{O\_DIRECT} non è previsto da nessuno standard, anche se è
+Il flag \constd{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
sulla scrittura sincrona dei metadati associati alla scrittura dei dati del
file.\footnote{la situazione si complica ulteriormente per NFS, in cui l'uso
del flag disabilita la bufferizzazione solo dal lato del client, e può
- causare problemi di prestazioni.} Per questo in genere è opportuno se si usa
+ causare problemi di prestazioni.} Per questo in genere 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
% 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.) fallirà con un errore di
+\errval{EBADF}, come se questo non fosse un file descriptor valido. Per questo
+motivo usando questo flag non è necessario avere nessun permesso per aprire un
+file, neanche quello di lettura (occorre ovviamente avere il permesso di
+esecuzione per le directory sovrastanti).
+
+Questo consente di usare il file descriptor con funzioni che non richiedono
+permessi sul file, come \func{fstat}, laddove un'apertura con
+\const{O\_RDONLY} sarebbe fallita. I permessi verranno eventualmente
+controllati, se necessario, nelle operazioni seguenti, ad esempio per usare
+\func{fchdir} con il file descriptor (se questo fa riferimento ad una
+directory) occorrerà avere il permesso di esecuzione.
+
+Se si usa \const{O\_PATH} tutti gli altri flag eccettuati \const{O\_CLOEXEC},
+\const{O\_DIRECTORY} e \const{O\_NOFOLLOW} verranno ignorati. I primi due
+mantengono il loro significato usuale, mentre \const{O\_NOFOLLOW} fa si che se
+il file indicato è un un link simbolico venga aperto quest'ultimo (cambiando
+quindi il comportamento ordinario che prova il fallimento della chiamata),
+così da poter usare il file descriptor ottenuto per le funzioni
+\func{fchownat}, \func{fstatat}, \func{linkat} e \func{readlinkat} che ne
+supportano l'uso come come primo argomento (torneremo su questo in
+sez.~\ref{sec:file_openat}).
+
+
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}
% TODO manca prototipo di linkat, verificare se metterlo o metter menzione
% altre modifiche al riguardo nel 3.11 (AT_EMPTY_PATH?) vedi
-% http://lwn.net/Articles/562488/
+% http://lwn.net/Articles/562488/
+
+% TODO: Trattare esempio di inzializzazione di file e successivo collegamento
+% con l'uso di O_TMPFILE e linkat, vedi man open
+
+
% TODO manca prototipo di utimensat, verificare se metterlo o metter menzione
% TODO manca prototipo di renameat2, introdotta nel 3.15, vedi
% http://lwn.net/Articles/569134/
% LocalWords: FIONREAD epoll FIOQSIZE side effects SAFE BYCALLER QUERY EACCES
% LocalWords: EBUSY OpenBSD syncfs futimes timespec only init ESRCH kill NTPL
% LocalWords: ENXIO NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK PGRP SZ
-% LocalWords: EFAULT capabilities GETPIPE SETPIPE RESOURCE
+% LocalWords: EFAULT capabilities GETPIPE SETPIPE RESOURCE dell'I all' NFSv
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
+
+% LocalWords: nell' du vm Documentation Urlich Drepper futimesat times
+% LocalWords: futimens fs Tread all'I ll TMPFILE EDQUOT extN Minix UDF XFS
+% LocalWords: shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF
+% LocalWords: fstatfs sull'