-\subsection{I permessi per l'accesso ai file}
-\label{sec:filedir_perm_overview}
-
-Il controllo di accesso ai file in unix segue un modello abbastanza semplice,
-ma adatto alla gran parte delle esigenze, in cui si dividono i permessi su tre
-livelli. Si tenga conto poi che quanto diremo è vero solo per filesystem di
-tipo unix, e non è detto che sia applicabile a un filesystem
-qualunque\footnote{ed infatti non è vero per il filesystem vfat di Windows,
- per il quale vengono assegnati in maniera fissa con un opzione in fase di
- montaggio}. 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
-identificatori di utenti e gruppi (\textsl{uid} e \textsl{gid}), e accessibili
-da programm tramite i campi \var{st\_uid} e \var{st\_gid} della struttura
-\var{stat} (si veda \secref{sec:filedir_stat}). Ad ogni file viene inoltre
-associato un insieme di permessi che sono divisi in tre classi, e cioè
-attribuiti rispettivamente all'utente proprietario del file, a un 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
-\textsl{w}, \textit{r} \textsl{x} nei comandi di sistema) applicabili
-rispettivamente al proprietario, al gruppo, a tutti. I restanti tre bit
-(\textsl{suid}, \textsl{sgid}, e \textsl{sticky}) sono usati per indicare
-alcune caratteristiche più complesse su cui torneremo in seguito (vedi
-\secref{sec:filedir_suid_sgid} e \secref{sec:filedir_sticky}).
-
-Anche i permessi sono tenuti per ciascun file (di qualunque tipo, quindi anche
-per le fifo, i socket e i file di dispositivo) nell'inode, in opportuni bit
-del campo \var{st\_mode} della struttura letta da \func{stat} (vedi
-\figref{fig:filedir_stat_struct}).
-
-
-In genere ci si riferisce a questi permessi usando le lettere \textsl{u} (per
-\textit{user}), \textsl{g} (per \textit{group}) e \textsl{o} (per
-\textit{other}), inoltre se si vuole indicare tutti questi gruppi insieme si
-usa la lettera \textsl{a} (per \textit{all}). Si tenga ben presente questa
-distinzione, dato che in certi casi, mutuando la termimologia in uso nel VMS,
-si parla dei permessi base come di permessi di owner, group ed all, le cui
-iniziali possono da luogo a confuzione. Le costanti che permettono di accedere
-al valore numerico di questi bit sono riportate in \ntab.
+\subsection{Le funzioni \func{link} e \func{unlink}}
+\label{sec:file_link}
+
+Una caratteristica comune a diversi sistemi operativi è quella di poter creare
+dei nomi fittizi (come gli alias del MacOS o i collegamenti di Windows) che
+permettono di fare riferimento allo stesso file chiamandolo con nomi diversi
+o accedendovi da directory diverse.
+
+Questo è possibile anche in ambiente Unix, dove tali collegamenti sono
+usualmente chiamati \textit{link}; ma data la struttura del sistema di
+gestione dei file (ed in particolare quanto trattato in
+\secref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per
+fare questa operazione.
+
+Come spiegato in \secref{sec:file_filesystem} l'accesso al contenuto di un
+file su disco avviene attraverso il suo inode\index{inode}, e il nome che si
+trova in una directory è solo un'etichetta associata ad un puntatore a che fa
+riferimento al suddetto 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 o originalità
+rispetto agli altri.
+
+Per aggiungere un nome ad un inode si utilizza la funzione \func{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 \var{oldpath}
+ dandogli nome \var{newpath}.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 in
+ caso di errore. La variabile \var{errno} viene settata
+ opportunamente, i principali codici di errore sono:
+ \begin{errlist}
+ \item[\macro{EXDEV}] \var{oldpath} e \var{newpath} non sono sullo
+ stesso filesystem.
+ \item[\macro{EPERM}] il filesystem che contiene \var{oldpath} e
+ \macro{newpath} non supporta i link diretti o è una directory.
+ \item[\macro{EEXIST}] un file (o una directory) con quel nome esiste di
+ già.
+ \item[\macro{EMLINK}] ci sono troppi link al file \var{oldpath} (il
+ numero massimo è specificato dalla variabile \macro{LINK\_MAX}, vedi
+ \secref{sec:sys_limits}).
+ \end{errlist}
+ ed inoltre \macro{EACCES}, \macro{ENAMETOOLONG}, \macro{ENOTDIR},
+ \macro{EFAULT}, \macro{ENOMEM}, \macro{EROFS}, \macro{ELOOP},
+ \macro{ENOSPC}, \macro{EIO}.}
+\end{prototype}
+
+La creazione di un nuovo collegamento diretto non copia il contenuto del file,
+ma si limita a creare una voce nella directory specificata con \var{newpath} e
+ad aumentare di uno il numero di referenze al file (riportato nel campo
+\var{st\_nlink} della struttura \var{stat}, vedi \secref{sec:file_stat})
+aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può
+essere così chiamato con vari nomi in diverse directory.
+
+Per quanto dicevamo in \secref{sec:file_filesystem} la creazione di un
+collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
+filesystem; inoltre il filesystem deve supportare i collegamenti diretti (il
+meccanismo non è disponibile ad esempio con il filesystem \acr{vfat} di
+Windows).
+
+La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del
+filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo
+l'amministratore è in grado di creare un collegamento diretto ad un'altra
+directory: questo viene fatto perché con una tale operazione è possibile
+creare dei circoli nel filesystem (vedi l'esempio mostrato in
+\secref{sec:file_symlink}, dove riprenderemo il discorso) che molti programmi
+non sono in grado di gestire e la cui rimozione diventerebbe estremamente
+complicata (in genere per questo tipo di errori occorre far girare il
+programma \cmd{fsck} per riparare il filesystem).
+
+Data la pericolosità di questa operazione e la disponibilità dei link
+simbolici che possono fornire la stessa funzionalità senza questi problemi,
+nei filesystem usati in Linux questa caratteristica è stata completamente
+disabilitata, e al tentativo di creare un link diretto ad una directory la
+funzione restituisce l'errore \macro{EPERM}.
+
+La rimozione di un file (o più precisamente della voce che lo referenzia
+all'interno di una directory) si effettua con la funzione \func{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.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso il file non viene toccato. La variabile
+ \var{errno} viene settata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item[\macro{EISDIR}] \var{pathname} si riferisce ad una directory
+ (valore specifico ritornato da Linux che non consente l'uso di
+ \var{unlink} con le directory, e non conforme allo standard POSIX, che
+ prescrive invece l'uso di \macro{EPERM} in caso l'operazione non sia
+ consentita o il processo non abbia privilegi sufficienti).
+ \item[\macro{EROFS}] \var{pathname} è su un filesystem montato in sola
+ lettura.
+ \item[\macro{EISDIR}] \var{pathname} fa riferimento a una directory.
+ \end{errlist}
+ ed inoltre: \macro{EACCES}, \macro{EFAULT}, \macro{ENOENT}, \macro{ENOTDIR},
+ \macro{ENOMEM}, \macro{EROFS}, \macro{ELOOP}, \macro{EIO}.}
+\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 in \secref{sec:file_access_control}),
+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
+del nome dalla directory e l'incremento/decremento del numero di riferimenti
+nell'inode devono essere effettuati in maniera atomica (si veda
+\secref{sec:proc_atom_oper}) senza possibili interruzioni fra le due
+operazioni. 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 un'altra condizione, e cioè che non ci siano processi
+che abbiano detto file aperto.
+
+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 \func{unlink} subito dopo, in questo modo il
+contenuto del file è sempre disponibile all'interno del processo attraverso il
+suo file descriptor (vedi \secref{sec:file_fd}) fintanto che il processo non
+chiude il file, ma non ne resta traccia in nessuna directory, e lo spazio
+occupato su disco viene immediatamente rilasciato alla conclusione del
+processo (quando tutti i file vengono chiusi).
+
+
+\subsection{Le funzioni \func{remove} e \func{rename}}
+\label{sec:file_remove}
+
+Al contrario di quanto avviene con altri unix in Linux non è possibile usare
+\func{unlink} sulle directory; per cancellare una directory si può usare la
+funzione \func{rmdir} (vedi \secref{sec:file_dir_creat_rem}), oppure la
+funzione \func{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). Per i file è identica a \func{unlink} e per le
+directory è identica a \func{rmdir}:
+\begin{prototype}{stdio.h}{int remove(const char *pathname)}
+ Cancella un nome dal filesystem. Usa \func{unlink} per i file e
+ \func{rmdir} per le directory.
+
+ \bodydesc{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
+ errore vedi quanto riportato nelle descrizioni di \func{unlink} e
+ \func{rmdir}.}
+\end{prototype}
+
+Per cambiare nome ad un file o a una directory (che devono comunque essere
+nello stesso filesystem) si usa invece la funzione \func{rename},\footnote{la
+ funzione è definita dallo standard ANSI C solo per i file, POSIX estende la
+ funzione anche alle directory.} il cui prototipo è:
+\begin{prototype}{stdio.h}
+ {int rename(const char *oldpath, const char *newpath)}
+
+ Rinomina \var{oldpath} in \var{newpath}, eseguendo se necessario lo
+ spostamento di un file fra directory diverse. Eventuali altri link diretti
+ allo stesso file non vengono influenzati.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso il file non viene toccato. La variabile
+ \var{errno} viene settata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item[\macro{EISDIR}] \var{newpath} è una directory mentre \var{oldpath} non
+ è una directory.
+ \item[\macro{EXDEV}] \var{oldpath} e \var{newpath} non sono sullo stesso
+ filesystem.
+ \item[\macro{ENOTEMPTY}] \var{newpath} è una directory già esistente e non
+ vuota.
+ \item[\macro{EBUSY}] o \var{oldpath} o \var{newpath} sono in uso da parte di
+ qualche processo (come directory di lavoro o come radice) o del sistema
+ (come mount point).
+ \item[\macro{EINVAL}] \var{newpath} contiene un prefisso di \var{oldpath} o
+ più in generale si è cercato di creare una directory come sottodirectory
+ di se stessa.
+ \item[\macro{ENOTDIR}] Uno dei componenti dei pathname non è una directory o
+ \var{oldpath} è una directory e \var{newpath} esiste e non è una
+ directory.
+ \end{errlist}
+ ed inoltre \macro{EACCESS}, \macro{EPERM}, \macro{EMLINK}, \macro{ENOENT},
+ \macro{ENOMEM}, \macro{EROFS}, \macro{ELOOP} e \macro{ENOSPC}.}
+\end{prototype}
+
+Il comportamento della funzione è diverso a seconda che si voglia rinominare
+un file o una directory; se ci riferisce a un file allora \var{newpath}, se
+esiste, non deve essere una directory (altrimenti si ha l'errore
+\macro{EISDIR}). Nel caso \var{newpath} indichi un file esistente questo viene
+cancellato e rimpiazzato (atomicamente).
+
+Se \var{oldpath} è una directory allora \var{newpath}, se esiste, deve essere
+una directory vuota, altrimenti si avranno gli errori \macro{ENOTDIR} (se non
+è una directory) o \macro{ENOTEMPTY} (se non è vuota). Chiaramente
+\var{newpath} non può contenere \var{oldpath} altrimenti si avrà un errore
+\macro{EINVAL}.
+
+Se \var{oldpath} si riferisce a un link simbolico questo sarà rinominato; se
+\var{newpath} è un link simbolico verrà cancellato come qualunque altro file.
+Infine qualora \var{oldpath} e \var{newpath} siano due nomi dello stesso file
+lo standard POSIX prevede che la funzione non dia errore, e non faccia nulla,
+lasciando entrambi i nomi; Linux segue questo standard, anche se, come fatto
+notare dal manuale delle \textit{glibc}, il comportamento più ragionevole
+sarebbe quello di cancellare \var{oldpath}.
+
+Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di
+\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non
+può esistere cioè nessun istante in cui un altro processo può trovare attivi
+entrambi i nomi dello stesso file, o, in caso di sostituzione di un file
+esistente, non trovare quest'ultimo prima che la sostituzione sia stata
+eseguita.
+
+In ogni caso se \var{newpath} esiste e l'operazione fallisce per un qualche
+motivo (come un crash del kernel), \func{rename} garantisce di lasciare
+presente un'istanza di \var{newpath}. Tuttavia nella sovrascrittura potrà
+esistere una finestra in cui sia \var{oldpath} che \var{newpath} fanno
+riferimento allo stesso file.
+
+
+\subsection{I link simbolici}
+\label{sec:file_symlink}
+
+Come abbiamo visto in \secref{sec:file_link} la funzione \func{link} crea
+riferimenti agli inodes, pertanto può funzionare soltanto per file che
+risiedono sullo stesso filesystem e solo per un filesystem di tipo Unix.
+Inoltre abbiamo visto che 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 speciali che contengono
+semplicemente il riferimento ad un altro file (o directory). In questo modo è
+possibile effettuare link anche attraverso filesystem diversi, a file posti in
+filesystem che non supportano i link diretti, a delle directory, ed anche a
+file che non esistono ancora.