+errore ed \var{errno} viene impostata al valore \errcode{ELOOP}, che nella
+quasi totalità dei casi indica appunto che si è creato un collegamento
+simbolico che fa riferimento ad una directory del suo stesso
+\textit{pathname}.
+
+Un altro punto da tenere sempre presente è che, come abbiamo accennato, un
+collegamento simbolico può fare riferimento anche ad un file che non esiste;
+ad esempio possiamo usare il comando \cmd{ln} per creare un collegamento
+simbolico nella nostra directory con:
+\begin{Command}
+$ ln -s /tmp/tmp_file symlink
+\end{Command}
+%$
+e questo avrà successo anche se \file{/tmp/tmp\_file} non esiste:
+\begin{Command}
+$ ls symlink
+\end{Command}
+\begin{Terminal}
+symlink
+\end{Terminal}
+%$
+ma questo può generare confusione, perché accedendo in sola lettura a
+\file{symlink}, ad esempio con \cmd{cat}, otterremmo un errore:
+\begin{Command}
+$ cat symlink
+\end{Command}
+\begin{Terminal}
+cat: symlink: No such file or directory
+\end{Terminal}
+%$
+con un errore che può sembrare sbagliato, dato che \cmd{ls} ci ha mostrato
+l'esistenza di \file{symlink}, se invece scrivessimo su \file{symlink}
+otterremmo la creazione di \file{/tmp/tmp\_file} senza errori.
+
+
+\itindend{symbolic~link}
+\index{collegamento!simbolico|)}
+
+
+Un'altra funzione relativa alla gestione dei nomi dei file, anche se a prima
+vista parrebbe riguardare un argomento completamente diverso, è quella che per
+la cancellazione di un file. In realtà una \textit{system call} che serva
+proprio a cancellare un file non esiste neanche perché, come accennato in
+sez.~\ref{sec:file_filesystem}, quando in un sistema unix-like si richiede la
+rimozione di un file quella che si va a cancellare è soltanto la voce che
+referenzia il suo \itindex{inode} \textit{inode} all'interno di una directory.
+
+La funzione di sistema che consente di effettuare questa operazione, il cui
+nome come si può notare ha poco a che fare con il concetto di rimozione, è
+\funcd{unlink}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int unlink(const char *pathname)}
+\fdesc{Cancella un file.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà uno dei valori:\footnotemark
+ \begin{errlist}
+ \item[\errcode{EACCES}] non si ha il permesso di scrittura sulla directory
+ che contiene \param{pathname} o di attraversamento di una delle directory
+ superiori.
+ \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una
+ directory.
+ \item[\errcode{EPERM}] il filesystem non consente l'operazione, o la
+ directory che contiene \param{pathname} ha lo \itindex{sticky~bit}
+ \textit{sticky bit} e non si è il proprietario o non si hanno privilegi
+ amministrativi.
+ \end{errlist} ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP},
+ \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EROFS} nel loro
+ significato generico.}
+\end{funcproto}
+
+\footnotetext{questa funzione su Linux ha alcune peculiarità nei codici di
+ errore, in particolare riguardo la rimozione delle directory che non è mai
+ permessa e che causa l'errore \errcode{EISDIR}; questo è un valore specifico
+ di Linux non conforme allo standard POSIX che prescrive invece l'uso di
+ \errcode{EPERM} in caso l'operazione non sia consentita o il processo non
+ abbia privilegi sufficienti, valore che invece Linux usa anche se il
+ filesystem non supporta la funzione, inoltre il codice \errcode{EBUSY} nel
+ caso la directory sia occupata su Linux non esiste.}
+
+La funzione elimina il nome specificato dall'argomento \param{pathname} nella
+directory che lo contiene e decrementa il numero di riferimenti nel relativo
+\itindex{inode} \textit{inode}.\footnote{come per \func{link} queste due
+ operazioni sono effettuate all'interno della \textit{system call} in maniera
+ atomica.} Nel caso di socket, fifo o file di dispositivo
+\index{file!di~dispositivo} rimuove il nome, ma come per i file normali i
+processi che hanno aperto uno di questi oggetti possono continuare ad
+utilizzarli. Nel caso di cancellazione di un collegamento simbolico, che
+consiste solo nel rimando ad un altro file, questo viene immediatamente
+eliminato.
+
+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/attraversamento sulla directory che la contiene
+(affronteremo in dettaglio l'argomento dei permessi di file e directory in
+sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit}
+\textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato
+occorrerà anche essere proprietari del file o proprietari della directory o
+avere i privilegi di amministratore.
+
+Si ricordi inoltre che anche se se ne è rimosso il nome da una directory, un
+file non viene eliminato dal disco fintanto che tutti i riferimenti ad esso
+sono stati cancellati: solo quando il numero di collegamenti mantenuto
+\itindex{inode} nell'\textit{inode} diventa nullo, questo viene disallocato e
+lo spazio occupato su disco viene liberato. Si tenga presente comunque che a
+questo si aggiunge sempre un'ulteriore condizione e cioè che non ci siano
+processi che abbiano il suddetto file aperto.\footnote{come vedremo in
+ sez.~\ref{sec:file_unix_interface} il kernel mantiene anche una tabella dei
+ file aperti nei vari processi, che a sua volta contiene i riferimenti agli
+ \itindex{inode} \textit{inode} ad essi relativi; prima di procedere alla
+ cancellazione dello spazio occupato su disco dal contenuto di un file il
+ kernel controlla anche questa tabella, per verificare che anche in essa non
+ ci sia più nessun riferimento all'\textit{inode} in questione.}
+
+Questa caratteristica del sistema può essere usata per essere sicuri di non
+lasciare file temporanei su disco in caso di crash di un programma. La tecnica
+è quella di aprire un nuovo file e chiamare \func{unlink} su di esso subito
+dopo, in questo modo il contenuto del file sarà sempre disponibile all'interno
+del processo attraverso il suo file descriptor (vedi sez.~\ref{sec:file_fd}),
+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.
+
+Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
+la funzione \func{unlink} sulle directory, nel qual caso si otterrebbe un
+errore di \errcode{EISDIR}. Per cancellare una directory si deve usare la
+apposita funzione di sistema \func{rmdir} (che vedremo in
+sez.~\ref{sec:file_dir_creat_rem}), oppure la funzione \func{remove}.
+Quest'ultima è la funzione prevista dallo standard ANSI C per effettuare una
+cancellazione generica di un file o di una directory e funziona anche per i
+sistemi operativo che non supportano gli \textit{hard link}. Nei sistemi
+unix-like \funcd{remove} è equivalente ad usare in maniera trasparente
+\func{unlink} per i file ed \func{rmdir} per le directory; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int remove(const char *pathname)}
+\fdesc{Cancella un file o una directory.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori relativi alla chiamata utilizzata,
+ pertanto si può fare riferimento a quanto illustrato nelle descrizioni di
+ \func{unlink} e \func{rmdir}.}
+\end{funcproto}
+
+La funzione utilizza la funzione \func{unlink} per cancellare i file e la
+funzione \func{rmdir} (vedi sez.~\ref{sec:file_dir_creat_rem}) per cancellare
+le directory.\footnote{questo vale usando la \acr{glibc}; nella libc4 e nella
+ libc5 la funzione \func{remove} era un semplice alias alla funzione
+ \func{unlink} e quindi non poteva essere usata per le directory.} Si tenga
+presente che per alcune implementazioni del protocollo NFS utilizzare questa
+funzione può comportare la scomparsa di file ancora in uso.
+
+Infine per cambiare nome ad un file o a una directory si usa la funzione di
+sistema \funcd{rename},\footnote{la funzione è definita dallo standard ANSI C,
+ ma si applica solo per i file, lo standard POSIX estende la funzione anche
+ alle directory.} il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int rename(const char *oldpath, const char *newpath)}
+\fdesc{Rinomina un file o una directory.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCESS}] non c'è permesso di scrivere nelle directory
+ contenenti \param{oldpath} e \param{newpath} o di attraversare
+ quelle dei loro \textit{pathname} o di scrivere su \param{newpath}
+ se questa è una directory.
+ \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da
+ parte di qualche processo (come \index{directory~di~lavoro} directory di
+ lavoro o come radice) o del sistema (come \itindex{mount~point}
+ \textit{mount point}) ed il sistema non riesce a risolvere la situazione.
+ \item[\errcode{EEXIST}] \param{newpath} è una directory già esistente e
+ non è vuota (anche \errcode{ENOTEMPTY}).
+ \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di
+ \param{oldpath} o più in generale si è cercato di creare una directory come
+ sotto-directory di sé stessa.
+ \item[\errcode{EISDIR}] \param{newpath} è una directory mentre
+ \param{oldpath} non è una directory.
+ \item[\errcode{ENOTDIR}] uno dei componenti dei \textit{pathname} non è una
+ directory o \param{oldpath} è una directory e
+ \param{newpath} esiste e non è una directory.
+ \item[\errval{EPERM}] la directory contenente \param{oldpath} o quella
+ contenente un \param{newpath} esistente hanno lo
+ \itindex{sticky~bit} \textit{sticky bit} e non si è i proprietari dei
+ rispettivi file (o non si hanno privilegi amministrativi) oppure il
+ filesystem non supporta l'operazione.
+ \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo
+ stesso filesystem e sotto lo stesso \itindex{mount~point} \textit{mount
+ point}.
+ \end{errlist} ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{EMLINK},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOSPC} e
+ \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+La funzione rinomina in \param{newpath} il file o la directory indicati
+dall'argomento \param{oldpath}. Il nome viene eliminato nella directory
+originale e ricreato nella directory di destinazione mantenendo il riferimento
+allo stesso \itindex{inode} \textit{inode}. Non viene spostato nessun dato e
+\itindex{inode} l'\textit{inode} del file non subisce nessuna modifica in
+quanto le modifiche sono eseguite sulle directory che
+contengono \param{newpath} ed \param{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
+c'è modifica, per quanto temporanea, al \textit{link count} del file e non può
+esistere un istante in cui un altro processo possa trovare attivi entrambi i
+nomi per lo stesso file se la destinazione non esiste o in cui questa sparisca
+temporaneamente se già esiste.
+
+Dato che opera in maniera analoga la funzione è soggetta alle stesse
+restrizioni di \func{link}, quindi è necessario che \param{oldpath}
+e \param{newpath} siano nello stesso filesystem e facciano riferimento allo
+stesso \itindex{mount~point} \textit{mount point}, e che il filesystem
+supporti questo tipo di operazione. Qualora questo non avvenga si dovrà
+effettuare l'operazione in maniera non atomica copiando il file a destinazione
+e poi cancellando l'originale.
+
+Il comportamento della funzione è diverso a seconda che si voglia rinominare
+un file o una directory. Se ci riferisce ad un file allora \param{newpath}, se
+esiste, non deve essere una directory, altrimenti si avrà un errore di
+\errcode{EISDIR}. Se \param{newpath} indica un file già esistente questo verrà
+rimpiazzato atomicamente, ma nel caso in cui \func{rename} fallisca il kernel
+assicura che esso non sarà toccato. I caso di sovrascrittura però potrà
+esistere una breve finestra di tempo in cui sia \param{oldpath}
+che \param{newpath} potranno fare entrambi riferimento al file che viene
+rinominato.
+
+Se \param{oldpath} è una directory allora \param{newpath}, se esistente, deve
+essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR}
+(se non è una directory) o \errcode{ENOTEMPTY} o \errcode{EEXIST} (se non è
+vuota). Chiaramente \param{newpath} non potrà contenere \param{oldpath} nel
+suo \textit{pathname}, non essendo possibile rendere una directory una
+sottodirectory di sé stessa, se questo fosse il caso si otterrebbe un errore
+di \errcode{EINVAL}.
+
+Se \param{oldpath} si riferisce ad un collegamento simbolico questo sarà
+rinominato restando tale senza nessun effetto sul file a cui fa riferimento.
+Se invece \param{newpath} esiste ed è un collegamento simbolico verrà
+cancellato come qualunque altro file. Infine qualora \param{oldpath}
+e \param{newpath} siano due nomi che già fanno riferimento allo stesso file lo
+standard POSIX prevede che la funzione non ritorni un errore, e semplicemente
+non faccia nulla, lasciando entrambi i nomi. Linux segue questo standard,
+anche se, come fatto notare dal manuale della \acr{glibc}, il comportamento
+più ragionevole sarebbe quello di cancellare \param{oldpath}.
+
+In tutti i casi si dovranno avere i permessi di scrittura nelle directory
+contenenti \param{oldpath} e \param{newpath}, e nel caso \param{newpath} sia
+una directory vuota già esistente anche su di essa (perché dovrà essere
+aggiornata la voce ``\texttt{..}''). Se poi le directory
+contenenti \param{oldpath} o \param{newpath} hanno lo \itindex{sticky~bit}
+\textit{sticky bit} attivo (vedi sez.~\ref{sec:file_special_perm}) si dovrà
+essere i proprietari dei file (o delle directory) che si vogliono rinominare,
+o avere i permessi di amministratore.