Trattazione di linkat e openat con O_TMPFILE, con programmi di test ed
[gapil.git] / fileio.tex
index 7c2a1718c0e212292330ed6a27236aed83b28684..d2522e1442955588d0147419db29764fdb6eeed0 100644 (file)
@@ -1,6 +1,6 @@
 %% fileio.tex (merge fileunix.tex - filestd.tex)
 %%
-%% Copyright (C) 2000-2018 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2019 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -510,16 +510,16 @@ 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
+Il flag \label{open_o_tmpfile_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
@@ -1722,7 +1722,8 @@ descriptor su cui si sta operando, e la registrazione immediata dei dati sarà
 limitata al filesystem su cui il file ad esso corrispondente si trova.
 
 
-\subsection{Le \textit{at-functions}: \func{openat} e compagnia}
+
+\subsection{Le \textit{at-functions}: \func{openat} e le altre}
 \label{sec:file_openat}
 
 \itindbeg{at-functions}
@@ -1760,6 +1761,9 @@ specificata.\footnote{l'introduzione è avvenuta su proposta dello sviluppatore
   prestazioni inferiori, funzionava facendo ricorso all'uso del filesystem
   \textit{proc} con l'apertura del file attraverso il riferimento a
   \textit{pathname} del tipo di \texttt{/proc/self/fd/dirfd/relative\_path}.}
+Essendo accomunate dalla stessa interfaccia le tratteremo insieme in questa
+sezione pur non essendo strettamente attinenti l'I/O su file.
+
 
 Benché queste funzioni non siano presenti negli standard tradizionali esse
 sono state adottate da altri sistemi unix-like come Solaris, i vari BSD, fino
@@ -1772,8 +1776,8 @@ si intende usare come base per la risoluzione dei \textit{pathname} relativi
 (ad esempio usando \func{open} con il flag \const{O\_PATH} visto in
 sez.~\ref{sec:file_open_close}) per ottenere un file descriptor che dovrà
 essere passato alle stesse.  Tutte queste funzioni infatti prevedono la
-presenza un apposito argomento, in genere il primo, che negli esempi seguenti
-chiameremo sempre \param{dirfd}.
+presenza un apposito argomento, in genere il primo che negli esempi seguenti
+chiameremo sempre \param{dirfd}, per indicare la directory di partenza.
 
 In questo modo, una volta aperta la directory di partenza, si potranno
 effettuare controlli ed aperture solo con \textit{pathname} relativi alla
@@ -1793,7 +1797,7 @@ profonde. Infatti in questo caso basta eseguire la risoluzione del
 file che essa contiene. Infine poter identificare una directory di partenza
 tramite il suo file descriptor consente di avere un riferimento stabile alla
 stessa anche qualora venisse rinominata, e tiene occupato il filesystem dove
-si trova, come per la directory di lavoro di un processo.
+si trova come per la directory di lavoro di un processo.
 
 La sintassi generica di queste nuove funzioni prevede l'utilizzo come primo
 argomento del file descriptor della directory da usare come base per la
@@ -1888,11 +1892,12 @@ per fornire un meccanismo con cui modificarne il comportamento.
 Per tutte quelle che non hanno un argomento aggiuntivo il comportamento è
 identico alla corrispondente funzione ordinaria, pertanto non le tratteremo
 esplicitamente, vale per loro quanto detto con \func{openat} per l'uso del
-nuovo argomento \param{dirfd}. Quando invece l'argomento è presente il
-comportamento viene modificato a seconda del valore assegnato a \param{flags},
-che deve essere passato come maschera binaria con una opportuna combinazione
-delle costanti elencate in tab.~\ref{tab:at-functions_constant_values}, in
-quanto sono possibili diversi valori a seconda della funzione usata.
+nuovo argomento \param{dirfd}. Tratteremo invece esplicitamente tutte quelle
+per cui l'argomento è presente, in quanto il loro comportamento viene
+modificato a seconda del valore assegnato a \param{flags}; questo deve essere
+passato come maschera binaria con una opportuna combinazione delle costanti
+elencate in tab.~\ref{tab:at-functions_constant_values}, in quanto sono
+possibili diversi valori a seconda della funzione usata.
 
 \begin{table}[htb]
   \centering
@@ -1952,11 +1957,11 @@ funzioni. Il primo di questi è \const{AT\_SYMLINK\_NOFOLLOW}, che viene usato
 da tutte le funzioni tranne \func{linkat} e \func{unlinkat}, e che consente di
 scegliere, quando si sta operando su un collegamento simbolico, se far agire
 la funzione direttamente sullo stesso o sul file da esso referenziato. Si
-tenga presente però che per \func{fchmodat} questo, che è l'unico flag
+tenga presente però che per \funcm{fchmodat} questo, che è l'unico flag
 consentito e previsto dallo standard, non è attualmente implementato (anche
 perché non avrebbe molto senso cambiare i permessi di un link simbolico) e
 pertanto l'uso della funzione è analogo a quello delle altre funzioni che non
-hanno l'argomento \param{flags}.
+hanno l'argomento \param{flags} (e non la tratteremo esplicitamente).
 
 L'altro flag comune è \const{AT\_EMPTY\_PATH}, utilizzabile a partire dal
 kernel 2.6.39, che consente di usare per \param{dirfd} un file descriptor
@@ -1967,13 +1972,13 @@ pag.~\pageref{open_o_path_flag}). Quando si usa questo flag \param{pathname}
 deve essere vuoto, da cui il nome della costante, ed in tal caso la funzione
 agirà direttamente sul file associato al file descriptor \param{dirfd}.
 
