sequenza logica porterebbe a verificare prima l'esistenza del file con una
\func{stat} per poi crearlo con una \func{creat}; di nuovo avremmo la
possibilità di una race condition da parte di un altro processo che crea lo
-stesso file fra il controllo e la creazione.
-
-Per questo motivo sono stati introdotti i flag \macro{O\_CREAT}
-\macro{O\_EXCL}
+stesso file fra il controllo e la creazione.
+Per questo motivo sono stati introdotti i due flag \macro{O\_CREAT} e
+\macro{O\_EXCL}, in questo modo l'operazione di controllo dell'esistenza del
+file (con relativa uscita dalla funzione con un errore) e creazione in caso di
+assenza, diventa atomica essendo svolta tutta all'interno di una singola
+\func{open}.
\subsection{La funzioni \func{dup} e \func{dup2}}
\label{sec:file_dup}
+Abbiamo già visto in \secref{sec:file_sharing} come un processo figlio
+condivida gli stessi file descriptor del padre; è possibile però ottenere un
+comportamento analogo all'interno di uno stesso processo \textit{duplicando}
+un file descriptor. Per far questo si usa la funzione \func{dup} il cui
+prototipo è:
+\begin{prototype}{unistd.h}{int dup(int oldfd)}
+
+ La funzione crea una copia del file descriptor \param{oldfd}.
+
+ La funzione ritorna il nuovo file descriptor in caso di successo e -1 in
+ caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori:
+ \begin{errlist}
+ \item \macro{EBADF} \param{oldfd} non è un file aperto.
+ \item \macro{EMFILE} si è raggiunto il numero massimo consentito di file
+ descriptor aperti.
+ \end{errlist}
+\end{prototype}
+La funzione ritorna, come \func{open}, il primo file descriptor libero. Il
+file descriptor è una copia esatta del precedente ed entrambi possono essere
+interscambiati nell'uso. Per capire meglio il funzionamento della funzione si
+può fare riferimento a \figref{fig:file_dup}: l'effetto della funzione è
+semplicamente quello di copiare il valore nella struttura \var{file\_struct},
+cosicché anche il nuovo file descriptor fa riferirimento alla stessa voce
+nella \textit{file table}.
\begin{figure}[htb]
\centering \includegraphics[width=14cm]{img/filedup.eps}
\label{fig:file_dup}
\end{figure}
+In questo modo entrambi i file condivideranno eventuali lock, \textit{file
+ status flag}, e posizione corrente: se ad esempio \func{lseek} modifica la
+posizione su uno dei due file descriptor essa sarà modificata anche sull'altro
+(al solito viene modificato lo stesso campo nella voce della \textit{file
+ table} a cui entrambi fanno riferimento).
+
+L'unica differenza fra i due file descriptor è che ciascuno avrà il suo
+\textit{file descriptor flag}; nel caso di \func{dup} il flag di \textit{close
+ on exec} viene sempre cancellato nella copia.
+
+Una diversa versione della funzione, \func{dup2} viene utilizzata per
+specificare esplicitamente il nuovo file descriptor; il suo prototipo è:
+\begin{prototype}{unistd.h}{int dup2(int oldfd, int newfd)}
+
+ La funzione rende \param{newfd} una copia del file descriptor \param{oldfd}.
+
+ La funzione ritorna il nuovo file descriptor in caso di successo e -1 in
+ caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori:
+ \begin{errlist}
+ \item \macro{EBADF} \param{oldfd} non è un file aperto o \param{newfd} ha un
+ valore fuori dall'intervallo consentito per i file descriptor.
+ \item \macro{EMFILE} si è raggiunto il numero massimo consentito di file
+ descriptor aperti.
+ \end{errlist}
+\end{prototype}
+\noindent la funzione chiude il file descriptor \param{newfd} se è aperto.
+
+La duplicazione dei file descriptor può essere effettuata anche usando la
+funzione di controllo dei file \func{fnctl} (che esamineremo in
+\secref{sec:file_fcntl}) con il parametro \macro{F\_DUPFD}.
+
+L'operazione ha la sintassi \func{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0
+come valore per \param{newfd} diventa equivalente a \func{dup}. La sola
+differenza, a parte i codici di errore, è che \func{dup2} chiude il nuovo file
+se è già aperto mentre \func{fcntl} apre il primo disponibile con un valore
+superiore, per cui per poterla usare come \func{dup2} occorrerebbe prima
+effettare una \func{close}, perdendo l'atomicità dell'operazione.
+
+L'uso principale di queste funzioni è per la redirezione dell'input e
+dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec};
+diventa così possibile associare un file (o una pipe) allo standard input o
+allo standard output, torneremo su questo uso più avanti quando tratteremo le
+pipe.
+
\subsection{La funzione \func{fcntl}}
\label{sec:file_fcntl}
+Oltre alle operazioni base esaminate in \secref{sec:file_base_func} esistono
+tutta una serie di operazioni ausiliarie che è possibile eseguire su un file
+descriptor. Per queste operazioni di manipolazione delle varie proprietà di un
+file descriptor viene usata la funzione \func{fcntl} il cui prototipo è:
+\begin{functions}
+ \headdecl{unistd.h}
+ \headdecl{fcntl.h}
+ \funcdecl{int fcntl(int fd, int cmd)}
+ \funcdecl{int fcntl(int fd, int cmd, long arg)}
+ \funcdecl{int fcntl(int fd, int cmd, struct flock *lock)}
+ La funzione esegue una delle possibili operazioni specificate da \param{cmd}
+ sul file \param{fd}.
+
+ La funzione ha valori di ritorno diversi a seconda dell'operazione. In caso
+ di errore il valore di ritorno è -1 e la variabile \var{errno} viene settata
+ ad un opportuno codice, quelli validi in generale sono:
+ \begin{errlist}
+ \item \macro{EBADF} \param{oldfd} non è un file aperto.
+ \end{errlist}
+\end{functions}
+
+Il comportamento di questa funzione è determinato dal valore del comando
+\param{cmd} che le viene fornito; in \secref{sec:file_dup} abbiamo incontrato
+un esempio, una lista dei possibili valori è riportata di seguito:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{F\_DUPFD}] trova il primo file descriptor disponibile di valore
+ maggiore o uguale ad \param{arg} e ne fa una copia di \var{fd}. In caso di
+ successo ritorna il nuovo file descriptor. Gli errori possibili sono
+ \macro{EINVAL} se \param{arg} è negativo o maggiore del massimo consentito o
+ \macro{EMFILE} se il processo ha già raggiunto il massimo numero di
+ descrittori consentito.
+\item[\macro{F\_GETFD}] ritorna il valore dei \textit{file descriptor flag} di
+ \var{fd}, al momento è definito solo \macro{FD\_CLOEXEC}. Prova prov proep
+\item[\macro{F\_SETFD}] setta il valore dei \textit{file descriptor flag}
+ specificato da \param{arg}.
+\end{basedescript}
+
\subsection{La funzione \func{ioctl}}
\label{sec:file_ioctl}