\chapter{L'interfaccia unix di I/O con i file}
\label{cha:file_unix_interface}

Esamineremo in questo capitolo la prima delle due interfacce di programmazione
per i file, quella dei \textit{file descriptor}, nativa di unix. Questa è
l'interfaccia di basso livello, che non prevede funzioni evolute come la
bufferizzazione o funzioni di lettura o scrittura formattata, ma è su questa
che è costruita anche l'interfaccia standard dei file definita dallo standard
ANSI C.



\section{L'architettura di base}
\label{sec:file_base_arch}

Esamineremo in questa sezione la architettura su cui è basata dell'interfaccia
con cui i processi accedono ai file, che, pure nelle differenze di
implementazione, è comune ad ogni implementazione di unix. 


\subsection{L'architettura dei \textit{file descriptors}}
\label{sec:file_fd}

Per poter accedere al contenuto di un file occorre creare un canale di
comunicazione con il kernel che renda possibile operare su di esso (si ricordi
quanto visto in \secref{sec:file_vfs_work}). Questo si fa aprendo il file con
la funzione \func{open} che provvederà a localizzare l'inode del file e
inizializzare le funzioni che il VFS mette a disposizione (riportate in
\tabref{tab:file_file_operations}). Una volta terminate le operazioni, il file
dovrà essere chiuso, e questo chiuderà il canale di comunicazione impedendo
ogni ulteriore operazione.

All'interno di ogni processo i file aperti sono identificati da un intero non
negativo, chiamato appunto \textit{file descriptors}, quando un file viene
aperto la funzione restituisce il file descriptor, e tutte le successive
operazioni devono passare il \textit{file descriptors} come argomento.

Per capire come funziona il meccanismo occorre spiegare a grandi linee come è
che il kernel gestisce l'interazione fra processi e file.  Il kernel mantiene
sempre un elenco dei processi attivi nella cosiddetta \textit{process table}
ed un elenco dei file aperti nella \textit{file table}.

La \textit{process table} è una tabella che contiene una voce per ciascun
processo attivo nel sistema. In Linux la tabella è costituita da strutture di
tipo \var{task\_struct} nelle quali sono raccolte tutte le informazioni
relative ad un singolo processo; fra queste informazioni c'è anche il
puntatore ad una ulteriore struttura di tipo \var{files\_struct} in cui sono
contenute le informazioni relative ai file che il processo ha aperto, ed in
particolare:
\begin{itemize}
\item i flag relativi ai file descriptor.
\item il numero di file aperti.
\item una tabella che contiene un puntatore alla relativa voce nella
  \textit{file table} per ogni file aperto.
\end{itemize}
il \textit{file descriptor} in sostanza è l'intero positivo che indicizza
questa tabella.

La \textit{file table} è una tabella che contiene una voce per ciascun file
che è stato aperto nel sistema. In Linux è costituita da strutture di tipo
\var{file}; in ciascuna di esse sono tenute varie informazioni relative al
file, fra cui:
\begin{itemize}
\item lo stato del file (lettura, scrittura, append, etc.).
\item il valore della posizione corrente (l'\textit{offset}) nel file.
\item un puntatore all'inode\footnote{nel kernel 2.4.x si è in realtà passati
    ad un puntatore ad una struttura \var{dentry} che punta a sua volta
    all'inode passando per la nuova struttura del VFS} del file.
\item un puntatore alla tabella delle funzioni \footnote{la struttura
    \var{f\_op} descritta in \secref{sec:file_vfs_work}} che si possono usare
  sul file.
\end{itemize}
In \nfig\ si è riportato lo schema di questa architettura, con le
interrelazioni fra tutti questi elementi.

\begin{figure}[htb]
  \centering
  \includegraphics[width=14cm]{img/procfile.eps}
  \caption{Schema delle operazioni del VFS}
  \label{fig:file_VFS_scheme}
\end{figure}


\subsection{I file standard}
\label{sec:file_std_descr}

Come accennato i \textit{file descriptor} non sono altro che un indice nella
tabella dei file aperti di ciascun processo; per questo motivo normalmente
essi vengono assegnati in successione tutte le volte che apre un nuovo file
(senza averne chiuso nessuno in precedenza).  


In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
processo viene lanciato con almeno tre file aperti. Questi, per quanto
dicevamo prima, avranno come \textit{file descriptor} i valori 0, 1 e 2.
Benché questa sia soltanto una convenzione, essa è seguita dalla gran parte
delle applicazioni, e non seguirla potrebbe portare a gravi problemi di
incompatibilità.


Il primo file è sempre associato a quello che viene chiamato \textit{standard
  input}, è cioè il file da cui il processo si aspetta di ricevere i dati in
ingresso (nel caso della shell, è associato alla lettura della tastiera); il
secondo file è il cosiddetto \textit{standard output}, cioè il file su cui ci
si aspetta debbano essere inviati i dati in uscita (sempre nel caso della
shell, è il terminale su cui si sta scrivendo), il terzo è lo \textit{standard
  error}, su cui viene inviato l'output relativo agli errori.

Lo standard POSIX.1 provvede tre costanti simboliche, definite nell'header
\file{unistd.h}, al posto di questi valori numerici: 
\begin{itemize}
\item \macro{STDIN\_FILENO} \textit{file descriptor} dello \textit{standard
    input}
\item \macro{STDOUT\_FILENO} \textit{file descriptor} dello \textit{standard
    output}
\item \macro{STDERR\_FILENO} \textit{file descriptor} dello \textit{standard
    error}
\end{itemize}



\subsection{La condivisione dei files}
\label{sec:file_sharing}



\section{Le funzioni base}
\label{sec:file_base_func}

L'interfaccia standard unix per l'input/output sui file è basata su cinque
funzioni fondamentali \func{open}, \func{read}, \func{write},
\func{lseek} e \func{close};


\subsection{La funzione \func{open}}
\label{sec:file_open}

\subsection{La funzione \func{creat}}
\label{sec:file_creat}

\subsection{La funzione \func{close}}
\label{sec:file_close}

\subsection{La funzione \func{lseek}}
\label{sec:file_lseek}

\subsection{La funzione \func{read}}
\label{sec:file_read}

\subsection{La funzione \func{write}}
\label{sec:file_write}

\subsection{Operazioni atomiche coi file}
\label{sec:file_atomic}

\section{Funzioni avanzate}
\label{sec:file_adv_func}

\subsection{La funzioni \func{dup} e \func{dup2}}
\label{sec:file_dup}

\subsection{La funzione \func{fcntl}}
\label{sec:file_fcntl}

\subsection{La funzione \func{ioctl}}
\label{sec:file_ioctl}