-Come esempio di funzione che utilizza solo questi due flag generici possiamo
-considerare \funcd{fchownat}, che può essere usata per sostituire sia
-\func{chown} che \func{lchown}; il suo prototipo è:
+Una prima funzione di sistema che utilizza l'argomento \param{flag} è
+\funcd{fchownat}, che può essere usata per sostituire sia \func{chown} che
+\func{lchown}; il suo prototipo è:
 
 \begin{funcproto}{
-\fhead{unistd.h}
 \fhead{fcntl.h} 
+\fhead{unistd.h}
 \fdecl{int fchownat(int dirfd, const char *pathname, uid\_t owner, gid\_t
     group, int flags)}
 \fdesc{Modifica il proprietario di un file.} 
@@ -1990,16 +1995,20 @@ considerare \funcd{fchownat}, che può essere usata per sostituire sia
 }  
 \end{funcproto}
 
-In questo caso se si è impostato \const{AT\_SYMLINK\_NOFOLLOW} si 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}. 
+In questo caso, oltre a quanto già detto per \func{openat} riguardo all'uso di
+\param{dirfd}, se si è impostato \const{AT\_SYMLINK\_NOFOLLOW} in
+\param{flags}, si 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}. La funzione supporta anche l'uso
+di \const{AT\_EMPTY\_PATH}, con il significato illustrato in precedenza e non
+ha flag specifici.
 
-Un'altra funzione che utilizza l'argomento \param{flags}, usandolo per
-indicare altro rispetto alla possibilità di seguire o meno un collegamento
-simbolico, è \funcd{faccessat}, ed il suo prototipo è:
+Una seconda funzione di sistema che utilizza l'argomento \param{flags}, in
+questo caso anche per modificare il suo comportamento, è \funcd{faccessat}, ed
+il suo prototipo è:
 
 \begin{funcproto}{
+\fhead{fcntl.h} 
 \fhead{unistd.h}
 \fdecl{int faccessat(int dirfd, const char *path, int mode, int flags)}
 \fdesc{Controlla i permessi di accesso.} 
@@ -2016,22 +2025,22 @@ simbolico, è \funcd{faccessat}, ed il suo prototipo è:
 }  
 \end{funcproto}
 
-La funzione esegue il controllo di accesso ad un file, ma l'argomento
-\param{flags} consente di modificarne il comportamento rispetto a quello
-ordinario di \func{access}. In questo caso esso può essere specificato come
-maschera binaria di due valori: il solito \const{AT\_SYMLINK\_NOFOLLOW}, con
-il significato già spiegato, e \const{AT\_EACCES} per indicare alla funzione
-di eseguire il controllo dei permessi usando l'\ids{UID} effettivo invece di
-quello reale (il comportamento di default, che riprende quello di
-\func{access}). 
+La funzione esegue il controllo di accesso ad un file, e \param{flags}
+consente di modificarne il comportamento rispetto a quello ordinario di
+\func{access} (cui è analoga e con cui condivide i problemi di sicurezza
+visti in sez.~\ref{sec:file_stat}) usando il valore \const{AT\_EACCES} per
+indicare alla funzione di eseguire il controllo dei permessi con l'\ids{UID}
+\textsl{effettivo} invece di quello \textsl{reale}. L'unico altro valore
+consentito è \const{AT\_SYMLINK\_NOFOLLOW}, con il significato già spiegato.
 
