l'indicazione di quale dispositivo contiene il filesystem da usare come punto
di partenza e questo viene montato come radice dell'albero (cioè nella
directory \texttt{/}); tutti gli ulteriori dischi devono poi essere inseriti
-nell'albero utilizzando opportune sottodirectory (in genere sotto
+nell'albero utilizzando opportune subdirectory (in genere sotto
\texttt{/mnt}) .
Alcuni filesystem speciali (come \texttt{/proc} che contiene un'interfaccia ad
All'interno dello stesso albero si potranno poi inserire anche gli altri
oggetti visti attraverso l'interfaccia che manipola i files come le FIFO, i
-link, i socket e gli stessi i file di dipositivo (questi ultimi, per
+link, i socket e gli stessi i file di dispositivo (questi ultimi, per
convenzione, sono inseriti nella directory \texttt{/dev}).
\subsection{Il \textit{virtual filesystem} di linux}
kernel (\texttt{linux/Documentation/vfs.txt}).
L'argomento è abbastanza ``esoterico'' e questa sezione può essere saltata ad
-una prima lettura; è bene però tenere presente che vengono intodotti qui
-alcuni termini che potranno comparire in seguito, come \textit{imode},
+una prima lettura; è bene però tenere presente che vengono introdotti qui
+alcuni termini che potranno comparire in seguito, come \textit{inode},
\textit{dentry}, \textit{dcache}.
In linux il concetto di \textit{everything is a file} è stato implementato
L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
una struttura di tipo \texttt{file} in cui viene inserito un puntatore alla
-dentry e una struttura \verb|f_ops| che contiene i puntatotori ai metodi che
+dentry e una struttura \verb|f_ops| che contiene i puntatori ai metodi che
implementano le operazioni disponibili sul file. In questo modo i processi in
-use space possono accedere alle operazioni attraverso detti metodi, che
+user space possono accedere alle operazioni attraverso detti metodi, che
saranno diversi a seconda del tipo di file (o dispositivo) aperto. Un elenco
delle operazioni disponibili è riportato in \ntab.
\begin{table}[htb]
\centering
- \begin{tabular}[c]{c l}
+ \begin{tabular}[c]{c p{7cm}}
\textbf{funzione} & \textbf{operazione} \\
\hline
- open & apre il file \\
- read & legge dal file \\
- write & scrive sul file \\
- llseek & sposta la posizione corrente sul file \\
- ioctl & accede alle operazioni di controllo (tramite la \texttt{ioctl})\\
- readdir & per leggere il contenuto di una directory \\
- poll & \\
- mmap & chiamata dalla system call \texttt{mmap} \\
- release & chiamata quando l'ultima referenza a un file aperto è chiusa\\
- fsync & chiamata dalla system call \texttt{fsync} \\
- fasync & chiamate da \texttt{fcntl} quando è abilitato il modo asincrono
- per l'I/O su file. \\
+ \textit{open} & apre il file \\
+ \textit{read} & legge dal file \\
+ \textit{write} & scrive sul file \\
+ \textit{llseek} & sposta la posizione corrente sul file \\
+ \textit{ioctl} & accede alle operazioni di controllo
+ (tramite la \texttt{ioctl})\\
+ \textit{readdir} & per leggere il contenuto di una directory \\
+ \textit{poll} & \\
+ \textit{mmap} & chiamata dalla system call \texttt{mmap}.
+ mappa il file in memoria\\
+ \textit{release} & chiamata quando l'ultima referenza a un file
+ aperto è chiusa\\
+ \textit{fsync} & chiamata dalla system call \texttt{fsync} \\
+ \textit{fasync} & chiamate da \texttt{fcntl} quando è abilitato
+ il modo asincrono per l'I/O su file. \\
\hline
\end{tabular}
\caption{Operazioni sui file definite nel VFS.}
In unix è implementata da qualunque filesystem standard una forma elementare
(ma adatta alla maggior parte delle esigenze) di controllo di accesso ai
-files. Torneremo sull'argomento in dettaglo più avanti, qui ci limitiamo ad
+files. Torneremo sull'argomento in dettaglio più avanti, qui ci limitiamo ad
una introduzione dei concetti essenziali.
Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo unix,
\begin{table}[htb]
\begin{center}
- \begin{tabular}[c]{l l l}
+ \begin{tabular}[c]{l l p{7cm}}
+ \multicolumn{2}{c}{\textbf{Nome}} & \textbf{Descrizione} \\
+ \hline
\textit{regular file} & \textsl{file normale} &
un file che contiene dei dati (l'accezione normale di file) \\
\textit{directory} & \textsl{cartella o direttorio} &
\textit{fifo} & \textsl{tubo} &
un file speciale che identifica una linea di comunicazione software
(unidirezionale) \\
- \textit{socket} & \textsl{presa}
+ \textit{socket} & \textsl{presa} &
un file speciale che identifica una linea di comunicazione software
(bidirezionale) \\
+ \hline
\end{tabular}
\caption{Tipologia dei file definiti nel VFS}
\label{tab:file_types}
Per poter accedere al contenuto dei file occorre anzitutto aprirlo. Questo
crea un canale di comunicazione che permette di eseguire una serie di
operazioni. Una volta terminate le operazioni, il file dovrà essere chiuso, e
-questo chiuderà il canale di comuniczione impedendo ogni ulteriore operazione.
+questo chiuderà il canale di comunicazione impedendo ogni ulteriore operazione.
\subsection{Le due interfacce ai file}
\label{sec:file_base_api}
-In unix le modalità di accesso ai file e le relative insterfacce di
+In unix le modalità di accesso ai file e le relative interfacce di
programmazione sono due, basate su due diversi meccanismi di connessione.
La prima è quella dei cosiddetti \textit{file descriptor} (descrittore di
file), che è specifica di unix e che provvede un accesso diretto a basso
livello non bufferizzato, con un'interfaccia primitiva ed essenziale; i file
-descriptors sono rappresetati da numeri interi (cioè semplici variabili di
+descriptors sono rappresentati da numeri interi (cioè semplici variabili di
tipo \texttt{int}). L'interfaccia è definita nell'header \texttt{unistd.h}.
La seconda è quella degli \textit{stream}, che provvede un'interfaccia più
-complessa e un'accesso bufferizzato, questa è anche l'intefaccia standard
-usata dal linguaggio C e che perciò si trova anche su tutti i sistemi non
-unix. Gli stream sono più complessi e sono rappresentati da puntatori ad un
-opportuno oggetto, cioè del tipo \texttt{FILE *}. L'interfaccia è definita
-nell'header \texttt{stdio.h}.
+evoluta e un accesso bufferizzato. Questa è anche l'interfaccia standard usata
+dal linguaggio C e perciò si trova anche su tutti i sistemi non unix. Gli
+stream sono oggetti complessi e sono rappresentati da puntatori ad un
+opportuna struttura definita dalle librerie del C, si accede ad essi sempre in
+maniera indiretta utilizzando il tipo \texttt{FILE *}. L'interfaccia è
+definita nell'header \texttt{stdio.h}.
Entrambe le interfacce possono essere usate per l'accesso ai file come agli
altri oggetti del VFS (pipes, socket, device), ma per poter accedere alle
operazioni di controllo sul particolare tipo di oggetto del VFS scelto occorre
usare l'interfaccia a basso livello dei file descriptor. Allo stesso modo
devono essere usati i file descriptor se si vuole ricorrere a modalità
-speciali di I/O come il polling o il non-bloccante (vedi \ref{sec:file_bohhhhh}).
+speciali di I/O come il polling o il non-bloccante (vedi
+\ref{sec:file_bohhhhh}).
-Gli stream però forniscono un'interfaccia di alto livello costruita sopra
-quella dei file descriptor, e tratta tutti i file nello stesso modo, con
+Gli stream forniscono un'interfaccia di alto livello costruita sopra quella
+dei file descriptor, che tratta tutti i file nello stesso modo, con
l'eccezione di poter scegliere tre diversi stili di bufferizzazione. Il
maggior vantaggio degli stream è che l'interfaccia per le operazioni di
input/output è enormemente più ricca di quella dei file descriptor, che
provvedono solo funzioni elementari per la lettura/scrittura diretta di
blocchi di bytes. In particolare dispongono di tutte le funzioni di
formattazione per l'input e l'output adatte per manipolare anche i dati in
-forma di linee o singoli caratteri.
+forma di linee o singoli caratteri.
In ogni caso, dato che gli stream sono implementati sopra l'interfaccia a
-basso livello dei file decriptor, è sempre possibile extrarre il file
+basso livello dei file descriptor, è sempre possibile estrarre il file
descriptor da uno stream ed eseguirvi operazioni di basso livello, o associare
in un secondo tempo uno stream ad un file descriptor.
-In generale, se non necessitano specificamente le funzionalità di basso
+In generale, se non necessitano specificatamente le funzionalità di basso
livello, è opportuno usare sempre gli stream per la loro maggiore portabilità
-essendo questi ultimi definito nello stadard ISO C; l'interfaccia con i file
+essendo questi ultimi definito nello standard ISO C; l'interfaccia con i file
descriptor invece segue solo lo standard POSIX.1 dei sistemi unix ed è
pertanto di portabilità più limitata.
\label{sec:files_spec_unix}
Essendo un sistema multitasking e multiutente esistono alcune caratteristiche
-specifiche di unix che devono essere tenute in conto nell'acceso ai file. È
+specifiche di unix che devono essere tenute in conto nell'accesso ai file. È
infatti normale che più processi o programmi possano accedere
contemporaneamente allo stesso file e devono poter eseguire le loro operazioni
indipendentemente da quello che fanno gli altri processi.
indipendente.
Questo ha delle conseguenze di cui è bene tenere conto; ad esempio in tutti i
-sistemi POSIX uno degli attibuti di un file aperto è la posizione corrente nel
+sistemi POSIX uno degli attributi di un file aperto è la posizione corrente nel
file, cioè il punto nel file in cui verrebbe letto o scritto alla operazione
successiva. Essa è rappresentata da un numero intero che indica il numero di
bytes dall'inizio del file, che viene (a meno che non si apra il file in
append) inizializzato a zero all'apertura del medesimo.
-Questo è uno dei dati che viene mantento nella suddetta struttura, per cui
+Questo è uno dei dati che viene mantenuto nella suddetta struttura, per cui
ogni processo avrà la sua posizione corrente nel file, che non sarà
influenzata da quello che altri processi possono fare. Anzi, aprire un file
-significa appuntio creare ed inizializzare una tale struttura, per cui se si
+significa appunto creare ed inizializzare una tale struttura, per cui se si
apre due volte lo stesso file all'interno dello stesso processo, si otterrano
-due file descriptor o due stream che avreanno ancora un posizione corrente nel
-file assolutamente independente.
+due file descriptor o due stream che avranno ancora un posizione corrente nel
+file assolutamente indipendente.
Si tenga conto inoltre che un'altro dei dati contenuti nella struttura di
accesso è un riferimento all'inode del file, pertanto anche se il file viene
e lo spazio su disco non verrà rilasciato fintanto che il file non sarà chiuso
e l'ultimo riferimento cancellato. È pertanto possibile (e pratica comune)
aprire un file provvisorio per cancellarlo immediatamente dopo; in questo modo
-all'uscita del programma il file scomparità definitivamente dal disco, ma il
+all'uscita del programma il file scomparirà definitivamente dal disco, ma il
file ed il suo contenuto saranno disponibili per tutto il tempo in cui il
processo è attivo.
-\subsection{L'accesso ai files: nomi e direcory}
+\subsection{L'accesso ai files: nomi e directory}
\label{sec:file_names}
L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
Il processo con cui si associa ad un pathname uno specifico file (cioè si
identifica l'inode a cui fare riferimento) è chiamato risoluzione del nome
-(\textit{file name resoluzion} o \textit{pathname resolution}).
+(\textit{file name resolution} o \textit{pathname resolution}).
La risoluzione viene fatta esaminando il pathname da destra a sinistra e
localizzando ogni componente nella directory indicata dal componente
-precedente: ovviamente perchè il procedimento funzioni occorre che i
+precedente: ovviamente perché il procedimento funzioni occorre che i
componenti indicati come directory esistano e siano effettivamente directory,
-inoltre i permessi devono consenite l'accesso.
+inoltre i permessi devono consentire l'accesso.
Se il pathname comincia per \texttt{/} la ricerca parte dalla directory radice
la stessa per tutti i processi ed equivale alla radice dell'albero
(\ref{sec:file_gen}): in questo caso si parla di un pathname
\textsl{assoluto}. Altrimenti la ricerca parte dalla directory di lavoro
-corrente (\texit{current working directory}, su cui pure torneremo più avanti)
+corrente (\textit{current working directory}, su cui pure torneremo più avanti)
ed il pathname è detto \textsl{relativo}.
I componenti \texttt{.} e \texttt{..} hanno un significato speciale e vengono
-inseriti in ogni directory;
+inseriti in ogni directory, il primo fa riferimento alla directory corrente e
+il secondo alla directory \textsl{genitore} (\textit{parent directory}) cioè
+la directory che contiene il riferimento alla directory corrente; nel caso
+questa sia la directory radice allora il riferimento è a se stessa.
+
+Infine si ricordi che in unix non esistono i tipi di file e che non c'è nessun
+supporto per le estensioni come parte del filesystem. Ciò non ostante molti
+programmi adottano delle convenzioni per i nomi dei file, ad esempio il codice
+C normalmente si mette in file con l'estensione .c, ma questa è solo una
+convenzione.
+
+
+\section{I file stream}
+\label{sec:file_stream}
+
+Esamineremo in questa sezione l'interfaccia per i file stream, le modalità per
+crearli, e le funzioni disponibili per leggere, scrivere e compiere le varie
+operazioni connesse all'uso dei file. L'interfaccia è accessibile includendo
+l'header file \texttt{stdio.h}.
+
+Per ragioni storiche la struttura di dati che rappresenta un stream è stata
+chiamata \texttt{FILE}, dato che le funzioni di libreria usano sempre come
+parametri oggetti di tipo \texttt{FILE *} alle volte si usa il termine
+puntatore a file come sinonimo di stream.
+
+
+
%La struttura fondamentale che contiene i dati essenziali relativi ai file è il
%tipo di file (file di dispositivo, directory, file di dati, per un elenco
%completo vedi \ntab), i permessi (vedi \ref{sec:file_perms}), le date (vedi
%\ref{sec:file_times}).
+