revisioni varie
[gapil.git] / filedir.tex
index ab50dc299d1af9f2af4434e6bf18acf28cde1e67..f5261b3a435ae2a95dc6757a7eab78d37d2e360b 100644 (file)
@@ -12,16 +12,16 @@ contenuto dei file 
 
 
 
-\section{La manipolazione di file e directory}
+\section{La gestione di file e directory}
 
 Come già accennato in \secref{sec:file_filesystem} in un sistema unix-like la
 gestione dei file ha delle caratteristiche specifiche che derivano
 direttamente dall'architettura del sistema; in questa sezione esamineremo le
 funzioni usate per manipolazione nel filesytem di file e directory, per la
 creazione di link simbolici e diretti, per la gestione e la lettura delle
-directory; mettendo in evidenza le conseguenze della struttura standard della
-gestione dei file in un sistema unix-like, già accennate al capitolo
-precedente.
+directory; il tutto mettendo in evidenza le conseguenze della struttura
+standard della gestione dei file in un sistema unix-like, già accennate al
+capitolo precedente.
 
 
 \subsection{Le funzioni \func{link} e \func{unlink}}
@@ -29,11 +29,11 @@ precedente.
 
 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 riferiremento allo stesso file, chiamandolo con nomi
-diversi o accedendovi da directory diverse.
+permettono di fare riferiremento 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
+usualmente chiamati \textit{link}; ma data la struttura del sistema di
 gestione dei file (ed in particolare quanto trattato in
 \secref{sec:file_architecture}) ci sono due metodi sostanzialmente diversi per
 fare questa operazione.
@@ -43,7 +43,6 @@ 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 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
@@ -91,14 +90,14 @@ mneccanismo non 
 Windows). 
 
 La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del
-filesystem, con l'eccezione delle directory. In alcuni sistemi solo
+filesystem, con l'eccezione delle directory. In alcuni 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 occorre far girare il programma \cmd{fsck} per riparare
-il filesystem). 
+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,
@@ -132,7 +131,6 @@ suo prototipo 
   \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
@@ -169,7 +167,7 @@ processo (quando tutti i file vengono chiusi).
 \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
+\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
@@ -185,13 +183,17 @@ le directory 
   riportato nelle descrizioni di \func{unlink} e \func{rmdir}.
 \end{prototype}
 
-Per cambiare nome ad un file (o a una directory) 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 è:
+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 un file, spostandolo fra directory diverse quando richiesto.
+  {int rename(const char *oldpath, const char *newpath)} 
+  
+  Rinomina \var{oldpath} in \var{newpth}, eseguendo se necessario lo
+  spostamento di un file fra directory diverse. Eventuali altri link diretti
+  allo stesso file non vengono influenzati.
   
   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
@@ -204,7 +206,7 @@ Per cambiare nome ad un file (o a una directory) si usa invece la funzione
   \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 root) o del sistema
+    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
@@ -224,20 +226,37 @@ Per cambiare nome ad un file (o a una directory) si usa invece la funzione
   \macro{ELOOP} e \macro{ENOSPC}.
 \end{prototype}
 
-
-il vantaggio nell'uso
-di questa funzione al posto della chiamata successiva di \func{link} e
-\func{unlink} è che l'operazione è eseguita atomicamente, e non c'è un momento
-in cui il file su disco presenta ad un altro processo un diverso numero di
-collegamenti diretti. Inoltre in questo modo non c'è modo che il nuovo nome
-esista senza essere connesso all'inode; se si ha un crollo del sistema durante
-l'esecuzione può essere possibile che entrambi i nomi esistano, ma il nuovo
-nome quando esiste, è sempre connesso al file.
-
-
-L'effetto è diverso a seconda che si voglia spostare un file o una directory;
-se ci riferisce a un file allora \var{newpath} deve essere una di
-
+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}. 
+
+Se \var{oldpath} si riferisce a un link simbolico questo sara 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 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 una 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}
@@ -289,9 +308,10 @@ dichiarate nell'header file \file{unistd.h}.
   \end{errlist}
 \end{prototype}
 
