files e directories, ed in particolare esamineremo come è strutturato il
sistema base di protezioni e controllo di accesso ai files, e tutta
l'interfaccia che permette la manipolazione dei vari attributi di files e
-directories. Tutto quello che riguarda invece la manipolazione dei contenuti è
-lasciato ai capitoli successivi.
+directories. Tutto quello che riguarda invece la manipolazione del contenuto
+dei file è lasciato ai capitoli successivi.
+
+
+\section{La gestione di file e directory}
+
+Le prime funzioni che considereremo sono quelle relative alla gestione di file
+e directory, secondo le caratteristiche standard che essi presentano in un
+filesystem unix, già esaminate in precedenza (vedi
+\secref{sec:fileintr_filesystem}).
+
+\subsection{Le funzioni \texttt{link} e \texttt{unlink}}
+\label{sec:fileintr_link}
+
+Una delle caratteristiche 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 è appena detto l'accesso al contenuto di un file su disco avviene
+attraverso il suo 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 link è 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}; si
+suole chiamare questo tipo di associazione un collegamento diretto (o
+\textit{hard link}). Il prototipo della funzione e le sue caratteristiche
+principali, come risultano dalla man page, sono le seguenti:
+\begin{prototype}{unistd.h}
+{int link(const char * oldpath, const char * newpath)}
+ Crea un nuovo collegamento diretto al file indicato da \texttt{oldpath}
+ dandogli nome \texttt{newpath}.
+
+ 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 seguenti
+ codici di errore:
+ \begin{errlist}
+ \item \texttt{EXDEV} \texttt{oldpath} e \texttt{newpath} non sono sullo
+ stesso filesystem.
+ \item \texttt{EPERM} il filesystem che contiene \texttt{oldpath} e
+ \texttt{newpath} non supporta i link diretti o è una directory.
+ \item \texttt{EFAULT} una delle stringhe passate come parametri è fuori
+ dello spazio di indirizzi del processo.
+ \item \texttt{EACCESS} errore di accesso (mancano i permessi per scrivere o
+ per attraversare le directories), vedi \secref{sec:filedir_access_control}
+ per i dettagli.
+ \item \texttt{ENAMETOOLONG} una dei due pathname è troppo lungo.
+ \item \texttt{ENOENT} un componente di \texttt{oldpath} o \texttt{newpath}
+ non esiste o è un link simbolico spezzato.
+ \item \texttt{ENOTDIR} un componente di \texttt{oldpath} o \texttt{newpath}
+ non è una directory.
+ \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
+ completare l'operazione.
+ \item \texttt{EROFS} la directory su cui si vuole inserire il nuovo link è
+ su un filesystem montato readonly.
+ \item \texttt{EEXIST} un file (o una directory) con quel nome esiste di
+ già.
+ \item \texttt{EMLINK} ci sono troppi link al file \texttt{oldpath} (il
+ numero massimo è specificato dalla variabile \texttt{LINK\_MAX}, vedi
+ \secref{sec:xxx_limits}).
+ \item \texttt{ELOOP} si incontrati troppi link simbolici nella risoluzione
+ di \texttt{oldpath} o \texttt{newpath}.
+ \item \texttt{ENOSPC} la directory in cui si vuole creare il link non ha
+ spazio per ulteriori voci.
+ \item \texttt{EIO} c'è stato un errore di input/output.
+ \end{errlist}
+\end{prototype}
+
+La creazione di un nuovo collegamento diretto non copia il contenuto del file,
+ma si limita ad aumentare di uno il numero di referenze al file aggiungendo il
+nuovo nome ai precedenti. Si noti che uno stesso file può essere così
+richiamato in diverse directory.
+
+Per quanto dicevamo in \secref{sec:fileintr_filesystem} la creazione del
+collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
+filesystem; inoltre il filesystem deve supportare i collegamenti diretti (non è
+il caso ad esempio del filesystem \texttt{vfat} di windows).
+
+La funzione opera sui file ordinari, come sugli altri oggetti del filesystem,
+ma solo l'amministratore è in grado di creare un collegamento diretto ad
+un'altra directory, questo lo si fa perché in questo caso è possibile creare
+dei circoli nel filesystem (vedi \secref{sec:fileintr_symlink}) che molti
+programmi non sono in grado di gestire e la cui rimozione diventa estremamente
+complicata (in genere occorre far girare il programma \texttt{fsck} per
+riparare il filesystem); data la sua pericolosità in Linux questa
+caratteristica è stata disabilitata, e la funzione restituisce l'errore
+\texttt{EPERM}.
+
+La rimozione di un file (o più precisamente della voce che lo referenzia) si
+effettua con la funzione \texttt{unlink}; il suo prototipo è il seguente:
+
+\begin{prototype}{unistd.h}{int unlink(const char * pathname)}
+ Cancella il nome specificato dal pathname nella relativa directory e
+ decrementa il numero di riferimenti nel relativo inode. Nel caso di link
+ simbolico cancella il link simbolico; nel caso di socket, fifo o file di
+ dispositivo rimuove il nome, ma come per i file i processi che hanno aperto
+ uno di questi oggetti possono continuare ad utilizzarlo.
+
+ La funzione restituisce zero in caso di successo e -1 per un errore, nel
+ qual caso il file non viene toccato. La variabile \texttt{errno} viene
+ settata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item \texttt{EACCESS} errore di accesso (mancano i permessi per scrivere o
+ per attraversare le directories), vedi \secref{sec:filedir_access_control}
+ per i dettagli.
+ \item \texttt{EISDIR} \texttt{pathname} si riferisce ad una directory
+ (valore specifico ritornato da linux che non consente l'uso di
+ \texttt{unlink} con le directory, e non conforme allo standard POSIX, che
+ prescrive invece l'uso di \texttt{EPERM} in caso l'operazione non sia
+ consnetita o il processo non abbia privilegi sufficienti).
+ \item \texttt{EFAULT} la stringa
+ passata come parametro è fuori dello spazio di indirizzi del processo.
+ \item \texttt{ENAMETOOLONG} il pathname troppo lungo.
+ \item \texttt{ENOENT} uno dei componenti del pathname non esiste o è un link
+ simbolico spezzato.
+ \item \texttt{ENOTDIR} uno dei componenti del pathname non è una directory.
+ \item \texttt{EISDIR} \texttt{pathname} fa riferimento a una directory.
+ \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
+ completare l'operazione.
+ \item \texttt{EROFS} \texttt{pathname} è su un filesystem montato in sola
+ lettura.
+ \item \texttt{ELOOP} ci sono troppi link simbolici nella risoluzione del
+ pathname.
+ \item \texttt{EIO} errore di input/output.
+ \end{errlist}
+\end{prototype}
+
+Per cancellare una voce in una directory è necessario avere il permesso di
+scrittura su di essa (dato che si va a rimuovere una voce dal suo contenuto) e
+il diritto di esecuzione sulla directory che la contiene (torneremo in
+dettaglio sui permessi e gli attributi fra poco), se inoltre lo
+\textit{sticky} bit è settato occorrerà anche essere proprietari del file o
+proprietari della directory (o root, per cui nessuna delle restrizioni è
+applicata).
+
+Una delle caratteristiche di queste funzioni è che la creazione/rimozione
+della nome dalla directory e l'incremento/decremento del numero di riferimenti
+nell'inode deve essere una operazione atomica (cioè non interrompibile da
+altri) processi, per questo entrambe queste funzioni sono realizzate tramite
+una singola system call.
+
+Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti
+i riferimenti ad esso sono stati cancellati, solo quando il \textit{link
+ count} mantenuto nell'inode diventa zero lo spazio occupato viene rimosso. A
+questo però si aggiunge una altra condizione, e cioè che non ci siano processi
+che abbiano detto file aperto. Come accennato questa proprietà viene spesso
+usata per essere sicuri di non lasciare file temporanei su disco in caso di
+crash dei programmi; la tecnica è quella di aprire il file e chiamare
+\texttt{unlink} subito dopo.
+
+\subsection{Le funzioni \texttt{remove} e \texttt{rename}}
+\label{sec:fileintr_remove}
+
+Al contrario di quanto avviene con altri unix in Linux non è possibile usare
+\texttt{unlink} sulle directory, per cancellare una directory si può usare la
+funzione \texttt{rmdir} (vedi \secref{sec:filedir_dir_creat_rem}), oppure la
+funzione \texttt{remove}. Questa è la funzione prevista dallo standard ANSI C
+per cancellare un file o una directory (e funziona anche per i sistemi che non
+supportano i link diretti), che per i file è identica alla \texttt{unlink} e
+per le directory è identica alla \texttt{rmdir}:
+
+\begin{prototype}{stdio.h}{int remove(const char *pathname)}
+ Cancella un nome dal filesystem. Usa \texttt{unlink} per i file e
+ \texttt{rmdir} per le directory.
+
+ La funzione restituisce zero in caso di successo e -1 per un errore, nel
+ qual caso il file non viene toccato. Per i codici di errori vedi quanto
+ riportato nella descrizione di \texttt{unlink} e \texttt{rmdir}.
+\end{prototype}
+
+Per cambiare nome ad un file si usa invece la funzione \texttt{rename}, il
+vantaggio nell'uso di questa funzione al posto della chiamata successiva di
+\texttt{unlink} e \texttt{link} è che l'operazione è eseguita atomicamente, in
+questo modo non c'è la possibilità che un processo che cerchi di accedere al
+nuovo nome dopo che il vecchio è stato cambiato lo trovi mancante.
+
+\begin{prototype}{stdio.h}
+{int rename(const char *oldpath, const char *newpath)}
+ Rinomina un file, spostandolo fra directory diverse quando richiesto.
+
+ La funzione restituisce zero in caso di successo e -1 per un errore, nel
+ qual caso il file non viene toccato. La variabile \texttt{errno} viene
+ settata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item \texttt{EISDIR} \texttt{newpath} è una directory già esistente mentre
+ \texttt{oldpath} non è una directory.
+ \item \texttt{EXDEV} \texttt{oldpath} e \texttt{newpath} non sono sullo
+ stesso filesystem.
+ \item \texttt{ENOTEMPTY} \texttt{newpath} è una directory già esistente e
+ non vuota.
+ \item \texttt{EBUSY} o \texttt{oldpath} o \texttt{newpath} sono in uso da
+ parte di qualche processo (come directory di lavoro o come root) o del
+ sistema (come mount point).
+ \item \texttt{EINVAL} \texttt{newpath} contiene un prefisso di
+ \texttt{oldpath} o più in generale si è cercato di creare una directory
+ come sottodirectory di se stessa.
+ \item \texttt{EMLINK} \texttt{oldpath} ha già il massimo numero di link
+ consentiti o è una directory e la directory che contiene \texttt{newpath}
+ ha già il massimo numero di link.
+ \item \texttt{ENOTDIR} Uno dei componenti dei pathname non è una directory
+ o\texttt{oldpath} è una directory e \texttt{newpath} esiste e non è una
+ directory.
+ \item \texttt{EFAULT} o \texttt{oldpath} o \texttt{newpath} è fuori dello
+ spazio di indirizzi del processo.
+ \item \texttt{EACCESS} Non c'è il permesso di scrittura per la directory in
+ cui si vuole creare il nuovo link o una delle directory del pathname non
+ consente la ricerca (permesso di esecuzione).
+ \item \texttt{EPERM} le directory contenenti \texttt{oldpath} o
+ \texttt{newpath} hanno lo sticky bit attivo e i permessi del processo non
+ consentono rispettivamente la cancellazione e la creazione del file, o il
+ filesystem non supporta i link.
+ \item \texttt{ENAMETOOLONG} uno dei pathname è troppo lungo.
+ \item \texttt{ENOENT} Uno dei componenti del pathname non esiste o è un link
+ simbolico spezzato.
+ \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
+ completare l'operazione.
+ \item \texttt{EROFS} I file sono su un filesystem montato in sola lettura.
+ \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione del
+ pathname.
+ \item \texttt{ENOSPC} Il device di destinazione non ha più spazio per la
+ nuova voce.
+ \end{errlist}
+\end{prototype}
+
+\subsection{I link simbolici}
+\label{sec:fileintr_symlink}
+
+Siccome la funzione \texttt{link} crea riferimenti agli inodes, essa può
+funzionare soltanto per file che risiedono sullo stesso filesystem, dato che
+in questo caso è garantita l'unicità dell'inode, e solo per un 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 simbolici sono le seguenti, esse sono tutte
+dichiarate nell'header file \texttt{unistd.h}.
+
+\begin{prototype}{unistd.h}
+{int symlink(const char * oldname, const char * newname)}
+ Crea un nuovo link simbolico 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
+ \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
+ \begin{errlist}
+ \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
+ già.
+ \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
+ su un filesystem montato readonly.
+ \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il
+ link è piena e non c'è ulteriore spazio disponibile.
+ \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
+ \texttt{oldname} o di \texttt{newname}.
+ \end{errlist}
+\end{prototype}
+
+Dato che la funzione \texttt{open} segue i link simbolici, è necessaria usare
+un'altra funzione quando si vuole leggere il contenuto di un link simbolico,
+questa funzione è la:
+
+\begin{prototype}{unistd.h}
+{int readlink(const char * path, char * buff, size\_t size)}
+ Legge il contenuto del link simbolico indicato da \texttt{path} nel buffer
+ \texttt{buff} di dimensione \texttt{size}. Non chiude la stringa con un
+ carattere nullo e la tronca a \texttt{size} nel caso il buffer sia troppo
+ piccolo per contenerla.
+
+ La funzione restituisce il numero di caratteri letti dentro \texttt{buff} o
+ -1 per un errore, in caso di errore. La variabile \texttt{errno} viene
+ settata secondo i codici di errore:
+ \begin{errlist}
+ \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
+ già.
+ \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
+ su un filesystem montato readonly.
+ \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il
+ link è piena e non c'è ulteriore spazio disponibile.
+ \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
+ \texttt{oldname} o di \texttt{newname}.
+ \end{errlist}
+\end{prototype}
+
+\section{La manipolazione delle directories}
+\label{sec:filedir_dir_handling}
+
+\subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}}
+\label{sec:filedir_dir_creat_rem}
+
+Per creare una nuova directory si può usare la seguente funzione, omonima
+dell'analogo comando di shell \texttt{mkdir}; per accedere ai tipi usati
+programma deve includere il file \texttt{sys/types.h}.
+
+\begin{prototype}{sys/stat.h}
+{int 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
+ \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
+ \begin{errlist}
+ \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 esiste 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{errlist}
+\end{prototype}
+
+
+\subsection{Accesso alle directory}
+\label{sec:filedir_dir_read}
+
+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 \secref{sec:fileintr_vfs}) in una opportuna struttura
+\texttt{struct dirent}.
+
+
+\subsection{La directory di lavoro}
+\label{sec:filedir_work_dir}
+
+A 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.
+
+\begin{prototype}{unistd.h}{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 disallocare 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{errlist}
+ \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{EACCESS} Manca il permesso di lettura o di ricerca su uno dei
+ componenti del pathname (cioè su una delle directory superiori alla
+ corrente).
+ \end{errlist}
+\end{prototype}
+
+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 bytes, vedi
+\secref{sec:xxx_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
+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{prototype}{unistd.h}{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 specificata dal pathname
+ contenuto nella stringa \texttt{pathname}.
+\end{prototype}
+
+\begin{prototype}{unistd.h}{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
+ \secref{sec:filedir_access_control}) ai quali si aggiunge il codice
+ \texttt{ENOTDIR} nel caso il \texttt{filename} indichi un file che non sia
+ una directory.
+\end{prototype}
\section{La manipolazione delle caratteristiche dei files}
\label{sec:filedir_stat}
La lettura delle informazioni relative ai file è fatta attraverso la famiglia
-delle funzioni \texttt{stat}, questa è la funzione che il comando \texttt{ls}
-usa per poter stampare tutti i dati dei files; il prototipo della funzione è
-il seguente;
-\begin{prototype}{unistd.h}
-{int stat(const char *file\_name, struct stat *buf)}
+delle funzioni \texttt{stat}, che è la funzione che il comando \texttt{ls} usa
+per poter stampare tutti i dati dei files. I prototipi di queste funzioni sono
+i seguenti:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/stat.h}
+ \headdecl{unistd.h}
+
+ \funcdecl{int stat(const char *file\_name, struct stat *buf)} Legge le
+ informazione del file specificato da \var{file\_name} e le inserisce in
+ \var{buf}.
- La funzione restituisce zero in caso di successo e -1 per un errore, in caso
- di errore \texttt{errno} viene settato ai valori:
+ \funcdecl{int lstat(const char *file\_name, struct stat *buf)} Identica a
+ \func{stat} eccetto che se il \var{file\_name} è un link simbolico vengono
+ lette le informazioni relativa ad esso e non al file a cui punta.
+
+ \funcdecl{int fstat(int filedes, struct stat *buf)} Identica a \func{stat}
+ eccetto che funziona con un file aperto, specificato tramite il suo file
+ descriptor \var{filedes}.
+
+ Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
+ caso di errore \texttt{errno} viene settato ai valori:
\begin{errlist}
\item \texttt{EACCESS} Non c'è il permesso di accedere al file.
\item \texttt{ENOTDIR} Una componente del pathname non è una directory.
completare l'operazione.
\item \texttt{ENAMETOOLONG} Il filename è troppo lungo.
\end{errlist}
-\end{prototype}
+\end{functions}
La struttura \texttt{stat} è definita nell'header \texttt{sys/stat.h} e in
generale dipende dall'implementazione, la versione usata da Linux è mostrata
Si noti come i vari membri della struttura siano specificati come tipi nativi
del sistema (di quelli definiti in \tabref{tab:xxx_sys_types}, e dichiarati in
-\texttt{sys/types.h})
-
-
+\texttt{sys/types.h}).
\subsection{I tipi di file}
\label{sec:filedir_file_types}
-Come riportato in \tabref{tab:fileintr_file_types} in linux oltre ai file e
+Come riportato in \tabref{tab:fileintr_file_types} in Linux oltre ai file e
alle directory esistono vari altri oggetti che possono stare su un filesystem;
-il tipo di file è ritornato dalla \texttt{stat} nel campo \texttt{st\_mode},
-dato che il valore numerico può variare a seconda delle implementazioni
+il tipo di file è ritornato dalla \texttt{stat} nel campo \texttt{st\_mode}.
+Dato che il valore numerico può variare a seconda delle implementazioni lo
+standard POSIX definisce un insieme di macro per verificare il tipo di files,
+queste venfono usate anche da Linux che supporta pure le estensioni per link
+simbolici e socket definite da BDS, l'elenco è riportato in \ntab:
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ Macro & Tipo del file \\
+ \hline
+ \hline
+ \macro{S\_ISREG(m)} & file normale \\
+ \macro{S\_ISDIR(m)} & directory \\
+ \macro{S\_ISCHR(m)} & device a caraetteri \\
+ \macro{S\_ISBLK(m)} & device a blocchi\\
+ \macro{S\_ISFIFO(m)} & fifo \\
+ \macro{S\_ISLNK(m)} & link simbolico \\
+ \macro{S\_ISSOCK(m)} & socket \\
+ \hline
+ \end{tabular}
+ \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h})}
+ \label{tab:filedir_file_type_macro}
+\end{table}
+
+Oltre a queste macro è possibile usare direttamente il valore di
+\var{st\_mode} per ricavare il significato dei vari bit del campo attraverso
+l'uso dei flag riportati in \ntab:
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|l|}
+ \hline
+ Flag & Valore & Significato \\
+ \hline
+ \hline
+ \macro{S\_IFMT} & 0170000 & bitmask for the file type bitfields \\
+ \macro{S\_IFSOCK} & 0140000 & socket \\
+ \macro{S\_IFLNK} & 0120000 & symbolic link \\
+ \macro{S\_IFREG} & 0100000 & regular file \\
+ \macro{S\_IFBLK} & 0060000 & block device \\
+ \macro{S\_IFDIR} & 0040000 & directory \\
+ \macro{S\_IFCHR} & 0020000 & character device \\
+ \macro{S\_IFIFO} & 0010000 & fifo \\
+ \macro{S\_ISUID} & 0004000 & set UID bit \\
+ \macro{S\_ISGID} & 0002000 & set GID bit (see below) \\
+ \macro{S\_ISVTX} & 0001000 & sticky bit (see below) \\
+ \macro{S\_IRWXU} & 00700 & mask for file owner permissions \\
+ \macro{S\_IRUSR} & 00400 & owner has read permission \\
+ \macro{S\_IWUSR} & 00200 & owner has write permission \\
+ \macro{S\_IXUSR} & 00100 & owner has execute permission \\
+ \macro{S\_IRWXG} & 00070 & mask for group permissions \\
+ \macro{S\_IRGRP} & 00040 & group has read permission \\
+ \macro{S\_IWGRP} & 00020 & group has write permission \\
+ \macro{S\_IXGRP} & 00010 & group has execute permission \\
+ \macro{S\_IRWXO} & 00007 & mask for permissions for others (not in
+ group) \\
+ \macro{S\_IROTH} & 00004 & others have read permission \\
+ \macro{S\_IWOTH} & 00002 & others have write permisson \\
+ \macro{S\_IXOTH} & 00001 & others have execute permission \\
+ \hline
+ \end{tabular}
+ \caption{Flag per il campo \var{st\_mode} (definite in
+ \texttt{sys/stat.h})}
+ \label{tab:filedir_file_mode_flags}
+\end{table}
\subsection{La dimensione dei file}
\label{sec:filedir_file_size}
+Il membro \var{st\_size} contiene la dimensione del
+
\subsection{I tempi dei file}
\label{sec:filedir_file_times}
\label{sec:filedir_chown}
-\section{La manipolazione delle directories}
-\label{sec:filedir_dir_handling}
-
-\subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}}
-\label{sec:filedir_dir_creat_rem}
-
-Per creare una nuova directory si può usare la seguente funzione, omonima
-dell'analogo comando di shell \texttt{mkdir}; per accedere ai tipi usati
-programma deve includere il file \texttt{sys/types.h}.
-
-\begin{prototype}{sys/stat.h}
-{int 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
- \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
- \begin{errlist}
- \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 esiste 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{errlist}
-\end{prototype}
-
-
-\subsection{Accesso alle directory}
-\label{sec:filedir_dir_read}
-
-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 \secref{sec:fileintr_vfs}) in una opportuna struttura
-\texttt{struct dirent}.
-
-
-\subsection{La directory di lavoro}
-\label{sec:filedir_work_dir}
-
-A 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.
-
-\begin{prototype}{unistd.h}{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 disallocare 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{errlist}
- \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{EACCESS} Manca il permesso di lettura o di ricerca su uno dei
- componenti del pathname (cioè su una delle directory superiori alla
- corrente).
- \end{errlist}
-\end{prototype}
-
-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 bytes, vedi
-\secref{sec:xxx_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
-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{prototype}{unistd.h}{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 specificata dal pathname
- contenuto nella stringa \texttt{pathname}.
-\end{prototype}
-
-\begin{prototype}{unistd.h}{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
- \secref{sec:filedir_access_control}) ai quali si aggiunge il codice
- \texttt{ENOTDIR} nel caso il \texttt{filename} indichi un file che non sia
- una directory.
-\end{prototype}
-
-
%La struttura fondamentale che contiene i dati essenziali relativi ai file è il
+
\chapter{I files: l'architettura}
\label{cha:files_intro}
-
+
Uno dei concetti fondamentali della architettura di unix è il cosiddetto
\textit{everything is a file}, cioè il fatto che l'accesso ai vari dispositivi
di input/output del computer viene effettuato attraverso un'interfaccia
L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
medesimi nell'albero descritto in precedenza; una directory comunque, come già
specificato in \secref{sec:fileintr_vfs}, è solo un particolare tipo di file
-che contiene le informazioni che associano un nome al contenuto. Per questo,
-anche se è usuale parlare di ``file in una directory'' in realtà una directory
-contiene solo delle etichette per fare riferimento ai file stessi.
+che contiene le informazioni che associano un nome al contenuto.
+
+% Per questo, anche se è usuale parlare di ``file in una directory'' in realtà
+% una directory contiene solo delle etichette per fare riferimento ai file
+% stessi.
I manuale delle glibc chiama i nomi contenuti nelle directory
\textsl{componenti} (in inglese \textit{file name components}), noi li
file viene usualmente chiamato \textit{pathname}, e anche se il manuale della
glibc depreca questo nome (poiché genererebbe confusione, dato che con
\textit{path} si indica anche un insieme di directory su cui effettuare una
-ricerca, come quello in cui si cercano i comandi) l'uso è ormai così comune
+ricerca, come quello in cui si cercano i comandi); l'uso è ormai così comune
che è senz'altro più chiaro dell'alternativa proposta.
Il processo con cui si associa ad un pathname uno specifico file è chiamato
questa sia la directory radice allora il riferimento è a se stessa.
-% \subsection{Il controllo di accesso}
-% \label{sec:fileintr_access_ctrl}
-
-
\subsection{I tipi di files}
\label{sec:fileintr_file_types}
\end{center}
\end{table}
-Una delle differenze principali con altri sistemi operativi (come il VMS o
-Windows) è che per Unix tutti i file di dati sono identici e contengono un
-flusso continuo di bytes; non esiste cioè differenza per come vengono visti
+Infatti una delle differenze principali con altri sistemi operativi (come il
+VMS o Windows) è che per Unix tutti i file di dati sono identici e contengono
+un flusso continuo di bytes. Non esiste cioè differenza per come vengono visti
dal sistema file di diverso contenuto o formato (come nel caso di quella fra
file di testo e binari che c'è in Windows) né c'è una strutturazione a record
-per il cosiddetto ``accesso diretto'' come nel caso del VMS.
-% (con i kernel
-% della serie 2.4 è disponibile una forma di accesso diretto ai dischi il
-% \textit{raw access} che però non ha nulla a che fare con questo).
+per il cosiddetto ``accesso diretto'' come nel caso del VMS\footnote{con i
+ kernel della serie 2.4 è disponibile una forma di accesso diretto ai dischi
+ (il \textit{raw access}) attraverso dei device file appositi, che però non
+ ha nulla a che fare con questo}.
Una seconda differenza è nel formato dei file ASCII; in Unix la fine riga è
codificata in maniera diversa da Windows o MacIntosh, in particolare il fine
accedere al loro contenuto.
La prima è l'interfaccia standard di unix, quella che il manuale delle glibc
-chiama interfaccia dei descrittore di file (o \textit{file descriptor}). È
+chiama interfaccia dei descrittori di file (o \textit{file descriptor}). È
un'interfaccia specifica di unix e provvede un accesso non bufferizzato.
L'interfaccia è primitiva ed essenziale, l'accesso viene detto non
La seconda interfaccia è quella che il manuale della glibc chiama degli
\textit{stream}, essa provvede funzioni più evolute e un accesso bufferizzato
(controllato dalla implementazione fatta dalle librerie del C). Questa è
-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}.
+l'interfaccia standard specificata dall'ANSI 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
descriptor invece segue solo lo standard POSIX.1 dei sistemi unix ed è
pertanto di portabilità più limitata.
+
\subsection{Caratteristiche specifiche dei file in unix}
\label{sec:fileint_unix_spec}
Quando un processo esegue una system call che opera su un file il kernel
chiama sempre una funzione implementata nel VFS; la funzione eseguirà le
-manipolazioni sulle strutture generiche e ridirigendo la chiamata alla
+manipolazioni sulle strutture generiche e utilizzaerà poi la chiamata alla
opportune routine del filesystem specifico a cui si fa riferimento. Saranno
queste a chiamare le funzioni di più basso livello che eseguono le operazioni
di I/O sul dispositivo fisico, secondo lo schema riportato in \nfig.
\end{figure}
Il VFS definisce un insieme di funzioni che tutti i filesystem devono
-implementare, queste funzioni
-
+implementare. L'interfaccia comprende tutte le funzioni che riguardano i
+files; le operazioni sono suddivise su tre tipi di oggetti: filesystem, inode
+e file, corrispondenti a tre apposite strutture definite nel kernel.
+
+Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun
+filesystem supportato, quando si vuole inserire il supporto di un nuovo
+filesystem tutto quello che occorre è una chiamata alla funzione
+\func{register\_filesystem} passando un'apposita struttura che
+(\var{file\_system\_type}) contiene l'implementazione edl medesimo, che sarà
+aggiunta alla citata tabella.
+
+
+In questo modo quando viene effettuata la richiesta di montare un nuovo disco
+(o qualunque altro \textit{block device} che può contenere un filesystem), il
+VFS può ricavare dalla citata tabella il puntatore alle funzioni da chiamare
+nelle operazioni di montaggio. Quest'ultima è responsabile di leggere da disco
+il superblock (vedi \ref{sec:fileintro_ext2}), inizializzare tutte le
+variabili interne e restituire uno speciale descrittore dei filesystem montati
+al VFS; attraverso quest'ultimo diventa possible accedere alle routine
+specifiche per l'uso di quel filesystem.
+
+Il primo oggetto usato dal VFS è il descrittore di filesystem, un puntatore ad
+una apposita struttura che contiene vari dati come le informazioni comuni ad
+ogni filesystem, i dati privati relativi a quel filesystem specifico, e i
+puntatori alle funzioni del kernel relative al filesystem. Il VFS può così
+usare le funzioni contenute nel filesystem decriptor per accedere alle routine
+specifiche di quel filesystem.
+
+Gli altri due descrittori usati dal VFS sono relativi agli altri due oggetti
+su cui è strutturata l'interfaccia. Ciascuno di essi contiene le informazioni
+relative al file in uso, insieme ai puntatori alle funzioni dello specifico
+filesystem usate per l'accesso dal VFS; in particolare il descrittore
+dell'inode contiene i puntatori alle funzioni che possono essere usate su
+qualunque file (come \func{link}, \func{stat} e \func{open}), mentre il
+descrittore di file contiene i puntatori alle funzioni che vengono usate sui
+file già aperti.
\subsection{Il funzionamento del VFS}
\label{sec:fileintr_vfs_work}
-La funzione più importante implementata dal VFS è la system call \texttt{open}
-che permette di aprire un file. Dato un pathname viene eseguita una ricerca
-dentro la \textit{directory entry cache} (in breve \textit{dcache}),
-una tabella di hash che contiene tutte le \textit{directory entry} (in breve
-\textit{dentry}) che permette di associare in maniera rapida ed efficiente il
-pathname a una specifica dentry.
+La funzione più fondamentale implementata dal VFS è la system call
+\texttt{open} che permette di aprire un file. Dato un pathname viene eseguita
+una ricerca dentro la \textit{directory entry cache} (in breve
+\textit{dcache}), una tabella di hash che contiene tutte le \textit{directory
+ entry} (in breve \textit{dentry}) che permette di associare in maniera
+rapida ed efficiente il pathname a una specifica dentry.
Una singola dentry contiene in genere il puntatore ad un \textit{inode};
quest'ultimo è la struttura base che sta sul disco e che identifica un singolo
adesso sarà referenziata anche dalla voce \texttt{..} di \texttt{textdir}.
-\subsection{Le funzioni \texttt{link} e \texttt{unlink}}
-\label{sec:fileintr_link}
-
-Una delle caratteristiche 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 è appena detto l'accesso al contenuto di un file su disco avviene
-attraverso il suo 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 link è 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}; si
-suole chiamare questo tipo di associazione un collegamento diretto (o
-\textit{hard link}). Il prototipo della funzione e le sue caratteristiche
-principali, come risultano dalla man page, sono le seguenti:
-\begin{prototype}{unistd.h}
-{int link(const char * oldpath, const char * newpath)}
- Crea un nuovo collegamento diretto al file indicato da \texttt{oldpath}
- dandogli nome \texttt{newpath}.
-
- 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 seguenti
- codici di errore:
- \begin{errlist}
- \item \texttt{EXDEV} \texttt{oldpath} e \texttt{newpath} non sono sullo
- stesso filesystem.
- \item \texttt{EPERM} il filesystem che contiene \texttt{oldpath} e
- \texttt{newpath} non supporta i link diretti o è una directory.
- \item \texttt{EFAULT} una delle stringhe passate come parametri è fuori
- dello spazio di indirizzi del processo.
- \item \texttt{EACCESS} errore di accesso (mancano i permessi per scrivere o
- per attraversare le directories), vedi \secref{sec:filedir_access_control}
- per i dettagli.
- \item \texttt{ENAMETOOLONG} una dei due pathname è troppo lungo.
- \item \texttt{ENOENT} un componente di \texttt{oldpath} o \texttt{newpath}
- non esiste o è un link simbolico spezzato.
- \item \texttt{ENOTDIR} un componente di \texttt{oldpath} o \texttt{newpath}
- non è una directory.
- \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
- completare l'operazione.
- \item \texttt{EROFS} la directory su cui si vuole inserire il nuovo link è
- su un filesystem montato readonly.
- \item \texttt{EEXIST} un file (o una directory) con quel nome esiste di
- già.
- \item \texttt{EMLINK} ci sono troppi link al file \texttt{oldpath} (il
- numero massimo è specificato dalla variabile \texttt{LINK\_MAX}, vedi
- \secref{sec:xxx_limits}).
- \item \texttt{ELOOP} si incontrati troppi link simbolici nella risoluzione
- di \texttt{oldpath} o \texttt{newpath}.
- \item \texttt{ENOSPC} la directory in cui si vuole creare il link non ha
- spazio per ulteriori voci.
- \item \texttt{EIO} c'è stato un errore di input/output.
- \end{errlist}
-\end{prototype}
-
-La creazione di un nuovo collegamento diretto non copia il contenuto del file,
-ma si limita ad aumentare di uno il numero di referenze al file aggiungendo il
-nuovo nome ai precedenti. Si noti che uno stesso file può essere così
-richiamato in diverse directory.
-
-Per quanto dicevamo in \secref{sec:fileintr_filesystem} la creazione del
-collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
-filesystem; inoltre il filesystem deve supportare i collegamenti diretti (non è
-il caso ad esempio del filesystem \texttt{vfat} di windows).
-
-La funzione opera sui file ordinari, come sugli altri oggetti del filesystem,
-ma solo l'amministratore è in grado di creare un collegamento diretto ad
-un'altra directory, questo lo si fa perché in questo caso è possibile creare
-dei circoli nel filesystem (vedi \secref{sec:fileintr_symlink}) che molti
-programmi non sono in grado di gestire e la cui rimozione diventa estremamente
-complicata (in genere occorre far girare il programma \texttt{fsck} per
-riparare il filesystem); data la sua pericolosità in Linux questa
-caratteristica è stata disabilitata, e la funzione restituisce l'errore
-\texttt{EPERM}.
-
-La rimozione di un file (o più precisamente della voce che lo referenzia) si
-effettua con la funzione \texttt{unlink}; il suo prototipo è il seguente:
-
-\begin{prototype}{unistd.h}{int unlink(const char * pathname)}
- Cancella il nome specificato dal pathname nella relativa directory e
- decrementa il numero di riferimenti nel relativo inode. Nel caso di link
- simbolico cancella il link simbolico; nel caso di socket, fifo o file di
- dispositivo rimuove il nome, ma come per i file i processi che hanno aperto
- uno di questi oggetti possono continuare ad utilizzarlo.
-
- La funzione restituisce zero in caso di successo e -1 per un errore, nel
- qual caso il file non viene toccato. La variabile \texttt{errno} viene
- settata secondo i seguenti codici di errore:
- \begin{errlist}
- \item \texttt{EACCESS} errore di accesso (mancano i permessi per scrivere o
- per attraversare le directories), vedi \secref{sec:filedir_access_control}
- per i dettagli.
- \item \texttt{EISDIR} \texttt{pathname} si riferisce ad una directory
- (valore specifico ritornato da linux che non consente l'uso di
- \texttt{unlink} con le directory, e non conforme allo standard POSIX, che
- prescrive invece l'uso di \texttt{EPERM} in caso l'operazione non sia
- consnetita o il processo non abbia privilegi sufficienti).
- \item \texttt{EFAULT} la stringa
- passata come parametro è fuori dello spazio di indirizzi del processo.
- \item \texttt{ENAMETOOLONG} il pathname troppo lungo.
- \item \texttt{ENOENT} uno dei componenti del pathname non esiste o è un link
- simbolico spezzato.
- \item \texttt{ENOTDIR} uno dei componenti del pathname non è una directory.
- \item \texttt{EISDIR} \texttt{pathname} fa riferimento a una directory.
- \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
- completare l'operazione.
- \item \texttt{EROFS} \texttt{pathname} è su un filesystem montato in sola
- lettura.
- \item \texttt{ELOOP} ci sono troppi link simbolici nella risoluzione del
- pathname.
- \item \texttt{EIO} errore di input/output.
- \end{errlist}
-\end{prototype}
-
-Per cancellare una voce in una directory è necessario avere il permesso di
-scrittura su di essa (dato che si va a rimuovere una voce dal suo contenuto) e
-il diritto di esecuzione sulla directory che la contiene (torneremo in
-dettaglio sui permessi e gli attributi fra poco), se inoltre lo
-\textit{sticky} bit è settato occorrerà anche essere proprietari del file o
-proprietari della directory (o root, per cui nessuna delle restrizioni è
-applicata).
-
-Una delle caratteristiche di queste funzioni è che la creazione/rimozione
-della nome dalla directory e l'incremento/decremento del numero di riferimenti
-nell'inode deve essere una operazione atomica (cioè non interrompibile da
-altri) processi, per questo entrambe queste funzioni sono realizzate tramite
-una singola system call.
-
-Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti
-i riferimenti ad esso sono stati cancellati, solo quando il \textit{link
- count} mantenuto nell'inode diventa zero lo spazio occupato viene rimosso. A
-questo però si aggiunge una altra condizione, e cioè che non ci siano processi
-che abbiano detto file aperto. Come accennato questa proprietà viene spesso
-usata per essere sicuri di non lasciare file temporanei su disco in caso di
-crash dei programmi; la tecnica è quella di aprire il file e chiamare
-\texttt{unlink} subito dopo.
-
-\subsection{Le funzioni \texttt{remove} e \texttt{rename}}
-\label{sec:fileintr_remove}
-
-Al contrario di quanto avviene con altri unix in Linux non è possibile usare
-\texttt{unlink} sulle directory, per cancellare una directory si può usare la
-funzione \texttt{rmdir} (vedi \secref{sec:filedir_dir_creat_rem}), oppure la
-funzione \texttt{remove}. Questa è la funzione prevista dallo standard ANSI C
-per cancellare un file o una directory (e funziona anche per i sistemi che non
-supportano i link diretti), che per i file è identica alla \texttt{unlink} e
-per le directory è identica alla \texttt{rmdir}:
-
-\begin{prototype}{stdio.h}{int remove(const char *pathname)}
- Cancella un nome dal filesystem. Usa \texttt{unlink} per i file e
- \texttt{rmdir} per le directory.
-
- La funzione restituisce zero in caso di successo e -1 per un errore, nel
- qual caso il file non viene toccato. Per i codici di errori vedi quanto
- riportato nella descrizione di \texttt{unlink} e \texttt{rmdir}.
-\end{prototype}
-
-Per cambiare nome ad un file si usa invece la funzione \texttt{rename}, il
-vantaggio nell'uso di questa funzione al posto della chiamata successiva di
-\texttt{unlink} e \texttt{link} è che l'operazione è eseguita atomicamente, in
-questo modo non c'è la possibilità che un processo che cerchi di accedere al
-nuovo nome dopo che il vecchio è stato cambiato lo trovi mancante.
-
-\begin{prototype}{stdio.h}
-{int rename(const char *oldpath, const char *newpath)}
- Rinomina un file, spostandolo fra directory diverse quando richiesto.
-
- La funzione restituisce zero in caso di successo e -1 per un errore, nel
- qual caso il file non viene toccato. La variabile \texttt{errno} viene
- settata secondo i seguenti codici di errore:
- \begin{errlist}
- \item \texttt{EISDIR} \texttt{newpath} è una directory già esistente mentre
- \texttt{oldpath} non è una directory.
- \item \texttt{EXDEV} \texttt{oldpath} e \texttt{newpath} non sono sullo
- stesso filesystem.
- \item \texttt{ENOTEMPTY} \texttt{newpath} è una directory già esistente e
- non vuota.
- \item \texttt{EBUSY} o \texttt{oldpath} o \texttt{newpath} sono in uso da
- parte di qualche processo (come directory di lavoro o come root) o del
- sistema (come mount point).
- \item \texttt{EINVAL} \texttt{newpath} contiene un prefisso di
- \texttt{oldpath} o più in generale si è cercato di creare una directory
- come sottodirectory di se stessa.
- \item \texttt{EMLINK} \texttt{oldpath} ha già il massimo numero di link
- consentiti o è una directory e la directory che contiene \texttt{newpath}
- ha già il massimo numero di link.
- \item \texttt{ENOTDIR} Uno dei componenti dei pathname non è una directory
- o\texttt{oldpath} è una directory e \texttt{newpath} esiste e non è una
- directory.
- \item \texttt{EFAULT} o \texttt{oldpath} o \texttt{newpath} è fuori dello
- spazio di indirizzi del processo.
- \item \texttt{EACCESS} Non c'è il permesso di scrittura per la directory in
- cui si vuole creare il nuovo link o una delle directory del pathname non
- consente la ricerca (permesso di esecuzione).
- \item \texttt{EPERM} le directory contenenti \texttt{oldpath} o
- \texttt{newpath} hanno lo sticky bit attivo e i permessi del processo non
- consentono rispettivamente la cancellazione e la creazione del file, o il
- filesystem non supporta i link.
- \item \texttt{ENAMETOOLONG} uno dei pathname è troppo lungo.
- \item \texttt{ENOENT} Uno dei componenti del pathname non esiste o è un link
- simbolico spezzato.
- \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
- completare l'operazione.
- \item \texttt{EROFS} I file sono su un filesystem montato in sola lettura.
- \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione del
- pathname.
- \item \texttt{ENOSPC} Il device di destinazione non ha più spazio per la
- nuova voce.
- \end{errlist}
-\end{prototype}
-
-\subsection{I link simbolici}
-\label{sec:fileintr_symlink}
-
-Siccome la funzione \texttt{link} crea riferimenti agli inodes, essa può
-funzionare soltanto per file che risiedono sullo stesso filesystem, dato che
-in questo caso è garantita l'unicità dell'inode, e solo per un filesystem di
-tipo unix. Inoltre in Linux non è consentito eseguire un link diretto ad una
-directory.
+\subsection{Il filesystem \texttt{ext2}}
+\label{sec:fileintro_ext2}
+
+Il filesystem standard usato da Linux è il cosidetto \textit{second extended
+ filesystem}, identificato dalla sigla \texttt{ext2}. Esso supporta tutte le
+caratteristiche di un filesystem standard unix, è in grado di gestire
+filenames lunghi (256 caratteri, estendibili a 1012), una dimensione fino a
+4~Tb.
+
+Oltre alle caratteristiche standard ext2 fornisce alcune estensioni che non
+sono presenti sugli altri filesystem unix. Caratteristiche particolari di ext2
+sono le seguenti''
+
+\begin{itemize}
+\item i \textit{file attributes} consentono di modificare il comportamento del
+ kernel quando agisce su gruppi di file. Possono essere settati su file e
+ directory e in quest'ultimo caso i nuovi file creati nella directory
+ ereditano i suoi attributi.
+\item sono supportate entrambe le semantiche di BSD e SysV come opzioni di
+ montaggio. La semantica BSD comporta che i file in una directory sono creati
+ con lo stesso identificatore di gruppo della directory che li contiene. La
+ semantica SysV comporta che i file vengono creati con l'identificatore del
+ gruppo primario del processo, eccetto il caso in cui la directory ha il bit
+ di setgid settata (per una descrizione dettagliata del sigificato di questi
+ termini si veda \secref{sec:filedir_access_control}), nel qual caso file e
+ sottodirectory ereditano sia il group id che il setgid.
+\item l'amministratore può scegliere la dimensione dei blocchi del filesystem
+ in fase di creazione, a seconda delle sue esigenze (blocchi più grandi
+ peremttono un accesso più veloce, ma sprecano più spazio disco).
+\item il filesystem implementa link simbolici veloci, in cui il nome del file
+ non è salvato su un blocco, ma tenuto all'interno dell'inode (evitando
+ letture multiple e spreco di spazio), non tutti i nomi però possono essere
+ gestiti così per limiti di spazio (il limite è 60 caratteri).
+\item vengono supportati i file immutabili (che possono solo essere letti) per
+ la protezione di file di configurazione sensibili, o file
+ \textit{append-only} che possono essere aperti in scrittura solo per
+ aggiungere dati (caratteristica utilizzabile per la protezione dei file di
+ log).
+\end{itemize}
+
+La struttura di ext2 è stata ispirata a quella del filesystem di BSD, un
+filesystem è composto da un insieme di blocchi, la struttura generale è
+riportata in \nfig; su ciascun gruppo di blocchi contiene una copia delle
+informazioni essenziali del filesystem (superblock e descrittore del
+filesystem) per una maggiore affidabilità e possibilità di recupero in caso di
+corruzione del superblock principale.
-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 simbolici sono le seguenti, esse sono tutte
-dichiarate nell'header file \texttt{unistd.h}.
-
-\begin{prototype}{unistd.h}
-{int symlink(const char * oldname, const char * newname)}
- Crea un nuovo link simbolico 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
- \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
- \begin{errlist}
- \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
- già.
- \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
- su un filesystem montato readonly.
- \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il
- link è piena e non c'è ulteriore spazio disponibile.
- \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
- \texttt{oldname} o di \texttt{newname}.
- \end{errlist}
-\end{prototype}
-
-Dato che la funzione \texttt{open} segue i link simbolici, è necessaria usare
-un'altra funzione quando si vuole leggere il contenuto di un link simbolico,
-questa funzione è la:
-
-\begin{prototype}{unistd.h}
-{int readlink(const char * path, char * buff, size\_t size)}
- Legge il contenuto del link simbolico indicato da \texttt{path} nel buffer
- \texttt{buff} di dimensione \texttt{size}. Non chiude la stringa con un
- carattere nullo e la tronca a \texttt{size} nel caso il buffer sia troppo
- piccolo per contenerla.
+\begin{figure}[htb]
+ \centering
- La funzione restituisce il numero di caratteri letti dentro \texttt{buff} o
- -1 per un errore, in caso di errore. La variabile \texttt{errno} viene
- settata secondo i codici di errore:
- \begin{errlist}
- \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
- già.
- \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
- su un filesystem montato readonly.
- \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il
- link è piena e non c'è ulteriore spazio disponibile.
- \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
- \texttt{oldname} o di \texttt{newname}.
- \end{errlist}
-\end{prototype}
+ \caption{Organizzazione logica del \textit{second extented filesystem}.}
+ \label{fig:fileintr_ext2_struct}
+\end{figure}
+
+L'utilizzo di raggrupamenti di blocchi ha inoltre degli effetti positivi nelle
+performance dato che viene ridotta la distanza fra i dati e la tabella degli
+inodes.
+
+Le directory sono implementate come una linked list di entrate di dimensione
+variabile. Ciascuna entry contiene il numero di inode, la sua lunghezza, il
+nome del file e la sua lunghezza.
+
+
+
+