Ristrutturati capitoli sui file
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 30 Jun 2001 14:44:39 +0000 (14:44 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 30 Jun 2001 14:44:39 +0000 (14:44 +0000)
filedir.tex
fileintro.tex
fileunix.tex
intro.tex
macro.tex
prochand.tex

index cf928fc21cc347155c99d76b14f332075def4910..daf947a8ced46053c5df9ae3c25effc427526c86 100644 (file)
 \chapter{Files e directories}
 \label{cha:files_and_dirs}
 
 \chapter{Files e directories}
 \label{cha:files_and_dirs}
 
-In questo capitolo tratteremo in dettaglio le varie caratteristiche di files e
-directories, ed in particolare approfondiremo i dettagli su come è organizzata
-la struttura dei files in un sistema unix, esamineremo come è strutturato il
+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 dei contenuti è
 lasciato ai capitoli successivi.
 
 
 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.
 
 
-\section{L'organizzazione di files e directories}
-\label{sec:filedir_org}
-
-L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
-medesimi nell'albero descritto brevemente in \secref{sec:fileintr_overview};
-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.
-
-I manuale delle librerie del C chiama i nomi contenuti nelle directory
-\textsl{componenti} (in inglese \textit{file name components}), noi li
-chiameremo più semplicemente nomi. Un file può essere indicato rispetto alla
-directory corrente semplicemente specificando il nome da essa contenuto. Una
-directory contiene semplicemente un elenco di questi nomi, che possono
-corrispondere a un qualunque oggetto del filesystem, compresa un'altra
-directory; l'albero viene appunto creato inserendo directory in altre
-directory.
-
-Il nome completo di file generico è composto da una serie di questi
-\textsl{componenti} separati da una \texttt{/} (in Linux più \texttt{/}
-consecutive sono considerate equivalenti ad una sola). Il nome completo di un
-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
-che è senz'altro più chiaro dell'alternativa proposta.
-
-Il processo con cui si associa ad un pathname uno specifico file è chiamato
-risoluzione del nome (\textit{file name resolution} o \textit{pathname
-  resolution}).  La risoluzione viene fatta esaminando il pathname da destra a
-sinistra e localizzando ogni nome nella directory indicata dal nome
-precedente: ovviamente perché il procedimento funzioni occorre che i nomi
-indicati come directory esistano e siano effettivamente directory, inoltre i
-permessi devono consentire l'accesso.
-
-Se il pathname comincia per \texttt{/} la ricerca parte dalla directory radice
-del processo; questa, a meno di un \textit{chroot} (su cui torneremo in
-seguito, vedi \secref{sec:xxx_chroot}) è la stessa per tutti i processi ed
-equivale alla directory radice dell'albero (come descritto in
-\secref{sec:fileintr_overview}): in questo caso si parla di un pathname
-\textsl{assoluto}. Altrimenti la ricerca parte dalla directory corrente (su
-cui torneremo più avanti in \secref{sec:filedir_work_dir}) ed il pathname è
-detto \textsl{relativo}.
-
-I nomi \texttt{.} e \texttt{..} hanno un significato speciale e vengono
-inseriti in ogni directory, il primo fa riferimento alla directory corrente e
-il secondo alla directory \textsl{genitore} (\textit{parent directory}) cioè
-la directory che contiene il riferimento alla directory corrente; nel caso
-questa sia la directory radice allora il riferimento è a se stessa.
-
-
-\section{L'architettura della gestione dei file}
-\label{sec:filedir_file_handling}
-
-Per capire fino in fondo le proprietà di files e directories in un sistema
-unix ed il funzionamento delle relative funzioni di manipolazione occorre una
-breve introduzione sulla gestione dei medesimo e sugli oggetti su cui è basato
-un filesystem unix; in particolare si riprenderà, approfondendolo sul piano
-dell'uso nelle funzioni di libreria, il concetto di \textit{inode} di cui
-abbiamo brevemente accennato le caratteristiche (dal lato dell'implementazione
-nel kernel) in \secref{sec:fileintr_vfs}.
-
-
-\subsection{Il funzionamento di un filesystem unix}
-\label{sec:filedir_filesystem}
-
-Come già accennato in \secref{sec:fileintr_overview} Linux (ed ogni unix in
-generale) organizza i dati che tiene su disco attraverso l'uso di un
-filesystem. Una delle caratteristiche di Linux rispetto agli altri unix è
-quella di poter supportare grazie al VFS una enorme quantità di filesystem
-diversi, ognuno dei quali ha una sua particolare struttura e funzionalità
-proprie; per questo non entreremo nei dettagli di un filesystem specifico, ma
-daremo una descrizione a grandi linee che si adatta alle caratteristiche
-comuni di un qualunque filesystem standard unix.
-
-Dato un disco lo spazio fisico viene usualmente diviso in partizioni; ogni
-partizione può contenere un filesystem; quest'ultimo è in genere strutturato
-secondo \nfig, con una lista di inodes all'inizio e il resto dello spazio a
-disposizione per i dati e le directory.
-
-\begin{figure}[htb]
-  \centering
-  
-  \caption{Organizzazione dello spazio su un disco in partizioni e filesystem}
-  \label{fig:filedir_disk_filesys}
-\end{figure}
-
-Se si va ad esaminare come è strutturata l'informazione all'interno di un
-singolo filesystem (tralasciando le parti connesse alla strutturazione e al
-funzionamento del filesystem stesso come il super-block) avremo una situazione
-del tipo di quella esposta in \nfig.
-\begin{figure}[htb]
-  \centering
-  
-  \caption{Organizzazione di un filesystem}
-  \label{fig:filedir_filesys_detail}
-\end{figure}
-da questa figura si evidenziano alcune caratteristiche su cui è bene porre
-attenzione in quanto sono fondamentali per capire il funzionamento delle
-funzioni che manipolano i file e le directory su cui torneremo fra poco; in
-particolare è opportuno ricordare sempre che:
-
-\begin{enumerate}
-  
-\item L'\textit{inode} contiene tutte le informazioni riguardanti il file: il
-  tipo di file, i permessi di accesso, le dimensioni, i puntatori ai blocchi
-  fisici che contengono i dati e così via; le informazioni che la funzione
-  \texttt{stat} fornisce provengono dall'\textit{inode}; dentro una directory
-  si troverà solo il nome del file e il numero dell'\textit{inode} ad esso
-  associato, cioè quella che da qui in poi chiameremo una \textsl{voce}
-  (traduzione approssimata dell'inglese \textit{directory entry}, che non
-  useremo anche per evitare confusione con le \textit{dentries} del kernel di
-  cui si parlava in \secref{sec:fileintr_vfs}).
-  
-\item Come mostrato in \curfig si possono avere più voci che puntano allo
-  stesso \textit{inode}. Ogni \textit{inode} ha un contatore che contiene il
-  numero di riferimenti (\textit{link count}) che sono stati fatti ad esso;
-  solo quando questo contatore si annulla i dati del file vengono
-  effettivamente rimossi dal disco. Per questo la funzione per cancellare un
-  file si chiama \texttt{unlink}, ed in realtà non cancella affatto i dati del
-  file, ma si limita a eliminare la relativa voce da una directory e
-  decrementare il numero di riferimenti nell'\textit{inode}.
-  
-\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
-  nello stesso filesystem e non ci può essere una directory che contiene
-  riferimenti ad \textit{inodes} relativi ad altri filesystem. Questo limita
-  l'uso del comando \texttt{ln} (che crea una nuova voce per un file
-  esistente, con la funzione \texttt{link}) al filesystem corrente.
-  
-\item Quando si cambia nome ad un file senza cambiare filesystem il contenuto
-  del file non deve essere spostato, viene semplicemente creata una nuova voce
-  per l'\textit{inode} in questione e rimossa la vecchia (questa è la modalità
-  in cui opera normalmente il comando \texttt{mv} attraverso la funzione
-  \texttt{rename}).
-
-\end{enumerate}
-
-Infine è bene avere presente che essendo file pure loro, esiste un numero di
-riferimenti anche per le directories; per cui se ad esempio a partire dalla
-situazione mostrata in \curfig\ creiamo una nuova directory \texttt{textdir}
-nella directory corrente avremo una situazione come quella in \nfig, dove per
-chiarezza abbiamo aggiunto dei numeri di inode.
-
-La nuova directory avrà allora un numero di riferimenti pari a due, in quanto
-è referenziata dalla directory da cui si era partiti (in cui è inserita la
-nuova voce che fa riferimento a \texttt{textdir}) e dalla voce \texttt{.}
-che è sempre inserita in ogni directory; questo vale sempre per ogni directory
-che non contenga a sua volta altre directories. Al contempo la directory da
-cui si era partiti avrà un numero di riferiementi di almeno tre, in quanto
-adesso sarà referenziata anche dalla voce \texttt{..} di \texttt{textdir}.
-
-
-\subsection{Le funzioni \texttt{link} e \texttt{unlink}}
-\label{sec:filedir_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:filedir_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:filedir_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:filedir_cre_canc}
-
-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:filedir_sym_link}
-
-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 caratteristiche dei files}
 \label{sec:filedir_infos}
 
 \section{La manipolazione delle caratteristiche dei files}
 \label{sec:filedir_infos}
 