-Dato che la funzione \func{open} segue i link simbolici, è necessaria usare
-un'altra funzione quando si vuole leggere il contenuto di un link simbolico,
-questa funzione è la:
+Dato che, come indicato in \secref{tab:file_symb_effect}, la funzione
+\func{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)} 
@@ -547,7 +567,7 @@ per cambiare directory di lavoro.
 \begin{prototype}{unistd.h}{int chdir (const char * pathname)}
   Come dice il nome (che significa \textit{change directory}) questa funzione
   serve a cambiare la directory di lavoro a quella specificata dal pathname
-  contenuto nella stringa \texttt{pathname}.
+  contenuto nella stringa \var{pathname}.
 \end{prototype}
   
 \begin{prototype}{unistd.h}{int fchdir (int filedes)} 
@@ -761,18 +781,18 @@ corrente.
 In tal caso si avranno differenti risultati a seconda del modi in cui si
 calcola la lunghezza del file, ad esempio il comando \cmd{du}, (che riporta il
 numero di blocchi occupati) potrà dare una dimensione inferiore, mentre se si
-legge dal file (ad esempio usando \cmd{wc -c}), dato che in tal caso per le
-parti non scritte vengono restituiti degli zeri, si avrà lo stesso risultato
-di \cmd{ls}.
-
-Se è sempre possibile allargare un file scrivendoci sopra od usando la
-funzione \func{seek} per spostarsi oltre la sua fine. Esistono però anche casi
-in cui si può avere bisogno di effettuare un troncamento scartando i dati al
-di là della dimensione scelta come nuova fine del file.
-
-Un file può essere troncato a zero aprendolo con il flag \macro{O\_TRUNC}, ma
-questo è un caso particolare; per qualunque altra dimensione si possono usare
-le due funzioni:
+legge dal file (ad esempio usando il comando \cmd{wc -c}), dato che in tal
+caso per le parti non scritte vengono restituiti degli zeri, si avrà lo stesso
+risultato di \cmd{ls}.
+
+Se è sempre possibile allargare un file, scrivendoci sopra od usando la
+funzione \func{seek} per spostarsi oltre la sua fine, esistono anche casi in
+cui si può avere bisogno di effettuare un troncamento, scartando i dati
+presenti al di là della dimensione scelta come nuova fine del file.
+
+Un file può sempre essere troncato a zero aprendolo con il flag
+\macro{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra
+dimensione si possono usare le due funzioni:
 \begin{functions}
   \headdecl{unistd.h} \funcdecl{int truncate(const char *file\_name, off\_t
     length)} Fa si che la dimensione del file \var{file\_name} sia troncata ad
@@ -782,19 +802,19 @@ le due funzioni:
   eccetto che si usa con un file aperto, specificato tramite il suo file
   descriptor \var{fd}.
   
-  Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
-  caso di errore \var{errno} viene settato opportunamente; per
-  \func{ftruncate} si hanno i valori:
+  Le funzioni restituiscono zero in caso di successo e -1 per un errore, nel
+  qual caso \var{errno} viene settato opportunamente; per \func{ftruncate} si
+  hanno i valori:
   \begin{errlist}
   \item \macro{EBADF} \var{fd}  non è un file descriptor.
-  \item \texttt{EINVAL} \var{fd} è un riferimento ad un socket, non a un file
+  \item \macro{EINVAL} \var{fd} è un riferimento ad un socket, non a un file
     o non è aperto in scrittura.
   \end{errlist}
   per \func{truncate} si hanno:
   \begin{errlist}
-  \item \texttt{EACCES} il file non ha permesso di scrittura o non si ha il
+  \item \macro{EACCES} il file non ha permesso di scrittura o non si ha il
     permesso di esecuzione una delle directory del pathname. 
-  \item \texttt{ETXTBSY} Il file è un programma in esecuzione.
+  \item \macro{ETXTBSY} Il file è un programma in esecuzione.
   \end{errlist}
   ed anche \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT},
   \macro{EROFS}, \macro{EIO}, \macro{EFAULT}, \macro{ELOOP}.
