+\param{newfd} diventa equivalente a \func{dup}. La sola differenza fra le due
+funzioni (a parte la sintassi ed i diversi codici di errore) è che \func{dup2}
+chiude il file descriptor \param{newfd} se questo è già aperto, garantendo che
+la duplicazione sia effettuata esattamente su di esso, invece \func{fcntl}
+restituisce il primo file descriptor libero di valore uguale o maggiore
+di \param{newfd}, per cui se \param{newfd} è aperto la duplicazione avverrà su
+un altro file descriptor.
+
+Su Linux inoltre è presente una terza funzione di sistema non
+standard,\footnote{la funzione è stata introdotta con il kernel 2.6.27 e resa
+ disponibile con la \acr{glibc} 2.9.} \funcd{dup3}, che consente di duplicare
+un file descriptor reimpostandone i flag, per usarla occorre definire la macro
+\macro{\_GNU\_SOURCE} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int dup3(int oldfd, int newfd, int flags)}
+\fdesc{Duplica un file descriptor su un altro.}
+}
+
+{La funzione ritorna il nuovo file descriptor in caso di successo e $-1$ per
+ un errore, nel qual caso \var{errno} assumerà gli stessi valori di
+ \func{dup2} più \errcode{EINVAL} qualora \param{flags} contenga un valore
+ non valido o \param{newfd} sia uguale a \param{oldfd}.
+}
+\end{funcproto}
+
+La funzione è identica a \func{dup2} ma prevede la possibilità di mantenere il
+flag di \textit{close-on-exec} \itindex{close-on-exec} sul nuovo
+file descriptor specificando \const{O\_CLOEXEC} in \param{flags} (che è l'unico
+flag usabile in questo caso). Inoltre rileva esplicitamente la possibile
+coincidenza fra \param{newfd} e \param{oldfd}, fallendo con un errore di
+\errval{EINVAL}.
+
+
+\subsection{Le funzioni di sincronizzazione dei dati}
+\label{sec:file_sync}
+
+Come accennato in sez.~\ref{sec:file_open_close} tutte le operazioni di
+scrittura sono in genere bufferizzate dal kernel, che provvede ad effettuarle
+in maniera asincrona, ad esempio accorpando gli accessi alla stessa zona del
+disco, in un secondo tempo rispetto al momento della esecuzione della
+\func{write}.
+
+Per questo motivo quando è necessaria una sincronizzazione dei dati il sistema
+mette a disposizione delle funzioni che provvedono a forzare lo scarico dei
+dati dai buffer del kernel. La prima di queste funzioni di sistema è
+\funcd{sync}, il cui prototipo è:\footnote{questo è il prototipo usato a
+ partire dalla \acr{glibc} 2.2.2 seguendo gli standard, in precedenza la
+ funzione era definita come \code{int sync(void)} e ritornava sempre $0$.}
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{void sync(void)}
+\fdesc{Sincronizza il buffer della cache dei file col disco.}
+}
+
+{La funzione non ritorna nulla e non prevede condizioni di errore.}
+\end{funcproto}
+
+I vari standard prevedono che la funzione si limiti a far partire le
+operazioni, ritornando immediatamente; con Linux fin dal kernel 1.3.20 invece
+la funzione aspetta la conclusione delle operazioni di sincronizzazione. Si
+tenga presente comunque che questo non dà la garanzia assoluta che i dati
+siano integri dopo la chiamata, l'hardware dei dischi è in genere dotato di un
+suo meccanismo interno di bufferizzazione che può ritardare ulteriormente la
+scrittura effettiva.
+
+La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
+esplicitamente lo scarico dei dati su disco, un tempo era invocata da un
+apposito demone di sistema (in genere chiamato \cmd{update}) che eseguiva lo
+scarico dei dati ad intervalli di tempo fissi, ad esempio il valore
+tradizionale usato da BSD era di 30 secondi, mentre su Linux il valore
+utilizzato è di 5 secondi.
+
+Con le nuove versioni del kernel le operazioni di scarico periodico dei dati
+su disco vengono gestite direttamente dal sistema della memoria virtuale,
+attraverso opportuni \textit{task} interni al kernel il cui comportamento può
+essere controllato attraverso il file \sysctlfile{vm/bdflush}. Per il
+significato dei valori si può leggere la documentazione allegata ai sorgenti
+del kernel nel file \file{Documentation/sysctl/vm.txt}. Si tenga presente che
+la funzione di sistema \funcm{bdflush} che un tempo veniva usata per queste
+impostazioni è deprecata e causa semplicemente la stampa di un messaggio nei
+log del kernel, pertanto non la prenderemo in esame.
+
+Quando si vogliono scaricare soltanto i dati di un singolo file (ad esempio
+essere sicuri che i dati di un database sono stati registrati su disco) si
+possono usare le due funzioni di sistema \funcd{fsync} e \funcd{fdatasync}, i
+cui prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int fsync(int fd)}
+\fdesc{Sincronizza dati e metadati di un file.}
+\fdecl{int fdatasync(int fd)}
+\fdesc{Sincronizza i dati di un file.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{fd} è un \index{file!speciali} file speciale
+ che non supporta la sincronizzazione.
+ \end{errlist}
+ ed inoltre \errval{EBADF}, \errval{EROFS} e \errval{EIO} nel loro
+ significato generico.}
+\end{funcproto}
+
+Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
+file specificato, ed attendono fino alla conclusione delle operazioni;
+\func{fsync} forza anche la sincronizzazione dei meta-dati del file (che
+riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli
+altri dati contenuti \itindex{inode} nell'\textit{inode} che si leggono con
+\func{fstat}, come i tempi del file).
+
+Si tenga presente che questo non comporta la sincronizzazione della
+directory che contiene il file (e scrittura della relativa voce su
+disco) che deve essere effettuata esplicitamente.\footnote{in realtà per
+ il filesystem \acr{ext2}, quando lo si monta con l'opzione \cmd{sync},
+ il kernel provvede anche alla sincronizzazione automatica delle voci
+ delle directory.}