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}.
-Una prima funzione che utilizza l'argomento \param{flag} è \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{fcntl.h}
di \const{AT\_EMPTY\_PATH}, con il significato illustrato in precedenza e non
ha flag specifici.
-Una seconda funzione che utilizza l'argomento \param{flags}, in questo caso
-anche per modificare il suo comportamento, è \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}
\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}
maschera binaria, essendo \const{AT\_REMOVEDIR} l'unico flag disponibile per
questa funzione, lo si può assegnare direttamente.
-Un'altra funzione 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 è:
+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}
disabilitato, e la funzione, seguendo lo standard POSIX, ritorna un errore di
\errval{EINVAL} se invocata in questo modo.
-Come analoga delle funzioni \func{stat}, \func{fstat} e \func{lstat} si può
-utilizzare invece \funcd{fstatat}, il cui prototipo è:
+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}
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},\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 è:
+
+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}
\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{ENOTDIR}] \param{oldpath} e \param{newpath} sono
+ \textit{pathname} relativi, ma \param{oldirfd} o \param{newdirfd} fa
riferimento ad un file.
\end{errlist}
}
\end{funcproto}
+Anche in questo caso la funzione è sostanzialmente identica alla 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, mentre si può usare \const{AT\_EMPTY\_PATH} con il
-significato illustrato in precedenza. A partire dal kernel 2.6.18 è è stato
-inoltre aggiunto per questa funzione la possibilità di usare il valore
-\const{AT\_SYMLINK\_FOLLOW}, che richiede di dereferenziare i collegamenti
-simbolici.
+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 precendenti, 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 i collegamenti simbolici, inoltre a partire dal kernel 3.11 si
+può usare \const{AT\_EMPTY\_PATH} con il significato illustrato in precedenza.
+
+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 soltanti \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 relativie 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}
-Un'altra funzione che
+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 approfomdimento 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.
+
+\itindend{overlay~filesytem}
+\itindend{union~filesytem}
-% TODO trattare fstatat e con essa
% TODO trattare anche statx, aggiunta con il kernel 4.11 (vedi
-% https://lwn.net/Articles/707602/ e
+ % 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/
+% 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