\chapter{Files e directories}
\label{cha:files_and_dirs}

In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
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 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_infos}

Come spiegato in \secref{sec:fileintr_filesystem} tutte le informazioni
generali relative alle caratteristiche di ciascun file sono mantenute
nell'inode. Vedremo in questa sezione come sia possibile accedervi usando la
funzione \texttt{stat} ed esamineremo alcune funzioni utilizzabili per
manipolare una parte di questa informazione. Tutto quello che invece riguarda
il meccanismo di controllo di accesso ad i file e le relative funzioni di
manipolazione sarà invece esaminanto in \secref{sec:filedir_access_control}.


\subsection{Le funzioni \texttt{stat}, \texttt{fstat} e \texttt{lstat}}
\label{sec:filedir_stat}

La lettura delle informazioni relative ai file è fatta attraverso la famiglia
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}.
  
  \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.
  \item \texttt{EMLOOP} Ci sono troppi link simbolici nel pathname.
  \item \texttt{EFAULT} I puntatori usati sono fuori dallo spazio di indirizzi
    del processo.
  \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
    completare l'operazione. 
  \item \texttt{ENAMETOOLONG} Il filename è troppo lungo.
  \end{errlist}
\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
in \nfig, così come riportata dalla man page (in realtà la definizione
effettivamente usata nel kernel dipende dall'archietettura e ha altri campi
riservati per estensioni come tempo più precisi, o per il padding dei campi).

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{15cm}
    \begin{lstlisting}[]{}
struct stat {
    dev_t         st_dev;      /* device */
    ino_t         st_ino;      /* inode */
    mode_t        st_mode;     /* protection */
    nlink_t       st_nlink;    /* number of hard links */
    uid_t         st_uid;      /* user ID of owner */
    gid_t         st_gid;      /* group ID of owner */
    dev_t         st_rdev;     /* device type (if inode device) */
    off_t         st_size;     /* total size, in bytes */
    unsigned long st_blksize;  /* blocksize for filesystem I/O */
    unsigned long st_blocks;   /* number of blocks allocated */
    time_t        st_atime;    /* time of last access */
    time_t        st_mtime;    /* time of last modification */
    time_t        st_ctime;    /* time of last change */
};
    \end{lstlisting}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \texttt{stat} per la lettura delle informazioni dei 
    file}
  \label{fig:filedir_stat_struct}
\end{figure}

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}). 


\subsection{I tipi di file}
\label{sec:filedir_file_types}

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 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}

\subsection{La funzione \texttt{utime}}
\label{sec:filedir_utime}




\section{Il controllo di accesso ai file}
\label{sec:filedir_access_control}


In unix è implementata da qualunque filesystem standard una forma elementare
(ma adatta alla maggior parte delle esigenze) di controllo di accesso ai
files. Torneremo sull'argomento in dettaglio più avanti (vedi
\secref{sec:filedir_access_control}), qui ci limitiamo ad una introduzione dei
concetti essenziali.

Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo Unix,
e non è detto che sia applicabile (ed infatti non è vero per il filesystem di
Windows) a un filesystem qualunque. Esistono inoltre estensioni che permettono
di implementare le ACL (\textit{Access Control List}) che sono un meccanismo
di controllo di accesso molto più sofisticato.

Ad ogni file Unix associa sempre l'utente che ne è proprietario (il cosiddetto
\textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli uid e
gid accennato in \secref{sec:intro_multiuser}, e un insieme di permessi che
sono divisi in tre classi, e cioè attribuiti rispettivamente al proprietario,
a qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti
gli altri utenti.

I permessi sono espressi da un insieme di 12 bit: di questi i nove meno
significativi sono usati a gruppi di tre per indicare i permessi base di
lettura, scrittura ed esecuzione (indicati rispettivamente con le lettere
\textit{w}, \textit{r} \textit{x}) applicabili rispettivamente al
proprietario, al gruppo, a tutti (una descrizione più dettagliata dei vari
permessi associati ai file è riportata in \secref{sec:filedir_suid_sgid}).  I
restanti tre bit sono usati per indicare alcune caratteristiche più complesse
(\textit{suid}, \textit{sgid}, e \textit{sticky}) su cui pure torneremo in
seguito (vedi \secref{sec:filedir_suid_sgid} e \secref{sec:filedir_sticky}).

Tutte queste informazioni sono tenute per ciascun file nell'inode. Quando un
processo cerca l'accesso al file esso controlla i propri uid e gid
confrontandoli con quelli del file e se l'operazione richiesta è compatibile
con i permessi associati al file essa viene eseguita, altrimenti viene
bloccata ed è restituito un errore di \texttt{EPERM}. Questo procedimento non
viene eseguito per l'amministratore di sistema (il cui uid è zero) il quale ha
pertanto accesso senza restrizione a qualunque file del sistema.

% In realtà il procedimento è più complesso di quanto descritto in maniera
% elementare qui; inoltre ad un processo sono associati diversi identificatori,
% torneremo su questo in maggiori dettagli in seguito in \secref{sec:proc_perms}.



\subsection{I flag \texttt{suid} e \texttt{sgid}}
\label{sec:filedir_suid_sgid}

\subsection{La titolarità di nuovi files e directory}
\label{sec:filedir_ownership}

\subsection{La funzione \texttt{access}}
\label{sec:filedir_access}

\subsection{La funzione \texttt{umask}}
\label{sec:filedir_umask}

\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
\label{sec:filedir_chmod}

\subsection{Il flag \texttt{sticky}}
\label{sec:filedir_sticky}

\subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
\label{sec:filedir_chown}




%La struttura fondamentale che contiene i dati essenziali relativi ai file è il
%cosiddetto \textit{inode}; questo conterrà informazioni come il
%tipo di file (file di dispositivo, directory, file di dati, per un elenco
%completo vedi \ntab), i permessi (vedi \secref{sec:file_perms}), le date (vedi
%\secref{sec:file_times}).