@@ -501,9 +51,11 @@ in \nfig, cos
 effettivamente usata nel kernel dipende dall'archietettura e ha altri campi
 riservati per estensioni come tempo più precisi, o per il padding dei campi).
 
 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}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \footnotesize
-  \begin{lstlisting}{}
+  \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[]{}
 struct stat {
     dev_t         st_dev;      /* device */
     ino_t         st_ino;      /* inode */
 struct stat {
     dev_t         st_dev;      /* device */
     ino_t         st_ino;      /* inode */
@@ -519,7 +71,9 @@ struct stat {
     time_t        st_mtime;    /* time of last modification */
     time_t        st_ctime;    /* time of last change */
 };
     time_t        st_mtime;    /* time of last modification */
     time_t        st_ctime;    /* time of last change */
 };
-  \end{lstlisting}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
   \caption{La struttura \texttt{stat} per la lettura delle informazioni dei 
     file}
   \label{fig:sock_sa_gen_struct}
   \caption{La struttura \texttt{stat} per la lettura delle informazioni dei 
     file}
   \label{fig:sock_sa_gen_struct}
@@ -531,6 +85,7 @@ del sistema (di quelli definiti in \tabref{tab:xxx_sys_types}, e dichiarati in
 
 
 
 
 
 
+
 \subsection{I tipi di file}
 \label{sec:filedir_file_types}
 
 \subsection{I tipi di file}
 \label{sec:filedir_file_types}
 
@@ -556,6 +111,49 @@ dato che il valore numerico pu
 \label{sec:filedir_access_control}
 
 
 \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{I flag \texttt{suid} e \texttt{sgid}}
 \label{sec:filedir_suid_sgid}
 
index c03e36032d1b25e5e39a42c322eb9b982a0cf4e2..4f5282680fa349d7f88ecc1aa43656036e5eb740 100644 (file)
@@ -1,11 +1,10 @@
-\chapter{I files: introduzione}
+\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
 \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
-astratta che tratta le periferiche allo stesso modo degli usuali file di
-dati.
+astratta che tratta le periferiche allo stesso modo degli usuali file di dati.
 
 Questo significa che si può accedere cioè a qualunque periferica del computer,
 dalla seriale, alla parallela, alla console, e agli stessi dischi attraverso i
 
 Questo significa che si può accedere cioè a qualunque periferica del computer,
 dalla seriale, alla parallela, alla console, e agli stessi dischi attraverso i
@@ -14,32 +13,37 @@ speciali agendo sui quali i programmi possono leggere, scrivere e compiere
 operazioni direttamente sulle periferiche, usando le stesse funzioni che si
 usano per i normali file di dati.
 
 operazioni direttamente sulle periferiche, usando le stesse funzioni che si
 usano per i normali file di dati.
 
-In questo capitolo forniremo un'introduzione alle principali caratteristiche
-di questa interfaccia, su come essa viene implementata in Linux e su come sono
-organizzati i file nel sistema.
+In questo capitolo forniremo un'introduzione all'architettura della gestione
+dei file, sia nelle sue caratteristiche generiche comuni a tutti gli unix, che
+nelle particolarità che ha la specifica implementazione usata da Linux. Al
+comtempo tratteremo l'organizzazione dei file in un sistema unix-like, e le
+varie caratteristiche distintive.
 
 
 
 
-\section{I file in un sistema unix-like}
-\label{sec:fileintr_overview}
+
+\section{L'organizzazione di files e directories}
+\label{sec:filedir_org}
 
 Visto il ruolo fondamentale che i files vengono ad assumere in un sistema
 
 Visto il ruolo fondamentale che i files vengono ad assumere in un sistema
-unix, è anzitutto opportuno fornire un'introduzione dettagliata su come essi
-vengono trattati dal sistema. In particolare occorre tenere presente dov'è che
-si situa il limite fondamentale fra kernel space e user space che tracciavamo
-al \capref{cha:intro_unix}.
+unix-like, è anzitutto opportuno fornire un'introduzione dettagliata su come
+essi vengono organizzati all'interno del  sistema.
+
+
+\subsection{Una breve introduzione}
+\label{sec:fileintr_org_intro}
 
 Partiamo allora da come viene strutturata nel sistema la disposizione dei
 file: per potervi accedere il kernel usa una apposita interfaccia che permetta
 di strutturare l'informazione tenuta sullo spazio grezzo disponibile sui
 
 Partiamo allora da come viene strutturata nel sistema la disposizione dei
 file: per potervi accedere il kernel usa una apposita interfaccia che permetta
 di strutturare l'informazione tenuta sullo spazio grezzo disponibile sui
-dischi, cioè quello che si chiama un \textit{filesystem} (useremo per brevità
-questo nome al posto della più prolissa traduzione italiana sistema di file). 
+dischi, cioè quello che si chiama un \textit{filesystem}\footnote{useremo per
+  brevità questo nome al posto della più prolissa traduzione italiana sistema
+  di file}, che descriviremo in dettaglio in \secref{sec:fileintr_vfs}.
 
 Sarà attraverso quest'ultimo che il kernel andrà a gestire l'accesso ai dati
 memorizzati all'interno del disco stesso, strutturando l'informazione in files
 
 Sarà attraverso quest'ultimo che il kernel andrà a gestire l'accesso ai dati
 memorizzati all'interno del disco stesso, strutturando l'informazione in files
-e directory (su questo aspetto torneremo con maggiori dettagli in
-\secref{sec:filedir_filesystem}).  Per poter accedere ai file contenuti in un
-disco occorrerà perciò attivare il filesystem, questo viene fatto
-\textsl{montando} il disco (o la partizione del disco).
+e directory.  Per poter accedere ai file contenuti in un disco occorrerà
+perciò attivare il filesystem, questo viene fatto \textsl{montando} il disco
+(o la partizione del disco).
 
 %In generale un filesystem piazzerà opportunamente sul disco dei blocchi di
 %informazioni riservate che tengono conto degli inodes allocati, di quelli
 
 %In generale un filesystem piazzerà opportunamente sul disco dei blocchi di
 %informazioni riservate che tengono conto degli inodes allocati, di quelli
@@ -66,179 +70,76 @@ oggetti visti attraverso l'interfaccia che manipola i files come le FIFO, i
 link, i socket e gli stessi i file di dispositivo (questi ultimi, per
 convenzione, sono inseriti nella directory \texttt{/dev}).
 
 link, i socket e gli stessi i file di dispositivo (questi ultimi, per
 convenzione, sono inseriti nella directory \texttt{/dev}).
 
-\subsection{Il \textit{virtual filesystem} di Linux}
-\label{sec:fileintr_vfs}
 
 
-Esamineremo adesso come viene implementato l'accesso ai files in Linux. Questa
-sezione riporta informazioni sui dettagli di come il kernel gestisce i files.
-L'argomento è abbastanza ``esoterico'' e questa sezione può essere saltata ad
-una prima lettura; è bene però tenere presente che vengono introdotti qui
-alcuni termini che potranno comparire in seguito, come \textit{inode},
-\textit{dentry}, \textit{dcache}.
+\subsection{La struttura di file e directories}
+\label{sec:fileintr_filedir_struct}
+
+L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
+medesimi nell'albero descritto brevemente in \secref{sec:fileintr_org_intro};
+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.
+
+I manuale delle glibc chiama i nomi contenuti nelle directory
+\textsl{componenti} (in inglese \textit{file name components}), noi li
+chiameremo più semplicemente nomi. Un file può essere indicato rispetto alla
+directory corrente semplicemente specificando il nome da essa contenuto. Una
+directory contiene semplicemente un elenco di questi nomi, che possono
+corrispondere a un qualunque oggetto del filesystem, compresa un'altra
+directory; l'albero viene appunto creato inserendo directory in altre
+directory.
+
+Il nome completo di file generico è composto da una serie di questi
+\textsl{componenti} separati da una \texttt{/} (in Linux più \texttt{/}
+consecutive sono considerate equivalenti ad una sola). Il nome completo di un
+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
+che è senz'altro più chiaro dell'alternativa proposta.
+
+Il processo con cui si associa ad un pathname uno specifico file è chiamato
+risoluzione del nome (\textit{file name resolution} o \textit{pathname
+  resolution}).  La risoluzione viene fatta esaminando il pathname da destra a
+sinistra e localizzando ogni nome nella directory indicata dal nome
+precedente: ovviamente perché il procedimento funzioni occorre che i nomi
+indicati come directory esistano e siano effettivamente directory, inoltre i
+permessi devono consentire l'accesso.
+
+Se il pathname comincia per \texttt{/} la ricerca parte dalla directory radice
+del processo; questa, a meno di un \textit{chroot} (su cui torneremo in
+seguito, vedi \secref{sec:xxx_chroot}) è la stessa per tutti i processi ed
+equivale alla directory radice dell'albero (come descritto in
+\secref{sec:fileintr_overview}): in questo caso si parla di un pathname
+\textsl{assoluto}. Altrimenti la ricerca parte dalla directory corrente (su
+cui torneremo più avanti in \secref{sec:filedir_work_dir}) ed il pathname è
+detto \textsl{relativo}.
+
+I nomi \texttt{.} e \texttt{..} hanno un significato speciale e vengono
+inseriti in ogni directory, il primo fa riferimento alla directory corrente e
+il secondo alla directory \textsl{genitore} (\textit{parent directory}) cioè
+la directory che contiene il riferimento alla directory corrente; nel caso
+questa sia la directory radice allora il riferimento è a se stessa.
+
+
+% \subsection{Il controllo di accesso}
+% \label{sec:fileintr_access_ctrl}
 
 
-In Linux il concetto di \textit{everything is a file} è stato implementato
-attraverso il \textit{virtual filesystem} (da qui in avanti VFS) che è
-l'interfaccia che il kernel rende disponibile ai programmi in user space
-attraverso la quale vengono manipolati i files; esso provvede un livello di
-indirezione che permette di collegare le operazioni di manipolazione sui files
-alle operazioni di I/O e gestisce l'organizzazione di questi ultimi nei vari
-modi in cui diversi filesystem la effettuano, permettendo la coesistenza
-di filesystem differenti all'interno dello stesso albero delle directory
-
-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
-opportune routine del filesystem specifico a cui si fa riferimento, saranno
-queste a chiamare le funzioni di piu basso livello che eseguono le operazioni
-di I/O sul dispositivo fisico, secondo lo schema riportato in \nfig.
-
-\begin{figure}[htb]
-  \centering
-  
-  \caption{Schema delle operazioni del VFS}
-  \label{fig:fileintro_VFS_scheme}
-\end{figure}
-
-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.
-
-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
-oggetto del VFS sia esso un file ordinario, una directory, una FIFO, un file
-di dispositivo, o una qualsiasi altra cosa che possa essere rappresentata dal
-VFS (sui tipi di ``files'' possibili torneremo in seguito). A ciascuno di essi
-è associata pure una struttura che sta in memoria, e che oltre alle
-informazioni sullo specifico file contiene pure il riferimento alle funzioni
-(i \textsl{metodi}) da usare per poterlo manipolare.
-
-Le dentries ``vivono'' in memoria e non vengono mai salvate su disco, vengono
-usate per motivi di velocità, gli inodes invece stanno su disco e vengono
-copiati in memoria quando serve, ed ogni cambiamento viene copiato
-all'indietro sul disco, gli inodes che stanno in memoria sono inodes del VFS
-ed è ad essi che puntano le singole dentry.
-
-La dcache costituisce perciò una sorta di vista completa di tutto l'albero dei
-files, ovviamente per non riempire tutta la memoria questa vista è parziale
-(la dcache cioè contiene solo le dentry per i file per i quali è stato
-richiesto l'accesso), quando si vuole risolvere un nuovo pathname il VFS deve
-creare una nuova dentry e caricare l'inode corrispondente in memoria. 
-
-Questo procedimento viene eseguito dal metodo \texttt{lookup()} dell'inode
-della directory che contiene il file; questo viene installato nelle relative
-strutture in memoria quando si effettua il montaggio lo specifico filesystem
-su cui l'inode va a vivere.
-
-Una volta che il VFS ha a disposizione la dentry (ed il relativo inode)
-diventa possibile accedere alle varie operazioni sul file come la
-\texttt{open} per aprire il file o la \texttt{stat} per leggere i dati
-dell'inode e passarli in user space.
-
-L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
-una struttura di tipo \texttt{file} in cui viene inserito un puntatore alla
-dentry e una struttura \verb|f_ops| che contiene i puntatori ai metodi che
-implementano le operazioni disponibili sul file. In questo modo i processi in
-user space possono accedere alle operazioni attraverso detti metodi, che
-saranno diversi a seconda del tipo di file (o dispositivo) aperto (su questo
-torneremo in dettaglio in \secref{sec:fileunix_fd}). Un elenco delle operazioni
-previste dal kernel è riportato in \ntab.
-
-\begin{table}[htb]
-  \centering
-  \begin{tabular}[c]{c p{7cm}}
-    \textbf{funzione} & \textbf{operazione} \\
-    \hline
-    \textit{open}    & apre il file \\
-    \textit{read}    & legge dal file \\
-    \textit{write}   & scrive sul file \\ 
-    \textit{llseek}  & sposta la posizione corrente sul file \\
-    \textit{ioctl}   & accede alle operazioni di controllo 
-                       (tramite la \texttt{ioctl})\\
-    \textit{readdir} & per leggere il contenuto di una directory \\
-    \textit{poll}    & \\
-    \textit{mmap}    & chiamata dalla system call \texttt{mmap}. 
-                       mappa il file in memoria\\
-    \textit{release} & chiamata quando l'ultima referenza a un file 
-                       aperto è chiusa\\
-    \textit{fsync}   & chiamata dalla system call \texttt{fsync} \\
-    \textit{fasync}  & chiamate da \texttt{fcntl} quando è abilitato 
-                       il modo asincrono per l'I/O su file. \\
-    \hline
-  \end{tabular}
-  \caption{Operazioni sui file definite nel VFS.}
-  \label{tab:fileintr_file_operations}
-\end{table}
-
-In questo modo per ciascun file diventano utilizzabili una serie di operazioni
-(non è dette che tutte siano disponibili), che costituiscono l'interfaccia
-astratta del VFS, e qualora se ne voglia eseguire una il kernel andrà ad
-utilizzare la opportuna routine dichiarata in \verb|f_ops| appropriata al tipo
-di file in questione. 
-
-Così sarà possibile scrivere sulla porta seriale come su un file di dati
-normale; ovviamente certe operazioni (nel caso della seriale ad esempio la
-\textit{seek}) non saranno disponibili, però con questo sistema l'utilizzo di
-diversi filesystem (come quelli usati da Windows o MacOs) è immediato e
-(relativamente) trasparente per l'utente ed il programmatore.
-
-\subsection{Il controllo di accesso}
-\label{sec:fileintr_access_ctrl}
-
-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_usergroup}, 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 tipi di files}
 \label{sec:fileintr_file_types}
 
 
 \subsection{I tipi di files}
 \label{sec:fileintr_file_types}
 
-Come detto in precedenza esistono vari tipi di oggetti implementati del VFS
-per i quali è disponibile l'interfaccia astratta da esso provveduta. Un elenco
-dei vari tipi di file definiti nel VFS è il seguente:
+Come detto in precedenza in unix esistono vari tipi di file, in Linux questi
+sono implementati come oggetti del \textit{Virtual File System} e sono
+presenti in tutti i filesystem unix-like utilizzabili con Linux. L'elenco dei
+vari tipi di file definiti dal Virtual File System è il seguente:
  
 \begin{table}[htb]
   \begin{center}
     \begin{tabular}[c]{l l p{7cm}}
  
 \begin{table}[htb]
   \begin{center}
     \begin{tabular}[c]{l l p{7cm}}
-    \multicolumn{2}{c}{\textbf{Nome}} & \textbf{Descrizione} \\
+    \multicolumn{2}{c}{\textbf{Tipo di file}} & \textbf{Descrizione} \\
     \hline
       \textit{regular file} & \textsl{file normale} &
       un file che contiene dei dati (l'accezione normale di file) \\
     \hline
       \textit{regular file} & \textsl{file normale} &
       un file che contiene dei dati (l'accezione normale di file) \\
@@ -263,11 +164,13 @@ dei vari tipi di file definiti nel VFS 
   \end{center}
 \end{table}
 
   \end{center}
 \end{table}
 
-Tutto ciò non ha ovviamente nulla a che fare con la classificazione sui tipi
-di file (in questo caso file di dati) in base al loro contenuto, o tipo di
-accesso.  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
+Si tenga ben presente che tutto ciò non ha nulla a che fare con la
+classificazione sui tipi di file (che in questo caso sono sempre file di dati)
+in base al loro contenuto, o tipo di accesso.  
+
+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.
 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.
@@ -283,24 +186,17 @@ problemi qualora nei programmi si facciano assunzioni sul terminatore della
 riga.
 
 
 riga.
 
 
-\section{Una panoramica sull'uso dei file}
-\label{sec:fileintr_io_overview}
-
-Per poter accedere al contenuto dei file occorre anzitutto aprirlo. Questo
-crea un canale di comunicazione che permette di eseguire una serie di
-operazioni. Una volta terminate le operazioni, il file dovrà essere chiuso, e
-questo chiuderà il canale di comunicazione impedendo ogni ulteriore
-operazione.
-
 \subsection{Le due interfacce ai file}
 \label{sec:fileintr_io_api}
 
 In unix le modalità di accesso ai file e le relative interfacce di
 \subsection{Le due interfacce ai file}
 \label{sec:fileintr_io_api}
 
 In unix le modalità di accesso ai file e le relative interfacce di
-programmazione sono due, basate su due diversi meccanismi di connessione. 
+programmazione sono due, basate su due diversi meccanismi con cui è possibile
+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}).  È
 un'interfaccia specifica di unix e provvede un accesso non bufferizzato.
 
 La prima è l'interfaccia standard di unix, quella che il manuale delle glibc
 chiama interfaccia dei descrittore 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
 bufferizzato in quanto la lettura e la scrittura vengono eseguite chiamando
 direttamente le system call del kernel (in realtà il kernel effettua al suo
 L'interfaccia è primitiva ed essenziale, l'accesso viene detto non
 bufferizzato in quanto la lettura e la scrittura vengono eseguite chiamando
 direttamente le system call del kernel (in realtà il kernel effettua al suo
@@ -399,3 +295,524 @@ programmi adottano delle convenzioni per i nomi dei file, ad esempio il codice
 C normalmente si mette in file con l'estensione .c, ma questa è, appunto, solo
 una convenzione.
 
 C normalmente si mette in file con l'estensione .c, ma questa è, appunto, solo
 una convenzione.
 
+
+
+\section{L'architettura della gestione dei file}
+\label{sec:filedir_file_handling}
+
+Per capire fino in fondo le proprietà di files e directories in un sistema
+unix ed il funzionamento delle relative funzioni di manipolazione occorre una
+breve introduzione sulla gestione dei medesimo e sugli oggetti su cui è basato
+un filesystem unix; in particolare si riprenderà, approfondendolo sul piano
+dell'uso nelle funzioni di libreria, il concetto di \textit{inode} di cui
+abbiamo brevemente accennato le caratteristiche (dal lato dell'implementazione
+nel kernel) in \secref{sec:fileintr_vfs}.
+
+In particolare occorre tenere presente dov'è che si situa la divisione
+fondamentale fra kernel space e user space che tracciavamo al
+\capref{cha:intro_unix}.
+
+
+\subsection{Il \textit{virtual filesystem} di Linux}
+\label{sec:fileintr_vfs}
+
+Esamineremo adesso come viene implementato l'accesso ai files in Linux. Questa
+sezione riporta informazioni sui dettagli di come il kernel gestisce i files.
+L'argomento è abbastanza ``esoterico'' e questa sezione può essere saltata ad
+una prima lettura; è bene però tenere presente che vengono introdotti qui
+alcuni termini che potranno comparire in seguito, come \textit{inode},
+\textit{dentry}, \textit{dcache}.
+
+In Linux il concetto di \textit{everything is a file} è stato implementato
+attraverso il \textit{virtual filesystem} (da qui in avanti VFS) che è
+l'interfaccia che il kernel rende disponibile ai programmi in user space
+attraverso la quale vengono manipolati i files; esso provvede un livello di
+indirezione che permette di collegare le operazioni di manipolazione sui files
+alle operazioni di I/O e gestisce l'organizzazione di questi ultimi nei vari
+modi in cui diversi filesystem la effettuano, permettendo la coesistenza
+di filesystem differenti all'interno dello stesso albero delle directory
+
+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
+opportune routine del filesystem specifico a cui si fa riferimento, saranno
+queste a chiamare le funzioni di piu basso livello che eseguono le operazioni
+di I/O sul dispositivo fisico, secondo lo schema riportato in \nfig.
+
+\begin{figure}[htb]
+  \centering
+  
+  \caption{Schema delle operazioni del VFS}
+  \label{fig:fileintro_VFS_scheme}
+\end{figure}
+
+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.
+
+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
+oggetto del VFS sia esso un file ordinario, una directory, una FIFO, un file
+di dispositivo, o una qualsiasi altra cosa che possa essere rappresentata dal
+VFS (sui tipi di ``files'' possibili torneremo in seguito). A ciascuno di essi
+è associata pure una struttura che sta in memoria, e che oltre alle
+informazioni sullo specifico file contiene pure il riferimento alle funzioni
+(i \textsl{metodi}) da usare per poterlo manipolare.
+
+Le dentries ``vivono'' in memoria e non vengono mai salvate su disco, vengono
+usate per motivi di velocità, gli inodes invece stanno su disco e vengono
+copiati in memoria quando serve, ed ogni cambiamento viene copiato
+all'indietro sul disco, gli inodes che stanno in memoria sono inodes del VFS
+ed è ad essi che puntano le singole dentry.
+
+La dcache costituisce perciò una sorta di vista completa di tutto l'albero dei
+files, ovviamente per non riempire tutta la memoria questa vista è parziale
+(la dcache cioè contiene solo le dentry per i file per i quali è stato
+richiesto l'accesso), quando si vuole risolvere un nuovo pathname il VFS deve
+creare una nuova dentry e caricare l'inode corrispondente in memoria. 
+
+Questo procedimento viene eseguito dal metodo \texttt{lookup()} dell'inode
+della directory che contiene il file; questo viene installato nelle relative
+strutture in memoria quando si effettua il montaggio lo specifico filesystem
+su cui l'inode va a vivere.
+
+Una volta che il VFS ha a disposizione la dentry (ed il relativo inode)
+diventa possibile accedere alle varie operazioni sul file come la
+\texttt{open} per aprire il file o la \texttt{stat} per leggere i dati
+dell'inode e passarli in user space.
+
+L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
+una struttura di tipo \texttt{file} in cui viene inserito un puntatore alla
+dentry e una struttura \verb|f_ops| che contiene i puntatori ai metodi che
+implementano le operazioni disponibili sul file. In questo modo i processi in
+user space possono accedere alle operazioni attraverso detti metodi, che
+saranno diversi a seconda del tipo di file (o dispositivo) aperto (su questo
+torneremo in dettaglio in \secref{sec:fileunix_fd}). Un elenco delle operazioni
+previste dal kernel è riportato in \ntab.
+
+\begin{table}[htb]
+  \centering
+  \begin{tabular}[c]{c p{7cm}}
+    \textbf{funzione} & \textbf{operazione} \\
+    \hline
+    \textit{open}    & apre il file \\
+    \textit{read}    & legge dal file \\
+    \textit{write}   & scrive sul file \\ 
+    \textit{llseek}  & sposta la posizione corrente sul file \\
+    \textit{ioctl}   & accede alle operazioni di controllo 
+                       (tramite la \texttt{ioctl})\\
+    \textit{readdir} & per leggere il contenuto di una directory \\
+    \textit{poll}    & \\
+    \textit{mmap}    & chiamata dalla system call \texttt{mmap}. 
+                       mappa il file in memoria\\
+    \textit{release} & chiamata quando l'ultima referenza a un file 
+                       aperto è chiusa\\
+    \textit{fsync}   & chiamata dalla system call \texttt{fsync} \\
+    \textit{fasync}  & chiamate da \texttt{fcntl} quando è abilitato 
+                       il modo asincrono per l'I/O su file. \\
+    \hline
+  \end{tabular}
+  \caption{Operazioni sui file definite nel VFS.}
+  \label{tab:fileintr_file_operations}
+\end{table}
+
+In questo modo per ciascun file diventano utilizzabili una serie di operazioni
+(non è dette che tutte siano disponibili), che costituiscono l'interfaccia
+astratta del VFS, e qualora se ne voglia eseguire una il kernel andrà ad
+utilizzare la opportuna routine dichiarata in \verb|f_ops| appropriata al tipo
+di file in questione. 
+
+Così sarà possibile scrivere sulla porta seriale come su un file di dati
+normale; ovviamente certe operazioni (nel caso della seriale ad esempio la
+\textit{seek}) non saranno disponibili, però con questo sistema l'utilizzo di
+diversi filesystem (come quelli usati da Windows o MacOs) è immediato e
+(relativamente) trasparente per l'utente ed il programmatore.
+
+
+\subsection{Il funzionamento di un filesystem unix}
+\label{sec:filedir_filesystem}
+
+Come già accennato in \secref{sec:fileintr_overview} Linux (ed ogni unix in
+generale) organizza i dati che tiene su disco attraverso l'uso di un
+filesystem. Una delle caratteristiche di Linux rispetto agli altri unix è
+quella di poter supportare grazie al VFS una enorme quantità di filesystem
+diversi, ognuno dei quali ha una sua particolare struttura e funzionalità
+proprie; per questo non entreremo nei dettagli di un filesystem specifico, ma
+daremo una descrizione a grandi linee che si adatta alle caratteristiche
+comuni di un qualunque filesystem standard unix.
+
+Dato un disco lo spazio fisico viene usualmente diviso in partizioni; ogni
+partizione può contenere un filesystem; quest'ultimo è in genere strutturato
+secondo \nfig, con una lista di inodes all'inizio e il resto dello spazio a
+disposizione per i dati e le directory.
+
+\begin{figure}[htb]
+  \centering
+  
+  \caption{Organizzazione dello spazio su un disco in partizioni e filesystem}
+  \label{fig:filedir_disk_filesys}
+\end{figure}
+
+Se si va ad esaminare come è strutturata l'informazione all'interno di un
+singolo filesystem (tralasciando le parti connesse alla strutturazione e al
+funzionamento del filesystem stesso come il super-block) avremo una situazione
+del tipo di quella esposta in \nfig.
+\begin{figure}[htb]
+  \centering
+  
+  \caption{Organizzazione di un filesystem}
+  \label{fig:filedir_filesys_detail}
+\end{figure}
+da questa figura si evidenziano alcune caratteristiche su cui è bene porre
+attenzione in quanto sono fondamentali per capire il funzionamento delle
+funzioni che manipolano i file e le directory su cui torneremo fra poco; in
+particolare è opportuno ricordare sempre che:
+
+\begin{enumerate}
+  
+\item L'\textit{inode} contiene tutte le informazioni riguardanti il file: il
+  tipo di file, i permessi di accesso, le dimensioni, i puntatori ai blocchi
+  fisici che contengono i dati e così via; le informazioni che la funzione
+  \texttt{stat} fornisce provengono dall'\textit{inode}; dentro una directory
+  si troverà solo il nome del file e il numero dell'\textit{inode} ad esso
+  associato, cioè quella che da qui in poi chiameremo una \textsl{voce}
+  (traduzione approssimata dell'inglese \textit{directory entry}, che non
+  useremo anche per evitare confusione con le \textit{dentries} del kernel di
+  cui si parlava in \secref{sec:fileintr_vfs}).
+  
+\item Come mostrato in \curfig si possono avere più voci che puntano allo
+  stesso \textit{inode}. Ogni \textit{inode} ha un contatore che contiene il
+  numero di riferimenti (\textit{link count}) che sono stati fatti ad esso;
+  solo quando questo contatore si annulla i dati del file vengono
+  effettivamente rimossi dal disco. Per questo la funzione per cancellare un
+  file si chiama \texttt{unlink}, ed in realtà non cancella affatto i dati del
+  file, ma si limita a eliminare la relativa voce da una directory e
+  decrementare il numero di riferimenti nell'\textit{inode}.
+  
+\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
+  nello stesso filesystem e non ci può essere una directory che contiene
+  riferimenti ad \textit{inodes} relativi ad altri filesystem. Questo limita
+  l'uso del comando \texttt{ln} (che crea una nuova voce per un file
+  esistente, con la funzione \texttt{link}) al filesystem corrente.
+  
+\item Quando si cambia nome ad un file senza cambiare filesystem il contenuto
+  del file non deve essere spostato, viene semplicemente creata una nuova voce
+  per l'\textit{inode} in questione e rimossa la vecchia (questa è la modalità
+  in cui opera normalmente il comando \texttt{mv} attraverso la funzione
+  \texttt{rename}).
+
+\end{enumerate}
+
+Infine è bene avere presente che essendo file pure loro, esiste un numero di
+riferimenti anche per le directories; per cui se ad esempio a partire dalla
+situazione mostrata in \curfig\ creiamo una nuova directory \texttt{textdir}
+nella directory corrente avremo una situazione come quella in \nfig, dove per
+chiarezza abbiamo aggiunto dei numeri di inode.
+
+La nuova directory avrà allora un numero di riferimenti pari a due, in quanto
+è referenziata dalla directory da cui si era partiti (in cui è inserita la
+nuova voce che fa riferimento a \texttt{textdir}) e dalla voce \texttt{.}
+che è sempre inserita in ogni directory; questo vale sempre per ogni directory
+che non contenga a sua volta altre directories. Al contempo la directory da
+cui si era partiti avrà un numero di riferiementi di almeno tre, in quanto
+adesso sarà referenziata anche dalla voce \texttt{..} di \texttt{textdir}.
+
+
+\subsection{Le funzioni \texttt{link} e \texttt{unlink}}
+\label{sec:filedir_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:filedir_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:filedir_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:filedir_cre_canc}
+
+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:filedir_sym_link}
+
+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}
+
+
index 2aeda784b8de5e9eaab35bff174923d18572a019..a4fb47991a1450c23e02113f3c90aa177e7f2ac5 100644 (file)
@@ -1,6 +1,12 @@
 \chapter{I files: l'interfaccia I/O di unix}
 \label{cha:file_unix_interface}
 
 \chapter{I files: l'interfaccia I/O di unix}
 \label{cha:file_unix_interface}
 
+Per poter accedere al contenuto dei file occorre anzitutto aprirlo. Questo
+crea un canale di comunicazione che permette di eseguire una serie di
+operazioni. Una volta terminate le operazioni, il file dovrà essere chiuso, e
+questo chiuderà il canale di comunicazione impedendo ogni ulteriore
+operazione.
+
 
 
 \section{I file descriptors}
 
 
 \section{I file descriptors}
index 4c871ac0e67b32ce7853f3d6f56df6d0e1365c0c..0913f58fd9a0499786ff22adf9b14504d0c63ef9 100644 (file)
--- a/intro.tex
+++ b/intro.tex
@@ -206,13 +206,13 @@ essere associato a pi
 accesso ai file e quindi anche alle periferiche, in maniera più flessibile,
 definendo gruppi di lavoro, di accesso a determinate risorse, etc.
 
 accesso ai file e quindi anche alle periferiche, in maniera più flessibile,
 definendo gruppi di lavoro, di accesso a determinate risorse, etc.
 
-L'utente e il gruppo sono identificati da due numeri (la cui corrispondenza ad
-un nome in espresso in caratteri \`e inserita nei due files
-\texttt{/etc/passwd} e \texttt{/etc/groups}). Questi numeri sono
-l'\textit{user identifier}, detto in breve \textit{uid} e il \textit{group
-%  identifier}, detto in breve \textit{gid} che sono quelli che identificano
-l'utente di fronte al sistema.
-
+L'utente e il gruppo sono identificati da due numeri (la cui corrispondenza ad
+un nome in espresso in caratteri \`e inserita nei due files
+\texttt{/etc/passwd} e \texttt{/etc/groups}). Questi numeri sono
+l'\textit{user identifier}, detto in breve \textit{uid} e il \textit{group
+  identifier}, detto in breve \textit{gid} che sono quelli che identificano
+l'utente di fronte al sistema.
 In questo modo il sistema è in grado di tenere traccia per ogni processo
 dell'utente a cui appartiene ed impedire ad altri utenti di interferire con
 esso. Inoltre con questo sistema viene anche garantita una forma base di
 In questo modo il sistema è in grado di tenere traccia per ogni processo
 dell'utente a cui appartiene ed impedire ad altri utenti di interferire con
 esso. Inoltre con questo sistema viene anche garantita una forma base di
@@ -226,7 +226,7 @@ qualunque operazione; pertanto per l'utente root i meccanismi di controllo
 descritti in precedenza sono disattivati.
 
 
 descritti in precedenza sono disattivati.
 
 
-\section{Gli standard di unix e Linux}
+\section{Gli standard di unix e GNU/Linux}
 \label{sec:intro_standard}
 
 
 \label{sec:intro_standard}
 
 
index e20120d89fc0d562e803ca545fcc706a87f0d5b6..8f3092da243a139423e0572c0eab9586175fe74d 100644 (file)
--- a/macro.tex
+++ b/macro.tex
@@ -98,7 +98,7 @@ tab.~\thechapter.\theusercount}
 \newenvironment{functions}
 {% defining what is done by \begin
   \center
 \newenvironment{functions}
 {% defining what is done by \begin
   \center
-   \footnotesize
+  \footnotesize
   \begin{minipage}[c]{14cm}
   \begin{description}{}{} 
 
   \begin{minipage}[c]{14cm}
   \begin{description}{}{} 
 
@@ -123,4 +123,3 @@ tab.~\thechapter.\theusercount}
 \newcommand{\link}[1]{\texttt{#1}}    % html link
 \newcommand{\type}[1]{\texttt{#1}}    % variable type
 \newcommand{\param}[1]{\texttt{#1}}   % function parameter
 \newcommand{\link}[1]{\texttt{#1}}    % html link
 \newcommand{\type}[1]{\texttt{#1}}    % variable type
 \newcommand{\param}[1]{\texttt{#1}}   % function parameter
-
index 9a59964518678dc76eb79dd4d452b0db20664a3d..721b899fe852690493596a0bb8aefeffb5675262 100644 (file)
@@ -50,12 +50,12 @@ Tutti i processi inoltre portano traccia del pid del genitore, chiamato in
 genere \textit{ppid} (da \textit{Parente Process Id}). Questi identificativi
 possono essere ottenuti da un programma usando le funzioni:
 \begin{functions}
 genere \textit{ppid} (da \textit{Parente Process Id}). Questi identificativi
 possono essere ottenuti da un programma usando le funzioni:
 \begin{functions}
-\incldecl{sys/types.h}
-\incldecl{unistd.h}
+\headdecl{sys/types.h}
+\headdecl{unistd.h}
 \funcdecl{pid\_t getpid(void)} restituisce il pid del processo corrente.
 \funcdecl{pid\_t getppid(void)} restituisce il pid del padre del processo
     corrente.
 \funcdecl{pid\_t getpid(void)} restituisce il pid del processo corrente.
 \funcdecl{pid\_t getppid(void)} restituisce il pid del padre del processo
     corrente.
-\end{}
+\end{functions}
 
 
 \section{Il controllo dei processi}
 
 
 \section{Il controllo dei processi}