-Un'altra funzione che ha un utilizzo specifico dell'argomento \param{flags} è
-\funcd{unlinkat}: in questo caso l'argomento viene utilizzato perché tramite
-esso si può indicare alla funzione di comportarsi sia come analogo di
-\func{unlink} che di \func{rmdir}; il suo prototipo è:
+Un utilizzo specifico dell'argomento \param{flags} viene fatto anche dalla
+funzione di sistema \funcd{unlinkat}, in questo caso l'argomento viene
+utilizzato perché tramite esso si può indicare alla funzione di comportarsi
+sia come analogo di \func{unlink} che di \func{rmdir}; il suo prototipo è:
 
 \begin{funcproto}{
 \fhead{fcntl.h}
+\fhead{unistd.h}
 \fdecl{int unlinkat(int dirfd, const char *pathname, int flags)}
 \fdesc{Rimuove una voce da una directory.} 
 }
@@ -2059,11 +2068,100 @@ valori (la funzione non segue comunque i collegamenti simbolici e
 maschera binaria, essendo \const{AT\_REMOVEDIR} l'unico flag disponibile per
 questa funzione, lo si può assegnare direttamente.
 
-Ancora diverso è il caso di \funcd{linkat},\footnote{si tenga presente che per
-  questa funzione l'argomento \param{flags} è disponibile ed utilizzabile solo
-  a partire dal kernel 2.6.18.} anche se in questo caso l'utilizzo continua ad
-essere attinente al comportamento con i collegamenti simbolici, il suo
-prototipo è:
+Un'altra funzione di sistema che usa l'argomento \param{flags} è
+\func{utimensat}, che però non è una corrispondente esatta delle funzioni
+classiche \func{utimes} e \func{lutimes}, in quanto ha una maggiore precisione
+nella indicazione dei tempi dei file, per i quali, come per \func{futimens},
+si devono usare strutture \struct{timespec} che consentono una precisione fino
+al nanosecondo; la funzione è stata introdotta con il kernel
+2.6.22,\footnote{in precedenza, a partire dal kernel 2.6.16, era stata
+  introdotta una \textit{system call} \funcm{futimesat} seguendo una bozza
+  della revisione dello standard poi modificata; questa funzione, sostituita
+  da \func{utimensat}, è stata dichiarata obsoleta, non è supportata da
+  nessuno standard e non deve essere più utilizzata: pertanto non ne
+  parleremo.} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{fcntl.h}
+\fhead{sys/stat.h}
+\fdecl{int utimensat(int dirfd, const char *pathname, const struct
+    timespec times[2],\\
+\phantom{int utimensat(}int flags)}
+\fdesc{Cambia i tempi di un file.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà i valori di \func{utimes}, \func{lutimes} e
+  \func{futimens} con lo stesso significato ed inoltre:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{dirfd} non è \const{AT\_FDCWD} o un file
+    descriptor valido.
+  \item[\errcode{EFAULT}] \param{dirfd} è \const{AT\_FDCWD} ma
+    \param{pathname} è \var{NULL} o non è un puntatore valido.
+  \item[\errcode{EINVAL}] si usato un valore non valido per \param{flags},
+    oppure \param{pathname} è \var{NULL}, \param{dirfd} non è
+    \const{AT\_FDCWD} e \param{flags} contiene \const{AT\_SYMLINK\_NOFOLLOW}.
+  \item[\errcode{ESRCH}] non c'è il permesso di attraversamento per una delle
+    componenti di \param{pathname}.
+  \end{errlist}
+}
+\end{funcproto}
+
+La funzione imposta i tempi dei file utilizzando i valori passati nel vettore
+di strutture \struct{timespec} ed ha in questo lo stesso comportamento di
+\func{futimens}, vista in sez.~\ref{sec:file_file_times}, ma al contrario di
+questa può essere applicata anche direttamente ad un file come \func{utimes};
+l'unico valore consentito per \param{flags} è \const{AT\_SYMLINK\_NOFOLLOW}
+che indica alla funzione di non dereferenziare i collegamenti simbolici, cosa
+che le permette di riprodurre anche le funzionalità di \func{lutimes} (con una
+precisione dei tempi maggiore).
+
+Su Linux solo \func{utimensat} è una \textit{system call} mentre
+\func{futimens} è una funzione di libreria, infatti \func{utimensat} ha un
+comportamento speciale se \param{pathname} è \var{NULL}, in tal caso
+\param{dirfd} viene considerato un file descriptor ordinario e il cambiamento
+del tempo viene applicato al file sottostante, qualunque esso sia. Viene cioè
+sempre usato il comportamento che per altre funzioni deve essere attivato con
+\const{AT\_EMPTY\_PATH} (che non è previsto per questa funzione) per cui
+\code{futimens(fd, times}) è del tutto equivalente a \code{utimensat(fd, NULL,
+  times, 0)}. Si tenga presente che nella \acr{glibc} questo comportamento è
+disabilitato, e la funzione, seguendo lo standard POSIX, ritorna un errore di
+\errval{EINVAL} se invocata in questo modo.
+
+Come corrispondente di \func{stat}, \func{fstat} e \func{lstat} si può
+utilizzare invece la funzione di sistema \funcd{fstatat}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{fcntl.h}
+\fhead{sys/stat.h}
+\fdecl{int fstatat(int dirfd, const char *pathname, struct stat *statbuf, int
+  flags)} 
+\fdesc{Rimuove una voce da una directory.} 
+}
+
+{La funzione ritorna gli stessi valori e gli stessi codici di errore di
+  \func{stat}, \func{fstat}, o \func{lstat} a seconda del valore di
+  \param{flags}, ed in più:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
+  \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \textit{pathname} relativo,
+    ma \param{dirfd} fa riferimento ad un file.
+  \end{errlist}
+}  
+\end{funcproto}
+
+La funzione ha lo stesso comportamento delle sue equivalenti classiche, l'uso
+di \param{flags} consente di farla comportare come \func{lstat} se si usa
+\const{AT\_SYMLINK\_NOFOLLOW}, o come \func{fstat} se si usa con
+\const{AT\_EMPTY\_PATH} e si passa il file descriptor in \param{dirfd}. Viene
+però supportato l'ulteriore valore \const{AT\_NO\_AUTOMOUNT} che qualora
+\param{pathname} faccia riferimento ad una directory marcata per
+l'\textit{automount} ne evita il montaggio automatico.
+            
+Ancora diverso è il caso di \funcd{linkat} anche se in questo caso l'utilizzo
+continua ad essere attinente al comportamento con i collegamenti simbolici, il
+suo prototipo è:
 
 \begin{funcproto}{
 \fhead{fcntl.h}
@@ -2078,148 +2176,262 @@ prototipo è:
   \item[\errcode{EBADF}] \param{olddirfd} o \param{newdirfd} non sono un file
     descriptor valido.
   \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
-  \item[\errcode{ENOTDIR}] \param{oldpath} e \param{newpath} è un
-    \textit{pathname} relativo, ma \param{oldirfd} o \param{newdirfd} fa
+  \item[\errcode{ENOENT}] \param{oldpath} o \param{newpath} è un
+    \textit{pathname} relativo, ma la corrispondente directory di partenza
+    (\param{olddirfd} o \param{newdirfd}) è stata cancellata, oppure si è
+    cercato di creare un \textit{link} da un file descriptor aperto con
+    \const{O\_TMPFILE} e \const{O\_EXCL}, oppure si è usato
+    \const{AT\_EMPTY\_PATH} senza privilegi amministrativi. 
+  \item[\errcode{ENOTDIR}] \param{oldpath} e \param{newpath} sono
+    \textit{pathname} relativi, ma \param{olddirfd} o \param{newdirfd} fa
     riferimento ad un file.
+  \item[\errcode{EPERM}] si è usato \const{AT\_EMPTY\_PATH} con
+    \param{oldpath} vuoto e \param{olddirfd} che fa riferimento ad una
+    directory.
   \end{errlist}
 }  
 \end{funcproto}
 
-In questo caso 
-
-Si ricordi che su Linux il comportamento di \func{link} è quello di non
-seguire mai i collegamenti simbolici, pertanto l'uso ordinario dell'argomento
-parrebbe in questo caso essere inutile.  A partire dal kernel 2.6.18 invece
-però è stato aggiunta per questa funzione la possibilità di usare il valore
-\const{AT\_SYMLINK\_FOLLOW}, che richiede di dereferenziare i collegamenti
-simbolici.
+Anche in questo caso la funzione svolge lo stesso compito della
+corrispondente classica \func{link}, ma dovendo specificare due
+\textit{pathname} (sorgente e destinazione) aggiunge a ciascuno di essi un
+argomento (rispettivamente \param{olddirfd} e \param{newdirfd}) per poter
+indicare entrambi come relativi a due directory aperte in precedenza.
+
+In questo caso, dato che su Linux il comportamento di \func{link} è quello di
+non seguire mai i collegamenti simbolici, \const{AT\_SYMLINK\_NOFOLLOW} non
+viene utilizzato. A partire dal kernel 2.6.18 è stato aggiunto a questa
+funzione la possibilità di usare il valore \const{AT\_SYMLINK\_FOLLOW} per
+l'argomento \param{flags},\footnote{nei kernel precedenti, dall'introduzione
+  nel 2.6.16, l'argomento \param{flags} era presente, ma senza alcun valore
+  valido, e doveva essere passato sempre con valore nullo.}  che richiede di
+dereferenziare un eventuale collegamento simbolico creando un \textit{hard
+  link} al file puntato da quest'ultimo.
+
+Inoltre a partire dal kernel 3.11 si può usare \const{AT\_EMPTY\_PATH} con lo
+stesso significato già visto in precedenza applicato ad \param{olddirfd}, si
+può cioè creare un nuovo \textit{hard link} al file associato al file
+descriptor \param{olddirfd}, passando un valore nullo per
+\param{oldpath}. Questa operazione però è privilegiata e richiede i privilegi
+di amministratore (la \textit{capability} \const{CAP\_DAC\_READ\_SEARCH}),
+infatti in questo modo la funzione si comporta come una ipotetica
+\texttt{flink}, una \textit{system call} di cui è stato spesso chiesta la
+creazione, che permetterebbe di associare direttamente un nome ad un file
+descriptor, ma che non è mai stata realizzata per problemi di sicurezza.
+
+Il problema infatti è che le verifiche di accesso sono fatte quando il file
+viene aperto e non attengono solo ai permessi del file stesso, ma anche a
+quelli delle directory del suo \textit{pathname}; se una volta aperto venisse
+collegato in un altra directory eventuali restrizioni imposte sulle directory
+del suo \textit{pathname} andrebbero perse. Inoltre sarebbe possibile accedere
+al file sottostante anche in scrittura per un file descriptor che è stato
+fornito come aperto in sola lettura, o con accesso libero per un file
+descriptor fornito aperto in \textit{append}. Infine e la funzione
+consentirebbe rendere accessibile all'interno di un \textit{choot} (vedi
+sez.~\ref{sec:file_chroot}) un qualunque file sia stato aperto fuori dallo
+stesso prima di entrarvi.
+
+
+% NOTE per la discussione sui problemi di sicurezza relativi a questa
+% funzionalità vedi http://lwn.net/Articles/562488/
+
+Per questo motivo l'uso di \const{AT\_EMPTY\_PATH} richiede comunque privilegi
+amministrativi, anche se, quando è disponibile il filesystem \texttt{/proc}, è
+possibile usare \func{linkat} per creare un file da un qualunque file
+descriptor un processo abbia aperto, usandola con un codice analogo al
+seguente:\footnote{non esiste, al momento, una modalità per evitare i rischi
+  illustrati in precedenza se si sta usando il filesystem \textit{proc}.}
+\includecodesnip{listati/procfd_linkat.c}
+
+Questa modalità è anche quella con cui è possibile assegnare in un secondo
+tempo il nome ad un file anonimo creato usando \func{open} con
+\const{O\_TMPFILE}; ma si deve tenere presente che per questi file la funzione
+ha un comportamento particolare. In generale infatti quando il file sorgente
+di \func{linkat} ha un numero di collegamenti nulli (cosa che avviene ad
+esempio quando si apre un file temporaneo e lo si cancella subito dopo oppure
+quando viene cancellato un file aperto in precedenza) la funzione non consente
+di ricollegarlo ad un altro file riassegnandogli un nuovo nome e fallisce
+sempre, qualunque siano i permessi del processo e che si usi questo approccio
+o \const{AT\_EMPTY\_PATH}, con un errore di \errval{ENOENT}.
+
+Questo non avviene se il file descriptor sorgente è stato ottenuto con
+\const{O\_TMPFILE} e la funzione ha successo, a meno che non si sia usato
+nell'apertura anche \const{O\_EXCL} per impedire questo specifico
+comportamento, e continuare ad ottenere l'errore di \errval{ENOENT}. In fig.
+
+Pertanto la modalità per creare in maniera sicura la versione iniziale di un
+file cui abbiamo accennato a pag.~\pageref{open_o_tmpfile_flag},
 
