+{La funzione ritorna gli stessi valori e gli stessi codici di errore di
+ \func{link}, ed in più:
+ \begin{errlist}
+ \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{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}
+
+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, se si sta usando il filesystem
+ \textit{proc}, una modalità per evitare i rischi illustrati in precedenza.}
+\includecodesnip{listati/procfd_linkat.c}
+e 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 con un errore di
+\errval{ENOENT} qualunque siano i permessi del processo, e che si usi questo
+approccio o \const{AT\_EMPTY\_PATH}. Ma questo non avviene se il file
+descriptor è stato ottenuto con \const{O\_TMPFILE}, in tal caso la funzione ha
+successo, a meno che non si sia usato nell'apertura anche \const{O\_EXCL} per
+impedire questo comportamento, e continuare ad ottenere \errval{ENOENT}.
+
+In fig.~\ref{fig:initfile} si è riportato il codice della funzione
+\func{InitFile}, che consente di creare in maniera sicura il contenuto
+iniziale di un file utilizzando \const{O\_TMPFILE} e \func{linkat}, come
+accennato a pag.~\pageref{open_o_tmpfile_flag}. La funzione richiede di
+indicare il file da creare usando la sintassi delle \textit{at-functions},
+specificando la directory in cui crearlo con il corrispondente file descriptor
+passato nell'argomento \texttt{dirfd} ed il pathname relativo ed essa passato
+l'argomento \texttt{file}; il contenuto iniziale del file deve essere fornito
+nel buffer \texttt{buf} di lunghezza \texttt{size}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/InitFile.c}
+ \end{minipage}
+ \caption{Esempio di codice per creare in maniera sicura il contenuto
+ iniziale di un file.}
+ \label{fig:initfile}
+\end{figure}
+
+La funzione come primo passo (\texttt{\small 6--10}) ottiene un file
+descriptor accessibile in lettura/scrittura invocando \func{openat} con il
+flag \const{O\_TMPFILE} per ottenere un file anonimo, facendo riferimento a
+quella che sarà la directory di destinazione in cui poi verrà collegato lo
+stesso passata dal chiamante in \texttt{dirfd}, usando ``\texttt{.}'' come
+\textit{pathname} relativo. Si noti come nella chiamata si impostino anche
+(per semplicità si è usato un valore fisso) i valori iniziali dei permessi del
+file (lettura e scrittura solo per il proprietario), e come dopo la chiamata
+si controlli la presenza di un eventuale errore, ritornandolo con un messaggio
+qualora avvenga.
+
+Il secondo passo (\texttt{\small 11--15}) è quello di chiamare la funzione
+\func{FullWrite} (che tratteremo in dettaglio in sez.~\ref{sec:sock_io_behav})
+per eseguire la scrittura del contenuto del buffer \texttt{buf} sul file
+anonimo ottenuto con \func{openat}; in sostanza la funzione scrive tutto il
+contenuto del buffer, iterando le scritture qualora non sia possibile eseguire
+tutto con una singola \func{write}, cosa che comunque per i file su disco in
+genere non avviene mai.
+
+Una volta completata con successo la scrittura l'ultimo passo (\texttt{\small
+ 17--23}) è collegare il file anonimo con \func{linkat}, per questo però
+occorre utilizzare il \textit{pathname} ad esso associato sotto
+\texttt{/proc}, che viene ottenuto (\texttt{\small 16}) con una
+\func{snprintf} (vedi sez.~\ref{sec:file_formatted_io}) usando file descriptor
+restituito da \func{openat}. Con questo \textit{pathname} si può procedere
+(\texttt{\small 17}) a chiamare \func{linkat} per eseguire il collegamento, in
+cui occorre usare il flag \const{AT\_SYMLINK\_NOFOLLOW} come nell'esempio
+precedente.
+
+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{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 funzioni ritornano gli stessi valori e gli stessi codici di errore di
+ \func{rename}, ed in più per entrambe:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{olddirfd} o \param{newdirfd} non sono un file
+ descriptor valido.
+ \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}
+}
+\end{funcproto}
+
+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 la sintassi
+delle \textit{at-functions} applicabile 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à specifiche di Linux non previste al momento da nessuno standard
+(la funzione è disponibile nelle \acr{glibc} a partire dalla versione 2.28).
+
+\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}; se specificato la funzione rinomina in un colpo
+solo \param{oldpath} in \param{newpath} e \param{newpath} in
+\param{oldpath}. Usando questo flag, entrambi i \textit{pathname} passati come
+argomenti devono esistere, e non è possibile usare \const{RENAME\_NOREPLACE},
+non ci sono infine restrizioni sul tipo di file (regolare, directory, link
+simbolici, dispositivo) 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 \textit{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
+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 un oggetto speciale del filesystem, chiamato
+\textit{whiteout}, che serve a renderlo non più visibile. La funzione consente
+di creare questo oggetto, che in un filesystem ordinario verrebbe visto come
+un file di dispositivo con \textit{major minor} e \textit{minor number} nulli,
+in maniera atomica quando si rinomina un file. Dato che l'uso di
+\const{RENAME\_WHITEOUT} comporta in sostanza la creazione di un file di
+dispositivo, l'operazione è privilegiata (occorre la \textit{capability}
+\const{CAP\_MKNOD}), inoltre occorre anche il supporto nel filesystem usato
+come supporto per la scrittura. Infine l'operazione non è compatibile con
+\const{RENAME\_EXCHANGE}.
+
+\itindend{overlay~filesytem}
+\itindend{union~filesytem}
+
+Benché non rientri nelle \textit{at-functions} previste nello standard
+POSIX.1-2008, tratteremo qui anche la funzione di sistema \funcd{statx},
+introdotta con il kernel 4.11 e disponibile dalle versione 2.28 della
+\acr{glibc}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fhead{unistd.h}
+\fhead{fcntl.h}
+\fdecl{int statx(int dirfd, const char *pathname, int flags, \\
+\phantom{int statx(}unsigned int mask, struct statx *statxbuf)}
+\fdesc{Legge le informazioni di un file.}
+}
+
+{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 o \param{mask}
+ ha un valore riservato.
+ \item[\errcode{ENOTDIR}] \param{pathname} è un \textit{pathname} relativo,
+ ma \param{dirfd} fa riferimento ad un file.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione è una estensione specifica di Linux consente di leggere le
+informazioni di un file; ha la stessa sintassi di \func{fstatat} utilizzando
+con lo stesso significato gli argomenti \param{dirfd} e \param{pathname} ed i
+valori \const{AT\_EMPTY\_PATH}, \const{AT\_NO\_AUTOMOUNT} e
+\const{AT\_SYMLINK\_NOFOLLOW} per \param{flags}. Si può pertanto indicare il
+file di cui si vogliono ottenere i dati con un \textit{pathname} assoluto, con
+un \textit{pathname} relativo (sia alla directory corrente che a quella
+indicata da \param{dirfd}) o con un file descriptor ad esso associato.
+
+La funzione però consente di ottenere informazioni più dettagliate rispetto a
+quelle fornite dalle funzioni tradizionali come \func{stat} e \func{fstatat},
+ed è in grado di controllare le modalità con cui le ottiene nel caso un file
+sia posto su un filesystem remoto. Per questo, oltre ai tre valori
+precedenti, l'argomento \param{flags} consente anche gli ulteriori valori
+elencati in tab.~\ref{tab:statx_flags_const}, con il significato ivi
+illustrato.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{AT\_STATX\_SYNC\_AS\_STAT}& si comporta esattamente come
+ \func{stat}, in questo caso (il default
+ se non viene indicato niente) il
+ risultato dipende dal tipo di
+ filesystem.\\
+ \constd{AT\_STATX\_FORCE\_SYNC}& richiede che i valori degli attributi
+ richiesti siano, in caso di un filesystem
+ di rete, siano sincronizzati con il server
+ remoto, questo può forzare una scrittura
+ dei dati (in particolare i tempi del file)
+ verso lo stesso.\\
+ \constd{AT\_STATX\_DONT\_SYNC} & chiede di non sincronizzare nessun dato,
+ ritornando quanto presente nella cache,
+ questo significa che i dati potrebbero
+ essere non coerenti ed aggiornati, ma si
+ evita, in caso di filesystem di rete, la
+ necessità di contattare il server remoto.\\
+ \hline
+ \end{tabular}
+ \caption{Valori specifici di \func{statx} per l'argomento \param{flags}.}
+ \label{tab:statx_flags_const}
+\end{table}
+
+La funzione restituisce le informazioni relative al file richiesto nella
+struttura \struct{statx} puntata dall'argomento \param{statxbuf}. Inoltre
+data la quantità di informazioni che possono essere richieste, la funzione
+consente, con l'argomento \param{mask} di selezionare quelle volute, questa
+deve essere assegnata ad una maschera binaria dei valori illustrati in
+tab.~\ref{tab:statx_mask_const}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{STATX\_TYPE} & Tipo del file (\texttt{stx\_mode \& S\_IFMT}).\\
+ \constd{STATX\_MODE} & Permessi del file (\texttt{stx\_mode \&
+ \tild{}S\_IFMT}).\\
+ \constd{STATX\_NLINK} & Numero di collegamenti (\textit{hard link},
+ \texttt{stx\_nlink}).\\
+ \constd{STATX\_UID} & Proprietario del file (per \ids{UID},
+ \texttt{stx\_uid}).\\
+ \constd{STATX\_GID} & Gruppo proprietario del file (per \ids{GID},
+ \texttt{stx\_gid}).\\
+ \constd{STATX\_ATIME} & Tempo di ultimo accesso (\texttt{stx\_atime}).\\
+ \constd{STATX\_MTIME} & Tempo di ultima modifica (\texttt{stx\_mtime}).\\
+ \constd{STATX\_CTIME} & Tempo di ultimo cambiamento (\texttt{stx\_ctime}).\\
+ \constd{STATX\_INO} & Numero di \textit{inode} (\texttt{stx\_ino}).\\
+ \constd{STATX\_SIZE} & Dimensione del file (\texttt{stx\_size}).\\
+ \constd{STATX\_BLOCKS}& Numero di blocchi del file (\texttt{stx\_blocks}).\\
+ \constd{STATX\_BASIC\_STATS}& Tutte le informazioni precedenti.\\
+ \constd{STATX\_BTIME} & Tempo di creazione (\texttt{stx\_btime}).\\
+% \constd{}& .\\
+ \constd{STATX\_ALL} & Tutte le informazioni.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti per i valori dell'argomento \param{mask} di
+ \func{statx}.}
+ \label{tab:statx_mask_const}
+\end{table}
+
+Si tenga presente che il kernel non richiede che \param{mask} contenga solo i
+flag di tab.~\ref{tab:statx_mask_const}, valori ulteriori in genere vengono
+ignorati ma non si può comunque indicare un valore qualunque in quanto alcuni
+bit sono riservati per future estensioni.\footnote{in particolare il bit
+ \constd{STATX\_\_RESERVED} che se usato causa il fallimento della funzione
+ con un errore di \errval{EINVAL}.} Inoltre non è detto che tutte le
+informazioni richieste con \param{mask} siano disponibili, per questo il
+kernel restituisce in un opportuno campo della struttura \struct{statx},
+\var{stx\_mask}, quali sono i dati effettivamente restituiti, che possono in
+alcuni casi essere anche di più di quelli richiesti (se l'informazione
+aggiuntiva è ottenuta senza costi ulteriori) per cui è normale che questo
+valore possa essere diverso da quanto richiesto.
+
+\begin{figure}[!htb]
+ \footnotesize
+ \centering
+ \begin{minipage}[c]{0.8\textwidth}
+ \includestruct{listati/statx.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{statx} per la lettura delle informazioni dei
+ file.}
+ \label{fig:file_statx_struct}
+\end{figure}
+
+Si è riportata in fig.~\ref{fig:file_statx_struct} la definizione della
+struttura \struct{statx} come presente in \headfile{sys/stat.h}; i campi
+\var{stx\_mode}, \var{stx\_nlink}, \var{stx\_uid}, \var{stx\_gid},
+\var{stx\_ino}, \var{stx\_size}, \var{stx\_blksize}, \var{stx\_blocks} sono
+identici agli analoghi (con prefisso \texttt{st\_}) dell'ordinaria struttura
+\struct{stat} illustrata in fig.~\ref{fig:file_stat_struct} e vale per essi
+quanto già detto in sez.~\ref{sec:file_stat} e seguenti.
+
+\begin{figure}[!htb]
+ \footnotesize
+ \centering
+ \begin{minipage}[c]{0.8\textwidth}
+ \includestruct{listati/statx_timestamp.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{statx\_timestamp} per i tempi dei file con
+ \func{statx}. }
+ \label{fig:file_statx_timestamp_struct}
+\end{figure}
+
+Anche i campi \var{stx\_atime}, \var{stx\_mtime}, \var{stx\_ctime} mantengono
+questa analogia, ma esprimono i tempi di ultimo accesso, modifica e
+cambiamento con una precisione ed estensione maggiore grazie all'uso di una
+struttura dedicata \struct{statx\_timestamp} (riportata in
+fig.~\ref{fig:file_statx_timestamp_struct}) che consente di estendere i tempi
+dei file ad una granularità del nanosecondo e con un valore dello \textit{unix
+ time} (vedi sez.~\ref{sec:sys_unix_time}) a 64 bit, che non darà problemi di
+overflow per parecchio tempo (sicuramente ben oltre la durata di questa
+guida).
+
+Oltre ai precedenti, e a \val{stx\_mask} che abbiamo già visto e che indica
+quali delle informazioni richieste alla funzione sono state fornite,
+\func{statx} prevede una serie di informazioni aggiuntive fornite in
+altrettanti nuovi campi, illustrati nell'elenco seguente. È comunque previsto
+che in futuro \struct{statx} venga estesa per supportare ulteriori
+informazioni.
+
+\begin{basedescript}{\desclabelwidth{1.6cm}\desclabelstyle{\nextlinelabel}}
+\item[\var{stx\_btime}] In questo campo viene restituito il \textsl{tempo di
+ creazione} del file. Come detto in sez.~\ref{sec:file_file_times} questo
+ tempo normalmente non esiste in un sistema \textit{unix-like}, ma per
+ migliorare l'interoperabilità è stato aggiunto nelle versioni più recenti di
+ vari filesystem (come XFS, \acr{ext4}, ecc.) in modo che possa essere
+ utilizzato da servizi di condivisione dei file (è usato da \textsl{Samba},
+ ed è previsto nello standard di NFSv4).
+\item[\var{stx\_attributes\_mask}] in questo campo viene restituita una
+ maschera che indica quali sono i bit restituiti in \var{stx\_attributes}
+ effettivamente supportati per il file, e per poter utilizzare quest'ultimo
+ occorre sempre eseguire un AND aritmetico con \var{stx\_attributes\_mask} per
+ ottenere i valori validi.
+\item[\var{stx\_attributes}] in questo campo vengono restituiti gli eventuali
+ attributi addizionali posseduti dal file. Gran parte di questi sono quelli
+ impostati con i comandi \cmd{lsattr} e \cmd{chattr} ed abbiamo già incontrato
+ alcuni di essi in sez.~\ref{sec:file_perm_overview}. Gli attributi vengono
+ restituiti in forma di maschera binaria con i valori delle costanti elencate
+ in tab.~\ref{tab:statx_stx_attributes}, dove si trova anche la relativa
+ descrizione.
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{STATX\_ATTR\_COMPRESSED}& Il file è compresso automaticamente dal
+ filesystem (quindi può richiedere un
+ maggior uso di risorse in caso di
+ accesso).\\
+ \constd{STATX\_ATTR\_IMMUTABLE} & Il file è marcato come
+ \textit{immutable} e non può essere
+ modificato in nessun modo (vedi
+ sez.~\ref{sec:file_perm_overview}).\\
+ \constd{STATX\_ATTR\_APPEND} & Il file è marcato come
+ \textit{append-only} e può essere
+ soltanto esteso in \textit{append} (vedi
+ sez.~\ref{sec:file_perm_overview}).\\
+ \constd{STATX\_ATTR\_NODUMP} & Il file è marcato per essere escluso da
+ eventuali backup a livello di filesystem
+ come quelli eseguiti con il comando
+ \cmd{dump}.\\
+ \constd{STATX\_ATTR\_ENCRYPTED} & Il file è cifrato sul filesystem ed è
+ necessaria una chiave di accesso per
+ decifrarne il contenuto.\\
+ \constd{STATX\_ATTR\_AUTOMOUNT} & Il file, in questo caso in genere una
+ directory, è marcata come punto di
+ innesco per un \textit{automount}.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti degli attributi addizionali restituiti in
+ \var{stx\_attributes}.}
+ \label{tab:statx_stx_attributes}
+\end{table}
+
+\item[\var{stx\_rdev\_major}, \var{stx\_rdev\_minor}] in questi campi vengono
+ restituiti rispettivamente \textit{major number} e \textit{minor number} del
+ file quando questo è un file di dispositivo (fanno le veci del campo
+ \var{st\_rdev} di \struct{stat}).
+
+\item[\var{stx\_dev\_major}, \var{stx\_dev\_minor}] in questi campi vengono
+ restituiti \textit{major number} e \textit{minor number} del dispositivo su
+ cui risiede il file (fanno le veci del campo \var{st\_dev} di \struct{stat}).
+\end{basedescript}
+
+Di questi campi \var{stx\_mode}, \var{stx\_nlink}, \var{stx\_uid},
+\var{stx\_gid}, \var{stx\_ino}, \var{stx\_size} e \var{stx\_blocks} e quelli
+relativi ai tempi ordinari dei file vengono sempre restituiti, ed il relativo
+valore in \struct{statx} sovrascritto, indipendentemente dal fatto che siano
+stati richiesti o no, con \var{stx\_mask} che indicherà quali sono quelli che
+hanno valori effettivamente validi.
+
+Se un filesystem ha dei campi che non esistono o hanno valori senza
+corrispondenza in un sistema unix-like, questi potranno essere restituiti con
+valori fittizi ricostruiti, ad esempio usando \ids{UID} e \ids{GID} impostati
+in fase di montaggio per un filesystem che non supporta gli utenti; in questi
+casi il relativo bit in \var{stx\_mask} sarà comunque cancellato. In caso di
+cambiamenti al file eseguiti in concorrenza a \func{statx} è possibile che
+campi diversi possano avere informazioni ottenute in momenti diversi, con
+valori precedenti o posteriori il cambiamento. Inoltre, se non richiesti
+esplicitamente, alcuni campi possono avere valori approssimati, ad esempio in
+caso di NFS, questi non vengono mai aggiornati dallo stato sul server remoto.
+
+Il campo \var{stx\_btime} viene restituito solo se richiesto, e si otterrà un
+valore nullo (ed il relativo bit in \var{stx\_mask} cancellato) se questo non
+esiste. Lo stesso vale nel caso si siano richiesti \var{stx\_rdev\_major} o
+\var{stx\_rdev\_minor} ed il file non è un file di dispositivo. I campi
+\var{stx\_dev\_major}, \var{stx\_dev\_minor} e \var{stx\_blksize} attengono
+ad informazioni locali, e sono sempre disponibili in maniera diretta.
+
+% NOTE: per statx https://lwn.net/Articles/707602/ e
+% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f)
+
+Infine trattiamo qui altre due funzioni, \func{fexecve} e \func{execveat}, che
+non attengono che in maniera indiretta all'uso dei file, ma sono comunque
+legate all'interfaccia delle \textit{at-functions}. In realtà la sola
+effettivamente collegata all'interfaccia delle \textit{at-functions} è la
+funzione di sistema \func{execveat}, introdotta con il kernel 3.19, e per la
+quale non è disponibile ancora un'interfaccia diretta nella \acr{glibc} che
+però la usa (quando disponibile) per realizzare \func{fexecve}.
+
+L'introduzione di queste funzioni nasce dall'esigenza di verificare i
+contenuti di un file eseguibile prima di eseguirlo. Fare il controllo (aprendo
+il file e verificandone il contenuto) e poi eseguirlo con \func{execve} è
+suscettibile alla possibilità che fra il controllo e l'esecuzione il nome del
+file o di una directory sovrastante venga cambiato.
+
+Per mitigare il problema nello standard POSIX.1-2008 è stata introdotta la
+funzione \funcd{fexecve} che consente di eseguire un programma usando un file
+descriptor al posto di un \textit{pathname}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int fexecve(int fd, char *const argv[], char *const envp[])}
+\fdesc{Esegue un programma da un file descriptor.}
+}
+
+{La funzione non ritorna in caso di successo e ritorna $-1$ per un errore,
+ nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{fd} non è un file descriptor, o \param{argv}
+ o \param{envp} sono \val{NULL}.
+ \item[\errcode{ENOSYS}] il filesystem \file{proc} non è disponibile (prima
+ del kernel 3.19).
+ \end{errlist}
+ oltre a tutti gli errori già visti per \func{execve}.}
+\end{funcproto}
+
+La funzione esegue il programma contenuto nel file (su cui il chiamante deve
+avere il permesso di esecuzione) corrispondente a \param{fd}; questo deve
+essere stato ottenuto aprendo il relativo eseguibile in sola lettura o con
+\const{O\_PATH}. Questa funzione fino al kernel 3.19 veniva realizzata nella
+\acr{glibc} usando il filesystem \file{/proc} per ottenere da \param{fd} il
+file corrispondente in \file{/proc/self/fd/}, in maniera analoga a quanto
+visto per l'esempio di fig.~\ref{fig:initfile}.
+
+La funzione di sistema \funcd{execveat} è stata introdotta proprio per rendere
+più sicura l'esecuzione ed evitare la necessità di avere disponibile
+\file{/proc} per poter usare \func{fexecve}, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int execveat(int dirfd, const char *pathname, char *const argv[], \\
+\phantom{int execveat(}char *const envp[], int flags)}
+\fdesc{Esegue un programma relativo ad una directory.}
+}
+
+{La funzione non ritorna in caso di successo e ritorna $-1$ per un errore, nel
+ qual caso \var{errno} assumerà, inoltre tutti gli errori già visti per
+ \func{execve}, uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido.
+ \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
+ \item[\errcode{ELOOP}] si è usato \const{AT\_SYMLINK\_NOFOLLOW} in
+ \param{flags} ma il file indicato è un link simbolico.
+ \item[\errcode{ENOENT}] il programma di cui si è richiesta l'esecuzione è
+ uno script, ma \func{dirfd} è aperto con il flag di
+ \textit{close-on-exec} e pertanto il programma non sarebbe accessibile
+ all'interprete.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione segue la sintassi delle \textit{at-functions} per indicare il file
+da eseguire, e per il resto si comporta esattamente con come \func{execve} (le
+cui caratteristiche sono già state illustrate in
+sez.~\ref{sec:proc_exec}). Diventa così possibile indicare il programma da
+eseguire sia con un \textit{pathname} assoluto che relativo (usando
+\const{AT\_FDCWD} come \param{dirfd}), oppure con un \textit{pathname}
+relativo alla directory indicata da \param{dirfd}. In quest'ultima forma l'uso
+della funzione consente estendere i vantaggi delle \textit{at-functions} anche
+al caso dell'esecuzione di un programma.
+
+Inoltre usando, per \param{flags} il valore \const{AT\_EMPTY\_PATH}, si può
+indicare direttamente il file da eseguire aprendolo e passandone il file
+descriptor nell'argomento \param{dirfd}, ottenendo il comportamento di
+\func{fexecve}; quest'ultima infatti è sostanzialmente equivalente
+all'esecuzione di:
+\includecodesnip{listati/fexecve.c}
+l'unico altro valore utilizzabile per \param{flags} è
+\const{AT\_SYMLINK\_NOFOLLOW}, che fa fallire la funzione con un errore di
+\errval{ELOOP} se il file indicato è un link simbolico.
+
+Quando si usano \func{execveat} o \func{fexecve} per eseguire un programma
+attraverso un file descriptor è naturale impostare sullo stesso il flag di
+\textit{close-on-exec} in modo che questo venga automaticamente chiuso
+all'esecuzione. Questo evita di lasciare aperto inutilmente un file descriptor
+(un programma in genere non ha bisogno di avere un file aperto su se stesso),
+ma soprattutto evita problemi in caso di un eventuale uso ricorsivo di queste
+funzioni, in tal caso infatti, restando aperto ad ogni iterazione un ulteriore
+file descriptor, si potrebbe arrivare all'esaurimento degli stessi.
+
+Tutto questo però non è vero quando si vuole eseguire uno script; in tal caso
+infatti (si ricordi quanto detto a questo riguardo in
+sez.~\ref{sec:proc_exec}) il programma che viene effettivamente messo in
+esecuzione è l'interprete indicato nella riga iniziale dello script, che poi
+legge ed interpreta il codice da eseguire dallo script stesso. Ma se lancia lo
+script usando un file descriptor su cui è attivo il flag di
+\textit{close-on-exec}, questo sarà già chiuso quando l'interprete viene posto
+in esecuzione, rendendo impossibile la lettura del programma da
+interpretare.
+
+Per questo motivo, quando ci si trova in questa situazione, \func{execveat} (e
+quindi anche \func{fexecve}) eseguono un controllo preventivo e falliscono con
+un errore di \errval{ENOENT}. Pertanto se si vuole eseguire uno script
+passandone il file descriptor l'unica possibilità è non attivare il flag di
+\textit{close-on-exec}, esponendosi però al rischio di incorrere nei problemi
+accennati in precedenza.
+
+% 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: trattare i nuovi AT_flags quando e se arriveranno, vedi
+% https://lwn.net/Articles/767547/
+
+\itindend{at-functions}
+
+
+\subsection{Le operazioni di controllo sui file descriptor}
+\label{sec:file_fcntl_ioctl}
+
+Oltre alle operazioni base esaminate in sez.~\ref{sec:file_unix_interface}