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}).\\
non sono presenti su un classico filesystem di tipo Unix; le principali sono
le seguenti:
\begin{itemize}
-\item i \textit{file attributes} consentono di modificare il comportamento del
- kernel quando agisce su gruppi di file. Possono essere impostati su file e
- directory e in quest'ultimo caso i nuovi file creati nella directory
- ereditano i suoi attributi.
+\item gli attributi estesi (vedi sez.~\ref{sec:file_xattr}) che consentono di
+ estendere le informazioni salvabili come metadati e le ACL (vedi
+ sez.~\ref{sec:file_ACL}) che consentono di estendere il modello tradizionale
+ dei permessi sui file.
\item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di
montaggio. La semantica BSD comporta che i file in una directory sono creati
con lo stesso identificatore di gruppo della directory che li contiene. La
dell'\textit{inode} (evitando letture multiple e spreco di spazio), non
tutti i nomi però possono essere gestiti così per limiti di spazio (il
limite è 60 caratteri).
-\item vengono supportati i file immutabili (che possono solo essere letti) per
- la protezione di file di configurazione sensibili, o file
- \textit{append-only} che possono essere aperti in scrittura solo per
- aggiungere dati (caratteristica utilizzabile per la protezione dei file di
- log).
+\item vengono supportati \itindex{file~attributes} i cosiddetti \textit{file
+ attributes} che attivano comportamenti specifici per i file su cui vengono
+ attivati come marcarli come immutabili (che possono cioè essere soltanto
+ letti) per la protezione di file di configurazione sensibili, o come
+ \textit{append-only} (che possono essere aperti in scrittura solo per
+ aggiungere dati) per la protezione dei file di log.
\end{itemize}
La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD: un
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
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
specifica di Linux che usa la omonima \textit{system call} e non è
portabile.}
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/mount.h}
\fdecl{mount(const char *source, const char *target, const char
*filesystemtype, \\
\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}
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}
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
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
``\textsl{smontarlo}'' usando la funzione di sistema \funcd{umount}, il cui
prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/mount.h}
\fdecl{umount(const char *target)}
\fdesc{Smonta un filesystem.}
consente un maggior controllo delle operazioni, come forzare lo smontaggio di
un filesystem anche quando questo risulti occupato; il suo prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/mount.h}
\fdecl{umount2(const char *target, int flags)}
\fdesc{Smonta un filesystem.}
diretta informazioni riguardo al filesystem su cui si trova un certo file,
sono \funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/vfs.h}
\fdecl{int statfs(const char *path, struct statfs *buf)}
\fdecl{int fstatfs(int fd, struct statfs *buf)}
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
viene denominato ``\textsl{collegamento diretto}'' (o \textit{hard link}), si
deve usare la funzione di sistema \funcd{link}, il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int link(const char *oldpath, const char *newpath)}
\fdesc{Crea un nuovo collegamento diretto (\textit{hard link}).}
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 è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int symlink(const char *oldpath, const char *newpath)}
\fdesc{Crea un nuovo collegamento simbolico (\textit{symbolic link}).}
esso fa riferimento. Quando si vuole leggere il contenuto di un collegamento
simbolico si usa la funzione di sistema \funcd{readlink}, il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int readlink(const char *path, char *buff, size\_t size)}
\fdesc{Legge il contenuto di un collegamento simbolico.}
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, è
\funcd{unlink}, ed il suo prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int unlink(const char *pathname)}
\fdesc{Cancella un file.}
unix-like \funcd{remove} è equivalente ad usare in maniera trasparente
\func{unlink} per i file ed \func{rmdir} per le directory; il suo prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{stdio.h}
\fdecl{int remove(const char *pathname)}
\fdesc{Cancella un file o una directory.}
ma si applica solo per i file, lo standard POSIX estende la funzione anche
alle directory.} il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{stdio.h}
\fdecl{int rename(const char *oldpath, const char *newpath)}
\fdesc{Rinomina un file o una directory.}
numero di file è molto grande.} La funzione di sistema usata per creare una
directory è \funcd{mkdir}, ed il suo prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/stat.h}
\fhead{sys/types.h}
\fdecl{int mkdir(const char *dirname, mode\_t mode)}
necessaria una specifica funzione di sistema, \funcd{rmdir}, il suo prototipo
è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/stat.h}
\fdecl{int rmdir(const char *dirname)}
\fdesc{Cancella una directory.}
cap.~\ref{cha:files_std_interface}. La prima funzione di questa interfaccia è
\funcd{opendir}, il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{DIR *opendir(const char *dirname)}
\texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o
\texttt{\macro{\_XOPEN\_SOURCE} >= 700}.} il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{int dirfd(DIR *dir)}
\texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o \texttt{\_XOPEN\_SOURCE >=
700} .} il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{DIR *fdopendir(int fd)}
contenuto della directory viene effettuata attraverso la funzione
\funcd{readdir}, il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{struct dirent *readdir(DIR *dir)}
può essere utilizzata anche con i \itindex{thread} \textit{thread}, il suo
prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{int readdir\_r(DIR *dir, struct dirent *entry, struct dirent **result)}
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
una delle macro \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE} o
\macro{\_SVID\_SOURCE}.} il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{dirent.h}
\fdecl{void seekdir(DIR *dir, off\_t offset)}
\fdesc{Cambia la posizione all'interno di un \textit{directory stream}.}
tipo \type{off\_t}, sostituito a partire dalla versione 2.1.2 da \ctyp{long}
per conformità a POSIX.1-2001.}
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{dirent.h}
\fdecl{long telldir(DIR *dir)}
\fdesc{Ritorna la posizione corrente in un \textit{directory stream}.}
stream}, ed il file descriptor ad esso associato, con la funzione
\funcd{closedir}, il cui prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{int closedir(DIR *dir)}
\acr{libc4} e richiede siano definite le macro \macro{\_BSD\_SOURCE} o
\macro{\_SVID\_SOURCE}.} ed il suo prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{dirent.h}
\fdecl{int scandir(const char *dir, struct dirent ***namelist, \\
\phantom{int scandir(}int(*filter)(const struct dirent *), \\
\param{compar}, sono disponibili due funzioni predefinite, \funcd{alphasort} e
\funcd{versionsort}, i cui prototipi sono:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{dirent.h}
\fdecl{int alphasort(const void *a, const void *b)}
\fdecl{int versionsort(const void *a, const void *b)}
il filesystem \texttt{/proc} da \procfile{/proc/self/cwd}.} il cui prototipo
è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fdecl{char *getcwd(char *buffer, size\_t size)}
\fdesc{Legge il \textit{pathname} della directory di lavoro corrente.}
{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
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
appunto per \textit{change directory}, il suo prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int chdir(const char *pathname)}
\fdesc{Cambia la directory di lavoro per \textit{pathname}.}
{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}
\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),
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
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
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.
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}
\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
\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ò
\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
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
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
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.
\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
\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}
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.
-
- \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}
+funzioni di sistema \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui
+prototipi sono:
+
+\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
\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
\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
\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.\\
\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{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{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} 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
\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
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
\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
& -- & -- &$\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}
& -- & -- &$\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}
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 ed ultima modifica possono essere modificati
+esplicitamente usando la funzione di sistema \funcd{utime}, il cui prototipo
+è:
-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.
+\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.}
+}
- \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}
+{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]
\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
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
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.
-
-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}.
+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 nelle versioni più recenti supporti, come accennato,
+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 di sistema, \funcd{futimens} e
+\funcd{utimensat}, in grado di eseguire questo compito; i rispettivi prototipi
+sono:
- \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{EACCES}] si è richiesta l'impostazione del tempo corrente ma
+ non si ha il permesso di scrittura sul file, o non si è proprietari del
+ file o non si hanno i privilegi di amministratore; oppure il file è
+ immutabile (vedi sez.~\ref{sec:file_perm_overview}).
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido (solo
+ \func{futimens}), oppure \param{dirfd} non è \const{AT\_FDCWD} o un file
+ descriptor valido (solo \func{utimensat}).
+ \item[\errcode{EFAULT}] \param{times} non è un puntatore valido (per
+ entrambe), oppure \param{dirfd} è \const{AT\_FDCWD} ma \param{pathname} è
+ \var{NULL} o non è un puntatore valido (solo \func{utimensat}).
+ \item[\errcode{EINVAL}] si sono usati dei valori non corretti per i tempi
+ di \param{times} (per entrambe), oppure è si usato un valore non valido
+ per \param{flags}, oppure \param{pathname} è \var{NULL}, \param{dirfd} non
+ è \const{AT\_FDCWD} e \param{flags} contiene \const{AT\_SYMLINK\_NOFOLLOW}
+ (solo \func{utimensat}).
+ \item[\errcode{EPERM}] si è richiesto un cambiamento nei tempi non al tempo
+ corrente, ma non si è proprietari del file o non si hanno i privilegi di
+ amministratore; oppure il file è \itindex{file~attributes} immutabile o
+ \textit{append-only} (vedi sez.~\ref{sec:file_perm_overview}).
+ \item[\errcode{ESRCH}] non c'è il permesso di attraversamento per una delle
+ componenti di \param{pathname} (solo \func{utimensat})
+ \end{errlist}
+ ed inoltre per entrambe \errval{EROFS} e per \func{utimensat}
+ \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} 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
-specificare un valore di tempo con una precisione fino al nanosecondo, la cui
-definizione è riportata in fig.~\ref{fig:sys_timespec_struct}.
+vettore \param{times} di due strutture \struct{timespec}, la cui definizione è
+riportata in fig.~\ref{fig:sys_timespec_struct}, che permette di specificare
+un valore dei tempi con una precisione fino al nanosecondo.
\begin{figure}[!htb]
\footnotesize \centering
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
-degli argomenti aggiuntivi alla trattazione generica delle varie funzioni che
-usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}.
+Queste due funzioni sono una estensione definita nella revisione POSIX.1-2008
+dello standard POSIX, in Linux sono state introdotte a partire dal kernel
+2.6.22,\footnote{si tenga presente però che per kernel precedenti il 2.6.26 le
+ due funzioni sono difettose nel rispetto di alcuni requisiti minori dello
+ standard e nel controllo della correttezza dei tempi, per i dettagli dei
+ quali si rimanda alla pagina di manuale.} e supportate dalla \acr{glibc} a
+partire dalla versione 2.6.\footnote{in precedenza, a partire dal kernel
+ 2.6.16, era stata introdotta una \textit{system call} \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 ne parleremo.} 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 consente una indicazione sicura del file su cui operare specificando la
+directory su cui si trova tramite il file descriptor \param{dirfd} ed il suo
+nome come \itindsub{pathname}{relativo} \textit{pathname relativo}
+in \param{pathname}.\footnote{su Linux solo \func{utimensat} è una
+ \textit{system call} e \func{futimens} è una funzione di libreria, infatti
+ se \param{pathname} è \var{NULL} \param{dirfd} viene considerato un file
+ descriptor ordinario e il cambiamento del tempo applicato al file
+ sottostante, qualunque esso sia, per cui \code{futimens(fd, times}) è del
+ tutto equivalente a \code{utimensat(fd, NULL, times, 0)}.}
+
+Torneremo su questa sintassi e sulla sua motivazione in
+sez.~\ref{sec:file_openat}, quando tratteremo tutte le altre funzioni (le
+cosiddette funzioni \textit{at}) che la utilizzano; essa prevede comunque
+anche la presenza dell'argomento \param{flags} con cui attivare flag di
+controllo che modificano il comportamento della funzione, nel caso specifico
+l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che indica alla
+funzione di non dereferenziare i collegamenti simbolici, cosa che le permette
+di riprodurre le funzionalità di \func{lutimes}.
+
+
\section{Il controllo di accesso ai file}
Una delle caratteristiche fondamentali di tutti i sistemi unix-like è quella
del controllo di accesso ai file, che viene implementato per qualunque
filesystem standard.\footnote{per standard si intende che implementa le
- caratteristiche previste dallo standard POSIX; in Linux sono disponibili
- anche una serie di altri filesystem, come quelli di Windows e del Mac, che
- non supportano queste caratteristiche.} In questa sezione ne esamineremo i
-concetti essenziali e le funzioni usate per gestirne i vari aspetti.
+ caratteristiche previste dallo standard POSIX; in Linux sono utilizzabili
+ anche filesystem di altri sistemi operativi, che non supportano queste
+ caratteristiche.} In questa sezione ne esamineremo i concetti essenziali e
+le funzioni usate per gestirne i vari aspetti.
\subsection{I permessi per l'accesso ai file}
\label{sec:file_perm_overview}
-Ad ogni file Linux associa sempre l'utente che ne è proprietario (il
-cosiddetto \textit{owner}) ed un gruppo di appartenenza, secondo il meccanismo
-degli identificatori di utente e gruppo (\ids{UID} e \ids{GID}). Questi valori
-sono accessibili da programma tramite la funzione \func{stat}, e sono
-mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura
-\struct{stat} (si veda sez.~\ref{sec:file_stat}).\footnote{questo è vero solo
- per filesystem di tipo Unix, ad esempio non è vero per il filesystem vfat di
- Windows, che non fornisce nessun supporto per l'accesso multiutente, e per
- il quale i permessi vengono assegnati in maniera fissa con un opzione in
- fase di montaggio.}
+Ad ogni file Linux associa sempre, oltre ad un insieme di permessi, l'utente
+che ne è proprietario (il cosiddetto \textit{owner}) ed un gruppo di
+appartenenza, indicati dagli identificatori di utente e gruppo (\ids{UID} e
+\ids{GID}) di cui abbiamo già parlato in
+sez.~\ref{sec:proc_access_id}.\footnote{questo è vero solo per filesystem di
+ tipo Unix, ad esempio non è vero per il filesystem VFAT di Windows, che non
+ fornisce nessun supporto per l'accesso multiutente, e per il quale queste
+ proprietà vengono assegnate in maniera fissa con opportune opzioni di
+ montaggio.} Anche questi sono mantenuti \index{itinode} sull'\textit{inode}
+insieme alle altre proprietà e sono accessibili da programma tramite la
+funzione \func{stat} (trattata in sez.~\ref{sec:file_stat}), che restituisce
+l'utente proprietario nel campo \var{st\_uid} ed il gruppo proprietario nel
+campo \var{st\_gid} della omonima struttura \struct{stat}.
Il controllo di accesso ai file segue un modello abbastanza semplice che
prevede tre permessi fondamentali strutturati su tre livelli di accesso.
-Esistono varie estensioni a questo modello,\footnote{come le \textit{Access
- Control List} che sono state aggiunte ai filesystem standard con opportune
- estensioni (vedi sez.~\ref{sec:file_ACL}) per arrivare a meccanismi di
- controllo ancora più sofisticati come il \textit{mandatory access control}
- di SE-Linux.} ma nella maggior parte dei casi il meccanismo standard è più
-che sufficiente a soddisfare tutte le necessità più comuni. I tre permessi di
-base associati ad ogni file sono:
+Esistono varie estensioni a questo modello,\footnote{come le
+ \itindex{Access~Control~List~(ACL)} \textit{Access Control List} che sono
+ state aggiunte ai filesystem standard con opportune estensioni (vedi
+ sez.~\ref{sec:file_ACL}) per arrivare a meccanismi di controllo ancora più
+ sofisticati come il \itindex{Mandatory~Access~Control~(MAC)}
+ \textit{mandatory access control} di SE-Linux e delle altre estesioni come
+ \textit{Smack} o.} ma nella maggior parte dei casi il meccanismo standard è
+più che sufficiente a soddisfare tutte le necessità più comuni. I tre
+permessi di base associati ad ogni file sono:
\begin{itemize*}
\item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
\textit{read}).
\itindex{sgid~bit} \textit{sgid bit}, e \itindex{sticky~bit} \textit{sticky
bit}) sono usati per indicare alcune caratteristiche più complesse del
meccanismo del controllo di accesso su cui torneremo in seguito (in
-sez.~\ref{sec:file_special_perm}); lo schema di allocazione dei bit è
-riportato in fig.~\ref{fig:file_perm_bit}.
-
-Anche i permessi, come tutte le altre informazioni pertinenti al file, sono
-memorizzati \itindex{inode} nell'\textit{inode}; in particolare essi sono
-contenuti in alcuni bit del campo \var{st\_mode} della struttura \struct{stat}
+sez.~\ref{sec:file_special_perm}), lo schema di allocazione dei bit è
+riportato in fig.~\ref{fig:file_perm_bit}. Come tutte le altre proprietà di
+una file anche i permessi sono memorizzati \itindex{inode}
+nell'\textit{inode}, e come accennato in sez.~\ref{sec:file_types} essi sono
+contenuti in una parte del campo \var{st\_mode} della struttura \struct{stat}
(si veda di nuovo fig.~\ref{fig:file_stat_struct}).
In genere ci si riferisce ai tre livelli dei privilegi usando le lettere
-\cmd{u} (per \textit{user}), \cmd{g} (per \textit{group}) e \cmd{o} (per
-\textit{other}), inoltre se si vuole indicare tutti i raggruppamenti insieme
-si usa la lettera \cmd{a} (per \textit{all}). Si tenga ben presente questa
-distinzione dato che in certi casi, mutuando la terminologia in uso nel VMS,
-si parla dei permessi base come di permessi per \textit{owner}, \textit{group}
-ed \textit{all}, le cui iniziali possono dar luogo a confusione. Le costanti
-che permettono di accedere al valore numerico di questi bit nel campo
-\var{st\_mode} sono riportate in tab.~\ref{tab:file_bit_perm}.
+\texttt{u} (per \textit{user}), \texttt{g} (per \textit{group}) e \texttt{o}
+(per \textit{other}), inoltre se si vuole indicare tutti i raggruppamenti
+insieme si usa la lettera \texttt{a} (per \textit{all}). Si tenga ben presente
+questa distinzione dato che in certi casi, mutuando la terminologia in uso a
+suo tempo nel VMS, si parla dei permessi base come di permessi per
+\textit{owner}, \textit{group} ed \textit{all}, le cui iniziali possono dar
+luogo a confusione. Le costanti che permettono di accedere al valore numerico
+di questi bit nel campo \var{st\_mode}, già viste in
+tab.~\ref{tab:file_mode_flags}, sono riportate per chiarezza in
+tab.~\ref{tab:file_bit_perm}.
\begin{table}[htb]
\centering
\textit{pathname} occorre il permesso di esecuzione in ciascuna delle
directory che compongono il \textit{pathname}; lo stesso vale per aprire un
file nella directory corrente (per la quale appunto serve il diritto di
-esecuzione).
-
-Per una directory infatti il permesso di esecuzione significa che essa può
-essere attraversata nella risoluzione del \textit{pathname}, ed è distinto dal
-permesso di lettura che invece implica che si può leggere il contenuto della
-directory.
+esecuzione). Per una directory infatti il permesso di esecuzione significa che
+essa può essere attraversata nella risoluzione del \textit{pathname}, e per
+questo viene anche chiamato permesso di attraversamento. Esso è sempre
+distinto dal permesso di lettura che invece implica che si può leggere il
+contenuto della directory.
Questo significa che se si ha il permesso di esecuzione senza permesso di
-lettura si potrà lo stesso aprire un file in una directory (se si hanno i
-permessi opportuni per il medesimo) ma non si potrà vederlo con \cmd{ls}
-(mentre per crearlo occorrerà anche il permesso di scrittura per la
-directory).
+lettura si potrà lo stesso aprire un file all'interno di una una directory (se
+si hanno i permessi adeguati per il medesimo) ma non si potrà vederlo con
+\cmd{ls} mancando il permesso di leggere il contenuto della directory. Per
+crearlo o rinominarlo o cancellarlo invece occorrerà avere anche il permesso
+di scrittura per la directory.
Avere il permesso di lettura per un file consente di aprirlo con le opzioni
(si veda quanto riportato in tab.~\ref{tab:file_open_flags}) di sola lettura o
esecuzione e di quello di scrittura per la directory di destinazione; gli
stessi permessi occorrono per cancellare un file da una directory (si ricordi
che questo non implica necessariamente la rimozione del contenuto del file dal
-disco), non è necessario nessun tipo di permesso per il file stesso (infatti
-esso non viene toccato, viene solo modificato il contenuto della directory,
-rimuovendo la voce che ad esso fa riferimento).
+disco). Per la cancellazione non è necessario nessun tipo di permesso per il
+file stesso dato che, come illustrato in sez.~\ref{sec:link_symlink_rename}
+esso non viene toccato, nella cancellazione viene solo modificato il contenuto
+della directory, rimuovendo la voce che ad esso fa riferimento.
Per poter eseguire un file (che sia un programma compilato od uno script di
-shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre
-avere il permesso di esecuzione, inoltre solo i file regolari possono essere
-eseguiti.
+shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre,
+oltre al permesso di lettura per accedere al contenuto, avere anche il
+permesso di esecuzione. Inoltre solo i file regolari possono essere eseguiti.
I permessi per un collegamento simbolico sono ignorati, contano quelli del
file a cui fa riferimento; per questo in genere il comando \cmd{ls} riporta
I passi attraverso i quali viene stabilito se il processo possiede il diritto
di accesso sono i seguenti:
-\begin{enumerate}
+\begin{enumerate*}
\item Se l'\ids{UID} effettivo del processo è zero (corrispondente
all'amministratore) l'accesso è sempre garantito senza nessun ulteriore
controllo. Per questo motivo \textsl{root} ha piena libertà di accesso a
proprietario del file (nel qual caso si dice che il processo è proprietario
del file) allora:
\begin{itemize*}
- \item se il relativo\footnote{per relativo si intende il bit di user-read se
- il processo vuole accedere in lettura, quello di user-write per
- l'accesso in scrittura, ecc.} bit dei permessi d'accesso dell'utente è
- impostato, l'accesso è consentito
- \item altrimenti l'accesso è negato
+ \item se il relativo\footnote{per relativo si intende il bit di
+ \textit{user-read} se il processo vuole accedere in lettura, quello di
+ \textit{user-write} per l'accesso in scrittura, ecc.} bit dei permessi
+ d'accesso dell'utente è impostato, l'accesso è consentito;
+ \item altrimenti l'accesso è negato.
\end{itemize*}
\item Se il \ids{GID} effettivo del processo o uno dei \ids{GID} supplementari
dei processi corrispondono al \ids{GID} del file allora:
\begin{itemize*}
\item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è
- consentito,
- \item altrimenti l'accesso è negato
+ consentito;
+ \item altrimenti l'accesso è negato.
\end{itemize*}
\item Se il bit dei permessi d'accesso per tutti gli altri è impostato,
l'accesso è consentito, altrimenti l'accesso è negato.
-\end{enumerate}
+\end{enumerate*}
Si tenga presente che questi passi vengono eseguiti esattamente in
quest'ordine. Questo vuol dire che se un processo è il proprietario di un file,
processo appartiene ad un gruppo appropriato, in questo caso i permessi per
tutti gli altri non vengono controllati.
+\itindbeg{file~attributes}
+A questi che sono i permessi ordinari si aggiungono, per i filesystem che
+supportano questa estensione, due permessi speciali mantenuti nei cosiddetti
+\textit{file attributes}, che si possono leggere ed impostare con i comandi
+\cmd{lsattr} e \cmd{chattr}.\footnote{per l'utilizzo di questo comando e le
+ spiegazioni riguardo gli altri \textit{file attributes} si rimanda alla
+ sezione 1.4.4 di \cite{AGL}.}
+
+Il primo è il cosiddetto attributo di immutabilità (\textit{immutable},
+identificato dalla lettera \texttt{i}) che impedisce ogni modifica al file,
+\textit{inode} compreso. Questo significa non solo che non se ne può cambiare
+il contenuto, ma neanche nessuno dei metadati, ed in particolare non si può
+cancellare, rinominare, modificare nei permessi o nei tempi, o creare
+\textit{hard link} verso di esso.
+
+Il secondo è il cosiddetto attributo di \textit{append-only}, (identificato
+dalla lettera \texttt{a}) che consente soltanto la scrittura del file in coda
+al file. Il file cioè può essere soltanto esteso, ma i suoi metadati, a parte
+i tempi che può però possono essere impostati al valore corrente, non possono
+essere modificati, quindi di nuovo non si potrà cancellare, rinominare, o
+modificare nei permessi.
+
+Entrambi questi attributi attivano queste proprietà a livello di filesytem,
+per cui a differenza dei permessi ordinari esse varranno per qualunque utente
+compreso l'amministratore. L'amministratore è l'unico che può attivare o
+disattivare questi attributi,\footnote{più precisamente un processo con la
+ \itindex{capabilities} capacità \const{CAP\_LINUX\_IMMUTABLE}.} e potendo
+rimuoverli è comunque capace di tornare in grado di eseguire qualunque
+operazione.
+\itindbeg{file~attributes}
+
+
\subsection{I bit dei permessi speciali}
\label{sec:file_special_perm}
sez.~\ref{sec:proc_perms}, non è detto siano uguali a quelli effettivi.
Per far questo si può usare la funzione \funcd{access}, il cui prototipo è:
-\begin{prototype}{unistd.h}
-{int access(const char *pathname, int mode)}
-Verifica i permessi di accesso.
-
-\bodydesc{La funzione ritorna 0 se l'accesso è consentito, -1 se l'accesso non
- è consentito ed in caso di errore; nel qual caso la variabile \var{errno}
- assumerà i valori:
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int access(const char *pathname, int mode)}
+\fdesc{Verifica i permessi di accesso.}
+}
+
+{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{EINVAL}] il valore di \param{mode} non è valido.
\item[\errcode{EACCES}] l'accesso al file non è consentito, o non si ha il
un filesystem montato in sola lettura.
\end{errlist}
ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
- \errval{ENOTDIR}, \errval{ELOOP}, \errval{EIO}.}
-\end{prototype}
+ \errval{ENOTDIR}, \errval{ELOOP}, \errval{EIO}
+ nel loro significato generico.}
+\end{funcproto}
La funzione verifica i permessi di accesso, indicati da \param{mode}, per il
file indicato da \param{pathname}. I valori possibili per l'argomento
Per cambiare i permessi di un file il sistema mette ad disposizione due
funzioni \funcd{chmod} e \funcd{fchmod}, che operano rispettivamente su un
filename e su un file descriptor, i loro prototipi sono:
-\begin{functions}
- \headdecl{sys/types.h}
- \headdecl{sys/stat.h}
-
- \funcdecl{int chmod(const char *path, mode\_t mode)} Cambia i permessi del
- file indicato da \param{path} al valore indicato da \param{mode}.
-
- \funcdecl{int fchmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa
- il file descriptor \param{fd} per indicare il file.
-
- \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per
- un errore, in caso di errore \var{errno} può assumere i valori:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fdecl{int chmod(const char *path, mode\_t mode)}
+\fdesc{Cambia i permessi del file indicato da \param{path} al valore indicato
+ da \param{mode}.}
+\fdecl{int fchmod(int fd, mode\_t mode)}
+\fdesc{Analoga alla precedente, ma usa il file descriptor \param{fd} per
+ indicare il 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{EPERM}] l'\ids{UID} effettivo non corrisponde a quello del
proprietario del file o non è zero.
- \item[\errcode{EROFS}] il file è su un filesystem in sola lettura.
+ \item[\errcode{EROFS}] il file è su un filesystem in sola lettura.
\end{errlist}
- ed inoltre \errval{EIO}; \func{chmod} restituisce anche \errval{EFAULT},
+ ed inoltre per entrambe \errval{EIO}, per \func{chmod} \errval{EFAULT},
\errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR},
- \errval{EACCES}, \errval{ELOOP}; \func{fchmod} anche \errval{EBADF}.}
-\end{functions}
+ \errval{EACCES}, \errval{ELOOP}, per \func{fchmod} \errval{EBADF}
+ nel loro significato generico.}
+\end{funcproto}
+
Entrambe le funzioni utilizzano come secondo argomento \param{mode}, una
variabile dell'apposito tipo primitivo \type{mode\_t} (vedi
La funzione che permette di impostare il valore di questa maschera di
controllo è \funcd{umask}, ed il suo prototipo è:
-\begin{prototype}{stat.h}
-{mode\_t umask(mode\_t mask)}
-Imposta la maschera dei permessi dei bit al valore specificato da \param{mask}
-(di cui vengono presi solo i 9 bit meno significativi).
-
- \bodydesc{La funzione ritorna il precedente valore della maschera. È una
- delle poche funzioni che non restituisce codici di errore.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{stat.h}
+\fdecl{mode\_t umask(mode\_t mask)}
+\fdesc{Imposta la maschera dei permessi.}
+}
+
+{La funzione ritorna ritorna il precedente valore della maschera, non sono
+ previste condizioni di errore.}
+\end{funcproto}
-In genere si usa questa maschera per impostare un valore predefinito che
-escluda preventivamente alcuni permessi (usualmente quello di scrittura per il
-gruppo e gli altri, corrispondente ad un valore per \param{mask} pari a
-$022$). In questo modo è possibile cancellare automaticamente i permessi non
-voluti. Di norma questo valore viene impostato una volta per tutte al login a
-$022$, e gli utenti non hanno motivi per modificarlo.
+La funzione imposta maschera dei permessi dei bit al valore specificato
+da \param{mask} (di cui vengono presi solo i 9 bit meno significativi). In
+genere si usa questa maschera per impostare un valore predefinito che escluda
+preventivamente alcuni permessi (usualmente quello di scrittura per il gruppo
+e gli altri, corrispondente ad un valore per \param{mask} pari a $022$). In
+questo modo è possibile cancellare automaticamente i permessi non voluti. Di
+norma questo valore viene impostato una volta per tutte al login a $022$, e
+gli utenti non hanno motivi per modificarlo.
\itindend{umask}
Come avviene nel caso dei permessi il sistema fornisce anche delle funzioni,
\funcd{chown}, \funcd{fchown} e \funcd{lchown}, che permettono di cambiare sia
l'utente che il gruppo a cui un file appartiene; i rispettivi prototipi sono:
-\begin{functions}
- \headdecl{sys/types.h}
- \headdecl{sys/stat.h}
-
- \funcdecl{int chown(const char *path, uid\_t owner, gid\_t group)}
- \funcdecl{int fchown(int fd, uid\_t owner, gid\_t group)}
- \funcdecl{int lchown(const char *path, uid\_t owner, gid\_t group)}
- Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori
- specificati dalle variabili \param{owner} e \param{group}.
-
- \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un
- errore, nel qual caso caso \var{errno} assumerà i valori:
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fdecl{int chown(const char *path, uid\_t owner, gid\_t group)}
+\fdecl{int fchown(int fd, uid\_t owner, gid\_t group)}
+\fdecl{int lchown(const char *path, uid\_t owner, gid\_t group)}
+\fdesc{Cambiano proprietario e gruppo proprietario 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{EPERM}] l'\ids{UID} effettivo non corrisponde a quello del
proprietario del file o non è zero, o utente e gruppo non sono validi
\end{errlist}
- Oltre a questi entrambe restituiscono gli errori \errval{EROFS} e
- \errval{EIO}; \func{chown} restituisce anche \errval{EFAULT},
- \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR},
- \errval{EACCES}, \errval{ELOOP}; \func{fchown} anche \errval{EBADF}.}
-\end{functions}
+ ed inoltre per tutte \errval{EROFS} e \errval{EIO}, per \func{chown}
+ \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM},
+ \errval{ENOTDIR}, \errval{EACCES}, \errval{ELOOP}, per \func{fchown}
+ \errval{EBADF} nel loro significato generico.}
+\end{funcproto}
-Con Linux solo l'amministratore\footnote{o in generale un processo con la
+Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori
+specificati dalle variabili \param{owner} e \param{group}. Con Linux solo
+l'amministratore\footnote{o in generale un processo con la
\itindex{capabilities} capacità \const{CAP\_CHOWN}, vedi
sez.~\ref{sec:proc_capabilities}.} può cambiare il proprietario di un file;
in questo viene seguita la semantica usata da BSD che non consente agli utenti
\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.\\
\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.\\
\funcd{getxattr}, \funcd{lgetxattr} e \funcd{fgetxattr}, che consentono
rispettivamente di richiedere gli attributi relativi a un file, a un
collegamento simbolico e ad un file descriptor; i rispettivi prototipi sono:
-\begin{functions}
- \headdecl{sys/types.h}
- \headdecl{attr/xattr.h}
-
- \funcdecl{ssize\_t getxattr(const char *path, const char *name, void
- *value, size\_t size)}
- \funcdecl{ssize\_t lgetxattr(const char *path, const char *name, void
- *value, size\_t size)}
-
- \funcdecl{ssize\_t fgetxattr(int filedes, const char *name, void *value,
- size\_t size)}
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{ssize\_t getxattr(const char *path, const char *name, void *value,
+ size\_t size)}
+\fdecl{ssize\_t lgetxattr(const char *path, const char *name, void *value,
+ size\_t size)}
+\fdecl{ssize\_t fgetxattr(int filedes, const char *name, void *value,
+ size\_t size)}
+\fdesc{Leggono il valore di un attributo esteso.}
+}
- Le funzioni leggono il valore di un attributo esteso.
-
- \bodydesc{Le funzioni restituiscono un intero positivo che indica la
- dimensione dell'attributo richiesto in caso di successo, e $-1$ in caso di
- errore, nel qual caso \var{errno} assumerà i valori:
+{Le funzioni ritornano un intero positivo che indica la dimensione
+ dell'attributo richiesto in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{ENOATTR}] l'attributo richiesto non esiste.
\item[\errcode{ERANGE}] la dimensione \param{size} del buffer \param{value}
\item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
filesystem o sono disabilitati.
\end{errlist}
- e tutti gli errori di \func{stat}, come \errcode{EPERM} se non si hanno i
- permessi di accesso all'attributo. }
-\end{functions}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
Le funzioni \func{getxattr} e \func{lgetxattr} prendono come primo argomento
un \textit{pathname} che indica il file di cui si vuole richiedere un
un attributo esteso, queste sono \funcd{setxattr}, \funcd{lsetxattr} e
\funcd{fsetxattr}, e consentono di operare rispettivamente su un file, su un
collegamento simbolico o specificando un file descriptor; i loro prototipi sono:
-\begin{functions}
- \headdecl{sys/types.h}
- \headdecl{attr/xattr.h}
-
- \funcdecl{int setxattr(const char *path, const char *name, const void
- *value, size\_t size, int flags)}
- \funcdecl{int lsetxattr(const char *path, const char *name, const void
- *value, size\_t size, int flags)}
-
- \funcdecl{int fsetxattr(int filedes, const char *name, const void *value,
- size\_t size, int flags)}
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{int setxattr(const char *path, const char *name, const void *value,
+ size\_t size, int flags)}
+\fdecl{int lsetxattr(const char *path, const char *name, const void *value,
+ size\_t size, int flags)}
+\fdecl{int fsetxattr(int filedes, const char *name, const void *value, size\_t
+ size, int flags)}
+\fdesc{Impostano il valore di un attributo esteso.}
+}
- Impostano il valore di un attributo esteso.
-
- \bodydesc{Le funzioni restituiscono 0 in caso di successo, e $-1$ in caso di
- errore, nel qual caso \var{errno} assumerà i valori:
+{Le funzioni ritornano un $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{ENOATTR}] si è usato il flag \const{XATTR\_REPLACE} e
l'attributo richiesto non esiste.
\item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
filesystem o sono disabilitati.
\end{errlist}
- Oltre a questi potranno essere restituiti tutti gli errori di \func{stat},
- ed in particolare \errcode{EPERM} se non si hanno i permessi di accesso
- all'attributo.
-}
-\end{functions}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
Le tre funzioni prendono come primo argomento un valore adeguato al loro
scopo, usato in maniera del tutto identica a quanto visto in precedenza per le
estesi, ma sarebbe altrettanto utile poter vedere quali sono gli attributi
presenti; a questo provvedono le funzioni \funcd{listxattr},
\funcd{llistxattr} e \funcd{flistxattr} i cui prototipi sono:
-\begin{functions}
- \headdecl{sys/types.h}
- \headdecl{attr/xattr.h}
-
- \funcdecl{ssize\_t listxattr(const char *path, char *list, size\_t size)}
- \funcdecl{ssize\_t llistxattr(const char *path, char *list, size\_t size)}
-
- \funcdecl{ssize\_t flistxattr(int filedes, char *list, size\_t size)}
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{ssize\_t listxattr(const char *path, char *list, size\_t size)}
+\fdecl{ssize\_t llistxattr(const char *path, char *list, size\_t size)}
+\fdecl{ssize\_t flistxattr(int filedes, char *list, size\_t size)}
+\fdesc{Leggono la lista degli attributi estesi di un file.}
+}
- Leggono la lista degli attributi estesi di un file.
-
- \bodydesc{Le funzioni restituiscono un intero positivo che indica la
- dimensione della lista in caso di successo, e $-1$ in caso di errore, nel
- qual caso \var{errno} assumerà i valori:
+{Le funzioni ritornano un intero positivo che indica la dimensione della lista
+ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà
+ uno dei valori:
\begin{errlist}
\item[\errcode{ERANGE}] la dimensione \param{size} del buffer \param{value}
non è sufficiente per contenere il risultato.
\item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
filesystem o sono disabilitati.
\end{errlist}
- Oltre a questi potranno essere restituiti tutti gli errori di \func{stat},
- ed in particolare \errcode{EPERM} se non si hanno i permessi di accesso
- all'attributo.
-}
-\end{functions}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
Come per le precedenti le tre funzioni leggono gli attributi rispettivamente
di un file, un collegamento simbolico o specificando un file descriptor, da
Infine per rimuovere semplicemente un attributo esteso, si ha a disposizione
un ultimo gruppo di funzioni: \funcd{removexattr}, \funcd{lremovexattr} e
\funcd{fremovexattr}; i rispettivi prototipi sono:
-\begin{functions}
- \headdecl{sys/types.h}
- \headdecl{attr/xattr.h}
-
- \funcdecl{int removexattr(const char *path, const char *name)}
-
- \funcdecl{int lremovexattr(const char *path, const char *name)}
-
- \funcdecl{int fremovexattr(int filedes, const char *name)}
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{int removexattr(const char *path, const char *name)}
+\fdecl{int lremovexattr(const char *path, const char *name)}
+\fdecl{int fremovexattr(int filedes, const char *name)}
+\fdesc{Rimuovono un attributo esteso di un file.}
+}
- Rimuovono un attributo esteso di un file.
-
- \bodydesc{Le funzioni restituiscono 0 in caso di successo, e $-1$ in caso di
- errore, nel qual caso \var{errno} assumerà i valori:
+{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{ENOATTR}] l'attributo richiesto non esiste.
\item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
filesystem o sono disabilitati.
\end{errlist}
- ed inoltre tutti gli errori di \func{stat}.
-}
-\end{functions}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
Le tre funzioni rimuovono l'attributo esteso indicato dall'argomento
\param{name} rispettivamente di un file, un collegamento simbolico o
\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
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},
``\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 è:
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
\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}).\\
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
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
\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
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.
2.4).\\
\const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare sui file gli
attributi \textit{immutable} e
- \itindex{append~mode} \textit{append only} (se
- supportati).\\
+ \itindex{append~mode} \textit{append-only} (vedi
+ sez.~\ref{sec:file_perm_overview}) se
+ supportati.\\
\const{CAP\_MKNOD} & La capacità di creare
\index{file!di~dispositivo} file di dispositivo
con \func{mknod} (vedi
-
% TODO: trattare la funzione setns e i namespace file descriptors (vedi
% http://lwn.net/Articles/407495/) introdotti con il kernel 3.0
% 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
% 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
+% LocalWords: member scan attack EOVERFLOW BITS blkcnt rdev
%%% Local Variables:
%%% mode: latex