file su disco avviene passando attraverso il suo inode\index{inode}, che è la
struttura usata dal kernel che lo identifica univocamente all'interno di un
singolo filesystem. Il nome del file che si trova nella voce di una directory
-è solo un'etichetta che viene associata ad un puntatore che fa riferimento al
-suddetto inode.
+è solo un'etichetta, mantenuta all'interno della directory, che viene
+associata ad un puntatore che fa riferimento al suddetto inode.
Questo significa che, fintanto che si resta sullo stesso filesystem, la
realizzazione di un link è immediata, ed uno stesso file può avere tanti nomi
-diversi allo stesso tempo, dati da altrettante diverse associazioni allo
-stesso inode\index{inode}. Si noti anche che nessuno di questi nomi viene ad
-assumere una particolare preferenza o originalità rispetto agli altri.
+diversi, dati da altrettante diverse associazioni allo stesso
+inode\index{inode} di etichette diverse in directory diverse. Si noti anche
+che nessuno di questi nomi viene ad assumere una particolare preferenza o
+originalità rispetto agli altri, in quanto tutti fanno comunque riferimento
+allo stesso inode\index{inode}.
Per aggiungere ad una directory una voce che faccia riferimento ad un
inode\index{inode} già esistente si utilizza la funzione \func{link}; si suole
chiamare questo tipo di associazione un collegamento diretto (o \textit{hard
- link}).
-
-Il prototipo della funzione e le sue caratteristiche principali,
-come risultano dalla pagina di manuale, sono le seguenti:
+ link}). Il prototipo della funzione è:
\begin{prototype}{unistd.h}
{int link(const char *oldpath, const char *newpath)}
- Crea un nuovo collegamento diretto al file indicato da \param{oldpath}
- dandogli nome \param{newpath}.
+ Crea un nuovo collegamento diretto.
\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
errore nel qual caso \var{errno} viene impostata ai valori:
\errval{ENOSPC}, \errval{EIO}.}
\end{prototype}
-La creazione di un nuovo collegamento diretto non copia il contenuto del file,
-ma si limita a creare una voce nella directory specificata con \param{newpath}
-e ad aumentare di uno il numero di riferimenti al file (riportato nel campo
-\var{st\_nlink} della struttura \struct{stat}, vedi \secref{sec:file_stat})
-aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può
-essere così chiamato con vari nomi in diverse directory.
+La funzione crea sul pathname \param{newpath} un collegamento diretto al file
+indicato da \param{oldpath}. Per quanto detto la creazione di un nuovo
+collegamento diretto non copia il contenuto del file, ma si limita a creare
+una voce nella directory specificata da \param{newpath} e ad aumentare di uno
+il numero di riferimenti al file (riportato nel campo \var{st\_nlink} della
+struttura \struct{stat}, vedi \secref{sec:file_stat}) aggiungendo il nuovo
+nome ai precedenti. Si noti che uno stesso file può essere così chiamato con
+vari nomi in diverse directory.
Per quanto dicevamo in \secref{sec:file_filesystem} la creazione di un
collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
funzione restituisce l'errore \errcode{EPERM}.
La rimozione di un file (o più precisamente della voce che lo referenzia
-all'interno di una directory) si effettua con la funzione \func{unlink}; il
+all'interno di una directory) si effettua con la funzione \funcd{unlink}; il
suo prototipo è il seguente:
\begin{prototype}{unistd.h}{int unlink(const char *pathname)}
\errcode{EPERM} in caso l'operazione non sia consentita o il processo non
abbia privilegi sufficienti.}
-La funzione cancella il nome specificato dal pathname nella relativa directory
-e decrementa il numero di riferimenti nel relativo inode\index{inode}. Nel
-caso di link simbolico cancella il link simbolico; nel caso di
-socket\index{socket}, fifo o file di dispositivo\index{file!di dispositivo}
-rimuove il nome, ma come per i file i processi che hanno aperto uno di questi
-oggetti possono continuare ad utilizzarlo.
+La funzione cancella il nome specificato da \param{pathname} nella relativa
+directory e decrementa il numero di riferimenti nel relativo
+inode\index{inode}. Nel caso di link simbolico cancella il link simbolico; nel
+caso di socket\index{socket}, fifo o file di dispositivo\index{file!di
+ dispositivo} rimuove il nome, ma come per i file i processi che hanno aperto
+uno di questi oggetti possono continuare ad utilizzarlo.
Per cancellare una voce in una directory è necessario avere il permesso di
scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e
Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
\func{unlink} sulle directory; per cancellare una directory si può usare la
funzione \func{rmdir} (vedi \secref{sec:file_dir_creat_rem}), oppure la
-funzione \func{remove}.
+funzione \funcd{remove}.
Questa è la funzione prevista dallo standard ANSI C per cancellare un file o
una directory (e funziona anche per i sistemi che non supportano i link
ancora in uso.
Per cambiare nome ad un file o a una directory (che devono comunque essere
-nello stesso filesystem) si usa invece la funzione \func{rename},\footnote{la
+nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la
funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo
standard POSIX estende la funzione anche alle directory.} il cui prototipo
è:
funzioni di libreria (come \func{open} o \func{stat}) dare come parametro un
link simbolico comporta l'applicazione della funzione al file da esso
specificato. La funzione che permette di creare un nuovo link simbolico è
-\func{symlink}; il suo prototipo è:
+\funcd{symlink}; il suo prototipo è:
\begin{prototype}{unistd.h}
{int symlink(const char *oldpath, const char *newpath)}
Crea un nuovo link simbolico di nome \param{newpath} il cui contenuto è
\func{open} seguono i link simbolici, occorrono funzioni apposite per accedere
alle informazioni del link invece che a quelle del file a cui esso fa
riferimento. Quando si vuole leggere il contenuto di un link simbolico si usa
-la funzione \func{readlink}, il cui prototipo è:
+la funzione \funcd{readlink}, il cui prototipo è:
\begin{prototype}{unistd.h}
{int readlink(const char *path, char *buff, size\_t size)}
Legge il contenuto del link simbolico indicato da \param{path} nel buffer
\subsection{La creazione e la cancellazione delle directory}
\label{sec:file_dir_creat_rem}
-Per creare e cancellare delle directory si usano le due funzioni (omonime
-degli analoghi comandi di shell) \func{mkdir} e \func{rmdir}. Per poter
-accedere ai tipi usati da queste funzioni si deve includere il file
-\file{sys/types.h}, il prototipo della prima è:
-\begin{prototype}{sys/stat.h}
- {int mkdir(const char *dirname, mode\_t mode)} Crea una nuova directory.
+Benché in sostanza le directory non siano altro che dei file contenenti
+elenchi di nomi ed inode, non è possibile trattarle come file ordinari e
+devono essere create direttamente dal kernel attraverso una opportuna system
+call.\footnote{questo permette anche, attraverso l'uso del VFS, l'utilizzo di
+ diversi formati per la gestione dei suddetti elenchi.} La funzione usata
+per creare una directory è \funcd{mkdir}, ed il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/stat.h}
+ \headdecl{sys/types.h}
+ \funcdecl{int mkdir(const char *dirname, mode\_t mode)}
+
+ Crea una nuova directory.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso \var{errno} assumerà i valori:
ed inoltre anche \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG},
\errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
\errval{EROFS}.}
-\end{prototype}
+\end{functions}
La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
-standard \file{.} e \file{..}, con il nome indicato dall'argomento
+standard (\file{.} e \file{..}), con il nome indicato dall'argomento
\param{dirname}. Il nome può essere indicato sia come pathname assoluto che
relativo.
nuova directory è impostata secondo quanto riportato in
\secref{sec:file_ownership}.
-La seconda funzione serve ad eliminare una directory già vuota (la directory
-deve cioè contenere soltanto le due voci standard \file{.} e \file{..}); il
-suo prototipo è:
+La funzione per la cancellazione di una directory è \funcd{rmdir}, il suo
+prototipo è:
\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)}
Cancella una directory.
\errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.}
\end{prototype}
-La funzione cancella la directory \param{dirname}, che deve essere vuota. Il
-nome può essere indicato con il pathname assoluto o relativo.
+La funzione cancella la directory \param{dirname}, che deve essere vuota (la
+directory deve cioè contenere soltanto le due voci standard \file{.} e
+\file{..}). Il nome può essere indicato con il pathname assoluto o relativo.
La modalità con cui avviene la cancellazione è analoga a quella di
\func{unlink}: fintanto che il numero di link all'inode\index{inode} della
\errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC},
\errval{ENOTDIR} e \errval{EROFS}.}
\end{functions}
-\noindent come per \func{mknod} il file \param{pathname} non deve esistere
-(neanche come link simbolico); al solito i permessi specificati da
-\param{mode} vengono modificati dal valore di \var{umask}.
+
+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 link
+simbolico); al solito i permessi specificati da \param{mode} vengono
+modificati dal valore di \var{umask}.
\label{sec:file_dir_read}
Benché le directory siano oggetti del filesystem come tutti gli altri non ha
-senso aprirle come fossero dei file di dati. Inoltre si
-
- Può però essere utile poterne
-leggere il contenuto ad esempio per fare la lista dei file che esse contengono
-o ricerche sui medesimi. Solo il kernel può scrivere direttamente il contenuto
-di una directory (onde evitare inconsistenze all'interno del filesystem), i
-processi devono creare i file usando le apposite funzioni.
-
-Per accedere al contenuto delle directory si usano i cosiddetti
-\textit{directory streams} (chiamati così per l'analogia con i file stream di
-\capref{cha:files_std_interface}); la funzione \funcd{opendir} apre uno di
-questi stream, il suo prototipo è:
+senso aprirle come fossero dei file di dati; per questo solo il kernel può
+scrivere direttamente il contenuto di una directory (onde evitare
+inconsistenze all'interno del filesystem), mentre i processi devono creare i
+file usando le apposite funzioni. Può però essere utile potere leggere il
+contenuto di una directory, ad esempio per fare la lista dei file che contiene
+o per delle ricerche.
+
+Per far questo lo standard POSIX\footnote{le funzioni sono previste pure in
+ BSD e SVID.} ha introdotto i cosiddetti \textit{directory streams} (chiamati
+così per l'analogia con i file stream di \capref{cha:files_std_interface}) ed
+una serie di funzioni per la loro gestione. La prima di queste è
+\funcd{opendir}, il cui prototipo è:
\begin{functions}
\headdecl{sys/types.h} \headdecl{dirent.h}
- \funcdecl{DIR * opendir(const char *name)}
+ \funcdecl{DIR * opendir(const char *dirname)}
Apre un \textit{directory stream}.
\errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR}.}
\end{functions}
-La funzione apre un \textit{directory stream} per la directory indicata da
-\param{name}, ritornando il puntatore allo stesso, e posizionandosi sulla
-prima voce della directory.
+La funzione apre un \textit{directory stream} per la directory
+\param{dirname}, ritornando il puntatore alla relativa struttura \type{DIR}
+(questo è un tipo opaco\index{tipo!opaco} usato dalle librerie per gestire i
+\textit{directory stream}) da usare per le successive operazioni, posizionando
+lo stream sulla prima voce contenuta nella directory.
-Dato che le directory sono comunque dei file, in alcuni casi può essere utile
-conoscere il file descriptor sottostante un \textit{directory stream}, ad
-esempio per utilizzarlo con la funzione \func{fchdir} per cambiare la
+Dato che le directory sono comunque dei file, in alcuni casi può servire
+conoscere il \textit{file descriptor} (tratteremo i \textit{file descriptor}
+in \capref{cha:file_unix_interface}) sottostante un \textit{directory stream},
+ad esempio per utilizzarlo con la funzione \func{fchdir} per cambiare la
directory di lavoro (vedi \secref{sec:file_work_dir}) a quella relativa allo
-stream che si è aperto. A questo scopo si può usare la funzione \funcd{dirfd},
-il cui prototipo è:
+stream stesso. A questo scopo si può usare la funzione \funcd{dirfd}, il cui
+prototipo è:
\begin{functions}
\headdecl{sys/types.h} \headdecl{dirent.h}
caso di successo e -1 in caso di errore.}
\end{functions}
-La funzione\footnote{questa funzione è una estensione di BSD introdotta con
- BSD 4.3-Reno; è presente in Linux con le libc5 (a partire dalla versione
- 5.1.2) e con le \acr{glibc}.} restituisce il file descriptor associato al
-\textit{directory stream} \param{dir}, essa è disponibile solo definendo
-\macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}.
-
-
+La funzione\footnote{questa funzione è una estensione di BSD non presente in
+ POSIX, introdotta con BSD 4.3-Reno; è presente in Linux con le libc5 (a
+ partire dalla versione 5.1.2) e con le \acr{glibc}.} restituisce il file
+descriptor associato al \textit{directory stream} \param{dir}, essa è
+disponibile solo definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}.
-La funzione \func{readdir} legge il contenuto della directory, i cui elementi
-sono le \textit{directory entry} (da distinguersi da quelle della cache di cui
-parlavamo in \secref{sec:file_vfs}) in un'opportuna struttura \struct{dirent}
-definita in \figref{fig:file_dirent_struct}.
+La lettura di una voce nella directory viene effettuata attraverso la funzione
+\funcd{readdir}; il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{struct dirent *readdir(DIR *dir)}
+
+ Legge una voce dal \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce il puntatore alla struttura contentente i
+ dati in caso di successo e \val{NULL} altrimenti, in caso di descrittore
+ non valido \var{errno} assumerà il valore \errval{EBADF}, il valore
+ \val{NULL} viene restituito anche quando si raggiunge la fine dello
+ stream.}
+\end{functions}
+La funzione legge la voce corrente nella directory, posizionandosi sulla voce
+successiva. I dati vengono memorizzati in una struttura \struct{dirent} (la
+cui definizione è riportata in \figref{fig:file_dirent_struct}). La funzione
+restituisce il puntatore alla struttura; si tenga presente però che questa
+viene sovrascritta tutte le volte che si ripete una lettura sullo stesso
+stream.
\begin{figure}[!htb]
- \footnotesize
- \centering
+ \footnotesize \centering
\begin{minipage}[c]{15cm}
\begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
struct dirent {
- ino_t d_ino;
- unsigned short int d_reclen;
- unsigned char d_type;
- char d_name[256]; /* We must not include limits.h! */
+ ino_t d_ino; /* inode number */
+ off_t d_off; /* offset to the next dirent */
+ unsigned short int d_reclen; /* length of this record */
+ unsigned char d_type; /* type of file */
+ char d_name[256]; /* We must not include limits.h! */
};
\end{lstlisting}
\end{minipage}
+
+
+Una volta completate le operazioni si può chiudere il \textit{directory
+ stream} con la funzione \funcd{closedir}, il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{int closedir(DIR * dir)}
+
+ Chiude un \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 altrimenti, nel
+ qual caso \var{errno} assume il valore \errval{EBADF}.}
+\end{functions}
+
+
\subsection{La directory di lavoro}
\label{sec:file_work_dir}
In genere il kernel tiene traccia per ciascun processo dell'inode\index{inode}
della directory di lavoro corrente, per ottenere il pathname occorre usare una
-apposita funzione di libreria, \func{getcwd}, il cui prototipo è:
+apposita funzione di libreria, \funcd{getcwd}, il cui prototipo è:
\begin{prototype}{unistd.h}{char *getcwd(char *buffer, size\_t size)}
- Restituisce il filename completo della directory di lavoro corrente nella
- stringa puntata da \param{buffer}, che deve essere precedentemente allocata,
- per una dimensione massima di \param{size}.
+ Legge il pathname della directory di lavoro corrente.
\bodydesc{La funzione restituisce il puntatore \param{buffer} se riesce,
\val{NULL} se fallisce, in quest'ultimo caso la variabile
\end{errlist}}
\end{prototype}
-Il buffer deve essere sufficientemente lungo da poter contenere il pathname
+La funzione restituisce il pathname completo della directory di lavoro
+corrente nella stringa puntata da \param{buffer}, che deve essere
+precedentemente allocata, per una dimensione massima di \param{size}. Il
+buffer deve essere sufficientemente lungo da poter contenere il pathname
completo più lo zero di terminazione della stringa. Qualora esso ecceda le
-dimensioni specificate con \param{size} la funzione restituisce un errore. Si
-può anche specificare un puntatore nullo come \param{buffer},\footnote{questa è
- un'estensione allo standard POSIX.1, supportata da Linux.} nel qual caso la
-stringa sarà allocata automaticamente per una dimensione pari a \param{size}
-qualora questa sia diversa da zero, o della lunghezza esatta del pathname
-altrimenti. In questo caso ci si deve ricordare di disallocare la stringa una
-volta cessato il suo utilizzo.
+dimensioni specificate con \param{size} la funzione restituisce un errore.
+
+Si può anche specificare un puntatore nullo come
+\param{buffer},\footnote{questa è un'estensione allo standard POSIX.1,
+ supportata da Linux.} nel qual caso la stringa sarà allocata automaticamente
+per una dimensione pari a \param{size} qualora questa sia diversa da zero, o
+della lunghezza esatta del pathname altrimenti. In questo caso ci si deve
+ricordare di disallocare la stringa una volta cessato il suo utilizzo.
Di questa funzione esiste una versione \code{char *getwd(char *buffer)}
fatta per compatibilità all'indietro con BSD, che non consente di specificare
passaggio attraverso eventuali link simbolici.
Per cambiare la directory di lavoro corrente si può usare la funzione
-\func{chdir} (equivalente del comando di shell \cmd{cd}) il cui nome sta
+\funcd{chdir} (equivalente del comando di shell \cmd{cd}) il cui nome sta
appunto per \textit{change directory}, il suo prototipo è:
\begin{prototype}{unistd.h}{int chdir(const char *pathname)}
Cambia la directory di lavoro corrente in \param{pathname}.
Dato che anche le directory sono file, è possibile riferirsi ad esse anche
tramite il file descriptor, e non solo tramite il filename, per fare questo si
-usa \func{fchdir}, il cui prototipo è:
+usa \funcd{fchdir}, il cui prototipo è:
\begin{prototype}{unistd.h}{int fchdir(int fd)}
Identica a \func{chdir}, ma usa il file descriptor \param{fd} invece del
pathname.
Le \acr{glibc} provvedono varie funzioni per generare nomi di file temporanei,
di cui si abbia certezza di unicità (al momento della generazione); la prima
-di queste funzioni è \func{tmpnam} il cui prototipo è:
+di queste funzioni è \funcd{tmpnam} il cui prototipo è:
\begin{prototype}{stdio.h}{char *tmpnam(char *string)}
Restituisce il puntatore ad una stringa contente un nome di file valido e
non esistente al momento dell'invocazione.
Di questa funzione esiste una versione rientrante, \func{tmpnam\_r}, che non
fa nulla quando si passa \val{NULL} come parametro. Una funzione simile,
-\func{tempnam}, permette di specificare un prefisso per il file
+\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)}
Restituisce il puntatore ad una stringa contente un nome di file valido e
esistente.
Per evitare di dovere effettuare a mano tutti questi controlli, lo standard
-POSIX definisce la funzione \func{tempfile}, il cui prototipo è:
+POSIX definisce la funzione \funcd{tempfile}, il cui prototipo è:
\begin{prototype}{stdio.h}{FILE *tmpfile (void)}
Restituisce un file temporaneo aperto in lettura/scrittura.
condition}\index{race condition}.
Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo
-caso si possono usare le vecchie funzioni \func{mktemp} e \func{mkstemp} che
+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
-unico. La prima delle due è analoga a \func{tmpnam} e genera un nome casuale,
+unico. La prima delle due è analoga a \funcd{tmpnam} e genera un nome casuale,
il suo prototipo è:
\begin{prototype}{stlib.h}{char *mktemp(char *template)}
Genera un filename univoco sostituendo le \code{XXXXXX} finali di
indovinare. Per tutti questi motivi la funzione è deprecata e non dovrebbe mai
essere usata.
-
-
-La seconda funzione, \func{mkstemp} è sostanzialmente equivalente a
+La seconda funzione, \funcd{mkstemp} è sostanzialmente equivalente a
\func{tmpfile}, ma restituisce un file descriptor invece di uno stream; il suo
prototipo è:
\begin{prototype}{stlib.h}{int mkstemp(char *template)}
In OpenBSD è stata introdotta un'altra funzione\footnote{introdotta anche in
Linux a partire dalle \acr{glibc} 2.1.91.} simile alle precedenti,
-\func{mkdtemp}, che crea una directory temporanea; il suo prototipo è:
+\funcd{mkdtemp}, che crea una directory temporanea; il suo prototipo è:
\begin{prototype}{stlib.h}{char *mkdtemp(char *template)}
Genera una directory temporaneo il cui nome è ottenuto sostituendo le
\code{XXXXXX} finali di \param{template}.
\label{sec:file_utime}
I tempi di ultimo accesso e modifica possono essere cambiati usando la
-funzione \func{utime}, il cui prototipo è:
+funzione \funcd{utime}, il cui prototipo è:
\begin{prototype}{utime.h}
{int utime(const char *filename, struct utimbuf *times)}
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:
-\begin{itemize*}
+\begin{itemize}
\item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
\textit{read}).
\item il permesso di scrittura (indicato con la lettera \texttt{w},
dall'inglese \textit{write}).
\item il permesso di esecuzione (indicato con la lettera \texttt{x},
dall'inglese \textit{execute}).
-\end{itemize*}
+\end{itemize}
mentre i tre livelli su cui sono divisi i privilegi sono:
-\begin{itemize*}
+\begin{itemize}
\item i privilegi per l'utente proprietario del file.
\item i privilegi per un qualunque utente faccia parte del gruppo cui
appartiene il file.
\item i privilegi per tutti gli altri utenti.
-\end{itemize*}
+\end{itemize}
L'insieme dei permessi viene espresso con un numero a 12 bit; di questi i nove
meno significativi sono usati a gruppi di tre per indicare i permessi base di
lettura, scrittura ed esecuzione e sono applicati rispettivamente
rispettivamente al proprietario, al gruppo, a tutti gli altri.
-I restanti tre bit (noti come \acr{suid}, \acr{sgid}, e \textsl{sticky}) sono
-usati per indicare alcune caratteristiche più complesse del meccanismo del
-controllo di accesso su cui torneremo in seguito (in
-\secref{sec:file_suid_sgid} e \secref{sec:file_sticky}); lo schema di
-allocazione dei bit è riportato in \figref{fig:file_perm_bit}.
-
\begin{figure}[htb]
\centering
\includegraphics[width=6cm]{img/fileperm}
\label{fig:file_perm_bit}
\end{figure}
+I restanti tre bit (noti come \acr{suid}, \acr{sgid}, e \textsl{sticky}) sono
+usati per indicare alcune caratteristiche più complesse del meccanismo del
+controllo di accesso su cui torneremo in seguito (in
+\secref{sec:file_suid_sgid} e \secref{sec:file_sticky}); lo schema di
+allocazione dei bit è riportato in \figref{fig:file_perm_bit}.
+
Anche i permessi, come tutte le altre informazioni pertinenti al file, sono
memorizzati nell'inode\index{inode}; in particolare essi sono contenuti in
alcuni bit del campo \var{st\_mode} della struttura \struct{stat} (si veda di
Per una directory infatti il permesso di esecuzione significa che essa può
essere attraversata nella risoluzione del pathname, ed è 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}
impostato un file potrà essere rimosso dalla directory soltanto se l'utente ha
il permesso di scrittura su di essa ed inoltre è vera una delle seguenti
condizioni:
-\begin{itemize*}
+\begin{itemize}
\item l'utente è proprietario del file
\item l'utente è proprietario della directory
\item l'utente è l'amministratore
-\end{itemize*}
+\end{itemize}
un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i
-permessi infatti di solito sono impostati come:
+permessi infatti di solito sono i seguenti:
\begin{verbatim}
$ ls -ld /tmp
drwxrwxrwt 6 root root 1024 Aug 10 01:03 /tmp
\end{verbatim}%$
-in questo modo chiunque può creare file in questa directory (che infatti è
-normalmente utilizzata per la creazione di file temporanei), ma solo l'utente
-che ha creato un certo file potrà cancellarlo o rinominarlo. In questo modo si
-evita che un utente possa, più o meno consapevolmente, cancellare i file degli
-altri.
+quindi con lo \textsl{sticky bit} bit impostato. In questo modo qualunque
+utente nel sistema può creare dei file in questa directory (che, come
+suggerisce il nome, è normalmente utilizzata per la creazione di file
+temporanei), ma solo l'utente che ha creato un certo file potrà cancellarlo o
+rinominarlo. In questo modo si evita che un utente possa, più o meno
+consapevolmente, cancellare i file temporanei creati degli altri utenti.
\subsection{La titolarità di nuovi file e directory}
Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda
all'userid effettivo del processo che lo crea; per il \acr{gid} invece prevede
due diverse possibilità:
-\begin{itemize*}
+\begin{itemize}
\item il \acr{gid} del file corrisponde al groupid effettivo del processo.
\item il \acr{gid} del file corrisponde al \acr{gid} della directory in cui
esso è creato.
-\end{itemize*}
+\end{itemize}
in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
semantica BSD. Linux invece segue quella che viene chiamata semantica SVr4; di
norma cioè il nuovo file viene creato, seguendo la prima opzione, con il
Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre
automaticamente propagato, restando coerente a quello della directory di
-partenza, in tutte le sottodirectory. La semantica SVr4 offre la possibilità
-di scegliere, ma per ottenere lo stesso risultato di coerenza che si ha con
-BSD necessita che per le nuove directory venga anche propagato anche il bit
-\acr{sgid}. Questo è il comportamento predefinito di \cmd{mkdir}, ed è in
-questo modo ad esempio che Debian assicura che le sottodirectory create nella
-home di un utente restino sempre con il \acr{gid} del gruppo primario dello
-stesso.
+partenza, in tutte le sottodirectory.
+
+La semantica SVr4 offre la possibilità di scegliere, ma per ottenere lo stesso
+risultato di coerenza che si ha con BSD necessita che per le nuove directory
+venga anche propagato anche il bit \acr{sgid}. Questo è il comportamento
+predefinito del comando \cmd{mkdir}, ed è in questo modo ad esempio che Debian
+assicura che le sottodirectory create nella home di un utente restino sempre
+con il \acr{gid} del gruppo primario dello stesso.
\subsection{La funzione \func{access}}
ed il groupid reale, vale a dire usando i valori di \acr{uid} e \acr{gid}
relativi all'utente che ha lanciato il programma, e che, come accennato in
\secref{sec:file_suid_sgid} e spiegato in dettaglio in
-\secref{sec:proc_perms}, non è detto siano uguali a quelli effettivi. Per far
-questo si può usare la funzione \func{access}, il cui prototipo è:
+\secref{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, indicati da \param{mode}, per il file indicato
-da \param{pathname}.
+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}
\errval{ENOTDIR}, \errval{ELOOP}, \errval{EIO}.}
\end{prototype}
-I valori possibili per l'argomento \param{mode} sono esprimibili come
-combinazione delle costanti numeriche riportate in
-\tabref{tab:file_access_mode_val} (attraverso un OR binario delle stesse). I
-primi tre valori implicano anche la verifica dell'esistenza del file, se si
-vuole verificare solo quest'ultima si può usare \const{F\_OK}, o anche
-direttamente \func{stat}. Nel caso in cui \param{pathname} si riferisca ad un
-link simbolico, questo viene seguito ed il controllo è fatto sul file a cui
-esso fa riferimento.
+La funzione verifica i permessi di accesso, indicati da \param{mode}, per il
+file indicato da \param{pathname}. I valori possibili per l'argomento
+\param{mode} sono esprimibili come combinazione delle costanti numeriche
+riportate in \tabref{tab:file_access_mode_val} (attraverso un OR binario delle
+stesse). I primi tre valori implicano anche la verifica dell'esistenza del
+file, se si vuole verificare solo quest'ultima si può usare \const{F\_OK}, o
+anche direttamente \func{stat}. Nel caso in cui \param{pathname} si riferisca
+ad un link simbolico, questo viene seguito ed il controllo è fatto sul file a
+cui esso fa riferimento.
La funzione controlla solo i bit dei permessi di accesso, si ricordi che il
fatto che una directory abbia permesso di scrittura non significa che ci si
Oltre che dai valori indicati in sede di creazione, i permessi assegnati ai
nuovi file sono controllati anche da una maschera di bit impostata con la
-funzione \func{umask}, il cui prototipo è:
+funzione \funcd{umask}, il cui prototipo è:
\begin{prototype}{stat.h}
{mode\_t umask(mode\_t mask)}
In certe situazioni però per motivi di sicurezza non si vuole che un processo
possa accedere a tutto il filesystem; per questo si può cambiare la directory
-radice con la funzione \func{chroot}, il cui prototipo è:
+radice con la funzione \funcd{chroot}, il cui prototipo è:
\begin{prototype}{unistd.h}{int chroot(const char *path)}
Cambia la directory radice del processo a quella specificata da
\param{path}.