Aggiunto paragrafo sui link simbolici e non (da finire)
[gapil.git] / files.tex
index b7ad2fd1c208f11fb3955eefe4949a84b68911af..64482d02e46f3a3a3198ab484d5436bfe058b85a 100644 (file)
--- a/files.tex
+++ b/files.tex
@@ -327,8 +327,7 @@ sistemi POSIX uno degli attributi di un file aperto 
 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. 
-
+append) inizializzato a zero all'apertura del medesimo.
 
 Questo è uno dei dati che viene mantenuto nella suddetta struttura, per cui
 ogni processo avrà la sua posizione corrente nel file, che non sarà
@@ -382,14 +381,13 @@ precedente: ovviamente perch
 componenti indicati come directory esistano e siano effettivamente directory,
 inoltre i permessi devono consentire l'accesso.
 
-
 Se il pathname comincia per \texttt{/} la ricerca parte dalla directory radice
-del processo che (a meno di un \textit{chroot} su cui torneremo in seguito) è
-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 (\textit{current working directory}, su cui pure torneremo più avanti)
-ed il pathname è detto \textsl{relativo}.
+del processo che (a meno di un \textit{chroot} su cui torneremo in seguito,
+vedi \ref{sec:file_chroot}) è 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
+corrente (su cui pure torneremo più avanti in \ref{sec:file_dir_working}) ed
+il pathname è detto \textsl{relativo}.
 
 I componenti \texttt{.} e \texttt{..} hanno un significato speciale e vengono
 inseriti in ogni directory, il primo fa riferimento alla directory corrente e
@@ -404,6 +402,236 @@ C normalmente si mette in file con l'estensione .c, ma questa 
 convenzione.
 
 
