Completato server elementare.
[gapil.git] / files.tex
index b7ad2fd1c208f11fb3955eefe4949a84b68911af..a9f253b42f83c52eb13068c24339401fcfa4cf13 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
 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à
 
 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.
 
 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
 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
 
 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.
 
 
 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}
 
 \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
 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
 
 
 %La struttura fondamentale che contiene i dati essenziali relativi ai file è il