1 \chapter{Files e directories}
2 \label{cha:files_and_dirs}
4 In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
5 files e directories, ed in particolare esamineremo come è strutturato il
6 sistema base di protezioni e controllo di accesso ai files, e tutta
7 l'interfaccia che permette la manipolazione dei vari attributi di files e
8 directories. Tutto quello che riguarda invece la manipolazione dei contenuti è
9 lasciato ai capitoli successivi.
12 \section{La manipolazione delle caratteristiche dei files}
13 \label{sec:filedir_infos}
15 Come spiegato in \secref{sec:filedir_file_handling} tutte le informazioni
16 generali relative alle caratteristiche di ciascun file sono mantenute
17 nell'inode. Vedremo in questa sezione come sia possibile accedervi usando la
18 funzione \texttt{stat} ed esamineremo alcune funzioni utilizzabili per
19 manipolare una parte di questa informazione. Tutto quello che invece riguarda
20 il meccanismo di controllo di accesso ad i file e le relative funzioni di
21 manipolazione sarà invece esaminanto in \secref{sec:filedir_access_control}.
24 \subsection{Le funzioni \texttt{stat}, \texttt{fstat} e \texttt{lstat}}
25 \label{sec:filedir_stat}
27 La lettura delle informazioni relative ai file è fatta attraverso la famiglia
28 delle funzioni \texttt{stat}, questa è la funzione che il comando \texttt{ls}
29 usa per poter stampare tutti i dati dei files; il prototipo della funzione è
31 \begin{prototype}{unistd.h}
32 {int stat(const char *file\_name, struct stat *buf)}
34 La funzione restituisce zero in caso di successo e -1 per un errore, in caso
35 di errore \texttt{errno} viene settato ai valori:
37 \item \texttt{EACCESS} Non c'è il permesso di accedere al file.
38 \item \texttt{ENOTDIR} Una componente del pathname non è una directory.
39 \item \texttt{EMLOOP} Ci sono troppi link simbolici nel pathname.
40 \item \texttt{EFAULT} I puntatori usati sono fuori dallo spazio di indirizzi
42 \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
43 completare l'operazione.
44 \item \texttt{ENAMETOOLONG} Il filename è troppo lungo.
48 La struttura \texttt{stat} è definita nell'header \texttt{sys/stat.h} e in
49 generale dipende dall'implementazione, la versione usata da Linux è mostrata
50 in \nfig, così come riportata dalla man page (in realtà la definizione
51 effettivamente usata nel kernel dipende dall'archietettura e ha altri campi
52 riservati per estensioni come tempo più precisi, o per il padding dei campi).
57 \begin{minipage}[c]{15cm}
58 \begin{lstlisting}[]{}
60 dev_t st_dev; /* device */
61 ino_t st_ino; /* inode */
62 mode_t st_mode; /* protection */
63 nlink_t st_nlink; /* number of hard links */
64 uid_t st_uid; /* user ID of owner */
65 gid_t st_gid; /* group ID of owner */
66 dev_t st_rdev; /* device type (if inode device) */
67 off_t st_size; /* total size, in bytes */
68 unsigned long st_blksize; /* blocksize for filesystem I/O */
69 unsigned long st_blocks; /* number of blocks allocated */
70 time_t st_atime; /* time of last access */
71 time_t st_mtime; /* time of last modification */
72 time_t st_ctime; /* time of last change */
77 \caption{La struttura \texttt{stat} per la lettura delle informazioni dei
79 \label{fig:sock_sa_gen_struct}
82 Si noti come i vari membri della struttura siano specificati come tipi nativi
83 del sistema (di quelli definiti in \tabref{tab:xxx_sys_types}, e dichiarati in
89 \subsection{I tipi di file}
90 \label{sec:filedir_file_types}
92 Come riportato in \tabref{tab:fileintr_file_types} in linux oltre ai file e
93 alle directory esistono vari altri oggetti che possono stare su un filesystem;
94 il tipo di file è ritornato dalla \texttt{stat} nel campo \texttt{st\_mode},
95 dato che il valore numerico può variare a seconda delle implementazioni
98 \subsection{La dimensione dei file}
99 \label{sec:filedir_file_size}
101 \subsection{I tempi dei file}
102 \label{sec:filedir_file_times}
104 \subsection{La funzione \texttt{utime}}
105 \label{sec:filedir_utime}
110 \section{Il controllo di accesso ai file}
111 \label{sec:filedir_access_control}
114 In unix è implementata da qualunque filesystem standard una forma elementare
115 (ma adatta alla maggior parte delle esigenze) di controllo di accesso ai
116 files. Torneremo sull'argomento in dettaglio più avanti (vedi
117 \secref{sec:filedir_access_control}), qui ci limitiamo ad una introduzione dei
120 Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo Unix,
121 e non è detto che sia applicabile (ed infatti non è vero per il filesystem di
122 Windows) a un filesystem qualunque. Esistono inoltre estensioni che permettono
123 di implementare le ACL (\textit{Access Control List}) che sono un meccanismo
124 di controllo di accesso molto più sofisticato.
126 Ad ogni file Unix associa sempre l'utente che ne è proprietario (il cosiddetto
127 \textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli uid e
128 gid accennato in \secref{sec:intro_multiuser}, e un insieme di permessi che
129 sono divisi in tre classi, e cioè attribuiti rispettivamente al proprietario,
130 a qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti
133 I permessi sono espressi da un insieme di 12 bit: di questi i nove meno
134 significativi sono usati a gruppi di tre per indicare i permessi base di
135 lettura, scrittura ed esecuzione (indicati rispettivamente con le lettere
136 \textit{w}, \textit{r} \textit{x}) applicabili rispettivamente al
137 proprietario, al gruppo, a tutti (una descrizione più dettagliata dei vari
138 permessi associati ai file è riportata in \secref{sec:filedir_suid_sgid}). I
139 restanti tre bit sono usati per indicare alcune caratteristiche più complesse
140 (\textit{suid}, \textit{sgid}, e \textit{sticky}) su cui pure torneremo in
141 seguito (vedi \secref{sec:filedir_suid_sgid} e \secref{sec:filedir_sticky}).
143 Tutte queste informazioni sono tenute per ciascun file nell'inode. Quando un
144 processo cerca l'accesso al file esso controlla i propri uid e gid
145 confrontandoli con quelli del file e se l'operazione richiesta è compatibile
146 con i permessi associati al file essa viene eseguita, altrimenti viene
147 bloccata ed è restituito un errore di \texttt{EPERM}. Questo procedimento non
148 viene eseguito per l'amministratore di sistema (il cui uid è zero) il quale ha
149 pertanto accesso senza restrizione a qualunque file del sistema.
151 % In realtà il procedimento è più complesso di quanto descritto in maniera
152 % elementare qui; inoltre ad un processo sono associati diversi identificatori,
153 % torneremo su questo in maggiori dettagli in seguito in \secref{sec:proc_perms}.
157 \subsection{I flag \texttt{suid} e \texttt{sgid}}
158 \label{sec:filedir_suid_sgid}
160 \subsection{La titolarità di nuovi files e directory}
161 \label{sec:filedir_ownership}
163 \subsection{La funzione \texttt{access}}
164 \label{sec:filedir_access}
166 \subsection{La funzione \texttt{umask}}
167 \label{sec:filedir_umask}
169 \subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
170 \label{sec:filedir_chmod}
172 \subsection{Il flag \texttt{sticky}}
173 \label{sec:filedir_sticky}
175 \subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
176 \label{sec:filedir_chown}
179 \section{La manipolazione delle directories}
180 \label{sec:filedir_dir_handling}
182 \subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}}
183 \label{sec:filedir_dir_creat_rem}
185 Per creare una nuova directory si può usare la seguente funzione, omonima
186 dell'analogo comando di shell \texttt{mkdir}; per accedere ai tipi usati
187 programma deve includere il file \texttt{sys/types.h}.
189 \begin{prototype}{sys/stat.h}
190 {int mkdir (const char * dirname, mode\_t mode)}
191 Questa funzione crea una nuova directory vuota con il nome indicato da
192 \texttt{dirname}, assegnandole i permessi indicati da \texttt{mode}. Il nome
193 può essere indicato con il pathname assoluto o relativo.
195 La funzione restituisce zero in caso di successo e -1 per un errore, in caso
196 di errore \texttt{errno} viene settata secondo i codici di errore standard
197 di accesso ai files (trattati in dettaglio in
198 \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
200 \item \texttt{EACCESS}
201 Non c'è il permesso di scrittura per la directory in cui si vuole inserire
203 \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di già.
204 \item \texttt{EMLINK} La directory in cui si vuole creare la nuova directory
205 contiene troppi file. Sotto Linux questo normalmente non avviene perché il
206 filesystem standard consente la creazione di un numero di file maggiore di
207 quelli che possono essere contenuti nell'hard-disk, ma potendo avere a che
208 fare anche con filesystem di altri sistemi questo errore può presentarsi.
209 \item \texttt{ENOSPC} Non c'è abbastanza spazio sul file system per creare
211 \item \texttt{EROFS} La directory su cui si vuole inserire la nuova
212 directory è su un filesystem montato readonly.
217 \subsection{Accesso alle directory}
218 \label{sec:filedir_dir_read}
220 Benché le directory siano oggetti del filesystem come tutti gli altri non ha
221 ovviamente senso aprirle come fossero dei file di dati. Può però essere utile
222 poterne leggere il contenuto ad esempio per fare la lista dei file che esse
223 contengono o ricerche sui medesimi.
225 Per accedere al contenuto delle directory si usano i cosiddetti
226 \textit{directory streams} (chiamati così per l'analogia con i file stream);
227 la funzione \texttt{opendir} apre uno di questi stream e la funzione
228 \texttt{readdir} legge il contenuto della directory, i cui elementi sono le
229 \textit{directory entries} (da distinguersi da quelle della cache di cui
230 parlavamo in \secref{sec:fileintr_vfs}) in una opportuna struttura
231 \texttt{struct dirent}.
234 \subsection{La directory di lavoro}
235 \label{sec:filedir_work_dir}
237 A ciascun processo è associato ad una directory nel filesystem che è chiamata
238 directory corrente o directory di lavoro (\textit{current working directory})
239 che è quella a cui si fa riferimento quando un filename è espresso in forma
240 relativa (relativa appunto a questa directory).
242 Quando un utente effettua il login questa directory viene settata alla
243 cosiddetta \textit{home directory} del suo account, il comando \texttt{cd}
244 della shell consente di cambiarla a piacere, spostandosi da una directory ad
245 un'altra. Siccome la directory corrente resta la stessa quando viene creato
246 un processo figlio, la directory corrente della shell diventa anche la
247 directory corrente di qualunque comando da essa lanciato.
249 Le funzioni qui descritte servono esaminare e cambiare la directory di lavoro
252 \begin{prototype}{unistd.h}{char * getcwd (char * buffer, size\_t size)}
253 Restituisce il filename completo della directory di lavoro corrente nella
254 stringa puntata da \texttt{buffer}, che deve essere precedentemente
255 allocata, per una dimensione massima di \texttt{size}. Si può anche
256 specificare un puntatore nullo come \textit{buffer}, nel qual caso la
257 stringa sarà allocata automaticamente per una dimensione pari a
258 \texttt{size} qualora questa sia diversa da zero, o della lunghezza esatta
259 del pathname altrimenti. In questo caso si deve ricordare di disallocare la
260 stringa una volta cessato il suo utilizzo.
262 La funzione restituisce il puntatore \texttt{buffer} se riesce,
263 \texttt{NULL} se fallisce, in quest'ultimo caso la variabile
264 \texttt{errno} è settata con i seguenti codici di errore:
266 \item \texttt{EINVAL} L'argomento \texttt{size} è zero e \texttt{buffer} non
268 \item \texttt{ERANGE} L'argomento \texttt{size} è più piccolo della
269 lunghezza del pathname.
270 \item \texttt{EACCESS} Manca il permesso di lettura o di ricerca su uno dei
271 componenti del pathname (cioè su una delle directory superiori alla
276 Di questa funzione esiste una versione \texttt{char * getwd(char * buffer)}
277 fatta per compatibilità all'indietro con BSD, che non consente di specificare
278 la dimensione del buffer; esso deve essere allocato in precedenza ed avere una
279 dimensione superiore a \texttt{PATH\_MAX} (di solito 256 bytes, vedi
280 \secref{sec:xxx_limits}; il problema è che in Linux non esiste una dimensione
281 superiore per un pathname, per cui non è detto che il buffer sia sufficiente a
282 contenere il nome del file, e questa è la ragione principale per cui questa
283 funzione è deprecata.
285 Una seconda funzione simile è \texttt{char * get\_current\_dir\_name(void)}
286 che è sostanzialmente equivalente ad una \texttt{getcwd(NULL, 0)}, con la sola
287 differenza che essa ritorna il valore della variabile di ambiente
288 \texttt{PWD}, che essendo costruita dalla shell può contenere anche dei
289 riferimenti simbolici.
291 Come già detto in unix anche le directory sono file, è possibile pertanto
292 riferirsi ad esse tramite il file descriptor dell'interfaccia a basso livello,
293 e non solo tramite il filename; per questo motivo ci sono due diverse funzioni
294 per cambiare directory di lavoro.
296 \begin{prototype}{unistd.h}{int chdir (const char * pathname)}
297 Come dice il nome (che significa \textit{change directory}) questa funzione
298 serve a cambiare la directory di lavoro a quella specificata dal pathname
299 contenuto nella stringa \texttt{pathname}.
302 \begin{prototype}{unistd.h}{int fchdir (int filedes)}
303 Analoga alla precedente, ma usa un file descriptor invece del pathname.
305 Entrambe le funzioni restituiscono zero in caso di successo e -1 per un
306 errore, in caso di errore \texttt{errno} viene settata secondo i codici di
307 errore standard di accesso ai files (trattati in dettaglio in
308 \secref{sec:filedir_access_control}) ai quali si aggiunge il codice
309 \texttt{ENOTDIR} nel caso il \texttt{filename} indichi un file che non sia
316 %La struttura fondamentale che contiene i dati essenziali relativi ai file è il
317 %cosiddetto \textit{inode}; questo conterrà informazioni come il
318 %tipo di file (file di dispositivo, directory, file di dati, per un elenco
319 %completo vedi \ntab), i permessi (vedi \secref{sec:file_perms}), le date (vedi
320 %\secref{sec:file_times}).