+\section{L'interfaccia al filesystem}
+\label{sec:file_filesys_interf}
+
+Prima di entrare nei dettagli della manipolazione del contenuto dei file
+esamineremo le funzioni utilizzate per operare sui file piuttosto che sul loro
+contenuto. Le funzioni che esamineremo in questa sezione pertanto sono quelle
+che permettono di esaminare e modificare le directory, rinominare o cancellare
+i file, esaminare o settare i loro attributi.
+
+\subsection{La directory di lavoro}
+\label{sec:file_dir_working}
+
+Come accennato ciascun processo è associato ad una directory nel filesystem
+che è chiamata directory corrente o directory di lavoro (\textit{current
+  working directory}) che è quella a cui si fa riferimento quando un filename
+è espresso in forma relativa (relativa appunto a questa directory).
+
+Quando un utente effettua il login questa directory viene settata alla
+cosiddetta \textit{home directory} del suo account, il comando \texttt{cd}
+della shell consente di cambiarla a piacere, spostandosi da una directory ad
+un'altra.  Siccome la directory corrente resta la stessa quando viene creato
+un processo figlio, la directory corrente della shell diventa anche la
+directory corrente di qualunque comando da essa lanciato.
+
+Le funzioni qui descritte servono esaminare e cambiare la directory di lavoro
+corrente. I prototipi di queste funzioni sono dichiarati in \texttt{unistd.h}. 
+
+\begin{itemize}
+\item \texttt{char * getcwd (char * buffer, size\_t size)}
+  
+  Restituisce il filename completo della directory di lavoro corrente nella
+  stringa puntata da \texttt{buffer}, che deve essere precedentemente
+  allocata, per una dimensione massima di \texttt{size}. Si può anche
+  specificare un puntatore nullo come \textit{buffer}, nel qual caso la
+  stringa sarà allocata automaticamente per una dimensione pari a
+  \texttt{size} qualora questa sia diversa da zero, o della lunghezza esatta
+  del pathname altrimenti. In questo caso si deve ricordare di disallocara la
+  stringa una volta cessato il suo utilizzo.
+  
+  La funzione restituisce il puntatore \texttt{buffer} se riesce,
+  \texttt{NULL} se fallisce, in quest'ultimo caso la variabile
+  \texttt{errno} è settata con i seguenti codici di errore:
+
+  \begin{itemize}
+  \item \texttt{EINVAL} L'argomento \texttt{size} è zero e \texttt{buffer} non
+    è nullo.
+  \item \texttt{ERANGE} L'argomento \texttt{size} è più piccolo della
+    lunghezza del pathname. 
+  \item \texttt{EACCES} Manca il permesso di lettura o di ricerca su uno dei
+    componenti del pathname (cioè su una delle directory superiori alla
+    corrente).
+  \end{itemize}
+\end{itemize}
+
+Di questa funzione esiste una versione \texttt{char * getwd(char * buffer)}
+fatta per compatibilità all'indietro con BSD, che non consente di specificare
+la dimensione del buffer; esso deve essere allocato in precedenza ed avere una
+dimensione superiore a \texttt{PATH\_MAX} (di solito 256 byters, vedi
+\ref{sec:xxxx_limits}; il problema è che in linux non esiste una dimensione
+superiore per un pathname, per cui non è detto che il buffer sia sufficiente a
+contenere il nome del file, e questa è la ragione principale per cui questa
+funzione è deprecata.
+
+Una seconda funzione simile è \texttt{char * get\_current\_dir\_name(void)}
+che è sostanzialmente equivalente ad una \texttt{getcwd(NULL, 0)}, con la sola
+differenza che essa ritorna il valore della variabile di ambiente
+\texttt{PWD}, che essendo costruita dalla shell può contenere anche dei
+riferimenti simbolici.
+
+Come già detto in unix anche le directory sono file, è possibile pertanto
+(come vedremo in \ref{sec:file_dir_access}) riferirsi ad esse tramite il file
+descriptor dell'interfaccia a basso livello, e non solo tramite il filename;
+per questo motivo ci sono due diverse funzioni per cambiare directory di
+lavoro.
+
+\begin{itemize}
+\item \texttt{int chdir (const char * pathname)}
+  
+  Come dice il nome (che significa \textit{change directory}) questa funzione
+  serve a cambiare la directory di lavoro a quella speficata dal pathname
+  contenuto nella stringa \texttt{pathname}.
+  
+\item \texttt{int fchdir (int filedes)} analoga alla precedente, ma usa un
+  file descriptor invece del pathname.
+
+
+  Entrambe le funzioni restituiscono zero in caso di successo e -1 per un
+  errore, in caso di errore \texttt{errno} viene settata secondo i codici di
+  errore standard di accesso ai files (trattati in dettaglio in
+  \ref{sec:file_err_acc}) ai quali si aggiunge il codice \texttt{ENOTDIR} nel
+  caso il \texttt{filename} indichi un file che non sia una directory.
+\end{itemize}
+
+\subsection{Creazione di una directory} 
+\label{sec:file_dir_creat}
+
+Per creare una nuova directory si può usare la seguente funzione, omonima
+dell'analogo comando di shell \texttt{mkdir}; per accedere alla funzioni il
+programma deve includere il file \texttt{sys/stat.h}.
+
+\begin{itemize}
+\item \texttt{char * mkdir (const char * dirname, mode\_t mode)}
+  
+  Questa funzione crea una nuova directory vuota con il nome indicato da
+  \texttt{dirname}, assegnandole i permessi indicati da \texttt{mode}. Il nome
+  può essere indicato con il pathname assoluto o relativo.
+
+  La funzione restituisce zero in caso di successo e -1 per un errore, in caso
+  di errore \texttt{errno} viene settata secondo i codici di errore standard
+  di accesso ai files (trattati in dettaglio in \ref{sec:file_err_acc}) ai
+  quali si aggiungono i seguenti:
+  \begin{itemize}
+  \item \texttt{EACCESS} 
+    Non c'è il permesso di scrittura per la directory in cui si vuole inserire
+    la nuova directory.
+  \item \texttt{EEXIST} Un file (o una directory) con quel nome essite di già. 
+  \item \texttt{EMLINK} La directory in cui si vuole creare la nuova directory
+    contiene troppi file. Sotto linux questo normalmente non avviene perchè il
+    filesystem standard consente la creazione di un numero di file maggiore di
+    quelli che possono essere contenuti nell'hard-disk, ma potendo avere a che
+    fare anche con filesystem di altri sistemi questo errore può presentarsi.
+  \item \texttt{ENOSPC} Non c'è abbastanza spazio sul file system per creare
+    la nuova directory.
+  \item \texttt{EROFS} La directory su cui si vuole inserire la nuova
+    directory è su un filesystem montato readonly.
+  \end{itemize}
+\end{itemize}
+
+\subsection{Accesso alle directory}
+\label{sec:file_dir_access}
+
+Benchè le directory siano oggetti del filesystem come tutti gli altri non ha
+ovviamente senso aprirle come fossero dei file di dati. Può però essere utile
+poterne leggere il contenuto ad esempio per fare la lista dei file che esse
+contengono o ricerche sui medesimi..
+
+Per accedere al contenuto delle directory si usano i cosiddetti
+\textit{directory streams} (chiamati così per l'analogia con i file stream);
+la funzione \texttt{opendir} apre uno di questi stream e la funzione
+\texttt{readdir} legge il contenuto della directory, i cui elementi sono le
+\textit{directory entries} (da distinguersi da quelle della cache di cui
+parlavamo in \ref{sec:file_vfs}) in una opportuna struttura \texttt{struct
+dirent}.
+
+\subsection{I link simbolici e i link diretti}
+\label{sec:file_link}
+
+Una delle caratteristiche più usate quando si opera con i file è quella di
+poter creare dei nomi fittizi (alias o collegamenti) per potersi riferire allo
+stesso file accedendovi da directory diverse. Questo è possibile anche in
+ambiente unix, dove tali collegamenti sono usualmente chiamati \textit{link},
+ma data la struttura del sistema ci sono due metodi sostanzialmente diversi
+per fare questa operazione.
+
+Come si è già accennato nell'introduzione in un sistema unix l'accesso al
+contenuto di un file su disco avviene attraverso il suo \textit{inode}, e il
+nome che si trova in una directory è solo una etichetta associata ad un
+puntatore a detto inode.  Questo significa che la realizzazione di un links è
+immediata in quanto uno stesso file può avere tanti nomi diversi allo stesso
+tempo, dati da altrettante diverse associazioni allo stesso inode; si noti poi
+che nessuno di questi nomi viene ad assumere una particolare preferenza
+rispetto agli altri.
+
+Per aggiungere un nome ad un inode si utilizza la funzione \texttt{link}, e si
+suole chiamare questa associazione un collegamento diretto (o \textit{hard
+  link}).  La creazione di un nuovo link diretto non copia il contenuto del
+file, ma si limita ad aumentare di uno il numero di referenze al file (uno dei
+dati contenuti nell'inode) aggiungendo il nuovo nome ai precedenti. Si noti
+che uno stesso file può essere così richiamato in diverse directory.
+
+Siccome tutto ciò funziona facendo riferimento ad un inode, questa funzione
+può essere applicata soltanto per file che risiedono sullo stesso filesystem,
+(dato che solo in questo caso è garantita l'unicità dell'inode) e solo per
+filesystem di tipo unix. Inoltre in linux non è consentito eseguire un link
+diretto ad una directory.
+
+Per ovviare a queste limitazioni i sistemi unix supportano un'altra forma di
+link (i cosiddetti \textit{soft link} o \textit{symbolic link}), che sono,
+come avviene in altri sistemi operativi, dei file che contengono il
+semplicemente il riferimento ad un altro file (o directory). In questo modo è
+possibile effettuare link anche attraverso filesystem diversi e a directory, e
+pure a file che non esistono ancora.
+
+Il sistema funziona in quanto i link simbolici sono contrassegnati come tali
+al kernel (analogamente a quanto avviene per le directory) per cui la chiamata
+ad una \texttt{open} o una \texttt{stat} su un link simbolico comporta la
+lettura del contenuto del medesimo e l'applicazione della funzione al file
+specificato da quest'ultimo. Invece altre funzioni come quelle per cancellare
+o rinominare i file operano direttamente sul link simbolico. Inoltre esistono
+funzioni apposite, come la \texttt{readlink} e la \texttt{lstat} per accedere
+alle informazioni del link invece che a quelle del file a cui esso fa
+riferimento.
+
+Le funzioni per operare sui link sono le seguenti, esse sono tutte dichiarate
+nell'header file \texttt{unistd.h}.
+
+\begin{itemize}
+\item \texttt{int link(const char * oldname, const char * newname)}
+  
+  Crea un nuovo link al file  indicato da \texttt{oldname} dandogli nome
+  \texttt{newname}.
+  
+  La funzione restituisce zero in caso di successo e -1 per un errore, in caso
+  di errore. La variabile \texttt{errno} viene settata secondo i codici di
+  errore standard di accesso ai files (trattati in dettaglio in
+  \ref{sec:file_err_acc}) ai quali si aggiungono i seguenti:
+
+  \begin{itemize}
+  \item \texttt{EACCESS} 
+    Non c'è il permesso di scrittura per la directory in cui si vuole creare
+    il nuovo link.
+  \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
+    già.
+  \item \texttt{EMLINK} Ci sono troppi link al file \texttt{oldname} (il
+    numero massimo è specificato dalla variabile \texttt{LINK_MAX}, vedi
+    \ref{sec:sys_limits}.
+  \item \texttt{ENOSPC} La directory in cui si vuole creare il link è piena e
+    non può essere .
+  \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
+    su un filesystem montato readonly.
+  \end{itemize}
+\end{itemize}
+
+
+\section{L'input/output di basso livello}
+\label{sec:file_lowlev_io}
+%
+% Questa va per ultima. Va bene che e` la più usata, ma è basata sulle altre
+%
 \section{I file stream}
 \label{sec:file_stream}
 
@@ -413,12 +641,35 @@ operazioni connesse all'uso dei file. L'interfaccia 
 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. 
-
-
-
+chiamata \texttt{FILE}, questi oggetti sono creati dalle funzioni di libreria
+e contengono tutte le informazioni necessarie a gestire le operazioni sugli
+stream, come la posizione corrente, lo stato del buffer e degli indicatori di
+stato e di fine del file. Per questo motivo gli utenti non devono mai
+utilizzare direttamente o allocare queste strutture, ma usare sempre puntatori
+del tipo \texttt{FILE *} (tanto che in certi caso il termine di puntatore a
+file è diventato sinonimo di stream). 
+
+\subsection{Gli stream standard}
+\label{sec:file_stream_std}
+
+Quando un programma viene lanciato il processo ha sempre tre stream
+predefiniti aperti, che rappresentano i canali standard di input/output
+prestabiliti per il processo; anche questi tre stream sono definiti
+nell'header \texttt{stdio.h} e sono:
+
+\begin{itemize}
+\item \texttt{FILE * stdin} Lo \textit{standard input} cioè lo stream da cui
+  il processo riceve ordinariamente i dati in ingresso. Normalmente è associato
+  dalla shell all'input del terminale e prende i caratteri dalla tastiera.
+\item \texttt{FILE * stdout} Lo \textit{standard input} cioè lo stream su cui
+  il processo invia ordinariamente i dati in uscita. Normalmente è associato
+  dalla shell all'output del terminale e scrive sullo schermo.
+\item \texttt{FILE * stderr} Lo \textit{standard input} cioè lo stream su cui
+  il processo è supposto inviare i messaaggi di errore. Normalmente anch'esso
+  è associato dalla shell all'output del terminale e scrive sullo schermo.
+\end{itemize}
+
+In linux 
 
 
 %La struttura fondamentale che contiene i dati essenziali relativi ai file è il