-
-
-Dato che questo è il comportamento adottato per un valore nullo
-di \param{flags} da tutte le altre funzioni, \func{linkat} è l'unica per cui
-può essere usato esplicitamente questo valore e per la quale non ha senso
-usare \const{AT\_SYMLINK\_NOFOLLOW}. Per avere un quadro d'insieme si è
-riassunto in tab.~\ref{tab:at-functions_constant_values} l'elenco delle
-costanti utilizzabili per i valori di \param{flags}.
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/initfile.c}
+  \end{minipage}
+  \caption{Esempio di codice creare in maniera sicura il contenuto iniziale di
+    un file.} 
+  \label{fig:initfile}
+\end{figure}
 
 
 
 
-% TODO trattare fstatat e con essa
-% TODO trattare anche statx, aggiunta con il kernel 4.11 (vedi
-% https://lwn.net/Articles/707602/ e
-% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) 
 
-% 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/
 
 % 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 renameat2, introdotta nel 3.15, vedi
 % http://lwn.net/Articles/569134/ 
-% TODO manca prototipo di execveat, introdotta nel 3.19, vedi
-% https://lwn.net/Articles/626150/ cerca anche fexecve
-
 
-% TODO: trattare i nuovi AT_flags quando e se arriveranno, vedi
-% https://lwn.net/Articles/767547/ 
 
