+ Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
+ caso di errore \texttt{errno} può assumere uno dei valori: \macro{EBADF},
+ \macro{ENOENT}, \macro{ENOTDIR}, \macro{ELOOP}, \macro{EFAULT},
+ \macro{EACCESS}, \macro{ENOMEM}, \macro{ENAMETOOLONG}.
+\end{functions}
+
+La struttura \var{stat} è definita nell'header \file{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'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}[labelstep=0,frame=,indent=1cm]{}
+struct stat {
+ dev_t st_dev; /* device */
+ ino_t st_ino; /* inode */
+ mode_t st_mode; /* protection */
+ nlink_t st_nlink; /* number of hard links */
+ uid_t st_uid; /* user ID of owner */
+ gid_t st_gid; /* group ID of owner */
+ dev_t st_rdev; /* device type (if inode device) */
+ off_t st_size; /* total size, in bytes */
+ unsigned long st_blksize; /* blocksize for filesystem I/O */
+ unsigned long st_blocks; /* number of blocks allocated */
+ time_t st_atime; /* time of last access */
+ time_t st_mtime; /* time of last modification */
+ time_t st_ctime; /* time of last change */
+};
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \texttt{stat} per la lettura delle informazioni dei
+ file}
+ \label{fig:file_stat_struct}
+\end{figure}
+
+Si noti come i vari membri della struttura siano specificati come tipi nativi
+del sistema (di quelli definiti in \tabref{tab:xxx_sys_types}, e dichiarati in
+\file{sys/types.h}).
+
+
+\subsection{I tipi di file}
+\label{sec:file_types}
+
+Come riportato in \tabref{tab:file_file_types} in Linux oltre ai file e
+alle directory esistono vari altri oggetti che possono stare su un filesystem;
+il tipo di file è ritornato dalla \func{stat} nel campo \var{st\_mode}
+(che è quello che contiene anche le informazioni relative ai permessi).
+
+Dato che il valore numerico può variare a seconda delle implementazioni, lo
+standard POSIX definisce un insieme di macro per verificare il tipo di files,
+queste vengono usate anche da Linux che supporta pure le estensioni per link
+simbolici e socket definite da BSD, l'elenco completo di tutte le macro è
+riportato in \ntab.
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Macro} & \textbf{Tipo del file} \\
+ \hline
+ \hline
+ \macro{S\_ISREG(m)} & file regolare \\
+ \macro{S\_ISDIR(m)} & directory \\
+ \macro{S\_ISCHR(m)} & device a caratteri \\
+ \macro{S\_ISBLK(m)} & device a blocchi\\
+ \macro{S\_ISFIFO(m)} & fifo \\
+ \macro{S\_ISLNK(m)} & link simbolico \\
+ \macro{S\_ISSOCK(m)} & socket \\
+ \hline
+ \end{tabular}
+ \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h})}
+ \label{tab:file_type_macro}
+\end{table}
+
+Oltre a queste macro è possibile usare direttamente il valore di
+\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
+ \begin{tabular}[c]{|l|c|l|}
+ \hline
+ \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \macro{S\_IFMT} & 0170000 & bitmask per i bit del tipo di file \\
+ \macro{S\_IFSOCK} & 0140000 & socket \\
+ \macro{S\_IFLNK} & 0120000 & link simbolico \\
+ \macro{S\_IFREG} & 0100000 & file regolare \\
+ \macro{S\_IFBLK} & 0060000 & device a blocchi \\
+ \macro{S\_IFDIR} & 0040000 & directory \\
+ \macro{S\_IFCHR} & 0020000 & device a caratteri \\
+ \macro{S\_IFIFO} & 0010000 & fifo \\
+ \hline
+ \macro{S\_ISUID} & 0004000 & set UID bit \\
+ \macro{S\_ISGID} & 0002000 & set GID bit \\
+ \macro{S\_ISVTX} & 0001000 & sticky bit \\
+ \hline
+% \macro{S\_IRWXU} & 00700 & bitmask per i permessi del proprietario \\
+ \macro{S\_IRUSR} & 00400 & il proprietario ha permesso di lettura \\
+ \macro{S\_IWUSR} & 00200 & il proprietario ha permesso di scrittura \\
+ \macro{S\_IXUSR} & 00100 & il proprietario ha permesso di esecuzione\\
+ \hline
+% \macro{S\_IRWXG} & 00070 & bitmask per i permessi del gruppo \\
+ \macro{S\_IRGRP} & 00040 & il gruppo ha permesso di lettura \\
+ \macro{S\_IWGRP} & 00020 & il gruppo ha permesso di scrittura \\
+ \macro{S\_IXGRP} & 00010 & il gruppo ha permesso di esecuzione \\
+ \hline
+% \macro{S\_IRWXO} & 00007 & bitmask per i permessi di tutti gli altri\\
+ \macro{S\_IROTH} & 00004 & gli altri hanno permesso di lettura \\
+ \macro{S\_IWOTH} & 00002 & gli altri hanno permesso di esecuzione \\
+ \macro{S\_IXOTH} & 00001 & gli altri hanno permesso di esecuzione \\
+ \hline
+ \end{tabular}
+ \caption{Costanti per l'identificazione dei vari bit che compongono il campo
+ \var{st\_mode} (definite in \texttt{sys/stat.h})}
+ \label{tab: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:file_file_size}
+
+Il membro \var{st\_size} contiene la dimensione del file in byte (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
+byte. 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:file_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 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
+ 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
+ permesso di esecuzione una delle directory del pathname.
+ \item \texttt{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}.
+\end{functions}
+
+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).
+
+
+\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:
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|l|l|c|}
+ \hline
+ \textbf{Membro} & \textbf{Significato} & \textbf{Funzione}
+ & \textbf{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:file_file_times}
+\end{table}
+
+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.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|c|c|c|l|}
+ \hline
+ \multicolumn{1}{|p{3cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} &
+ \multicolumn{3}{|p{3cm}|}{\centering{File o directory di riferimento}}&
+ \multicolumn{3}{|p{3cm}|}{\centering{Directory genitrice del riferimento}}
+ &\multicolumn{1}{|p{3.6cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\
+ \cline{2-7}
+ \cline{2-7}
+ \multicolumn{1}{|p{3cm}|}{}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}}
+ &\multicolumn{1}{|p{3cm}|}{} \\
+ \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{Prospetto dei cambiamenti effettuati sui tempi di ultimo
+ accesso \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento
+ \textsl{(c)} dalle varie funzioni operanti su file e directory.}
+ \label{tab:file_times_effects}
+\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
+esiste.
+
+
+\subsection{La funzione \func{utime}}
+\label{sec:file_utime}
+
+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 \macro{EACCESS} non si ha il permesso di scrittura sul file.
+\item \macro{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.