From: Simone Piccardi Date: Sun, 22 Jan 2012 20:56:58 +0000 (+0000) Subject: Revisione della terza sezione del quarto capitolo (e qualche X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=d78bf87e6d67988bd75cb18f8e74a8f4dcaaf710;p=gapil.git Revisione della terza sezione del quarto capitolo (e qualche correzione di indici altrove) --- diff --git a/filedir.tex b/filedir.tex index fb148de..d2cd284 100644 --- a/filedir.tex +++ b/filedir.tex @@ -224,7 +224,7 @@ tab.~\ref{tab:file_inode_operations} le più rilevanti. sez.~\ref{sec:file_dir_creat_rem}).\\ \textsl{\code{rmdir}} & Rimuove una directory (vedi sez.~\ref{sec:file_dir_creat_rem}).\\ - \textsl{\code{mknod}} & Crea un file speciale (vedi + \textsl{\code{mknod}} & Crea un \index{file!speciali} file speciale (vedi sez.~\ref{sec:file_mknod}).\\ \textsl{\code{rename}} & Cambia il nome di un file (vedi sez.~\ref{sec:link_symlink_rename}).\\ @@ -576,7 +576,7 @@ per una maggiore affidabilità e possibilità di recupero in caso di corruzione del \itindex{superblock} \textit{superblock} principale. L'utilizzo di raggruppamenti di blocchi ha inoltre degli effetti positivi nelle prestazioni dato che viene ridotta la distanza fra i dati e la tabella degli -\itindex{inode} inode. +\itindex{inode} \textit{inode}. \begin{figure}[!htb] \centering @@ -587,10 +587,10 @@ dato che viene ridotta la distanza fra i dati e la tabella degli Le directory sono implementate come una \itindex{linked~list} \textit{linked list} con voci di dimensione variabile. Ciascuna voce della lista contiene -il numero di inode \itindex{inode}, la sua lunghezza, il nome del file e la sua -lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs}; in questo modo -è possibile implementare nomi per i file anche molto lunghi (fino a 1024 -caratteri) senza sprecare spazio disco. +il numero di \itindex{inode} \textit{inode}, la sua lunghezza, il nome del +file e la sua lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs}; +in questo modo è possibile implementare nomi per i file anche molto lunghi +(fino a 1024 caratteri) senza sprecare spazio disco. Con l'introduzione del filesystem \textit{ext3} sono state introdotte diverse modifiche strutturali, la principale di queste è quella che \textit{ext3} è un @@ -636,7 +636,6 @@ memorizzati. L'operazione di attivazione del filesystem è chiamata \phantom{mount(}unsigned long mountflags, const void *data)} \fdesc{Monta un filesystem.} } - {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} @@ -742,8 +741,9 @@ solo i 16 meno significativi. Oggi invece, con un numero di opzioni superiore, sono utilizzati tutti e 32 i bit, ma qualora nei 16 più significativi sia presente detto valore, che non esprime una combinazione valida, esso viene ignorato. Il valore dell'argomento deve essere espresso come maschera binaria -e i vari bit devono essere impostati con un OR aritmetico dei rispettivi flag, -identificati dalle costanti riportate nell'elenco seguente: +e i vari bit che lo compongono, detti anche \textit{mount flags}, devono +essere impostati con un OR aritmetico dei valori dalle costanti riportate +nell'elenco seguente: \begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}} \itindbeg{bind~mount} @@ -757,8 +757,8 @@ identificati dalle costanti riportate nell'elenco seguente: e \param{data} vengono ignorati. In sostanza quello che avviene è che in corrispondenza del \textit{pathname} - indicato da \param{target} viene montato l'\textit{inode} di \param{source}, - così che la porzione di albero dei file presente sotto + indicato da \param{target} viene montato \itindex{inode} l'\textit{inode} + di \param{source}, così che la porzione di albero dei file presente sotto \param{source} diventi visibile allo stesso modo sotto \param{target}. Trattandosi esattamente dei dati dello stesso filesystem, ogni modifica fatta in uno qualunque dei due rami di albero sarà visibile @@ -768,9 +768,9 @@ identificati dalle costanti riportate nell'elenco seguente: Dal punto di vista del \itindex{Virtual~File~System} VFS l'operazione è analoga al montaggio di un filesystem proprio nel fatto che anche in questo caso si inserisce in corrispondenza della \textit{dentry} di \texttt{target} - un diverso \textit{inode}, che stavolta, invece di essere quello della - radice del filesystem indicato da un file di dispositivo, è quello di una - directory già montata. + un diverso \itindex{inode} \textit{inode}, che stavolta, invece di essere + quello della radice del filesystem indicato da un file di dispositivo, è + quello di una directory già montata. Si tenga presente che proprio per questo sotto \param{target} comparirà il contenuto che è presente sotto \param{source} all'interno del filesystem in @@ -1318,8 +1318,9 @@ In sez.~\ref{sec:file_filesystem} abbiamo spiegato come la capacità di chiamare un file con nomi diversi sia connaturata con l'architettura di un filesystem per un sistema Unix, in quanto il nome del file che si trova in una directory è solo un'etichetta associata ad un puntatore che permette di -ottenere il riferimento ad un \textit{inode}, e che è quest'ultimo che viene -usato dal kernel per identificare univocamente gli oggetti sul filesystem. +ottenere il riferimento ad un \itindex{inode} \textit{inode}, e che è +quest'ultimo che viene usato dal kernel per identificare univocamente gli +oggetti sul filesystem. Questo significa che fintanto che si resta sullo stesso filesystem la realizzazione di un \textit{link} è immediata: uno stesso file può avere tanti @@ -1458,11 +1459,11 @@ anche a file che non esistono ancora. Il meccanismo funziona in quanto i \textit{symbolic link} sono riconosciuti come tali dal kernel\footnote{è uno dei diversi tipi di file visti in - tab.~\ref{tab:file_file_types}, contrassegnato come tale nell'\textit{inode} - e riconoscibile dal valore del campo \var{st\_mode} della struttura - \struct{stat} (vedi sez.~\ref{sec:file_stat}).} e tutta una serie di -funzioni di sistema (come \func{open} o \func{stat}) quando ricevono come -argomento il \textit{pathname} di un collegamento simbolico vanno + tab.~\ref{tab:file_file_types}, contrassegnato come tale \itindex{inode} + nell'\textit{inode} e riconoscibile dal valore del campo \var{st\_mode} + della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).} e tutta una +serie di funzioni di sistema (come \func{open} o \func{stat}) quando ricevono +come argomento il \textit{pathname} di un collegamento simbolico vanno automaticamente ad operare sul file da esso specificato. La funzione di sistema che permette di creare un nuovo collegamento simbolico è \funcd{symlink}, ed il suo prototipo è: @@ -1656,7 +1657,7 @@ 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 \textit{inode} all'interno di una directory. +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, è @@ -2185,10 +2186,10 @@ presenti nella directory. Sia BSD che SVr4 che POSIX.1-2001\footnote{il dall'implementazione.} prevedono che siano sempre presenti il campo \var{d\_name}, che contiene il nome del file nella forma di una stringa terminata da uno zero, ed il campo \var{d\_ino}, che contiene il numero di -\textit{inode} cui il file è associato e corrisponde al campo \var{st\_ino} di -\struct{stat}. La presenza di ulteriori campi opzionali oltre i due citati è -segnalata dalla definizione di altrettante macro nella forma -\code{\_DIRENT\_HAVE\_D\_XXX} dove \code{XXX} è il nome del relativo +\itindex{inode} \textit{inode} cui il file è associato e corrisponde al campo +\var{st\_ino} di \struct{stat}. La presenza di ulteriori campi opzionali +oltre i due citati è segnalata dalla definizione di altrettante macro nella +forma \code{\_DIRENT\_HAVE\_D\_XXX} dove \code{XXX} è il nome del relativo campo. Come si può evincere da fig.~\ref{fig:file_dirent_struct} nel caso di Linux sono pertanto definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE}, \macro{\_DIRENT\_HAVE\_D\_OFF} e \macro{\_DIRENT\_HAVE\_D\_RECLEN}, mentre non @@ -2546,7 +2547,7 @@ dell'\textit{inode} della directory di lavoro, per ottenerne il {La funzione ritorna il puntatore a \param{buffer} in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EACCES}] manca il permesso di lettura o di attraversameto su + \item[\errcode{EACCES}] manca il permesso di lettura o di attraversamento su uno dei componenti del \textit{pathname} (cioè su una delle directory superiori alla corrente). \item[\errcode{EINVAL}] l'argomento \param{size} è zero e \param{buffer} non @@ -2574,29 +2575,32 @@ sia diversa da zero, o della lunghezza esatta del \textit{pathname} altrimenti. In questo caso ci si deve ricordare di disallocare la stringa con \func{free} una volta cessato il suo utilizzo. -Di questa funzione esiste una versione alternativa \code{char *getwd(char - *buffer)} fatta per compatibilità all'indietro con BSD, che non consente di -specificare la dimensione del buffer; esso deve essere allocato in precedenza -ed avere una dimensione superiore a \const{PATH\_MAX} (di solito 256 byte, -vedi sez.~\ref{sec:sys_limits}); il problema è che in Linux non esiste una -dimensione superiore per un \textit{pathname}, per cui non è detto che il -buffer sia sufficiente a contenere il nome del file, e questa è la ragione -principale per cui questa funzione è deprecata. - -Un uso comune di \func{getcwd} è quello di salvare la directory di lavoro -iniziale per poi potervi tornare in un tempo successivo, un metodo alternativo -più veloce, se non si è a corto di file descriptor, è invece quello di aprire -all'inizio la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in -seguito con \func{fchdir}. - -Una seconda funzione usata per ottenere la directory di lavoro è \code{char - *get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una -\code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore -della variabile di ambiente \envvar{PWD}, che essendo costruita dalla shell -può contenere un \textit{pathname} comprendente anche dei collegamenti -simbolici. Usando \func{getcwd} infatti, essendo il \textit{pathname} ricavato -risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni -passaggio attraverso eventuali collegamenti simbolici. +Un uso comune di \func{getcwd} è quello di salvarsi la directory di lavoro +all'avvio del programma per poi potervi tornare in un tempo successivo, un +metodo alternativo più veloce, se non si è a corto di file descriptor, è +invece quello di aprire all'inizio la directory corrente (vale a dire +``\texttt{.}'') e tornarvi in seguito con \func{fchdir}. + +Di questa funzione esiste una versione alternativa per compatibilità +all'indietro con BSD, \funcm{getwd}, che non prevede l'argomento \param{size} +e quindi non consente di specificare la dimensione di \param{buffer} che +dovrebbe essere allocato in precedenza ed avere una dimensione sufficiente +(per BSD maggiore \const{PATH\_MAX}, che di solito 256 byte, vedi +sez.~\ref{sec:sys_limits}). Il problema è che su Linux non esiste una +dimensione superiore per la lunghezza di un \textit{pathname}, per cui non è +detto che il buffer sia sufficiente a contenere il nome del file, e questa è +la ragione principale per cui questa funzione è deprecata, e non la tratteremo. + +Una seconda funzione usata per ottenere la directory di lavoro è +\funcm{get\_current\_dir\_name},\footnote{la funzione è una estensione GNU e + presente solo nella \acr{glibc}.} che non prende nessun argomento ed è +sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la differenza +che se disponibile essa ritorna il valore della variabile di ambiente +\envvar{PWD}, che essendo costruita dalla shell può contenere un +\textit{pathname} comprendente anche dei collegamenti simbolici. Usando +\func{getcwd} infatti, essendo il \textit{pathname} ricavato risalendo +all'indietro l'albero della directory, si perderebbe traccia di ogni passaggio +attraverso eventuali collegamenti simbolici. Per cambiare la directory di lavoro si può usare la funzione di sistema \funcd{chdir}, equivalente del comando di shell \cmd{cd}, il cui nome sta @@ -2610,21 +2614,22 @@ appunto per \textit{change directory}, il suo prototipo è: {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{EACCES}] manca il permesso di ricerca su uno dei componenti + di \param{pathname}. \item[\errcode{ENOTDIR}] non si è specificata una directory. - \item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti \end{errlist} - ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, - \errval{ENOMEM}, \errval{ELOOP} e \errval{EIO} - nel loro significato generico.} + ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{EIO}, + \errval{ENAMETOOLONG}, \errval{ENOENT} e \errval{ENOMEM} nel loro + significato generico.} \end{funcproto} La funzione cambia la directory di lavoro in \param{pathname} ed ovviamente \param{pathname} deve indicare una directory per la quale si hanno i permessi di accesso. -Dato che anche le directory sono file, è possibile riferirsi ad esse anche -tramite un file descriptor, e non solo tramite il \textit{pathname}, per fare -questo si usa \funcd{fchdir}, il cui prototipo è: +Dato che ci si può riferire ad una directory anche tramite un file descriptor, +per cambiare directory di lavoro è disponibile anche la funzione di sistema +\funcd{fchdir}, il cui prototipo è: \begin{funcproto}{ \fhead{unistd.h} @@ -2632,70 +2637,70 @@ questo si usa \funcd{fchdir}, il cui prototipo è: \fdesc{Cambia la directory di lavoro per file descriptor.} } {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} assumerà assumerà i valori \errval{EBADF} o \errval{EACCES} - nel loro significato generico.} + caso \var{errno} assumerà i valori \errval{EBADF} o \errval{EACCES} nel loro + significato generico.} \end{funcproto} -La funzione è identica a \func{chdir}, ma usa il file descriptor \param{fd} -invece del \textit{pathname}. Anche in questo caso \param{fd} deve essere un -file descriptor valido che fa riferimento ad una directory. Inoltre l'unico -errore di accesso possibile (tutti gli altri sarebbero occorsi all'apertura -di \param{fd}), è quello in cui il processo non ha il permesso di -attraversamento alla directory specificata da \param{fd}. +La funzione è identica a \func{chdir}, ma prende come argomento un file +descriptor \param{fd} invece di un \textit{pathname}. Anche in questo +caso \param{fd} deve essere un file descriptor valido che fa riferimento ad +una directory. Inoltre l'unico errore di accesso possibile (tutti gli altri +sarebbero occorsi all'apertura di \param{fd}), è quello in cui il processo non +ha il permesso di attraversamento alla directory specificata da \param{fd}. \index{directory~di~lavoro|)} -\subsection{La creazione di file speciali} +\subsection{La creazione dei \textsl{file speciali}} \label{sec:file_mknod} \index{file!di~dispositivo|(} +\index{file!speciali|(} Finora abbiamo parlato esclusivamente di file, directory e collegamenti -simbolici; in sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema -prevede pure degli altri tipi di file speciali, come i file di dispositivo, le -fifo ed i socket (questi ultimi sono un caso a parte, essendo associati anche -alla comunicazione via rete, per cui ci saranno trattati in dettaglio a -partire da cap.~\ref{cha:socket_intro}). - -La manipolazione delle caratteristiche di questi diversi tipi di file e la -loro cancellazione può essere effettuata con le stesse funzioni che operano -sui file regolari; ma quando li si devono creare sono necessarie delle -funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui -prototipo è: -\begin{functions} - \headdecl{sys/types.h} - \headdecl{sys/stat.h} - \headdecl{fcntl.h} - \headdecl{unistd.h} - \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} - - Crea un \textit{inode} del tipo specificato sul filesystem. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà i valori: +simbolici, ma in sez.~\ref{sec:file_file_types} abbiamo visto che il sistema +prevede anche degli altri tipi di file, che in genere vanno sotto il nome +generico di \textsl{file speciali}, come i file di dispositivo, le fifo ed i +socket. + +La manipolazione delle caratteristiche di questi file speciali, il cambiamento +di nome o la loro cancellazione può essere effettuata con le stesse funzioni +che operano sugli altri file, ma quando li si devono creare sono necessarie, +come per le directory, delle funzioni apposite. La prima di queste è la +funzione di sistema \funcd{mknod}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{sys/stat.h} +\fhead{fcntl.h} +\fhead{unistd.h} +\fdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} +\fdesc{Crea un file speciale sul filesystem.} +} +{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{EPERM}] non si hanno privilegi sufficienti a creare - l'\texttt{inode}, o il filesystem su cui si è cercato di - creare \param{pathname} non supporta l'operazione. - \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una - fifo, un socket o un dispositivo. \item[\errcode{EEXIST}] \param{pathname} esiste già o è un collegamento simbolico. + \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una + fifo, un socket o un dispositivo. + \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare + \itindex{inode} l'\texttt{inode}, o il filesystem su cui si è cercato di + creare \param{pathname} non supporta l'operazione. \end{errlist} - ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG}, - \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, - \errval{ENOSPC}, \errval{EROFS}.} -\end{functions} + ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ELOOP}, + \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOSPC}, + \errval{ENOTDIR} e \errval{EROFS} nel loro significato generico.} +\end{funcproto} -La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}'' -sul filesystem, e viene in genere utilizzata per creare i file di dispositivo, -ma si può usare anche per creare file regolari. L'argomento -\param{mode} specifica sia il tipo di file che si vuole creare che i relativi -permessi, secondo i valori riportati in tab.~\ref{tab:file_mode_flags}, che -vanno combinati con un OR binario. I permessi sono comunque modificati nella -maniera usuale dal valore di \itindex{umask} \textit{umask} (si veda -sez.~\ref{sec:file_perm_management}). +La funzione permette di creare un \itindex{inode} \textit{inode} di tipo +generico sul filesystem, e viene in genere utilizzata per creare i file di +dispositivo, ma si può usare anche per creare qualunque tipo di file speciale +ed anche file regolari. L'argomento \param{mode} specifica sia il tipo di file +che si vuole creare che i relativi permessi, secondo i valori riportati in +tab.~\ref{tab:file_mode_flags}, che vanno combinati con un OR aritmetico. I +permessi sono comunque modificati nella maniera usuale dal valore di +\itindex{umask} \textit{umask} (si veda sez.~\ref{sec:file_perm_management}). Per il tipo di file può essere specificato solo uno fra i seguenti valori: \const{S\_IFREG} per un file regolare (che sarà creato vuoto), @@ -2704,7 +2709,8 @@ dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO} per una fifo;\footnote{con Linux la funzione non può essere usata per creare directory o collegamenti simbolici, si dovranno usare le funzioni \func{mkdir} e \func{symlink} a questo dedicate.} un valore diverso -comporterà l'errore \errcode{EINVAL}. +comporterà l'errore \errcode{EINVAL}. Inoltre \param{pathname} non deve +esistere, neanche come collegamento simbolico. Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere @@ -2722,18 +2728,19 @@ Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è di un socket è consentito anche agli utenti normali. I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno -al proprietario e al gruppo del processo che li ha creati, a meno che non si -sia attivato il bit \acr{sgid} per la directory o sia stata attivata la -semantica BSD per il filesystem (si veda -sez.~\ref{sec:file_ownership_management}) in cui si va a creare -\itindex{inode} l'\textit{inode}. +al proprietario e al gruppo del processo (usando \ids{UID} e \ids{GID} del +gruppo effettivo) che li ha creati a meno non sia presente il bit \acr{sgid} +per la directory o sia stata attivata la semantica BSD per il filesystem (si +veda sez.~\ref{sec:file_ownership_management}) in cui si va a creare +\itindex{inode} l'\textit{inode}, nel qual caso per il gruppo verrà usato il +\ids{GID} del proprietario della directory. Nella creazione di un file di dispositivo occorre poi specificare correttamente il valore di \param{dev}; questo infatti è di tipo \type{dev\_t}, che è un tipo primitivo (vedi tab.~\ref{tab:intro_primitive_types}) riservato per indicare un -\textsl{numero} di dispositivo; il kernel infatti identifica ciascun -dispositivo con un valore numerico. Originariamente questo era un intero a 16 +\textsl{numero} di dispositivo. Il kernel infatti identifica ciascun +dispositivo con un valore numerico, originariamente questo era un intero a 16 bit diviso in due parti di 8 bit chiamate rispettivamente \itindex{major~number} \textit{major number} e \itindex{minor~number} \textit{minor number}, che sono poi i due numeri mostrati dal comando @@ -2743,9 +2750,9 @@ dispositivo. Il \itindex{major~number} \textit{major number} identifica una classe di dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per indicare al kernel quale è il modulo che gestisce quella classe di -dispositivi; per identificare uno specifico dispositivo di quella classe (ad -esempio una singola porta seriale, o una partizione di un disco) si usa invece -il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi +dispositivi. Per identificare uno specifico dispositivo di quella classe (ad +esempio una singola porta seriale, o uno dei dischi presenti) si usa invece il +\itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi numeri con le relative corrispondenze ai vari dispositivi può essere trovato nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei sorgenti del kernel. @@ -2755,60 +2762,81 @@ massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo \type{dev\_t}, con delle dimensioni passate a 12 bit per il \itindex{major~number} \textit{major number} e 20 bit per il -\itindex{minor~number} \textit{minor number}. La transizione però ha anche -comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la -necessità di specificare il numero tramite delle opportune macro, così da non -avere problemi di compatibilità con eventuali ulteriori estensioni. - -Le macro sono definite nel file \headfile{sys/sysmacros.h}, che viene -automaticamente incluso quando si include \headfile{sys/types.h}; si possono +\itindex{minor~number} \textit{minor number}. La transizione però ha +comportato il fatto che \type{dev\_t} è diventato un \index{tipo!opaco} tipo +opaco, e la necessità di specificare il numero tramite delle opportune macro, +così da non avere problemi di compatibilità con eventuali ulteriori +estensioni. + +Le macro sono definite nel file \headfile{sys/sysmacros.h},\footnote{se si usa + la \acr{glibc} dalla versione 2.3.3 queste macro sono degli alias alle + versioni specifiche di questa libreria, \macro{gnu\_dev\_major}, + \macro{gnu\_dev\_minor} e \macro{gnu\_dev\_makedev} che si possono usare + direttamente, al costo di una minore portabilità.} che viene +automaticamente incluso quando si include \headfile{sys/types.h}. Si possono pertanto ottenere i valori del \itindex{major~number} \textit{major number} e \itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente con le macro \macro{major} e \macro{minor}: -\begin{functions} - \headdecl{sys/types.h} - \funcdecl{int \macro{major}(dev\_t dev)} - Restituisce il \itindex{major~number} \textit{major number} del dispositivo - \param{dev}. - - \funcdecl{int \macro{minor}(dev\_t dev)} - Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo - \param{dev}. -\end{functions} + +{\centering +\vspace{3pt} +\begin{funcbox}{ +\fhead{sys/types.h} +\fdecl{int \macro{major}(dev\_t dev)} +\fdesc{Restituisce il \itindex{major~number} \textit{major number} del + dispositivo \param{dev}.} +\fdecl{int \macro{minor}(dev\_t dev)} +\fdesc{Restituisce il \itindex{minor~number} \textit{minor number} del + dispositivo \param{dev}.} +} +\end{funcbox} +} + \noindent mentre una volta che siano noti \itindex{major~number} \textit{major number} e \itindex{minor~number} \textit{minor number} si potrà costruire il relativo identificativo con la macro \macro{makedev}: -\begin{functions} - \headdecl{sys/types.h} - \funcdecl{dev\_t \macro{minor}(int major, int minor)} - Restituisce l'identificativo di un dispositivo dati \itindex{major~number} - \textit{major number} e \itindex{minor~number} \textit{minor number}. -\end{functions} +{\centering +\vspace{3pt} +\begin{funcbox}{ +\fhead{sys/types.h} +\fdecl{dev\_t \macro{makedev}(int major, int minor)} +\fdesc{Dati \itindex{major~number} \textit{major number} e + \itindex{minor~number} \textit{minor number} restituisce l'identificativo di + un dispositivo.} +} +\end{funcbox} +} \index{file!di~dispositivo|)} -Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica -per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe}); -la funzione è \funcd{mkfifo} ed il suo prototipo è: -\begin{functions} - \headdecl{sys/types.h} \headdecl{sys/stat.h} - - \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} - - Crea una fifo. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES}, - \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC}, - \errval{ENOTDIR} e \errval{EROFS}.} -\end{functions} +Dato che la funzione di sistema \func{mknod} presenta diverse varianti nei +vari sistemi unix-like, lo standard POSIX.1-2001 la dichiara portabile solo in +caso di creazione delle fifo, ma anche in questo caso alcune combinazioni +degli argomenti restano non specificate, per cui nello stesso standard è stata +introdotta una funzione specifica per creare una fifo deprecando l'uso di +\func{mknod} a tale riguardo. La funzione è \funcd{mkfifo} ed il suo +prototipo è: + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{sys/stat.h} +\fdecl{int mkfifo(const char *pathname, mode\_t mode)} +\fdesc{Crea una fifo.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà \errval{EACCES}, \errval{EEXIST}, + \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC}, \errval{ENOTDIR} e + \errval{EROFS} nel loro significato generico.} +\end{funcproto} La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come per \func{mknod} il file \param{pathname} non deve esistere (neanche come collegamento simbolico); al solito i permessi specificati da \param{mode} vengono modificati dal valore di \itindex{umask} \textit{umask}. +\index{file!speciali|)} + \subsection{I file temporanei} \label{sec:file_temp_file} @@ -2821,17 +2849,28 @@ controllo e la creazione si ha giusto lo spazio per una possibile \itindex{race~condition} \textit{race condition} (si ricordi quanto visto in sez.~\ref{sec:proc_race_cond}). +Molti problemi di sicurezza derivano proprio da una creazione non accorta di +file temporanei che lascia aperta questa \itindex{race~condition} \textit{race + condition}. Un attaccante allora potrà sfruttarla con quello che viene +chiamato ``\textit{symlink attack}'' dove nell'intervallo fra la generazione +di un nome e l'accesso allo stesso, viene creato un collegamento simbolico con +quel nome verso un file diverso, ottenendo, se il programma sotto attacco ne +ha la capacità, un accesso privilegiato. + La \acr{glibc} provvede varie funzioni per generare nomi di file temporanei, di cui si abbia certezza di unicità al momento della generazione; storicamente la prima di queste funzioni create a questo scopo era \funcd{tmpnam},\footnote{la funzione è stata deprecata nella revisione POSIX.1-2008 dello standard POSIX.} il cui prototipo è: -\begin{prototype}{stdio.h}{char *tmpnam(char *string)} - Genera un nome univoco per un file temporaneo. - - \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o - \val{NULL} in caso di fallimento. Non sono definiti errori.} -\end{prototype} + +\begin{funcproto}{ +\fhead{stdio.h} +\fdecl{char *tmpnam(char *string)} +\fdesc{Genera un nome univoco per un file temporaneo.} +} +{La funzione ritorna il puntatore alla stringa con il nome in caso di successo + e \val{NULL} in caso di fallimento, non sono definiti errori.} +\end{funcproto} La funzione restituisce il puntatore ad una stringa contente un nome di file valido e non esistente al momento dell'invocazione; se si è passato come @@ -2850,13 +2889,16 @@ Di questa funzione esiste una versione \index{funzioni!rientranti} rientrante, \funcm{tmpnam\_r}, che non fa nulla quando si passa \val{NULL} come argomento. Una funzione simile, \funcd{tempnam}, permette di specificare un prefisso per il file esplicitamente, il suo prototipo è: -\begin{prototype}{stdio.h}{char *tempnam(const char *dir, const char *pfx)} - Genera un nome univoco per un file temporaneo. - \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o - \val{NULL} in caso di fallimento, \var{errno} viene impostata a - \errval{ENOMEM} qualora fallisca l'allocazione della stringa.} -\end{prototype} +\begin{funcproto}{ +\fhead{stdio.h} +\fdecl{char *tempnam(const char *dir, const char *pfx)} +\fdesc{Genera un nome univoco per un file temporaneo.} +} +{La funzione ritorna il puntatore alla stringa con il nome in caso di successo + e \val{NULL} per un errore, nel qual caso \var{errno} potrà assumere solo il + valore \errval{ENOMEM} qualora fallisca l'allocazione della stringa.} +\end{funcproto} La funzione alloca con \code{malloc} la stringa in cui restituisce il nome, per cui è sempre \index{funzioni!rientranti} rientrante, occorre però @@ -2873,34 +2915,41 @@ verificando che esista e sia accessibile, la prima valida fra le seguenti: \item la directory \file{/tmp}. \end{itemize*} -In ogni caso, anche se la generazione del nome è casuale, ed è molto difficile -ottenere un nome duplicato, nulla assicura che un altro processo non possa -avere creato, fra l'ottenimento del nome e l'apertura del file, un altro file -con lo stesso nome; per questo motivo quando si usa il nome ottenuto da una di -queste funzioni occorre sempre aprire il nuovo file in modalità di esclusione -(cioè con l'opzione \const{O\_EXCL} per i file descriptor o con il flag -\code{x} per gli \textit{stream}) che fa fallire l'apertura in caso il file -sia già esistente. +In ogni caso, anche se con queste funzioni la generazione del nome è casuale, +ed è molto difficile ottenere un nome duplicato, nulla assicura che un altro +processo non possa avere creato, fra l'ottenimento del nome e l'apertura del +file, un altro file o un collegamento simbolico con lo stesso nome. Per questo +motivo quando si usa il nome ottenuto da una di queste funzioni occorre sempre +assicurarsi che non si stia usando un collegamento simbolico e aprire il nuovo +file in modalità di esclusione (cioè con l'opzione \const{O\_EXCL} per i file +descriptor o con il flag \code{x} per gli \textit{stream}) che fa fallire +l'apertura in caso il file sia già esistente. Essendo disponibili alternative +migliori l'uso di queste funzioni è deprecato. Per evitare di dovere effettuare a mano tutti questi controlli, lo standard POSIX definisce la funzione \funcd{tmpfile}, che permette di ottenere in maniera sicura l'accesso ad un file temporaneo, il suo prototipo è: -\begin{prototype}{stdio.h}{FILE *tmpfile(void)} - Restituisce un file temporaneo aperto in lettura/scrittura. - - \bodydesc{La funzione ritorna il puntatore allo \textit{stream} associato al - file temporaneo in caso di successo e \val{NULL} in caso di errore, nel - qual caso \var{errno} assumerà i valori: - \begin{errlist} - \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. + +\begin{funcproto}{ +\fhead{stdio.h} +\fdecl{FILE *tmpfile(void)} +\fdesc{Apre un file temporaneo in lettura/scrittura.} +} +{La funzione ritorna il puntatore allo \textit{stream} associato al file + temporaneo in caso di successo e \val{NULL} per un errore, nel qual caso + \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{EEXIST}] non è stato possibile generare un nome univoco. - \end{errlist} - ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE}, - \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES}.} -\end{prototype} + \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. + \end{errlist} + ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE}, + \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES} nel loro significato + generico.} +\end{funcproto} + La funzione restituisce direttamente uno \textit{stream} già aperto (in -modalità \code{r+b}, si veda sez.~\ref{sec:file_fopen}) e pronto per l'uso, +modalità \code{w+b}, si veda sez.~\ref{sec:file_fopen}) e pronto per l'uso, che viene automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo standard non specifica in quale directory verrà aperto il file, ma la \acr{glibc} prima tenta con \const{P\_tmpdir} e poi con @@ -2910,21 +2959,23 @@ soffre di problemi di \itindex{race~condition} \textit{race condition}. Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo caso si possono usare le vecchie funzioni \funcd{mktemp} e \func{mkstemp} che modificano una stringa di input che serve da modello e che deve essere -conclusa da 6 caratteri \code{X} che verranno sostituiti da un codice +conclusa da 6 caratteri ``\texttt{X}'' che verranno sostituiti da un codice unico. La prima delle due è analoga a \func{tmpnam} e genera un nome casuale, il suo prototipo è: -\begin{prototype}{stlib.h}{char *mktemp(char *template)} - Genera un nome univoco per un file temporaneo. - - \bodydesc{La funzione ritorna il puntatore \param{template} in caso di - successo e \val{NULL} in caso di errore, nel qual caso \var{errno} - assumerà i valori: - \begin{errlist} + +\begin{funcproto}{ +\fhead{stlib.h} +\fdecl{char *mktemp(char *template)} +\fdesc{Genera un nome univoco per un file temporaneo.} +} +{La funzione ritorna il puntatore a \param{template} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}. - \end{errlist}} -\end{prototype} + \end{errlist}} +\end{funcproto} -La funzionane genera un nome univoco sostituendo le \code{XXXXXX} finali di +La funzione genera un nome univoco sostituendo le \code{XXXXXX} finali di \param{template}; dato che \param{template} deve poter essere modificata dalla funzione non si può usare una stringa costante. Tutte le avvertenze riguardo alle possibili \itindex{race~condition} \textit{race condition} date per @@ -2938,17 +2989,23 @@ usata. La seconda funzione, \funcd{mkstemp} è sostanzialmente equivalente a \func{tmpfile}, ma restituisce un file descriptor invece di un nome; il suo prototipo è: -\begin{prototype}{stlib.h}{int mkstemp(char *template)} - Genera un file temporaneo. - - \bodydesc{La funzione ritorna il file descriptor in caso di successo e - -1 in caso di errore, nel qual caso \var{errno} assumerà i valori: - \begin{errlist} + +\begin{funcproto}{ +\fhead{stlib.h} +\fdecl{int mkstemp(char *template)} +\fdesc{Apre un file temporaneo.} +} + +{La funzione ritorna il file descriptor in caso di successo e $-1$ per un + errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}. \item[\errcode{EEXIST}] non è riuscita a creare un file temporaneo, il contenuto di \param{template} è indefinito. - \end{errlist}} -\end{prototype} + \end{errlist}} +\end{funcproto} + Come per \func{mktemp} anche in questo caso \param{template} non può essere una stringa costante. La funzione apre un file in lettura/scrittura con la @@ -2964,12 +3021,16 @@ questa funzione esiste una variante \funcd{mkostemp}, introdotta specificamente dalla \acr{glibc},\footnote{la funzione è stata introdotta nella versione 2.7 delle librerie e richiede che sia definita la macro \macro{\_GNU\_SOURCE}.} il cui prototipo è: -\begin{prototype}{stlib.h}{int mkostemp(char *template, int flags)} - Genera un file temporaneo. - - \bodydesc{La funzione ritorna il file descriptor in caso di successo e - -1 in caso di errore, con gli stessi errori di \func{mkstemp}.} -\end{prototype} + +\begin{funcproto}{ +\fhead{stlib.h} +\fdecl{int mkostemp(char *template, int flags)} +\fdesc{Apre un file temporaneo.} +} +{La funzione ritorna un file descriptor in caso di successo e $-1$ per un + errore, nel qual caso \var{errno} assumerà gli stessi valori di + \func{mkstemp}.} +\end{funcproto} \noindent la cui sola differenza è la presenza dell'ulteriore argomento \var{flags} che consente di specificare i flag da passare ad \func{open} nell'apertura del file. @@ -2979,17 +3040,20 @@ In OpenBSD è stata introdotta un'altra funzione simile alle precedenti, \funcd{mkdtemp}, che crea invece una directory temporanea;\footnote{la funzione è stata introdotta nella \acr{glibc} a partire dalla versione 2.1.91 ed inserita nello standard POSIX.1-2008.} il suo prototipo è: -\begin{prototype}{stlib.h}{char *mkdtemp(char *template)} - Genera una directory temporanea. - - \bodydesc{La funzione ritorna il puntatore al nome della directory in caso - successo e \val{NULL} in caso di errore, nel qual caso \var{errno} - assumerà i valori: - \begin{errlist} + +\begin{funcproto}{ +\fhead{stlib.h} +\fdecl{char *mkdtemp(char *template)} +\fdesc{Crea una directory temporanea.} +} +{La funzione ritorna il puntatore al nome della directory in caso di successo + e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei + valori: + \begin{errlist} \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}. - \end{errlist} - più gli altri eventuali codici di errore di \func{mkdir}.} -\end{prototype} + \end{errlist} + più gli altri eventuali codici di errore di \func{mkdir}.} +\end{funcproto} La funzione genera una directory il cui nome è ottenuto sostituendo le \code{XXXXXX} finali di \param{template} con permessi \code{0700} (al solito @@ -2998,20 +3062,21 @@ creazione della directory è sempre esclusiva i precedenti problemi di \itindex{race~condition} \textit{race condition} non si pongono. + + + \section{La manipolazione delle caratteristiche dei file} \label{sec:file_infos} Come spiegato in sez.~\ref{sec:file_filesystem} tutte le informazioni generali relative alle caratteristiche di ciascun file, a partire dalle informazioni relative al controllo di accesso, sono mantenute \itindex{inode} -nell'\textit{inode}. - -Vedremo in questa sezione come sia possibile leggere tutte queste informazioni -usando la funzione \func{stat}, che permette l'accesso a tutti i dati -memorizzati \itindex{inode} nell'\textit{inode}; esamineremo poi le varie -funzioni usate per manipolare tutte queste informazioni (eccetto quelle che -riguardano la gestione del controllo di accesso, trattate in in -sez.~\ref{sec:file_access_control}). +nell'\textit{inode}. Vedremo in questa sezione come sia possibile leggere +tutte queste informazioni usando la funzione \func{stat}, che permette +l'accesso a tutti i dati memorizzati \itindex{inode} nell'\textit{inode}; +esamineremo poi le varie funzioni usate per manipolare tutte queste +informazioni, eccetto quelle che riguardano la gestione del controllo di +accesso, trattate in in sez.~\ref{sec:file_access_control}. \subsection{La lettura delle caratteristiche dei file} @@ -3020,39 +3085,47 @@ sez.~\ref{sec:file_access_control}). La lettura delle informazioni relative ai file è fatta attraverso la famiglia delle funzioni \func{stat} che sono quelle che usa il comando \cmd{ls} per poter ottenere e mostrare tutti i dati relativi ad un file; ne fanno parte le -funzioni \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui prototipi sono: -\begin{functions} - \headdecl{sys/types.h} - \headdecl{sys/stat.h} - \headdecl{unistd.h} - - \funcdecl{int stat(const char *file\_name, struct stat *buf)} - \funcdecl{int lstat(const char *file\_name, struct stat *buf)} - \funcdecl{int fstat(int filedes, struct stat *buf)} - Legge le informazioni di un file. +funzioni di sistema \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui +prototipi sono: - \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà uno dei valori: \errval{EBADF}, - \errval{ENOENT}, \errval{ENOTDIR}, \errval{ELOOP}, \errval{EFAULT}, - \errval{EACCES}, \errval{ENOMEM}, \errval{ENAMETOOLONG}.} -\end{functions} +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{sys/stat.h} +\fhead{unistd.h} +\fdecl{int stat(const char *file\_name, struct stat *buf)} +\fdecl{int lstat(const char *file\_name, struct stat *buf)} +\fdecl{int fstat(int filedes, struct stat *buf)} +\fdesc{Leggono le informazioni di un file.} +} +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EOVERFLOW}] il file ha una dimensione che non può essere + rappresentata nel tipo \type{off\_t} (può avvenire solo in caso di + programmi compilati su piattaforme a 32 bit senza le estensioni + (\texttt{-D \_FILE\_OFFSET\_BITS=64}) per file a 64 bit). + \end{errlist} + ed inoltre \errval{EFAULT} ed \errval{ENOMEM}, per \func{stat} e + \func{lstat} anche \errval{EACCES}, \errval{ELOOP}, \errval{ENAMETOOLONG}, + \errval{ENOENT}, \errval{ENOTDIR}, per \func{fstat} anche \errval{EBADF}, + nel loro significato generico.} +\end{funcproto} -La funzione \func{stat} legge le informazioni del file il cui -\textit{pathname} è specificato dalla stringa puntata da \param{file\_name} e -le inserisce nel buffer puntato dall'argomento \param{buf}; la funzione -\func{lstat} è identica a \func{stat} eccetto che se \param{file\_name} è un -collegamento simbolico vengono lette le informazioni relative ad esso e non al -file a cui fa riferimento. Infine \func{fstat} esegue la stessa operazione su -un file già aperto, specificato tramite il suo file -descriptor \param{filedes}. +La funzione \func{stat} legge le informazioni del file indicato +da \param{file\_name} e le inserisce nel buffer puntato +dall'argomento \param{buf}; la funzione \func{lstat} è identica a \func{stat} +eccetto che se \param{file\_name} è un collegamento simbolico vengono lette le +informazioni relative ad esso e non al file a cui fa riferimento. Infine +\func{fstat} esegue la stessa operazione su un file già aperto, specificato +tramite il suo file descriptor \param{filedes}. La struttura \struct{stat} usata da queste funzioni è definita nell'header \headfile{sys/stat.h} e in generale dipende dall'implementazione; la versione usata da Linux è mostrata in fig.~\ref{fig:file_stat_struct}, così come -riportata dalla pagina di manuale di \func{stat}; in realtà la definizione +riportata dalla pagina di manuale di \func{stat}. In realtà la definizione effettivamente usata nel kernel dipende dall'architettura e ha altri campi riservati per estensioni come tempi dei file più precisi (vedi -sez.~\ref{sec:file_file_times}), o per il padding dei campi. +sez.~\ref{sec:file_file_times}). \begin{figure}[!htb] \footnotesize @@ -3067,24 +3140,65 @@ sez.~\ref{sec:file_file_times}), o per il padding dei campi. \end{figure} Si noti come i vari membri della struttura siano specificati come tipi -primitivi del sistema (di quelli definiti in -tab.~\ref{tab:intro_primitive_types}, e dichiarati in \headfile{sys/types.h}). +primitivi del sistema, di quelli definiti in +tab.~\ref{tab:intro_primitive_types}, e dichiarati in \headfile{sys/types.h}, +con l'eccezione di \type{blksize\_t} e \type{blkcnt\_t} che sono nuovi tipi +introdotti per rendersi indipendenti dalla piattaforma. + +Benché la descrizione dei commenti di fig.~\ref{fig:file_stat_struct} sia +abbastanza chiara, vale la pena illustrare maggiormente il significato dei +campi di \structd{stat} su cui non torneremo in maggior dettaglio nel resto di +questa sezione: +\begin{itemize*} + +\item Il campo \var{st\_nlink} contiene il numero di \textit{hard link} che + fanno riferimento al file (il cosiddetto \textit{link count}) di cui abbiamo + già parlato in numerose occasioni. + +\item Il campo \var{st\_ino} contiene il numero di \itindex{inode} + \textit{inode} del file, quello viene usato all'interno del filesystem per + identificarlo e che può essere usato da un programma per determinare se due + \textit{pathname} fanno riferimento allo stesso file. + +\item Il campo \var{st\_dev} contiene il numero del dispositivo su cui risiede + il file (o meglio il suo filesystem). Si tratta dello stesso numero che si + usa con \func{mknod} e che può essere decomposto in \itindex{major~number} + \textit{major number} e \itindex{minor~number} \textit{minor number} con le + macro \macro{major} e \macro{minor} viste in sez.~\ref{sec:file_mknod}. + +\item Il campo \var{st\_rdev} contiene il numero di dispositivo associato al + file stesso ed ovviamente ha un valore significativo soltanto quando il file + è un dispositivo a caratteri o a blocchi. + +\item Il campo \var{st\_blksize} contiene la dimensione dei blocchi di dati + usati nell'I/O su disco, che è anche la dimensione usata per la + bufferizzazione dei dati dalle librerie del C per l'interfaccia degli + \textit{stream}. Leggere o scrivere blocchi di dati in dimensioni inferiori + a questo valore è inefficiente in quanto le operazioni su disco usano + comunque trasferimenti di questa dimensione. + +\end{itemize*} + + \subsection{I tipi di file} \label{sec:file_types} -Come riportato in tab.~\ref{tab:file_file_types} in Linux oltre ai file e alle -directory esistono altri oggetti che possono stare su un filesystem. Il tipo -di file è ritornato dalla funzione \func{stat} come maschera binaria nel campo -\var{st\_mode} (che contiene anche le informazioni relative ai permessi) di -una struttura \struct{stat}. - -Dato che il valore numerico può variare a seconda delle implementazioni, lo -standard POSIX definisce un insieme di macro per verificare il tipo di file, -queste vengono usate anche da Linux che supporta pure le estensioni allo -standard per i collegamenti simbolici e i socket definite da BSD; l'elenco -completo delle macro con cui è possibile estrarre l'informazione da -\var{st\_mode} è riportato in tab.~\ref{tab:file_type_macro}. +Abbiamo sottolineato fin dall'introduzione che Linux, come ogni sistema +unix-like, supporta oltre ai file ordinari e alle directory una serie di altri +``\textsl{tipi}'' di file che possono stare su un filesystem (elencati in +tab.~\ref{tab:file_file_types}). Il tipo di file viene ritornato dalle +funzioni della famiglia \func{stat} all'interno del campo \var{st\_mode} di +una struttura \struct{stat}. + +Il campo \var{st\_mode} è una maschera binaria in cui l'informazione viene +suddivisa nei vari bit che compongono, ed oltre a quelle sul tipo di file, +contiene anche le informazioni relative ai permessi su cui torneremo in +sez.~\ref{sec:file_perm_overview}. Dato che i valori numerici usati per +definire il tipo di file possono variare a seconda delle implementazioni, lo +standard POSIX definisce un insieme di macro che consentono di verificare il +tipo di file in maniera standardizzata. + \begin{table}[htb] \centering \footnotesize @@ -3106,17 +3220,14 @@ completo delle macro con cui è possibile estrarre l'informazione da \label{tab:file_type_macro} \end{table} -Oltre alle macro di tab.~\ref{tab:file_type_macro} è possibile usare -direttamente il valore di \var{st\_mode} per ricavare il tipo di file -controllando direttamente i vari bit in esso memorizzati. Per questo sempre in -\headfile{sys/stat.h} sono definite le costanti numeriche riportate in -tab.~\ref{tab:file_mode_flags}. - -Il primo valore dell'elenco di tab.~\ref{tab:file_mode_flags} è la maschera -binaria che permette di estrarre i bit nei quali viene memorizzato il tipo di -file, i valori successivi sono le costanti corrispondenti ai singoli bit, e -possono essere usati per effettuare la selezione sul tipo di file voluto, con -un'opportuna combinazione. +Queste macro vengono usate anche da Linux che supporta pure le estensioni allo +standard per i collegamenti simbolici e i socket definite da BSD.\footnote{le + ultime due macro di tab.~\ref{tab:file_type_macro}, che non sono presenti + nello standard POSIX fino alla revisione POSIX.1-1996.} L'elenco completo +delle macro con cui è possibile estrarre da \var{st\_mode} l'informazione +relativa al tipo di file è riportato in tab.~\ref{tab:file_type_macro}, tutte +le macro restituiscono un valore intero da usare come valore logico e prendono +come argomento il valore di \var{st\_mode}. \begin{table}[htb] \centering @@ -3135,21 +3246,21 @@ un'opportuna combinazione. \const{S\_IFCHR} & 0020000 & Dispositivo a caratteri.\\ \const{S\_IFIFO} & 0010000 & Fifo.\\ \hline - \const{S\_ISUID} & 0004000 & Set UID bit \itindex{suid~bit}.\\ - \const{S\_ISGID} & 0002000 & Set GID bit \itindex{sgid~bit}.\\ - \const{S\_ISVTX} & 0001000 & Sticky bit \itindex{sticky~bit}.\\ + \const{S\_ISUID} & 0004000 & \itindex{suid~bit} \acr{suid} bit.\\ + \const{S\_ISGID} & 0002000 & \itindex{sgid~bit} \acr{sgid} bit.\\ + \const{S\_ISVTX} & 0001000 & \itindex{sticky~bit} \acr{sticky} bit.\\ \hline -% \const{S\_IRWXU} & 00700 & Bitmask per i permessi del proprietario.\\ + \const{S\_IRWXU} & 00700 & Maschera per i permessi del proprietario.\\ \const{S\_IRUSR} & 00400 & Il proprietario ha permesso di lettura.\\ \const{S\_IWUSR} & 00200 & Il proprietario ha permesso di scrittura.\\ \const{S\_IXUSR} & 00100 & Il proprietario ha permesso di esecuzione.\\ \hline -% \const{S\_IRWXG} & 00070 & Bitmask per i permessi del gruppo.\\ + \const{S\_IRWXG} & 00070 & Maschera per i permessi del gruppo.\\ \const{S\_IRGRP} & 00040 & Il gruppo ha permesso di lettura.\\ \const{S\_IWGRP} & 00020 & Il gruppo ha permesso di scrittura.\\ \const{S\_IXGRP} & 00010 & Il gruppo ha permesso di esecuzione.\\ \hline -% \const{S\_IRWXO} & 00007 & Bitmask per i permessi di tutti gli altri\\ + \const{S\_IRWXO} & 00007 & Maschera per i permessi di tutti gli altri\\ \const{S\_IROTH} & 00004 & Gli altri hanno permesso di lettura.\\ \const{S\_IWOTH} & 00002 & Gli altri hanno permesso di esecuzione.\\ \const{S\_IXOTH} & 00001 & Gli altri hanno permesso di esecuzione.\\ @@ -3160,106 +3271,141 @@ un'opportuna combinazione. \label{tab:file_mode_flags} \end{table} -Ad esempio se si volesse impostare una condizione che permetta di controllare -se un file è una directory o un file ordinario si potrebbe definire la macro -di preprocessore: -\includecodesnip{listati/is_file_dir.h} -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. +Oltre alle macro di tab.~\ref{tab:file_type_macro}, che semplificano +l'operazione, è possibile usare direttamente il valore di \var{st\_mode} per +ricavare il tipo di file controllando direttamente i vari bit in esso +memorizzati. Per questo sempre in \headfile{sys/stat.h} sono definite le varie +costanti numeriche riportate in tab.~\ref{tab:file_mode_flags}, che +definiscono le maschere che consentono di selezionare non solo i dati relativi +al tipo di file, ma anche le informazioni relative ai permessi su cui +torneremo in sez.~\ref{sec:file_access_control} ed identificare i rispettivi +valori. + +Le costanti che servono per la identificazione del tipo di file sono riportate +nella prima sezione di tab.~\ref{tab:file_mode_flags}, mentre le sezioni +successive attengono alle costanti usate per i permessi. Il primo valore +dell'elenco è la maschera binaria \const{S\_IFMT} che permette di estrarre da +\var{st\_mode} (con un AND aritmetico) il blocco di bit nei quali viene +memorizzato il tipo di file. I valori successivi sono le costanti +corrispondenti ai vari tipi di file, e possono essere usate per verificare la +presenza del tipo di file voluto ed anche, con opportune combinazioni, +alternative fra più tipi di file. + +Si tenga presente però che a differenza dei permessi, l'informazione relativa +al tipo di file non è una maschera binaria, per questo motivo se si volesse +impostare una condizione che permetta di controllare se un file è una +directory o un file ordinario non si possono controllare dei singoli bit, ma +si dovrebbe usare una macro di preprocessore come: +\includecodesnip{listati/is_regdir.h} +in cui si estraggono ogni volta da \var{st\_mode} i bit relativi al tipo di +file e poi si effettua il confronto con i due possibili tipi di file. \subsection{Le dimensioni dei file} \label{sec:file_file_size} -Il campo \var{st\_size} di una struttura \struct{stat} contiene la dimensione -del file in byte, se si tratta di un file regolare. Nel caso di un +Abbiamo visto in fig.~\ref{fig:file_stat_struct} che campo \var{st\_size} di +una struttura \struct{stat} contiene la dimensione del file in byte. Questo +però è vero solo se si tratta di un file regolare, mentre nel caso di un collegamento simbolico la dimensione è quella del \textit{pathname} che il -collegamento stesso contiene; per le fifo questo campo è sempre nullo. - -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 \textit{stream}); scrivere sul file a blocchi di dati di -dimensione inferiore sarebbe inefficiente. - -Si tenga conto che la 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 \index{file!\textit{hole}} \textit{holes} -(letteralmente \textsl{buchi}) che si formano tutte le volte che si va a -scrivere su un \itindex{sparse~file} file dopo aver eseguito uno spostamento -oltre la sua fine (tratteremo in dettaglio l'argomento in -sez.~\ref{sec:file_lseek}). +collegamento stesso contiene mentre per le fifo ed i file di dispositivo +questo campo è sempre nullo. + +Il campo \var{st\_blocks} invece definisce la lunghezza del file in blocchi di +512 byte. La differenze con \var{st\_size} è che in questo caso si fa +riferimento alla quantità di spazio disco allocata per il file, e non alla +dimensione dello stesso che si otterrebbe leggendolo sequenzialmente. + +Si deve tener presente infatti che la lunghezza del file riportata in +\var{st\_size} non è detto che corrisponda all'occupazione dello spazio su +disco, e non solo perché la parte finale del file potrebbe riempire +parzialmente un blocco. In un sistema unix-like infatti è possibile +l'esistenza dei cosiddetti \itindex{sparse~file} \textit{sparse file}, cioè +file in cui sono presenti dei ``\textsl{buchi}'' \index{file!\textit{hole}} +(\textit{holes} nella nomenclatura inglese) che si formano tutte le volte che +si va a scrivere su un file dopo aver eseguito uno spostamento oltre la sua +fine (tratteremo in dettaglio l'argomento in sez.~\ref{sec:file_lseek}). In questo caso si avranno risultati differenti a seconda del modo 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 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}. +caso per i ``\textsl{buchi}'' \index{file!\textit{hole}} 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{lseek} 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. +Se è sempre possibile allargare un file, scrivendoci sopra o usando la +funzione \func{lseek} (vedi sez.~\ref{sec:file_lseek}) 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 \const{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra -dimensione si possono usare le due funzioni \funcd{truncate} e +dimensione si possono usare le due funzioni di sistema \funcd{truncate} e \funcd{ftruncate}, i cui prototipi sono: -\begin{functions} - \headdecl{unistd.h} - - \funcdecl{int truncate(const char *file\_name, off\_t length)} - - \funcdecl{int ftruncate(int fd, off\_t length))} - Troncano un file alla lunghezza \param{length}. - - \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} viene impostata opportunamente; per - \func{ftruncate} si hanno i valori: +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int ftruncate(int fd, off\_t length))} +\fdecl{int truncate(const char *file\_name, off\_t length)} +\fdesc{Troncano un file.} +} +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EINTR}] si è stati interrotti da un segnale. + \item[\errcode{EINVAL}] \param{length} è negativa o maggiore delle + dimensioni massime di un file. + \item[\errcode{EPERM}] il filesystem non supporta il troncamento di un file. + \item[\errcode{ETXTBSY}] il file è un programma in esecuzione. + \end{errlist} + per entrambe, mentre per \func{ftruncate} si avranno anche: \begin{errlist} - \item[\errcode{EBADF}] \param{fd} non è un file descriptor. - \item[\errcode{EINVAL}] \param{fd} è un riferimento ad un socket, non a un - file o non è aperto in scrittura. + \item[\errcode{EBADF}] \param{fd} non è un file descriptor. + \item[\errcode{EINVAL}] \param{fd} non è un riferimento a un file o non è + aperto in scrittura. \end{errlist} - per \func{truncate} si hanno: + e per \func{truncate} si avranno anche: \begin{errlist} - \item[\errcode{EACCES}] il file non ha permesso di scrittura o non si ha il - permesso di esecuzione una delle directory del \textit{pathname}. - \item[\errcode{ETXTBSY}] il file è un programma in esecuzione. + \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file o il + permesso di attraversamento di una delle componenti del \textit{pathname}. + \item[\errcode{EISDIR}] \param{file\_name} fa riferimento ad una directory. \end{errlist} - ed anche \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT}, - \errval{EROFS}, \errval{EIO}, \errval{EFAULT}, \errval{ELOOP}.} -\end{functions} + ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP}, + \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} e \errval{EROFS} + nel loro significato generico.} +\end{funcproto} Entrambe le funzioni fan sì che la dimensione del file sia troncata ad un valore massimo specificato da \param{length}, e si distinguono solo per il -fatto che il file viene indicato con il \textit{pathname} \param{file\_name} -per \func{truncate} e con il file descriptor \param{fd} per \funcd{ftruncate}; -se il file è più lungo della lunghezza specificata i dati in eccesso saranno +fatto che il file viene indicato con un \textit{pathname} per \func{truncate} +e con un file descriptor per \funcd{ftruncate}. Si tenga presente che 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; nel caso di Linux viene esteso con la creazione di un -\index{file!\textit{hole}} \textsl{buco} nel \itindex{sparse~file} file e ad -una lettura si otterranno degli zeri; si tenga presente però che questo -comportamento è supportato solo per filesystem nativi, ad esempio su un -filesystem non nativo come il VFAT di Windows questo non è possibile. +Il comportamento in caso di lunghezza del file inferiore a \param{length} non +è specificato e dipende dall'implementazione: il file può essere lasciato +invariato o esteso fino alla lunghezza scelta. Nel caso di Linux viene esteso +con la creazione di un \index{file!\textit{hole}} \textsl{buco} nel +\itindex{sparse~file} file e ad una lettura si otterranno degli zeri, si tenga +presente però che questo comportamento è supportato solo per filesystem +nativi, ad esempio su un filesystem non nativo come il VFAT di Windows questo +non è possibile. + \subsection{I tempi dei file} \label{sec:file_file_times} -Il sistema mantiene per ciascun file tre tempi, questi sono registrati -\itindex{inode} nell'\textit{inode} insieme agli altri attributi del file e -possono essere letti tramite la funzione \func{stat}, che li restituisce -attraverso tre specifici campi della struttura \struct{stat} di -fig.~\ref{fig:file_stat_struct}. Il significato di detti tempi e dei relativi -campi è riportato nello schema in tab.~\ref{tab:file_file_times}, dove è anche -riportato un esempio delle funzioni che effettuano cambiamenti su di essi. Il -valore è espresso nel cosiddetto \itindex{calendar~time} \textit{calendar - time}, su cui torneremo in dettaglio in sez.~\ref{sec:sys_time}. +Il sistema mantiene per ciascun file tre tempi, che sono registrati +\itindex{inode} nell'\textit{inode} insieme agli altri attributi del +file. Questi possono essere letti tramite la funzione \func{stat}, che li +restituisce attraverso tre campi della struttura \struct{stat} di +fig.~\ref{fig:file_stat_struct}. Il significato di questi tempi e dei relativi +campi della struttura \struct{stat} è illustrato nello schema di +tab.~\ref{tab:file_file_times}, dove è anche riportato un esempio delle +funzioni che effettuano cambiamenti su di essi. Il valore del tempo è espresso +nel cosiddetto \itindex{calendar~time} \textit{calendar time}, su cui +torneremo in dettaglio in sez.~\ref{sec:sys_time}. \begin{table}[htb] \centering @@ -3283,28 +3429,32 @@ valore è espresso nel cosiddetto \itindex{calendar~time} \textit{calendar \end{table} Il primo punto da tenere presente è la differenza fra il cosiddetto tempo di -ultima modifica (il \textit{modification time}, \var{st\_mtime}) e il tempo di -ultimo 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 \itindex{inode} dell'\textit{inode}. Dato che -esistono molte operazioni, come la funzione \func{link} e altre che vedremo in -seguito, che modificano solo le informazioni contenute \itindex{inode} -nell'\textit{inode} senza toccare il contenuto del file, diventa necessario -l'utilizzo di questo secondo tempo. +ultima modifica (il \textit{modification time}) riportato in \var{st\_mtime}, +ed il tempo di ultimo cambiamento di stato (il \textit{change status time}) +riportato in \var{st\_ctime}. Il primo infatti fa riferimento ad una modifica +del contenuto di un file, mentre il secondo ad una modifica dei metadati +\itindex{inode} dell'\textit{inode}. Dato che esistono molte operazioni, come +la funzione \func{link} e altre che vedremo in seguito, che modificano solo le +informazioni contenute \itindex{inode} nell'\textit{inode} senza toccare il +contenuto del file, diventa necessario l'utilizzo di questo secondo tempo. Il tempo di ultima modifica viene usato ad esempio da programmi come -\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 tempo di ultimo accesso viene -di solito usato per identificare i file che non vengono più utilizzati per un -certo lasso di tempo. Ad esempio un programma come \texttt{leafnode} lo usa -per cancellare gli articoli letti più vecchi, mentre \texttt{mutt} lo usa per -marcare i messaggi di posta che risultano letti. Il sistema non tiene conto -dell'ultimo accesso \itindex{inode} all'\textit{inode}, pertanto funzioni come -\func{access} o \func{stat} non hanno alcuna influenza sui tre tempi. 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 -tab.~\ref{tab:file_file_times}. +\cmd{make} per decidere quali file necessitano di essere ricompilati perché +più recenti dei loro sorgenti oppure dai programmi di backup, talvolta insieme +anche al tempo di cambiamento di stato, per decidere quali file devono essere +aggiornati nell'archiviazione. Il tempo di ultimo accesso viene di solito +usato per identificare i file che non vengono più utilizzati per un certo +lasso di tempo. Ad esempio un programma come \texttt{leafnode} lo usa per +cancellare gli articoli letti più vecchi, mentre \texttt{mutt} lo usa per +marcare i messaggi di posta che risultano letti. + +Il sistema non tiene mai conto dell'ultimo accesso \itindex{inode} +all'\textit{inode}, pertanto funzioni come \func{access} o \func{stat} non +hanno alcuna influenza sui tre tempi. 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 tab.~\ref{tab:file_file_times}. Si noti anche +come non esista, a differenza di altri sistemi operativi, un \textsl{tempo di + creazione} di un file. L'aggiornamento del tempo di ultimo accesso è stato a lungo considerato un difetto progettuale di Unix, questo infatti comporta la necessità di @@ -3312,24 +3462,27 @@ effettuare un accesso in scrittura sul disco anche in tutti i casi in cui questa informazione non interessa e sarebbe possibile avere un semplice accesso in lettura sui dati bufferizzati. Questo comporta un ovvio costo sia in termini di prestazioni, che di consumo di risorse come la batteria per i -portatili, o cicli di riscrittura per i dischi su memorie riscrivibili. - -% TODO aggiustare per il contenuto duplicato con le analoghe MS_* - -Per questo motivo, onde evitare di mantenere una informazione che nella -maggior parte dei casi non interessa, è sempre stato possibile disabilitare -l'aggiornamento del tempo di ultimo accesso con l'opzione di montaggio -\texttt{noatime}. Dato però che questo può creare problemi a qualche -programma, in Linux è stata introdotta la opzione \texttt{relatime} che esegue -l'aggiornamento soltanto se il tempo di ultimo accesso è precedente al tempo di -ultima modifica o cambiamento, così da rendere evidente che vi è stato un -accesso dopo la scrittura, ed evitando al contempo ulteriori operazioni su -disco negli accessi successivi. In questo modo l'informazione relativa al -fatto che un file sia stato letto resta disponibile, e ad esempio i programmi -citati in precedenza continuano a funzionare. Questa opzione, a partire dal -kernel 2.6.30, è diventata il comportamento di default e non deve più essere -specificata esplicitamente.\footnote{si può comunque riottenere il vecchio - comportamento usando la opzione di montaggio \texttt{strictatime}.} +portatili, o i cicli di riscrittura per i dischi su memorie riscrivibili. + + +Per questo motivo abbiamo visto in sez.~\ref{sec:filesystem_mounting} come +nello sviluppo del kernel siano stati introdotti degli opportuni \textit{mount + flag} che consentissero di evitare di aggiornare continuamente una +informazione che nella maggior parte dei casi non interessa. Per questo i +valori che si possono trovare per l'\textit{access time} dipendono dalle +opzioni di montaggio, ed anche, essendo stato cambiato il comportamento di +default a partire dalla versione 2.6.30, dal kernel che si sta usando. + +In generale quello che si ha con i kernel più recenti è che il tempo di ultimo +accesso viene aggiornato solo se è precedente al tempo di ultima modifica o +cambiamento, o se è passato più di un giorno dall'ultimo accesso. Così si può +rendere evidente che vi è stato un accesso dopo una modifica e che il file +viene comunque osservato regolarmente, conservando tutte le informazioni +veramente utili senza dover consumare risorse in scritture continue per +mantenere costantemente aggiornata una informazione che questo punto non ha +più nessuna rilevanza pratica.\footnote{qualora ce ne fosse la necessità è + comunque possibile, tramite l'opzione di montaggio \texttt{strictatime}, + richiedere in ogni caso il comportamento tradizionale.} \begin{table}[htb] \centering @@ -3337,20 +3490,20 @@ specificata esplicitamente.\footnote{si può comunque riottenere il vecchio \begin{tabular}[c]{|l|c|c|c|c|c|c|l|} \hline \multicolumn{1}{|p{2.8cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} & - \multicolumn{3}{|p{3.4cm}|}{\centering{ + \multicolumn{3}{|p{3.2cm}|}{\centering{ \textbf{File o directory del riferimento}}}& - \multicolumn{3}{|p{3.4cm}|}{\centering{ + \multicolumn{3}{|p{3.2cm}|}{\centering{ \textbf{Directory contenente il riferimento}}} &\multicolumn{1}{|p{3.4cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\ \cline{2-7} \cline{2-7} - \multicolumn{1}{|p{3cm}|}{} - &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}} - &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}} - &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(c)}}} - &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}} - &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}} - &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(c)}}} + \multicolumn{1}{|p{2.8cm}|}{} + &\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 @@ -3372,6 +3525,8 @@ specificata esplicitamente.\footnote{si può comunque riottenere il vecchio & -- & -- &$\bullet$& -- &$\bullet$&$\bullet$&\\ \func{mkdir} &$\bullet$&$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&\\ + \func{mknod} + &$\bullet$&$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&\\ \func{mkfifo} &$\bullet$&$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&\\ \func{open} @@ -3401,13 +3556,15 @@ specificata esplicitamente.\footnote{si può comunque riottenere il vecchio & -- & -- &$\bullet$& -- &$\bullet$&$\bullet$&\\ \func{utime} &$\bullet$&$\bullet$&$\bullet$& -- & -- & -- &\\ + \func{utimes} + &$\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.} + accesso \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento di + stato \textsl{(c)} dalle varie funzioni operanti su file e directory.} \label{tab:file_times_effects} \end{table} @@ -3416,44 +3573,55 @@ L'effetto delle varie funzioni di manipolazione dei file sui relativi tempi è illustrato in tab.~\ref{tab:file_times_effects}, facendo riferimento al comportamento classico per quanto riguarda \var{st\_atime}. 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 anch'esse file che contengono -una lista di nomi, che il sistema tratta in maniera del tutto analoga a tutti -gli altri. +lo contiene. Questi ultimi possono essere capiti immediatamente se si tiene +conto di quanto già detto e ripetuto a partire da +sez.~\ref{sec:file_filesystem}, e cioè che anche le directory sono anch'esse +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 un'operazione su un file che 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 tipo di operazione 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. - -Si noti infine come \var{st\_ctime} non abbia nulla a che fare con il tempo di -creazione del file, usato in molti altri sistemi operativi, ma che in Unix non -esiste. Per questo motivo quando si copia un file, a meno di preservare +scrivere sulla directory che lo contiene cambiandone il tempo di ultima +modifica. Un esempio di questo tipo di operazione 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. + +Si ricordi infine come \var{st\_ctime} non è il tempo di creazione del file, +che in Unix non esiste, anche se può corrispondervi per file che non sono mai +stati modificati. Per questo motivo, a differenza di quanto avviene con altri +sistemi operativi, quando si copia un file, a meno di preservare esplicitamente i tempi (ad esempio con l'opzione \cmd{-p} di \cmd{cp}) esso -avrà sempre il tempo corrente come data di ultima modifica. +avrà sempre il tempo corrente in cui si è effettuata la copia come data di +ultima modifica. -I tempi di ultimo accesso e modifica possono essere modificati esplicitamente -usando la funzione \funcd{utime}, il cui prototipo è: -\begin{prototype}{utime.h} - {int utime(const char *filename, struct utimbuf *times)} - Modifica i tempi di ultimo accesso e modifica di un file. +I tempi di ultimo accesso ed ultima modifica possono essere modificati +esplicitamente usando la funzione di sistema \funcd{utime}, il cui prototipo +è: - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file. - \item[\errcode{EPERM}] non si è proprietari del file. - \end{errlist} - ed inoltre \errval{EROFS} e \errval{ENOENT}.} -\end{prototype} +\begin{funcproto}{ +\fhead{utime.h} +\fdecl{int utime(const char *filename, struct utimbuf *times)} +\fdesc{Modifica i tempi di ultimo accesso ed ultima modifica di un file.} +} + +{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{EACCES}] non c'è il permesso di attraversamento per uno dei + componenti di \param{filename} o \param{times} è \val{NULL} e non si ha il + permesso di scrittura sul file, o non si è proprietari del file o non si + hanno i privilegi di amministratore. + \item[\errcode{EPERM}] \param{times} non è \val{NULL}, e non si è + proprietari del file o non si hanno i privilegi di amministratore. + \end{errlist} + ed inoltre \errval{ENOENT} e \errval{EROFS} nel loro significato generico.} +\end{funcproto} -La funzione cambia i tempi di ultimo accesso e modifica del file specificato -dall'argomento \param{filename}, e richiede come secondo argomento il -puntatore ad una struttura \struct{utimbuf}, la cui definizione è riportata in -fig.~\ref{fig:struct_utimebuf}, con i nuovi valori di detti tempi -(rispettivamente nei campi \var{actime} e \var{modtime}). Se si passa un +La funzione cambia i tempi di ultimo accesso e di ultima modifica del file +specificato dall'argomento \param{filename}, e richiede come secondo argomento +il puntatore ad una struttura \struct{utimbuf}, la cui definizione è riportata +in fig.~\ref{fig:struct_utimebuf}, con i nuovi valori di detti tempi +(rispettivamente nei campi \var{actime} e \var{modtime}). Se si passa un puntatore nullo verrà impostato il tempo corrente. \begin{figure}[!htb] @@ -3467,21 +3635,28 @@ puntatore nullo verrà impostato il tempo corrente. \label{fig:struct_utimebuf} \end{figure} -L'effetto della funzione e i privilegi necessari per eseguirla dipendono da -cosa è l'argomento \param{times}; se è \val{NULL} la funzione imposta 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 +L'effetto della funzione ed i privilegi necessari per eseguirla dipendono dal +valore dell'argomento \param{times}. Se è \val{NULL} la funzione imposta il +tempo corrente ed è sufficiente avere accesso in scrittura al file o essere +proprietari del file o avere i privilegi di amministratore. Se invece si è +specificato un valore diverso la funzione avrà successo solo se si è +proprietari del file o se si hanno i privilegi di amministratore.\footnote{per + essere precisi la \itindex{capabilities} capacità \const{CAP\_FOWNER}.} In +entrambi i casi per verificare la proprietà del file viene utilizzato +l'\ids{UID} effettivo del processo. + +Si tenga presente che non è possibile modificare manualmente il tempo di cambiamento di stato del file, che viene aggiornato direttamente dal kernel -tutte le volte che si modifica \itindex{inode} l'\textit{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 \index{file!di~dispositivo} file di dispositivo, scrivendo direttamente sul -disco senza passare attraverso il filesystem, ma ovviamente in questo modo la -cosa è più complicata da realizzare. +tutte le volte che si modifica \itindex{inode} l'\textit{inode}, e 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 \index{file!di~dispositivo} file di dispositivo, +scrivendo direttamente sul disco senza passare attraverso il filesystem, ma +ovviamente in questo modo la cosa è più complicata da +realizzare.\footnote{esistono comunque molti programmi che consentono di farlo + con relativa semplicità per cui non si dia per scontato che il valore sia + credibile in caso di macchina compromessa.} A partire dal kernel 2.6 la risoluzione dei tempi dei file, che nei campi di tab.~\ref{tab:file_file_times} è espressa in secondi, è stata portata ai @@ -3495,22 +3670,18 @@ supporto per questa maggior precisione sia assente questi campi aggiuntivi saranno nulli. Per la gestione di questi nuovi valori è stata definita una seconda funzione -di modifica, \funcd{utimes}, che consente di specificare tempi con maggior +di sistema, \funcd{utimes}, che consente di specificare tempi con maggior precisione; il suo prototipo è: -\begin{prototype} - {sys/time.h} - {int utimes(const char *filename, struct timeval times[2])} - Modifica i tempi di ultimo accesso e modifica di un file. - - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file. - \item[\errcode{EPERM}] non si è proprietari del file. - \end{errlist} - ed inoltre \errval{EROFS} e \errval{ENOENT}.} -\end{prototype} +\begin{funcproto}{ +\fhead{sys/time.h} +\fdecl{int utimes(const char *filename, struct timeval times[2])} +\fdesc{Modifica i tempi di ultimo accesso e ultima modifica di un file.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà gli stessi valori di \func{utime}.} +\end{funcproto} + La funzione è del tutto analoga alla precedente \func{utime} ma usa come secondo argomento un vettore di due strutture \struct{timeval}, la cui definizione è riportata in fig.~\ref{fig:sys_timeval_struct}, che consentono @@ -3536,56 +3707,52 @@ Oltre ad \func{utimes} su Linux sono presenti altre due funzioni,\footnote{le consentono rispettivamente di effettuare la modifica utilizzando un file già aperto o di eseguirla direttamente su un collegamento simbolico. I relativi prototipi sono: -\begin{functions} - \headdecl{sys/time.h} - - \funcdecl{int futimes(int fd, const struct timeval tv[2])} Cambia i tempi - di un file già aperto specificato tramite il file descriptor \param{fd}. - \funcdecl{int lutimes(const char *filename, const struct timeval tv[2])} - Cambia i tempi di \param{filename} anche se questo è un collegamento - simbolico. - - - \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un - errore, nel qual caso \var{errno} assumerà gli stessi valori di - \func{utimes}, con in più per \func{futimes}: +\begin{funcproto}{ +\fhead{sys/time.h} +\fdecl{int futimes(int fd, const struct timeval tv[2])} +\fdesc{Cambia i tempi di un file già aperto.} +\fdecl{int lutimes(const char *filename, const struct timeval tv[2])} +\fdesc{Cambia i tempi di un collegamento simbolico.} +} + +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno gli stessi valori di \func{utimes}, con in più + per \func{futimes}: \begin{errlist} - \item[\errcode{EBADF}] \param{fd} non è un file descriptor. + \item[\errcode{EBADF}] \param{fd} non è un file descriptor. \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile. - \end{errlist}} -\end{functions} + \end{errlist}} +\end{funcproto} Le due funzioni anno lo stesso comportamento di \texttt{utimes} e richiedono gli stessi privilegi per poter operare, la differenza è che con \func{futimes} -si può indicare il file su cui operare facendo riferimento al relativo file -descriptor mentre con \func{lutimes} nel caso in cui \param{filename} sia un -collegamento simbolico saranno modificati i suoi tempi invece di quelli del -file a cui esso punta. +si può indicare il file su cui operare se questo è già aperto facendo +riferimento al suo file descriptor mentre con \func{lutimes} nel caso in +cui \param{filename} sia un collegamento simbolico saranno modificati i suoi +tempi invece di quelli del file a cui esso punta. Nonostante il kernel, come accennato, supporti risoluzioni dei tempi dei file fino al nanosecondo, le funzioni fin qui esaminate non consentono di impostare valori con questa precisione. Per questo sono state introdotte due nuove funzioni, \funcd{futimens} e \func{utimensat}, in grado di eseguire questo compito; i rispettivi prototipi sono: -\begin{functions} - \headdecl{sys/time.h} - - \funcdecl{futimens(int fd, const struct timespec times[2])} Cambia i tempi - di un file già aperto, specificato dal file descriptor \param{fd}. - \funcdecl{int utimensat(int dirfd, const char *pathname, const struct - timespec times[2], int flags)} Cambia i tempi del file \param{pathname}. - - - \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un - errore, nel qual caso \var{errno} assumerà gli stessi valori di - \func{utimes}, con in più per \func{futimes}: +\begin{funcproto}{ +\fhead{sys/time.h} +\fdecl{futimens(int fd, const struct timespec times[2])} +\fdesc{Cambia i tempi di un file già aperto.} +\fdecl{int utimensat(int dirfd, const char *pathname, const struct + timespec times[2], int flags)} +\fdesc{Cambia i tempi di un file.} +} +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EBADF}] \param{fd} non è un file descriptor. - \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile. - \end{errlist}} -\end{functions} + \item[\errcode{EBADF}] da fare + \end{errlist} + ed inoltre nel loro significato generico.} +\end{funcproto} Entrambe le funzioni utilizzano per indicare i valori dei tempi un vettore \param{times} di due strutture \struct{timespec} che permette di @@ -3614,22 +3781,22 @@ aggiornare in maniera specifica soltanto uno fra il tempo di ultimo accesso e quello di ultima modifica. Quando si usa uno di questi valori speciali per \var{tv\_nsec} il corrispondente valore di \var{tv\_sec} viene ignorato. -Queste due funzioni sono una estensione definita in una recente revisione -dello standard POSIX (la POSIX.1-2008); sono state introdotte a partire dal -kernel 2.6.22, e supportate dalla \acr{glibc} a partire dalla versione -2.6.\footnote{in precedenza, a partire dal kernel 2.6.16, era stata introdotta - la funzione \funcm{futimesat} seguendo una bozza della revisione dello - standard poi modificata, questa funzione, sostituita da \func{utimensat}, è - stata dichiarata obsoleta, non è supportata da nessuno standard e non deve - essere più utilizzata: pertanto non la tratteremo.} La prima è -sostanzialmente una estensione di \func{futimes} che consente di specificare i -tempi con precisione maggiore, la seconda supporta invece, rispetto ad -\func{utimes}, una sintassi più complessa che, come vedremo in -sez.~\ref{sec:file_openat} consente una indicazione sicura dei -\itindsub{pathname}{relativo} \textit{pathname relativi} specificando la -directory da usare come riferimento in \param{dirfd} e la possibilità di -usare \param{flags} per indicare alla funzione di dereferenziare o meno i -collegamenti simbolici; si rimanda pertanto la spiegazione del significato +Queste due funzioni sono una estensione definita nella revisione POSIX.1-2008 +dello standard POSIX; sono state introdotte a partire dal kernel 2.6.22, e +supportate dalla \acr{glibc} a partire dalla versione 2.6.\footnote{in + precedenza, a partire dal kernel 2.6.16, era stata introdotta la funzione + \funcm{futimesat} seguendo una bozza della revisione dello standard poi + modificata, questa funzione, sostituita da \func{utimensat}, è stata + dichiarata obsoleta, non è supportata da nessuno standard e non deve essere + più utilizzata: pertanto non la tratteremo.} La prima è sostanzialmente una +estensione di \func{futimes} che consente di specificare i tempi con +precisione maggiore, la seconda supporta invece, rispetto ad \func{utimes}, +una sintassi più complessa che, come vedremo in sez.~\ref{sec:file_openat} +consente una indicazione sicura dei \itindsub{pathname}{relativo} +\textit{pathname relativi} specificando la directory da usare come riferimento +in \param{dirfd} e la possibilità di usare per \param{flags} il valore +\const{AT\_SYMLINK\_NOFOLLOW} per indicare alla funzione di non dereferenziare +i collegamenti simbolici; si rimanda pertanto la spiegazione del significato degli argomenti aggiuntivi alla trattazione generica delle varie funzioni che usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}. @@ -4334,20 +4501,23 @@ fornire un quadro d'insieme. \multicolumn{3}{|c|}{other}& \multirow{2}{*}{\textbf{Significato per i file}} \\ \cline{1-12} - \acr{s}&\acr{s}&\acr{t}&r&w&x&r&w&x&r&w&x& \\ + \texttt{s}&\texttt{s}&\texttt{t}& + \texttt{r}&\texttt{w}&\texttt{x}& + \texttt{r}&\texttt{w}&\texttt{x}& + \texttt{r}&\texttt{w}&\texttt{x}& \\ \hline \hline - 1&-&-&-&-&-&-&-&-&-&-&-&Se eseguito ha i permessi del proprietario.\\ - -&1&-&-&-&1&-&-&-&-&-&-&Se eseguito ha i permessi del gruppo proprietario.\\ + 1&-&-&-&-&1&-&-&-&-&-&-&Eseguito conferisce l'\ids{UID} effettivo dell'utente.\\ + -&1&-&-&-&1&-&-&-&-&-&-&Eseguito conferisce il \ids{GID} effettivo del gruppo.\\ -&1&-&-&-&0&-&-&-&-&-&-&Il \itindex{mandatory~locking} \textit{mandatory locking} è abilitato.\\ -&-&1&-&-&-&-&-&-&-&-&-&Non utilizzato.\\ - -&-&-&1&-&-&-&-&-&-&-&-&Permesso di lettura per il proprietario.\\ - -&-&-&-&1&-&-&-&-&-&-&-&Permesso di scrittura per il proprietario.\\ - -&-&-&-&-&1&-&-&-&-&-&-&Permesso di esecuzione per il proprietario.\\ - -&-&-&-&-&-&1&-&-&-&-&-&Permesso di lettura per il gruppo proprietario.\\ - -&-&-&-&-&-&-&1&-&-&-&-&Permesso di scrittura per il gruppo proprietario.\\ - -&-&-&-&-&-&-&-&1&-&-&-&Permesso di esecuzione per il gruppo proprietario.\\ + -&-&-&1&-&-&-&-&-&-&-&-&Permesso di lettura per l'utente.\\ + -&-&-&-&1&-&-&-&-&-&-&-&Permesso di scrittura per l'utente.\\ + -&-&-&-&-&1&-&-&-&-&-&-&Permesso di esecuzione per l'utente.\\ + -&-&-&-&-&-&1&-&-&-&-&-&Permesso di lettura per il gruppo.\\ + -&-&-&-&-&-&-&1&-&-&-&-&Permesso di scrittura per il gruppo.\\ + -&-&-&-&-&-&-&-&1&-&-&-&Permesso di esecuzione per il gruppo.\\ -&-&-&-&-&-&-&-&-&1&-&-&Permesso di lettura per tutti gli altri.\\ -&-&-&-&-&-&-&-&-&-&1&-&Permesso di scrittura per tutti gli altri.\\ -&-&-&-&-&-&-&-&-&-&-&1&Permesso di esecuzione per tutti gli altri.\\ @@ -4359,23 +4529,21 @@ fornire un quadro d'insieme. \multicolumn{3}{|c|}{other}& \multirow{2}{*}{\textbf{Significato per le directory}} \\ \cline{1-12} - \acr{s}&\acr{s}&\acr{t}&r&w&x&r&w&x&r&w&x& \\ + \texttt{s}&\texttt{s}&\texttt{t}& + \texttt{r}&\texttt{w}&\texttt{x}& + \texttt{r}&\texttt{w}&\texttt{x}& + \texttt{r}&\texttt{w}&\texttt{x}& \\ \hline \hline 1&-&-&-&-&-&-&-&-&-&-&-&Non utilizzato.\\ - -&1&-&-&-&-&-&-&-&-&-&-&Propaga il gruppo proprietario ai nuovi file - creati.\\ - -&-&1&-&-&-&-&-&-&-&-&-&Limita l'accesso in scrittura dei file nella - directory.\\ - -&-&-&1&-&-&-&-&-&-&-&-&Permesso di visualizzazione per il proprietario.\\ - -&-&-&-&1&-&-&-&-&-&-&-&Permesso di aggiornamento per il proprietario.\\ - -&-&-&-&-&1&-&-&-&-&-&-&Permesso di attraversamento per il proprietario.\\ - -&-&-&-&-&-&1&-&-&-&-&-&Permesso di visualizzazione per il gruppo - proprietario.\\ - -&-&-&-&-&-&-&1&-&-&-&-&Permesso di aggiornamento per il gruppo - proprietario.\\ - -&-&-&-&-&-&-&-&1&-&-&-&Permesso di attraversamento per il gruppo - proprietario.\\ + -&1&-&-&-&-&-&-&-&-&-&-&Propaga il gruppo ai nuovi file creati.\\ + -&-&1&-&-&-&-&-&-&-&-&-&Solo il proprietario di un file può rimuoverlo.\\ + -&-&-&1&-&-&-&-&-&-&-&-&Permesso di visualizzazione per l'utente.\\ + -&-&-&-&1&-&-&-&-&-&-&-&Permesso di aggiornamento per l'utente.\\ + -&-&-&-&-&1&-&-&-&-&-&-&Permesso di attraversamento per l'utente.\\ + -&-&-&-&-&-&1&-&-&-&-&-&Permesso di visualizzazione per il gruppo.\\ + -&-&-&-&-&-&-&1&-&-&-&-&Permesso di aggiornamento per il gruppo.\\ + -&-&-&-&-&-&-&-&1&-&-&-&Permesso di attraversamento per il gruppo.\\ -&-&-&-&-&-&-&-&-&1&-&-&Permesso di visualizzazione per tutti gli altri.\\ -&-&-&-&-&-&-&-&-&-&1&-&Permesso di aggiornamento per tutti gli altri.\\ -&-&-&-&-&-&-&-&-&-&-&1&Permesso di attraversamento per tutti gli altri.\\ @@ -4947,17 +5115,18 @@ ordinari vengono mappati le tre voci di tipo \const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER} che devono essere presenti in qualunque ACL; un cambiamento ad una di queste voci viene automaticamente riflesso sui permessi ordinari dei file\footnote{per permessi ordinari si - intende quelli mantenuti nell'\textit{inode}, che devono restare dato che un - filesystem può essere montato senza abilitare le ACL.} e viceversa. In -realtà la mappatura è diretta solo per le voci \const{ACL\_USER\_OBJ} e -\const{ACL\_OTHER}, nel caso di \const{ACL\_GROUP\_OBJ} questo vale soltanto -se non è presente una voce di tipo \const{ACL\_MASK}, se invece questa è -presente verranno tolti dai permessi di \const{ACL\_GROUP\_OBJ} tutti quelli -non presenti in \const{ACL\_MASK}.\footnote{questo diverso comportamento a - seconda delle condizioni è stato introdotto dalla standardizzazione - \textit{POSIX 1003.1e Draft 17} per mantenere il comportamento invariato sui - sistemi dotati di ACL per tutte quelle applicazioni che sono conformi - soltanto all'ordinario standard \textit{POSIX 1003.1}.} + intende quelli mantenuti \itindex{inode} nell'\textit{inode}, che devono + restare dato che un filesystem può essere montato senza abilitare le ACL.} e +viceversa. In realtà la mappatura è diretta solo per le voci +\const{ACL\_USER\_OBJ} e \const{ACL\_OTHER}, nel caso di +\const{ACL\_GROUP\_OBJ} questo vale soltanto se non è presente una voce di +tipo \const{ACL\_MASK}, se invece questa è presente verranno tolti dai +permessi di \const{ACL\_GROUP\_OBJ} tutti quelli non presenti in +\const{ACL\_MASK}.\footnote{questo diverso comportamento a seconda delle + condizioni è stato introdotto dalla standardizzazione \textit{POSIX 1003.1e + Draft 17} per mantenere il comportamento invariato sui sistemi dotati di + ACL per tutte quelle applicazioni che sono conformi soltanto all'ordinario + standard \textit{POSIX 1003.1}.} Un secondo aspetto dell'incidenza delle ACL sul comportamento del sistema è quello relativo alla creazione di nuovi file,\footnote{o oggetti sul @@ -5603,15 +5772,15 @@ ad un altra con \funcd{acl\_copy\_entry} o eliminare una voce da una ACL con Quella delle quote disco è una funzionalità introdotta inizialmente da BSD, e presente in Linux fino dai kernel dalla serie 2.0, che consente di porre dei tetti massimi al consumo delle risorse di un filesystem (spazio disco e -\textit{inode}) da parte di utenti e gruppi. Dato che la funzionalità ha senso -solo per i filesystem su cui si mantengono i dati degli utenti\footnote{in - genere la si attiva sul filesystem che contiene le \textit{home} degli - utenti, dato che non avrebbe senso per i file di sistema che in genere - appartengono all'amministratore.} essa deve essere esplicitamente richiesta; -questo si fa tramite due distinte opzioni di montaggio, \texttt{usrquota} e -\texttt{grpquota} che abilitano le quote rispettivamente per gli utenti e per -i gruppi. Grazie a questo è possibile usare le limitazioni sulle quote solo -sugli utenti o solo sui gruppi. +\itindex{inode} \textit{inode}) da parte di utenti e gruppi. Dato che la +funzionalità ha senso solo per i filesystem su cui si mantengono i dati degli +utenti\footnote{in genere la si attiva sul filesystem che contiene le + \textit{home} degli utenti, dato che non avrebbe senso per i file di sistema + che in genere appartengono all'amministratore.} essa deve essere +esplicitamente richiesta; questo si fa tramite due distinte opzioni di +montaggio, \texttt{usrquota} e \texttt{grpquota} che abilitano le quote +rispettivamente per gli utenti e per i gruppi. Grazie a questo è possibile +usare le limitazioni sulle quote solo sugli utenti o solo sui gruppi. Il meccanismo prevede che per ciascun filesystem che supporta le quote disco (i vari \textit{extN}, \textit{btrfs}, \textit{XFS}, \textit{JFS}, @@ -5645,8 +5814,8 @@ periodo di tempo per cui è possibile superare il \textit{soft limit} è detto ``\textsl{periodo di grazia}'' (\textit{grace period}), passato questo tempo il passaggio del \textit{soft limit} viene trattato allo stesso modo dell'\textit{hard limit}. Questi limiti riguardano separatamente sia lo -spazio disco (i blocchi) che il numero di file (gli \textit{inode}) e devono -pertanto essere specificati per entrambe le risorse. +spazio disco (i blocchi) che il numero di file (gli \itindex{inode} +\textit{inode}) e devono pertanto essere specificati per entrambe le risorse. La funzione che consente di controllare tutti i vari aspetti della gestione delle quote è \funcd{quotactl}, ed il suo prototipo è: @@ -5833,8 +6002,8 @@ correnti dei limiti e dell'occupazione delle risorse, che con sono alcuni campi (in sostanza \val{dqb\_curspace}, \val{dqb\_curinodes}, \val{dqb\_btime}, \val{dqb\_itime}) che hanno senso solo in lettura in quanto riportano uno stato non modificabile da \func{quotactl}, come l'uso corrente -di spazio e \textit{inode} o il tempo che resta nel caso si sia superato un -\textit{soft limit}. +di spazio e \itindex{inode} \textit{inode} o il tempo che resta nel caso si +sia superato un \textit{soft limit}. \begin{table}[htb] \centering @@ -5849,7 +6018,7 @@ di spazio e \textit{inode} o il tempo che resta nel caso si sia superato un \val{dqb\_bsoftlimit}).\\ \const{QIF\_SPACE} & Uso corrente dello spazio disco (\val{dqb\_curspace}).\\ - \const{QIF\_ILIMITS}& Limiti sugli \textit{inode} + \const{QIF\_ILIMITS}& Limiti sugli \itindex{inode} \textit{inode} (\val{dqb\_ihardlimit} e \val{dqb\_isoftlimit}).\\ \const{QIF\_INODES} & Uso corrente degli \textit{inode} (\val{dqb\_curinodes}).\\ @@ -5858,7 +6027,7 @@ di spazio e \textit{inode} o il tempo che resta nel caso si sia superato un blocchi (\val{dqb\_btime}).\\ \const{QIF\_ITIME} & Tempo di sforamento del \textit{soft limit} sul numero di - \textit{inode} (\val{dqb\_itime}).\\ + \itindex{inode} \textit{inode} (\val{dqb\_itime}).\\ \const{QIF\_LIMITS} & L'insieme di \const{QIF\_BLIMITS} e \const{QIF\_ILIMITS}.\\ \const{QIF\_USAGE} & L'insieme di \const{QIF\_SPACE} e @@ -5874,14 +6043,14 @@ di spazio e \textit{inode} o il tempo che resta nel caso si sia superato un Inoltre in caso di modifica di un limite si può voler operare solo su una -delle risorse (blocchi o \textit{inode});\footnote{non è possibile modificare - soltanto uno dei limiti (\textit{hard} o \textit{soft}) occorre sempre - rispecificarli entrambi.} per questo la struttura prevede un campo apposito, -\val{dqb\_valid}, il cui scopo è quello di indicare quali sono gli altri campi -che devono essere considerati validi. Questo campo è una maschera binaria che -deve essere espressa nei termini di OR aritmetico delle apposite costanti di -tab.~\ref{tab:quotactl_qif_const}, dove si è riportato il significato di -ciascuna di esse ed i campi a cui fanno riferimento. +delle risorse (blocchi o \itindex{inode} \textit{inode});\footnote{non è + possibile modificare soltanto uno dei limiti (\textit{hard} o \textit{soft}) + occorre sempre rispecificarli entrambi.} per questo la struttura prevede un +campo apposito, \val{dqb\_valid}, il cui scopo è quello di indicare quali sono +gli altri campi che devono essere considerati validi. Questo campo è una +maschera binaria che deve essere espressa nei termini di OR aritmetico delle +apposite costanti di tab.~\ref{tab:quotactl_qif_const}, dove si è riportato il +significato di ciascuna di esse ed i campi a cui fanno riferimento. In lettura con \const{Q\_SETQUOTA} eventuali valori presenti in \struct{dqblk} vengono comunque ignorati, al momento la funzione sovrascrive tutti i campi e @@ -5933,7 +6102,7 @@ significato di ciascuna di esse ed i campi a cui fanno riferimento. \const{IIF\_BGRACE}& Il \textit{grace period} per i blocchi (\val{dqi\_bgrace}).\\ \const{IIF\_IGRACE}& Il \textit{grace period} per gli \textit{inode} - (\val{dqi\_igrace}).\\ + \itindex{inode} (\val{dqi\_igrace}).\\ \const{IIF\_FLAGS} & I flag delle quote (\val{dqi\_flags}) (inusato ?).\\ \const{IIF\_ALL} & Tutti i precedenti.\\ \hline @@ -5988,7 +6157,7 @@ La funzione viene eseguita all'interno di un condizionale (\texttt{\small 5--16}) che in caso di successo provvede a costruire (\texttt{\small 6--12}) opportunamente una risposta restituendo tramite la opportuna funzione di interfaccia un oggetto Python contenente i dati della struttura \struct{dqblk} -relativi a uso corrente e limiti sia per i blocchi che per gli +relativi a uso corrente e limiti sia per i blocchi che per gli \itindex{inode} \textit{inode}. In caso di errore (\texttt{\small 13--15}) si usa un'altra funzione dell'interfaccia per passare il valore di \var{errno} come eccezione. @@ -7359,7 +7528,7 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: name TYPE OFF RECLEN UNKNOWN REG SOCK CHR BLK type IFTODT DTTOIF % LocalWords: DTYPE off reclen seekdir telldir void rewinddir closedir select % LocalWords: namelist compar malloc qsort alphasort versionsort strcoll myls -% LocalWords: strcmp direntry while current working home shell pwd get +% LocalWords: strcmp direntry while current working home shell pwd get stddef % LocalWords: getcwd ERANGE getwd change fd race condition tmpnam getfacl mark % LocalWords: string tmpdir TMP tempnam pfx TMPNAME suid tmp EXCL tmpfile pid % LocalWords: EINTR mktemp mkstemp stlib template filename XXXXXX OpenBSD buf @@ -7413,9 +7582,10 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: bind DIRSYNC lsattr Hierarchy FHS SHARED UNBINDABLE shared REC % LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW % LocalWords: lazy encfs sshfs setfsent getfsent getfsfile getfsspec endfsent -% LocalWords: setmntent getmntent addmntent endmntent hasmntopt such +% LocalWords: setmntent getmntent addmntent endmntent hasmntopt such offsetof %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: +% LocalWords: member scan attack EOVERFLOW BITS blkcnt rdev diff --git a/fileunix.tex b/fileunix.tex index 3a16ddd..c3e7ba5 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -575,9 +575,9 @@ per i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che non supportano questa funzione, come ad esempio per i file di terminale.\footnote{altri sistemi, usando \const{SEEK\_SET}, in questo caso ritornano il numero di caratteri che vi sono stati scritti.} Lo standard -POSIX però non specifica niente in proposito. Inoltre alcuni file speciali, ad -esempio \file{/dev/null}, non causano un errore ma restituiscono un valore -indefinito. +POSIX però non specifica niente in proposito. Inoltre alcuni +\index{file!speciali} file speciali, ad esempio \file{/dev/null}, non causano +un errore ma restituiscono un valore indefinito. \itindbeg{sparse~file} @@ -1008,8 +1008,8 @@ usare le due funzioni \funcd{fsync} e \funcd{fdatasync}, i cui prototipi sono: \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assume i valori: \begin{errlist} - \item[\errcode{EINVAL}] \param{fd} è un file speciale che non supporta la - sincronizzazione. + \item[\errcode{EINVAL}] \param{fd} è un \index{file!speciali} file speciale + che non supporta la sincronizzazione. \end{errlist} ed inoltre \errval{EBADF}, \errval{EROFS} e \errval{EIO}.} \end{functions} diff --git a/intro.tex b/intro.tex index 7378e59..d017939 100644 --- a/intro.tex +++ b/intro.tex @@ -400,9 +400,10 @@ programmi delle opportune \textit{system call} che consentano di leggere e scrivere il contenuto. Tutto ciò ha due aspetti: il primo è che il kernel, per il concetto dell'\textit{everything is a file}, deve fornire una interfaccia che consenta di operare sui file, sia che questi corrispondano ai normali file -di dati, sia che siano quei file speciali (i cosiddetti -\index{file!di~dispositivo} file di dispositivo, o \textit{device file}) che -permettono di accedere alle periferiche. +di dati, o ai cosiddetti \index{file!speciali} ``\textsl{file speciali}'', +come \index{file!di~dispositivo} i file di dispositivo (o \textit{device + file}) che permettono di accedere alle periferiche o le fifo ed i socket che +forniscono funzionalità di comunicazione fra processi. Il secondo aspetto è che per poter utilizzare dei normali file di dati il kernel deve provvedere ad organizzare e rendere accessibile in maniera diff --git a/ipc.tex b/ipc.tex index 6d0cb5d..be507a5 100644 --- a/ipc.tex +++ b/ipc.tex @@ -431,9 +431,10 @@ quello illustrato per le pipe in sez.~\ref{sec:ipc_pipes}. Abbiamo già visto in sez.~\ref{sec:file_mknod} le funzioni \func{mknod} e \func{mkfifo} che permettono di creare una fifo; per utilizzarne una un -processo non avrà che da aprire il relativo file speciale o in lettura o -scrittura; nel primo caso sarà collegato al capo di uscita della fifo, e dovrà -leggere, nel secondo al capo di ingresso, e dovrà scrivere. +processo non avrà che da aprire il relativo \index{file!speciale} file +speciale o in lettura o scrittura; nel primo caso sarà collegato al capo di +uscita della fifo, e dovrà leggere, nel secondo al capo di ingresso, e dovrà +scrivere. Il kernel crea una singola pipe per ciascuna fifo che sia stata aperta, che può essere acceduta contemporaneamente da più processi, sia in lettura che in @@ -727,20 +728,20 @@ dei socket in cap.~\ref{cha:socket_intro},\footnote{si tratta comunque di oggetti di comunicazione che, come le pipe, sono utilizzati attraverso dei file descriptor.} nell'ambito dell'interfaccia generale che essi forniscono per la programmazione di rete; e vedremo anche -(in~sez.~\ref{sec:sock_sa_local}) come si possono definire dei file speciali -(di tipo socket, analoghi a quello associati alle fifo) cui si accede però -attraverso quella medesima interfaccia; vale però la pena esaminare qui una -modalità di uso dei socket locali\footnote{la funzione \func{socketpair} è - stata introdotta in BSD4.4, ma è supportata in genere da qualunque sistema - che fornisca l'interfaccia dei socket.} che li rende sostanzialmente -identici ad una pipe bidirezionale. +(in~sez.~\ref{sec:sock_sa_local}) come si possono definire dei +\index{file!speciali} file speciali (di tipo socket, analoghi a quello +associati alle fifo) cui si accede però attraverso quella medesima +interfaccia; vale però la pena esaminare qui una modalità di uso dei socket +locali\footnote{la funzione \func{socketpair} è stata introdotta in BSD4.4, ma + è supportata in genere da qualunque sistema che fornisca l'interfaccia dei + socket.} che li rende sostanzialmente identici ad una pipe bidirezionale. La funzione \funcd{socketpair} infatti consente di creare una coppia di file descriptor connessi fra di loro (tramite un socket, appunto), senza dover -ricorrere ad un file speciale sul filesystem, i descrittori sono del tutto -analoghi a quelli che si avrebbero con una chiamata a \func{pipe}, con la sola -differenza è che in questo caso il flusso dei dati può essere effettuato in -entrambe le direzioni. Il prototipo della funzione è: +ricorrere ad un \index{file!speciali} file speciale sul filesystem, i +descrittori sono del tutto analoghi a quelli che si avrebbero con una chiamata +a \func{pipe}, con la sola differenza è che in questo caso il flusso dei dati +può essere effettuato in entrambe le direzioni. Il prototipo della funzione è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/socket.h} diff --git a/listati/is_file_dir.h b/listati/is_file_dir.h deleted file mode 100644 index fac2e21..0000000 --- a/listati/is_file_dir.h +++ /dev/null @@ -1 +0,0 @@ -#define IS_FILE_DIR(x) (((x) & S_IFMT) & (S_IFDIR | S_IFREG)) diff --git a/listati/is_regdir.h b/listati/is_regdir.h new file mode 100644 index 0000000..5326149 --- /dev/null +++ b/listati/is_regdir.h @@ -0,0 +1 @@ +#define IS_RGDR(x) ( ((x)&S_IFMT&S_IFDIR) | ((x)&S_IFMT&S_IFREG) ) diff --git a/listati/stat.h b/listati/stat.h index 9f1fc76..e02ae11 100644 --- a/listati/stat.h +++ b/listati/stat.h @@ -1,15 +1,15 @@ struct stat { - dev_t st_dev; /* device */ - ino_t st_ino; /* inode */ + dev_t st_dev; /* ID of device containing file */ + ino_t st_ino; /* inode number */ 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 */ + blksize_t st_blksize; /* blocksize for filesystem I/O */ + blkcnt_t 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 */ + time_t st_ctime; /* time of last status change */ };