-\texttt{ATTENZIONE PARTE DA RIVEDERE}
-
-
-Un'ultima differenza fra le \textit{at-functions} e le funzioni tradizionali
-di cui sono estensione è, come accennato in sez.~\ref{sec:file_temp_file},
-quella relativa a \func{utimensat} che non è propriamente una corrispondente
-esatta di \func{utimes} e \func{lutimes}, dato che questa funzione ha una
-maggiore precisione nella indicazione dei tempi dei file, per i quali come per
-\func{futimes}, si devono usare strutture \struct{timespec} che consentono una
-precisione fino al nanosecondo; la funzione è stata introdotta con il kernel
-2.6.22,\footnote{in precedenza, a partire dal kernel 2.6.16, era stata
-  introdotta una \textit{system call} \funcm{futimesat} seguendo una bozza
-  della revisione dello standard poi modificata; questa funzione, sostituita
-  da \func{utimensat}, è stata dichiarata obsoleta, non è supportata da
-  nessuno standard e non deve essere più utilizzata: pertanto non ne
-  parleremo.} ed il suo prototipo è:
+Altre due funzioni che utilizzano due \textit{pathname} (e due file
+descriptor) sono \funcd{renameat} e \funcd{renameat2}, corrispondenti alla
+classica \func{rename}; i rispettivi prototipi sono:
 
 \begin{funcproto}{
-\fhead{sys/time.h}
-\fdecl{int utimensat(int dirfd, const char *pathname, const struct
-    timespec times[2], int flags)}
-\fdesc{Cambia i tempi di un file.} 
+\fhead{fcntl.h}
+\fdecl{int renameat(int olddirfd, const char *oldpath, int newdirfd, const
+  char *newpath)} 
+\fdecl{int renameat2(int olddirfd, const char *oldpath, int newdirfd, \\
+\phantom{int renameat2(}const char *newpath, int flags)}
+\fdesc{Rinomina o sposta un file o una directory.} 
 }
 
-{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
-  caso \var{errno} assumerà uno dei valori: 
+{La funzioni ritornano gli stessi valori e gli stessi codici di errore di
+  \func{rename}, ed in più per entrambe:
   \begin{errlist}
-  \item[\errcode{EACCES}] si è richiesta l'impostazione del tempo corrente ma
-    non si ha il permesso di scrittura sul file, o non si è proprietari del
-    file o non si hanno i privilegi di amministratore; oppure il file è
-    immutabile (vedi sez.~\ref{sec:file_perm_overview}).
-  \item[\errcode{EBADF}] \param{dirfd} non è \const{AT\_FDCWD} o un file
+  \item[\errcode{EBADF}] \param{olddirfd} o \param{newdirfd} non sono un file
     descriptor valido.
-  \item[\errcode{EFAULT}] \param{times} non è un puntatore valido oppure
-    \param{dirfd} è \const{AT\_FDCWD} ma \param{pathname} è \var{NULL} o non è
-    un puntatore valido.
-  \item[\errcode{EINVAL}] si sono usati dei valori non corretti per i tempi di
-    \param{times}, oppure è si usato un valore non valido per \param{flags},
-    oppure \param{pathname} è \var{NULL}, \param{dirfd} non è
-    \const{AT\_FDCWD} e \param{flags} contiene \const{AT\_SYMLINK\_NOFOLLOW}.
-  \item[\errcode{EPERM}] si è richiesto un cambiamento nei tempi non al tempo
-    corrente, ma non si è proprietari del file o non si hanno i privilegi di
-    amministratore; oppure il file è immutabile o \textit{append-only} (vedi
-    sez.~\ref{sec:file_perm_overview}).
-  \item[\errcode{ESRCH}] non c'è il permesso di attraversamento per una delle
-    componenti di \param{pathname}.
+  \item[\errcode{ENOTDIR}] \param{oldpath} e \param{newpath} sono
+    \textit{pathname} relativi, ma i corrispondenti \param{oldirfd} o
+    \param{newdirfd} fan riferimento ad un file e non a una directory.
+  \end{errlist}
+  e per \func{renameat2} anche:
+  \begin{errlist}
+  \item[\errcode{EEXIST}] si è richiesto \macro{RENAME\_NOREPLACE} ma
+    \param{newpath} esiste già.
+  \item[\errcode{EINVAL}] Si è usato un flag non valido in \param{flags}, o si
+    sono usati insieme a \macro{RENAME\_EXCHANGE} o \macro{RENAME\_NOREPLACE}
+    o \macro{RENAME\_WHITEOUT}, o non c'è il supporto nel filesystem per una
+    delle operazioni richieste in \param{flags}.
+  \item[\errcode{ENOENT}] si è richiesto \macro{RENAME\_EXCHANGE} e
+    \param{newpath} non esiste.
+  \item[\errcode{EPERM}] si è richiesto \macro{RENAME\_WHITEOUT} ma il
+    chiamante non ha i privilegi di amministratore.
   \end{errlist}
-  ed inoltre per entrambe \errval{EROFS} e per \func{utimensat}
-  \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel
-  loro significato generico.}
+}  
 \end{funcproto}
 
-La funzione imposta i tempi dei file utilizzando i valori passati nel vettore
-di strutture \struct{timespec} esattamente come \func{futimes} (si veda quanto
-illustrato in sez.~\ref{sec:file_file_times}). 
-
-La funzione supporta invece, rispetto ad \func{utimes} che abbiamo visto in
-sez.~\ref{sec:file_file_times}, una sintassi più complessa che consente una
-indicazione sicura del file su cui operare specificando la directory su cui si
-trova tramite il file descriptor \param{dirfd} ed il suo nome come
-\textit{pathname relativo} in \param{pathname}.\footnote{su Linux solo
-  \func{utimensat} è una \textit{system call} e \func{futimens} è una funzione
-  di libreria, infatti se \param{pathname} è \var{NULL} \param{dirfd} viene
-  considerato un file descriptor ordinario e il cambiamento del tempo
-  applicato al file sottostante, qualunque esso sia, per cui
-  \code{futimens(fd, times}) è del tutto equivalente a \code{utimensat(fd,
-    NULL, times, 0)} ma nella \acr{glibc} questo comportamento è disabilitato
-  seguendo lo standard POSIX, e la funzione ritorna un errore di
-  \errval{EINVAL} se invocata in questo modo.}
-
-Torneremo su questa sintassi e sulla sua motivazione in
-sez.~\ref{sec:file_openat}, quando tratteremo tutte le altre funzioni (le
-cosiddette \textit{at-functions}) che la utilizzano; essa prevede comunque
-anche la presenza dell'argomento \param{flags} con cui attivare flag di
-controllo che modificano il comportamento della funzione, nel caso specifico
-l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che indica alla
-funzione di non dereferenziare i collegamenti simbolici, cosa che le permette
-di riprodurre le funzionalità di \func{lutimes}.
-
-
-\texttt{ATTENZIONE PARTE DA RIVEDERE}
+In realtà la corrispondente di \func{rename}, prevista dallo standard
+POSIX.1-2008 e disponibile dal kernel 2.6.16 come le altre
+\textit{at-functions}, sarebbe soltanto \func{renameat}, su Linux però, a
+partire dal kernel dal 3.15, questa è stata realizzata in termini della nuova
+funzione di sistema \func{renameat2} che prevede l'uso dell'argomento
+aggiuntivo \param{flags}; in questo caso \func{renameat} è totalmente
+equivalente all'utilizzo di \func{renamat2} con un valore nullo per
+\param{flags}.
+
+L'uso di \func{renameat} è identico a quello di \func{rename}, con le solite
+note relative alle estensioni delle \textit{at-functions}, applicate ad
+entrambi i \textit{pathname} passati come argomenti alla funzione. Con
+\func{renameat2} l'introduzione dell'argomento \func{flags} (i cui valori
+possibili sono riportati in tab.~\ref{tab:renameat2_flag_values}) ha permesso
+di aggiungere alcune funzionalità non previste al momento da nessuno standard,
+e specifiche di Linux. Si tenga conto che questa funzione di sistema non viene
+definita nella \acr{glibc} per cui deve essere chiamata utilizzando
+\func{syscall} come illustrato in sez.~\ref{sec:intro_syscall}.
 
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{RENAME\_EXCHANGE} & richiede uno scambio di nomi fra
+                               \param{oldpath} e \param{newpath}, non è
+                               usabile con \const{RENAME\_NOREPLACE}.\\
+    \const{RENAME\_NOREPLACE}& non sovrascrive  \param{newpath} se questo
+                               esiste dando un errore.\\
+    \const{RENAME\_WHITEOUT} & crea un oggetto di \textit{whiteout}
+                               contestualmente al cambio di nome 
+                               (disponibile a partire dal kernel 3.18).\\ 
+    \hline
+  \end{tabular}  
+  \caption{I valori specifici dei bit dell'argomento \param{flags} per l'uso
+    con \func{renameat2}.}
+  \label{tab:renameat2_flag_values}
+\end{table}
+
+L'uso dell'argomento \param{flags} in questo caso non attiene alle
+funzionalità relative alla \textit{at-functions}, ma consente di estendere le
+funzionalità di \func{rename}. In particolare \func{renameat2} consente di
+eseguire uno scambio di nomi in maniera atomica usando il flag
+\constd{RENAME\_EXCHANGE}; quando viene specificato la funzione non solo
+rinomina \param{oldpath} in \param{newpath}, ma rinomina anche, senza dover
+effettuare un passaggio intermedio, \param{newpath} in \param{oldpath}. Quando
+si usa questo flag, entrambi i \textit{pathname} passati come argomenti alla
+funzione devono esistere, e non è possibile usare \const{RENAME\_NOREPLACE},
+non ci sono infine restrizioni sul tipo dei file (regolari, directory, link
+simbolici, ecc.) di cui si scambia il nome.
+
+Il flag \constd{RENAME\_NOREPLACE} consente di richiedere la generazione di un
+errore nei casi in cui \func{rename} avrebbe causato una sovrascrittura della
+destinazione, rendendo possibile evitare la stessa in maniera atomica; un
+controllo preventivo dell'esistenza del file infatti avrebbe aperto alla
+possibilità di una \textit{race condition} fra il momento del controllo e
+quella del cambio di nome.
+
+\itindbeg{overlay~filesytem}
+\itindbeg{union~filesytem}
+
+Infine il flag \constd{RENAME\_WHITEOUT}, introdotto con il kernel 3.18,
+richiede un approfondimento specifico, in quanto attiene all'uso della
+funzione con dei filesystem di tipo \textit{overlay}/\textit{union}, dato che
+il flag ha senso solo quando applicato a file che stanno su questo tipo di
+filesystem. 
+
+Un \textit{overlay} o \texttt{union filesystem} è un filesystem speciale
+strutturato in livelli, in cui si rende scrivibile un filesystem accessibile
+in sola lettura, \textsl{sovrapponendogli} un filesystem scrivibile su cui
+vanno tutte le modifiche. Un tale tipo di filesystem serve ad esempio a
+rendere scrivibili i dati processati quando si fa partire una distribuzione
+\textit{Live} basata su CD o DVD, ad esempio usando una chiavetta o uno spazio
+disco aggiuntivo.
+
+In questo caso quando si rinomina un file che sta nello strato in sola lettura
+quello che succede è questo viene copiato a destinazione sulla parte
+accessibile in scrittura, ma l'originale non può essere cancellato, per far si
+che esso non appaia più è possibile creare 
+
+\itindend{overlay~filesytem}
+\itindend{union~filesytem}
+
+
+
+% TODO trattare anche statx, aggiunta con il kernel 4.11 (vedi
+% https://lwn.net/Articles/707602/ e
+% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) 
 
-\itindend{at-functions}
 
 % TODO: manca prototipo e motivazione di fexecve, da trattare qui in quanto
 % inserita nello stesso standard e da usare con openat, vedi 
 % http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
-
+% TODO manca prototipo di execveat, introdotta nel 3.19, vedi
+% https://lwn.net/Articles/626150/ cerca anche fexecve
 % TODO: manca prototipo e motivazione di execveat, vedi
 % http://man7.org/linux/man-pages/man2/execveat.2.html 
 
+
+% TODO: trattare i nuovi AT_flags quando e se arriveranno, vedi
+% https://lwn.net/Articles/767547/ 
+
+\itindend{at-functions}
+
+
 \subsection{Le operazioni di controllo}
 \label{sec:file_fcntl_ioctl}
 
@@ -3313,7 +3525,6 @@ sistemi più moderni.
 % TODO: mettere prototipi espliciti fseeko e ftello o menzione?
 
 
-
 \subsection{Input/output binario}
 \label{sec:file_binary_io}
 
@@ -4596,15 +4807,18 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o
 % 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 dell'I all' NFSv
+% LocalWords:  EFAULT capabilities GETPIPE SETPIPE RESOURCE NFSv
+% LocalWords:  Documentation Urlich Drepper futimesat times
+% LocalWords:  futimens fs Tread TMPFILE EDQUOT extN Minix UDF XFS
+% LocalWords:  shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF
+% LocalWords:  fstatfs SIGTTIN EDESTADDRREQ datagram connect seal pag
+% LocalWords:  dirty execveat execve scandirat statx AUTOMOUNT automount DAC
+% LocalWords:  wrapper EMPTY olddirfd oldpath newdirfd newpath capability
+% LocalWords:  SEARCH flink choot oldirfd NOREPLACE EXCHANGE WHITEOUT union
+% LocalWords:  renamat syscall whiteout overlay filesytem Live
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
 
-% LocalWords:  nell' du vm Documentation Urlich Drepper futimesat times l'I
-%  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' SIGTTIN EDESTADDRREQ datagram connect seal
-%  LocalWords:  dirty execveat execve scandirat statx