@@ -804,17 +824,17 @@ Se il file 
 perduti; il comportamento in caso di lunghezza inferiore non è specificato e
 dipende dall'implementazione: il file può essere lasciato invariato o esteso
 fino alla lunghezza scelta; in quest'ultimo caso lo spazio viene riempito con
-zeri (e in genere si ha la creazione di un hole nel file).
+zeri (e in genere si ha la creazione di un \textit{hole} nel file).
 
 
 \subsection{I tempi dei file}
 \label{sec:file_file_times}
 
 Il sistema mantiene per ciascun file tre tempi. Questi sono registrati
-nell'inode insieme agli altri attributi del file e possono essere letti tramite
-la funzione \func{stat}, che li restituisce attraverso tre campi della
-struttura in \figref{fig:file_stat_struct}. Il significato di detti tempi e
-dei relativi campi è riportato nello schema in \ntab:
+nell'inode insieme agli altri attributi del file e possono essere letti
+tramite la funzione \func{stat}, che li restituisce attraverso tre campi della
+struttura \var{stat} di \figref{fig:file_stat_struct}. Il significato di detti
+tempi e dei relativi campi è riportato nello schema in \ntab:
 
 \begin{table}[htb]
   \centering
@@ -837,7 +857,7 @@ dei relativi campi 
 
 Il primo punto da tenere presente è la differenza fra il cosiddetto tempo di
 modifica (il \textit{modification time} \var{st\_mtime}) e il tempo di
-cambiamento di stato (il \textit{chage time} \var{st\_ctime}). Il primo
+cambiamento di stato (il \textit{change time} \var{st\_ctime}). Il primo
 infatti fa riferimento ad una modifica del contenuto di un file, mentre il
 secondo ad una modifica dell'inode; siccome esistono molte operazioni (come la
 funzione \func{link} e molte altre che vedremo in seguito) che modificano solo
@@ -846,9 +866,9 @@ l'utilizzo di un altro tempo.
 
 Il sistema non tiene conto dell'ultimo accesso all'inode, pertanto funzioni
 come \func{access} o \func{stat} non hanno alcuna influenza sui tre tempi. Il
