\label{cha:files_and_dirs}
In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
-files e directories, ed in particolare esamineremo come è strutturato il
-sistema base di protezioni e controllo di accesso ai files, e tutta
-l'interfaccia che permette la manipolazione dei vari attributi di files e
-directories. Tutto quello che riguarda invece la manipolazione del contenuto
-dei file è lasciato ai capitoli successivi.
+file e directory, ed in particolare esamineremo come è strutturato il sistema
+base di protezioni e controllo di accesso ai file, e tutta l'interfaccia che
+permette la manipolazione dei vari attributi di file e directory. Tutto quello
+che riguarda invece la manipolazione del contenuto dei file è lasciato ai
+capitoli successivi.
-\section{La gestione di file e directory}
+
+\section{Il controllo di accesso ai file}
+\label{sec:filedir_access_control}
+
+Una delle caratteristiche fondamentali di tutti i sistemi unix-like è quella
+del controllo di accesso ai file, che viene implementato per qualunque
+filesystem standard. In questa sezione ne esamineremo i concetti essenziali e
+le funzioni usate per gestirne i vari aspetti.
+
+
+\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
+identificatoti di utenti e gruppi (uid e gig) già 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} nell'output di \cmd{ls}) 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, in
+opportuni bit del campo \var{st\_mode} della struttura letta da \func{stat}
+(vedi \figref{fig:filedir_stat_struct}) che possono essere controllati con i
+valori riportati in \ntab.
+
+\begin{table}[htb]
+ \centering
+
+ \caption{I bit deipermessi di accesso ai file, come definiti in
+ \texttt{<sys/stat.h>}}
+ \label{tab:file_bit_perm}
+\end{table}
+
+
+% 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
+% a
+% pertanto accesso senza restrizione a qualunque file del sistema.
+
+% In realtà il procedimento è più complesso di quanto descritto in maniera
+% elementare qui; inoltre ad un processo sono associati diversi identificatori,
+% torneremo su questo in maggiori dettagli in seguito in \secref{sec:proc_perms}.
+
+
+\subsection{I flag \texttt{suid} e \texttt{sgid}}
+\label{sec:filedir_suid_sgid}
+
+\subsection{La titolarità di nuovi files e directory}
+\label{sec:filedir_ownership}
+
+
+\subsection{La funzione \texttt{access}}
+\label{sec:filedir_access}
+
+
+\subsection{La funzione \texttt{umask}}
+\label{sec:filedir_umask}
+
+
+\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
+\label{sec:filedir_chmod}
+
+\subsection{Il flag \texttt{sticky}}
+\label{sec:filedir_sticky}
+
+\subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
+\label{sec:filedir_chown}
+
+
+
+
+%La struttura fondamentale che contiene i dati essenziali relativi ai file è il
+%cosiddetto \textit{inode}; questo conterrà informazioni come il
+%tipo di file (file di dispositivo, directory, file di dati, per un elenco
+%completo vedi \ntab), i permessi (vedi \secref{sec:file_perms}), le date (vedi
+%\secref{sec:file_times}).
+
+
+
+
+\section{La manipolazione di file e directory}
Le prime funzioni che considereremo sono quelle relative alla gestione di file
e directory, secondo le caratteristiche standard che essi presentano in un
-filesystem unix, già esaminate in precedenza (vedi
+filesystem unix, la cui struttura abbiamo esaminato in precedenza (vedi
\secref{sec:fileintr_filesystem}).
\subsection{Le funzioni \texttt{link} e \texttt{unlink}}
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.
+Come spiegato in \secref{sec:fileintr_architecture} 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
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:
+ La funzione restituisce zero in caso di successo e -1 in caso di errore. La
+ variabile \texttt{errno} viene settata opportunamente, i principali codici
+ di errore sono:
\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,
il caso ad esempio del filesystem \texttt{vfat} di windows).
La funzione opera sui file ordinari, come sugli altri oggetti del filesystem,
-ma solo l'amministratore è in grado di creare un collegamento diretto ad
-un'altra directory, questo lo si fa perché in questo caso è possibile creare
-dei circoli nel filesystem (vedi \secref{sec:fileintr_symlink}) che molti
-programmi non sono in grado di gestire e la cui rimozione diventa estremamente
-complicata (in genere occorre far girare il programma \texttt{fsck} per
-riparare il filesystem); data la sua pericolosità in Linux questa
-caratteristica è stata disabilitata, e la funzione restituisce l'errore
-\texttt{EPERM}.
+in alcuni filesystem solo l'amministratore è in grado di creare un
+collegamento diretto ad un'altra directory, questo lo si fa perché in questo
+caso è possibile creare dei circoli nel filesystem (vedi
+\secref{sec:fileintr_symlink}) che molti programmi non sono in grado di
+gestire e la cui rimozione diventa estremamente complicata (in genere occorre
+far girare il programma \texttt{fsck} per riparare il filesystem); data la sua
+pericolosità in generale nei filesystem usati 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:
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
+ \item \texttt{EISDIR} \var{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.
+ \item \texttt{EROFS} \var{pathname} è su un filesystem montato in sola
+ lettura.
+ \item \texttt{EISDIR} \var{pathname} fa riferimento a una directory.
\end{errlist}
\end{prototype}
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.
+o rinominare i file operano direttamente sul link simbolico (per l'elenco vedi
+\ntab). 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}.
\end{errlist}
\end{prototype}
-\section{La manipolazione delle directories}
-\label{sec:filedir_dir_handling}
+In \ntab\ si è riportato un elenco dei comportamenti delle varie funzioni che
+operano sui file rispetto ai link simbolici; specificando quali seguono il
+link simbolico e quali possono operare direttamente sul suo contenuto.
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|}
+ \hline
+ Funzione & Segue il link & Non segue il link \\
+ \hline
+ \hline
+ \func{access} & $\bullet$ & \\
+ \func{chdir} & $\bullet$ & \\
+ \func{chmod} & $\bullet$ & \\
+ \func{chown} & & $\bullet$ \\
+ \func{creat} & $\bullet$ & \\
+ \func{exec} & $\bullet$ & \\
+ \func{lchown} & $\bullet$ & $\bullet$ \\
+ \func{link} & & \\
+ \func{lstat} & & $\bullet$ \\
+ \func{mkdir} & $\bullet$ & \\
+ \func{mkfifo} & $\bullet$ & \\
+ \func{mknod} & $\bullet$ & \\
+ \func{open} & $\bullet$ & \\
+ \func{opendir} & $\bullet$ & \\
+ \func{pathconf} & $\bullet$ & \\
+ \func{readlink} & & $\bullet$ \\
+ \func{remove} & & $\bullet$ \\
+ \func{rename} & & $\bullet$ \\
+ \func{stat} & $\bullet$ & \\
+ \func{truncate} & $\bullet$ & \\
+ \func{unlink} & & $\bullet$ \\
+ \hline
+ \end{tabular}
+ \caption{Uso dei link simbolici da parte di alcune funzioni.}
+ \label{tab:filedir_symb_effect}
+\end{table}
+si noti che non si è specificato il comportamento delle funzioni che operano
+con i file descriptor, in quanto la gestione del link simbolico viene in
+genere effttuata dalla funzione che restituisce il file descriptor
+(normalmente la \func{open}).
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=5cm]{img/link_loop.eps}
+ \caption{Esempio di loop nel filesystem creato con un link simbolico.}
+ \label{fig:filedir_link_loop}
+\end{figure}
+
+Un caso comune che si può avere con i link simbolici è la creazione dei
+cosiddetti \textit{loop}. La situazione è illustrata in \curfig, che riporta
+la struttura della directory \file{/boot}. Come si vede si è creato al suo
+interno un link simbolico che punta di nuovo a \file{/boot}\footnote{Questo
+ tipo di loop è stato effettuato per poter permettere a \cmd{grub} (un
+ bootloader estremamente avanzato in grado di accedere direttamente
+ attraverso vari filesystem al file da lanciare come sistema operativo) di
+ vedere i file in questa directory, che è montata su una partizione separata
+ (e che grub vedrebbe come radice), con lo stesso path con cui verrebbero
+ visti dal sistema operativo.}.
+
+Questo può causare problemi per tutti quei programmi che effettuassero uno
+scan di una directory senza tener conto dei link simbolici, in quel caso
+infatti il loop nella directory
+
+Un secondo punto da tenere presente è che un link simbolico può essere fatto
+anche ad un file che non esiste; ad esempio possiamo creare un file temporaneo
+nella nostra directory con un link del tipo:
+\begin{verbatim}
+$ln -s /tmp/tmp_file temporaneo
+\end{verbatim}%$
+ma anche se \file{/tmp/tmp\_file} non esiste. Aprendo in scrittura
+\file{temporaneo} questo verrà scritto; ma se cercassimo di accederlo in sola
+lettura (ad esempio con \cmd{cat}) otterremmo:
+\begin{verbatim}
+$ cat prova
+cat: prova: No such file or directory
+\end{verbatim}%$
+con un errore che sembra sbagliato, dato \cmd{ls} ci mostrerebbe l'esistenza
+di \file{temporaneo}.
+
\subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}}
\label{sec:filedir_dir_creat_rem}
\begin{prototype}{unistd.h}{int fchdir (int filedes)}
Analoga alla precedente, ma usa un file descriptor invece del pathname.
-
+
Entrambe le funzioni restituiscono zero in caso di successo e -1 per un
errore, in caso di errore \texttt{errno} viene settata secondo i codici di
errore standard di accesso ai files (trattati in dettaglio in
\end{prototype}
+
\section{La manipolazione delle caratteristiche dei files}
\label{sec:filedir_infos}
\label{sec:filedir_stat}
La lettura delle informazioni relative ai file è fatta attraverso la famiglia
-delle funzioni \texttt{stat}, che è la funzione che il comando \texttt{ls} usa
+delle funzioni \func{stat}, che è la funzione che il comando \cmd{ls} usa
per poter stampare tutti i dati dei files. I prototipi di queste funzioni sono
i seguenti:
\begin{functions}
\funcdecl{int lstat(const char *file\_name, struct stat *buf)} Identica a
\func{stat} eccetto che se il \var{file\_name} è un link simbolico vengono
- lette le informazioni relativa ad esso e non al file a cui punta.
+ lette le informazioni relativa ad esso e non al file a cui fa riferimento.
\funcdecl{int fstat(int filedes, struct stat *buf)} Identica a \func{stat}
- eccetto che funziona con un file aperto, specificato tramite il suo file
+ eccetto che si usa con un file aperto, specificato tramite il suo file
descriptor \var{filedes}.
Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
caso di errore \texttt{errno} viene settato ai valori:
\begin{errlist}
- \item \texttt{EACCESS} Non c'è il permesso di accedere al file.
- \item \texttt{ENOTDIR} Una componente del pathname non è una directory.
- \item \texttt{EMLOOP} Ci sono troppi link simbolici nel pathname.
- \item \texttt{EFAULT} I puntatori usati sono fuori dallo spazio di indirizzi
+ \item \texttt{EACCESS} non c'è il permesso di accedere al file.
+ \item \texttt{ENOTDIR} una componente del pathname non è una directory.
+ \item \texttt{EMLOOP} ci sono troppi link simbolici nel pathname.
+ \item \texttt{EFAULT} i puntatori usati sono fuori dallo spazio di indirizzi
del processo.
\item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
completare l'operazione.
- \item \texttt{ENAMETOOLONG} Il filename è troppo lungo.
+ \item \texttt{ENAMETOOLONG} il filename è troppo lungo.
\end{errlist}
\end{functions}
La struttura \texttt{stat} è definita nell'header \texttt{sys/stat.h} e in
generale dipende dall'implementazione, la versione usata da Linux è mostrata
in \nfig, così come riportata dalla man page (in realtà la definizione
-effettivamente usata nel kernel dipende dall'archietettura e ha altri campi
-riservati per estensioni come tempo più precisi, o per il padding dei campi).
+effettivamente usata nel kernel dipende dall'architettura e ha altri campi
+riservati per estensioni come tempi più precisi, o per il padding dei campi).
\begin{figure}[!htb]
\footnotesize
\centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[]{}
+ \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
struct stat {
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
\end{table}
Oltre a queste macro è possibile usare direttamente il valore di
-\var{st\_mode} per ricavare il significato dei vari bit del campo attraverso
-l'uso dei flag riportati in \ntab:
+\var{st\_mode} per ricavare il significato dei vari bit in esso memorizzati,
+per questo sempre in \texttt{sys/stat.h} sono definiti i flag riportati in
+\ntab:
\begin{table}[htb]
\centering
\footnotesize
\label{tab:filedir_file_mode_flags}
\end{table}
+Il primo valore definisce la maschera dei bit usati nei quali viene
+memorizzato il tipo di files, mentre gli altri possono essere usati per
+effettuare delle selezioni sul tipo di file voluto, combinando opportunamente
+i vari flag; ad esempio se si volesse controllare se un file è una directory o
+un file ordinario si potrebbe definire la condizione:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+#define IS_FILE_DIR(x) (((x) & S_IFMT) & (S_IFDIR | S_IFREG))
+\end{lstlisting}
+in cui prima si estraggono da \var{st\_mode} i bit relativi al tipo di file e
+poi si effettua il confronto con la combinazione di tipi scelta.
+
\subsection{La dimensione dei file}
\label{sec:filedir_file_size}
-Il membro \var{st\_size} contiene la dimensione del
-
-\subsection{I tempi dei file}
-\label{sec:filedir_file_times}
-
-\subsection{La funzione \texttt{utime}}
-\label{sec:filedir_utime}
-
-
-
-
-\section{Il controllo di accesso ai file}
-\label{sec:filedir_access_control}
-
-
-In unix è implementata da qualunque filesystem standard una forma elementare
-(ma adatta alla maggior parte delle esigenze) di controllo di accesso ai
-files. Torneremo sull'argomento in dettaglio più avanti (vedi
-\secref{sec:filedir_access_control}), qui ci limitiamo ad una introduzione dei
-concetti essenziali.
-
-Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo Unix,
-e non è detto che sia applicabile (ed infatti non è vero per il filesystem di
-Windows) a un filesystem qualunque. Esistono inoltre estensioni che permettono
-di implementare le ACL (\textit{Access Control List}) che sono un meccanismo
-di controllo di accesso molto più sofisticato.
-
-Ad ogni file Unix associa sempre l'utente che ne è proprietario (il cosiddetto
-\textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli uid e
-gid accennato in \secref{sec:intro_multiuser}, e un insieme di permessi che
-sono divisi in tre classi, e cioè attribuiti rispettivamente al proprietario,
-a qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti
-gli altri utenti.
+Il membro \var{st\_size} contiene la dimensione del file in bytes (se il file
+è un file normale, nel caso di un link simbolico al dimensione è quella del
+pathname che contiene).
+
+Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512
+bytes. Il campo \var{st\_blksize} infine definisce la dimensione preferita per
+i trasferimenti sui file (che è la dimensione usata anche dalle librerie del C
+per l'interfaccia degli stream); scrivere sul file a blocchi di dati di
+dimensione inferiore sarebbe inefficiente.
+
+Si tenga conto che lunghezza del file riportata in \var{st\_size} non è detto
+che corrisponda all'occupazione dello spazio su disco per via della possibile
+esistenza dei cosiddetti \textsl{buchi} (detti normalmente \textit{holes}) che
+si formano tutte le volte che si va a scrivere su un file dopo aver eseguito
+una \func{seek} (vedi \secref{sec:fileunix_lseek}) oltre la sua conclusione
+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:
+\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
+ un valore massimo specificato da \var{lenght}.
+
+ \funcdecl{int ftruncate(int fd, off\_t length))} Identica a \func{truncate}
+ 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 \texttt{errno} viene settato ai valori:
+ \begin{errlist}
+ \item \texttt{EACCESS} non c'è il permesso di accedere al file.
+ \item \texttt{ENOTDIR} una componente del pathname non è una directory.
+ \item \texttt{EMLOOP} ci sono troppi link simbolici nel pathname.
+ \item \texttt{EFAULT} i puntatori usati sono fuori dallo spazio di indirizzi
+ del processo.
+ \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
+ completare l'operazione.
+ \item \texttt{ENOENT} il file non esiste.
+ \item \texttt{ENAMETOOLONG} il filename è troppo lungo.
+ \end{errlist}
+\end{functions}
-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.
+Se il file è più lungo della lunghezza specificata i dati in eccesso saranno
+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).
-% 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 tempi dei file}
+\label{sec:filedir_file_times}
+Il sistema mantiene per ciascun file tre tempi. Questi sono registrati
+nell'inode insieme agli altri attibuti del file e possono essere letti tramite
+la funzione \func{stat}, che li restituisce attraverso tre campi della
+struttura in \figref{fig:filedir_stat_struct}. Il significato di detti tempi e
+dei relativi campi è riportato nello schema in \ntab:
-\subsection{I flag \texttt{suid} e \texttt{sgid}}
-\label{sec:filedir_suid_sgid}
+\begin{table}[htb]
+ \centering
+ \begin{tabular}[c]{|c|l|l|c|}
+ \hline
+ Membro & Significato & Funzione&opzione \\
+ \hline
+ \hline
+ \var{st\_atime}& ultimo accesso ai dati del file &\func{read}& \cmd{-u}\\
+ \var{st\_mtime}& ultima modifica ai dati del file &\func{write}& default\\
+ \var{st\_ctime}& ultima modifica ai dati dell'inode&\func{chmod},
+ \func{utime} & \cmd{-c} \\
+ \hline
+ \end{tabular}
+ \caption{I tre tempi associati a ciascun file}
+ \label{tab:filedir_file_times}
+\end{table}
-\subsection{La titolarità di nuovi files e directory}
-\label{sec:filedir_ownership}
+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
+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
+le informazioni contenute nell'inode senza toccare il file, diventa necessario
+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).
+
+Il tempo di ultima modifica invece viene usato da \cmd{make} per decidere
+quali file necessitano di essere ricompilati o (talvolta insieme anche al
+tempo di cambiamento di stato) per decidere quali file devono essere
+archiviati per il backup. Il comando \cmd{ls} (quando usato con le opzioni
+\cmd{-l} o \cmd{-t}) mostra i tempi dei file secondo lo schema riportato
+nell'ultima colonna di \curtab.
+
+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.
+
+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.
-\subsection{La funzione \texttt{access}}
-\label{sec:filedir_access}
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|c|c|c|l|}
+ \hline
+ \multicolumn{1}{|c|}{Funzione}
+ &\multicolumn{3}{p{2cm}}{File o directory di riferimento}
+ &\multicolumn{3}{p{2cm}}{Directory genitrice del riferimento}
+ &\multicolumn{1}{|c|}{Note} \\
+ \cline{2-7}
+ & \textsl{(a)} & \textsl{(m)}& \textsl{(c)}
+ & \textsl{(a)} & \textsl{(m)}& \textsl{(c)}& \\
+ \hline
+ \hline
+ \func{chmod}, \func{fchmod}
+ & & &$\bullet$& & & & \\
+ \func{chown}, \func{fchown}
+ & & &$\bullet$& & & & \\
+ \func{creat}
+ &$\bullet$&$\bullet$&$\bullet$& &$\bullet$&$\bullet$& con
+ \macro{O\_CREATE} \\ \func{creat}
+ & &$\bullet$&$\bullet$& &$\bullet$&$\bullet$&
+ con \macro{O\_TRUNC} \\ \func{exec}
+ &$\bullet$& & & & & & \\
+ \func{lchown}
+ & & &$\bullet$& & & & \\
+ \func{link}
+ & & &$\bullet$& &$\bullet$&$\bullet$& \\
+ \func{mkdir}
+ &$\bullet$&$\bullet$&$\bullet$& &$\bullet$&$\bullet$& \\
+ \func{mkfifo}
+ &$\bullet$&$\bullet$&$\bullet$& &$\bullet$&$\bullet$& \\
+ \func{open}
+ &$\bullet$&$\bullet$&$\bullet$& &$\bullet$&$\bullet$& con
+ \macro{O\_CREATE} \\ \func{open}
+ & &$\bullet$&$\bullet$& & & & con
+ \macro{O\_TRUNC} \\ \func{pipe}
+ &$\bullet$&$\bullet$&$\bullet$& & & & \\
+ \func{read}
+ &$\bullet$& & & & & & \\
+ \func{remove}
+ & & &$\bullet$& &$\bullet$&$\bullet$& using
+ \func{unlink}\\ \func{remove}
+ & & & & &$\bullet$&$\bullet$& using
+ \func{rmdir}\\ \func{rename}
+ & & &$\bullet$& &$\bullet$&$\bullet$& per entrambi
+ gli argomenti\\ \func{rmdir}
+ & & & & &$\bullet$&$\bullet$& \\
+ \func{truncate}, \func{ftruncate}
+ & &$\bullet$&$\bullet$& & & & \\
+ \func{unlink}
+ & & &$\bullet$& &$\bullet$&$\bullet$& \\
+ \func{utime}
+ &$\bullet$&$\bullet$&$\bullet$& & & & \\
+ \func{write}
+ & &$\bullet$&$\bullet$& & & & \\
+ \hline
+ \end{tabular}
+ \caption{Effetti delle varie funzioni su tempi di ultimo accesso
+ \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento
+ \textsl{(c)}}
+ \label{tab:filedir_times_effects}
+\end{table}
-\subsection{La funzione \texttt{umask}}
-\label{sec:filedir_umask}
+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
+esiste.
-\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
-\label{sec:filedir_chmod}
-\subsection{Il flag \texttt{sticky}}
-\label{sec:filedir_sticky}
+\subsection{La funzione \texttt{utime}}
+\label{sec:filedir_utime}
-\subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
-\label{sec:filedir_chown}
+I tempi di ultimo accesso e modifica possono essere cambiati usando la
+funzione \func{utime}, il cui prototipo è:
+\begin{prototype}{utime.h}
+{int utime(const char * filename, struct utimbuf *times)}
+Cambia i tempi di ultimo accesso e modifica dell'inode specificato da
+\var{filename} secondo i campi \var{actime} e \var{modtime} di \var{times}. Se
+questa è \macro{NULL} allora viene usato il tempo corrente.
+La funzione restituisce zero in caso di successo e -1 in caso di errore, nel
+qual caso \var{errno} è settata opportunamente.
+\begin{errlist}
+\item \texttt{EACCESS} non si ha il permesso di scrittura sul file.
+\item \texttt{ENOENT} \var{filename} non esiste.
+\end{errlist}
+\end{prototype}
+
+La struttura \var{utimebuf} usata da \func{utime} è definita come:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+struct utimbuf {
+ time_t actime; /* access time */
+ time_t modtime; /* modification time */
+};
+\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
+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).
+
+Si tenga presente che non è comunque possibile specificare il tempo di
+cambiamento di stato del file, che viene comunque cambiato dal kernel tutte le
+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.
-%La struttura fondamentale che contiene i dati essenziali relativi ai file è il
-%cosiddetto \textit{inode}; questo conterrà informazioni come il
-%tipo di file (file di dispositivo, directory, file di dati, per un elenco
-%completo vedi \ntab), i permessi (vedi \secref{sec:file_perms}), le date (vedi
-%\secref{sec:file_times}).