Aggiunto paragrafo sui link simbolici e non (da finire)
[gapil.git] / files.tex
index 4f5e304ab8b16e2a7540cbc26ee72f3b6cf74572..64482d02e46f3a3a3198ab484d5436bfe058b85a 100644 (file)
--- a/files.tex
+++ b/files.tex
@@ -386,8 +386,8 @@ 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_cwd}) ed il
-pathname è detto \textsl{relativo}.
+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
@@ -412,7 +412,7 @@ 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_cvd}
+\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
@@ -427,24 +427,23 @@ 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}. 
+corrente. I prototipi di queste funzioni sono dichiarati in \texttt{unistd.h}. 
 
 \begin{itemize}
-\item \texttt{char * getcwd (char * buffer, size_t size)}
+\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 \texiti{buffer}, nel qual caso la
+  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 sono ritornate le seguenti
-  condizioni di errore:
+  \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
@@ -458,36 +457,53 @@ corrente. I prototipi di queste funzioni sono dichiarati in
 \end{itemize}
 
 Di questa funzione esiste una versione \texttt{char * getwd(char * buffer)}
-fatta per compatibilità ll'indietro con BSD, che non consente di specificare
+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
+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 noe è detto che il buffer sia sufficiente a
+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}.
   
-  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 aggiunge il codice \texttt{ENOTDIR} nel caso il \texttt{filename}
-  indichi un file che non sia una directory.
+\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}
-
+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)}
+\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
@@ -501,26 +517,114 @@ dell'analogo comando di shell \texttt{mkdir}.
   \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{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
+    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 monto readonly.
+    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.
+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}