-tempo di ultimo accesso viene di solito usato per cancellare i file che non
-servono più dopo un certo lasso di tempo (ad esempio \cmd{leafnode} cancella i
-vecchi articoli sulla base di questo tempo).  
+tempo di ultimo accesso (ai dati) viene di solito usato per cancellare i file
+che non servono più dopo un certo lasso di tempo (ad esempio \cmd{leafnode}
+cancella i vecchi articoli sulla base di questo tempo).
 
 Il tempo di ultima modifica invece viene usato da \cmd{make} per decidere
 quali file necessitano di essere ricompilati o (talvolta insieme anche al
@@ -861,14 +881,15 @@ L'effetto delle varie funzioni di manipolazione dei file sui tempi 
 illustrato in \ntab. Si sono riportati gli effetti sia per il file a cui si fa
 riferimento, sia per la directory che lo contiene; questi ultimi possono
 essere capiti se si tiene conto di quanto già detto, e cioè che anche le
-directory sono files, che il sistema tratta in maniera del tutto analoga agli
-altri. 
+directory sono file (che contengono una lista di nomi) che il sistema tratta
+in maniera del tutto analoga a tutti gli altri.
 
 Per questo motivo tutte le volte che compiremo una operazione su un file che
-comporta una modifica della sua directory entry, andremo anche a scrivere
-sulla directory che lo contiene cambiandone il tempo di modifica. Un esempio
-di questo può essere la cancellazione di un file, mentre leggere o scrivere o
-cambiarne i permessi ha effetti solo sui tempi del file.
+comporta una modifica del nome contenuto nella directory, andremo anche a
+scrivere sulla directory che lo contiene cambiandone il tempo di modifica. Un
+esempio di questo può essere la cancellazione di un file, invece leggere o
+scrivere o cambiare i permessi di un file ha effetti solo sui tempi di
+quest'ultimo.
 
 \begin{table}[htb]
   \centering
@@ -942,7 +963,7 @@ cambiarne i permessi ha effetti solo sui tempi del file.
 \end{table}
 
 Si noti infine come \var{st\_ctime} non abbia nulla a che fare con il tempo di
-creazione del file, usato da molti altri sistemi operativi, che in unix non
+creazione del file, usato in molti altri sistemi operativi, ma che in unix non
 esiste.
 
 
@@ -976,7 +997,7 @@ struct utimbuf {
 \end{lstlisting}
 
 L'effetto della funzione e i privilegi necessari per eseguirla dipendono da
-cosa è l'argomento \var{times}; se è \textit{NULL} la funzione setta il tempo
+cosa è l'argomento \var{times}; se è \macro{NULL} la funzione setta il tempo
 corrente ed è sufficiente avere accesso in scrittura al file; se invece si è
 specificato un valore la funzione avrà successo solo se si è proprietari del
 file (o si hanno i privilegi di amministratore).
@@ -987,9 +1008,8 @@ volte che si modifica l'inode (quindi anche alla chiamata di \func{utime}).
 Questo serve anche come misura di sicurezza per evitare che si possa
 modificare un file nascondendo completamente le proprie tracce.  In realtà la
 cosa resta possibile, se si è in grado di accedere al device, scrivendo
-direttamente sul disco senza passare attraverso il filesystem, ma ovviamente è
-molto più complicato da realizzare.
-
+direttamente sul disco senza passare attraverso il filesystem, ma ovviamente
+in questo modo la cosa è molto più complicata da realizzare.
 
 
 
@@ -1147,7 +1167,7 @@ di accesso sono i seguenti:
   all'amministratore) l'accesso è sempre garantito senza nessun ulteriore
   controllo. Per questo motivo \textsl{root} ha piena libertà di accesso a
   tutti i file.
-\item Se l'\textit{effective user id} del processo è uguale all'uid del
+\item Se l'\textit{effective user id} del processo è uguale all'\acr{uid} del
   proprietario del file (nel qual caso si dice che il processo è proprietario
   del file) allora:
   \begin{itemize}
@@ -1295,7 +1315,7 @@ file, non si pu
 stesso problema di presenta per la creazione di nuove directory (procedimento
 descritto in \secref{sec:file_dir_creat_rem}).
 
-Lo standard POSIX prescrive che l'uid del nuovo file corrisponda
+Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda
 all'\textit{effective user id} del processo che lo crea; per il \acr{gid}
 invece prevede due diverse possibilità:
 \begin{itemize}
@@ -1308,7 +1328,7 @@ in genere BSD usa sempre la seconda possibilit
 semantica BSD. Linux invece segue quella che viene chiamata semantica SVR4; di
 norma cioè il nuovo file viene creato, seguendo la prima opzione, con il
 \acr{gid} del processo, se però la directory in cui viene creato il file ha il
-bit \acr{sgid} settato allora viene usata la seconda opzione..
+bit \acr{sgid} settato allora viene usata la seconda opzione.
 
 Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre
 automaticamente propagato, restando coerente a quello della directory di
@@ -1327,7 +1347,7 @@ Come detto in \secref{sec:file_access_control} il controllo di accesso ad
 un file viene fatto usando \textit{effective user id} e \textit{effective
   group id} del processo, ma ci sono casi in cui si può voler effettuare il
 controllo usando il \textit{real user id} e il \textit{real group id} (cioè
-l'uid dell'utente che ha lanciato il programma, che, come accennato in
+l'\acr{uid} dell'utente che ha lanciato il programma, che, come accennato in
 \secref{sec:file_suid_sgid} e spiegato in \secref{sec:proc_perms} non è
 detto sia uguale all'\textit{effective user id}). Per far questo si può usare
 la funzione \func{access}, il cui prototipo è:
@@ -1339,13 +1359,12 @@ la funzione \func{access}, il cui prototipo 
   file indicato da \var{pathname}. 
   
   La funzione ritorna 0 se l'accesso è consentito, -1 altrimenti; in
-  quest'ultimo caso la variabile \texttt{errno} viene settata secondo i codici
+  quest'ultimo caso la variabile \var{errno} viene settata secondo i codici
   di errore: \macro{EACCES}, \macro{EROFS}, \macro{EFAULT}, \macro{EINVAL},
   \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOTDIR}, \macro{ELOOP},
   \macro{EIO}.
 \end{prototype}
 
-
 I valori possibili per il parametro \var{mode} sono esprimibili come
 combinazione delle costanti numeriche riportate in \ntab\ (attraverso un OR
 binario). I primi tre valori implicano anche la verifica dell'esistenza del
@@ -1381,16 +1400,16 @@ contrario (o di errore) ritorna -1.
 
 Un esempio tipico per l'uso di questa funzione è quello di un processo che sta
 eseguendo un programma coi privilegi di un altro utente (attraverso l'uso del
-suid bit) che vuole controllare se l'utente originale ha i permessi per
+\acr{suid} bit) che vuole controllare se l'utente originale ha i permessi per
 accedere ad un certo file.
 
 
-\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
+\subsection{Le funzioni \func{chmod} e \func{fchmod}}
 \label{sec:file_chmod}
 
 Per cambiare i permessi di un file il sistema mette ad disposizione due
 funzioni, che operano rispettivamente su un filename e su un file descriptor,
-i cui prototipi sono:
+i loro prototipi sono:
 
 \begin{functions}
   \headdecl{sys/types.h} 
@@ -1403,7 +1422,7 @@ i cui prototipi sono:
   il file descriptor \var{fd} per indicare il file.
   
   Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
-  caso di errore \texttt{errno} può assumere i valori:
+  caso di errore \var{errno} può assumere i valori:
   \begin{errlist}
   \item \macro{EPERM} L'\textit{effective user id} non corrisponde a quello
     del proprietario del file o non è zero.
@@ -1415,13 +1434,14 @@ i cui prototipi sono:
 \end{functions}
 
 I valori possibili per \var{mode} sono indicati in \ntab. I valori possono
-esser combinati con l'OR binario delle relative macro, o specificati
-direttamente, come per l'analogo comando di shell, con il valore ottale. Ad
-esempio i permessi standard assegnati ai nuovi file (lettura e scrittura per
-il proprietario, sola lettura per il gruppo e gli altri) sono corrispondenti
-al valore ottale $0644$, un programma invece avrebbe anche il bit di
-esecuzione attivo, con un valore di $0755$, se si volesse attivare il bit suid
-il valore da fornire sarebbe $4755$.
+esser combinati con l'OR binario delle relative costanti simboliche, o
+specificati direttamente, come per l'analogo comando di shell, con il valore
+numerico (la shell lo vuole in ottale, dato che i bit dei permessi sono
+divisibili in gruppi di tre). Ad esempio i permessi standard assegnati ai
+nuovi file (lettura e scrittura per il proprietario, sola lettura per il
+gruppo e gli altri) sono corrispondenti al valore ottale $0644$, un programma
+invece avrebbe anche il bit di esecuzione attivo, con un valore di $0755$, se
+si volesse attivare il bit suid il valore da fornire sarebbe $4755$.
 
 \begin{table}[!htb]
   \centering
@@ -1460,7 +1480,7 @@ alcune limitazioni, provviste per motivi di sicurezza. Questo significa che
 anche se si è proprietari del file non tutte le operazioni sono permesse, in
 particolare:
 \begin{itemize}
-\item siccome solo l'amministratore può settare lo \textit{sticky bit} se se
+\item siccome solo l'amministratore può settare lo \textit{sticky bit}; se
   l'\textit{effective user id} del processo non è zero esso viene
   automaticamente cancellato (senza notifica di errore) qualora sia stato
   indicato in \var{mode}.