X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=b747a4d468233d20f7ab77fd2e497ce8d14d5fae;hp=de5d17d40096afa65d99ff302b8dc6ae5696803f;hb=e9aa62ccbeefc114915aba31f257d55f6c19a05a;hpb=09fff83335c84e1290f725341b0959344e5a7b03 diff --git a/fileunix.tex b/fileunix.tex index de5d17d..b747a4d 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -1,52 +1,170 @@ -\chapter{I files: l'interfaccia I/O di unix} +\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{I file descriptors} -\label{sec:fileunix_fd} - \section{Le funzioni base} -\label{sec:fileunix_base_func} - -L'interfaccia standard unix per l'input/output sui file è su cinque funzioni -\texttt{open}, \texttt{read}, \texttt{write}, \texttt{lseek}, \texttt{close} +\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 \texttt{open}} -\label{sec:fileunix_open} -\subsection{La funzione \texttt{creat}} -\label{sec:fileunix_creat} +\subsection{La funzione \func{open}} +\label{sec:file_open} -\subsection{La funzione \texttt{lseek}} -\label{sec:fileunix_lseek} +\subsection{La funzione \func{creat}} +\label{sec:file_creat} -\subsection{La funzione \texttt{read}} -\label{sec:fileunix_read} +\subsection{La funzione \func{close}} +\label{sec:file_close} -\subsection{La funzione \texttt{write}} -\label{sec:fileunix_write} +\subsection{La funzione \func{lseek}} +\label{sec:file_lseek} -\section{La condivisione dei files} -\label{sec:fileunix_sharing} +\subsection{La funzione \func{read}} +\label{sec:file_read} +\subsection{La funzione \func{write}} +\label{sec:file_write} -\subsection{Operazioni atomiche} -\label{sec:fileunix_atomic} +\subsection{Operazioni atomiche coi file} +\label{sec:file_atomic} \section{Funzioni avanzate} -\label{sec:fileunix_adv_func} +\label{sec:file_adv_func} + +\subsection{La funzioni \func{dup} e \func{dup2}} +\label{sec:file_dup} -\subsection{La funzioni \texttt{dup} e \texttt{dup2}} -\label{sec:fileunix_dup} +\subsection{La funzione \func{fcntl}} +\label{sec:file_fcntl} -\subsection{La funzione \texttt{fcntl}} -\label{sec:fileunix_fcntl} +\subsection{La funzione \func{ioctl}} +\label{sec:file_ioctl} -\subsection{La funzione \texttt{fcntl}} -\label{sec:fileunix_ioctl}