Risistemati un sacco di riferiementi, e la riorganizzazione della parte
[gapil.git] / filedir.tex
1 \chapter{Files e directories}
2 \label{cha:files_and_dirs}
3
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.
10
11
12 \section{La manipolazione delle caratteristiche dei files}
13 \label{sec:filedir_infos}
14
15 Come spiegato in \secref{sec:fileintr_filesystem} 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}.
22
23
24 \subsection{Le funzioni \texttt{stat}, \texttt{fstat} e \texttt{lstat}}
25 \label{sec:filedir_stat}
26
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 è
30 il seguente;
31 \begin{prototype}{unistd.h}
32 {int stat(const char *file\_name, struct stat *buf)}
33   
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:
36   \begin{errlist}
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
41     del processo.
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.
45   \end{errlist}
46 \end{prototype}
47
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).
53
54 \begin{figure}[!htb]
55   \footnotesize
56   \centering
57   \begin{minipage}[c]{15cm}
58     \begin{lstlisting}[]{}
59 struct stat {
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 */
73 };
74     \end{lstlisting}
75   \end{minipage} 
76   \normalsize 
77   \caption{La struttura \texttt{stat} per la lettura delle informazioni dei 
78     file}
79   \label{fig:filedir_stat_struct}
80 \end{figure}
81
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
84 \texttt{sys/types.h}) 
85
86
87
88
89 \subsection{I tipi di file}
90 \label{sec:filedir_file_types}
91
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
96
97
98 \subsection{La dimensione dei file}
99 \label{sec:filedir_file_size}
100
101 \subsection{I tempi dei file}
102 \label{sec:filedir_file_times}
103
104 \subsection{La funzione \texttt{utime}}
105 \label{sec:filedir_utime}
106
107
108
109
110 \section{Il controllo di accesso ai file}
111 \label{sec:filedir_access_control}
112
113
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
118 concetti essenziali.
119
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.
125
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
131 gli altri utenti.
132
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}).
142
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.
150
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}.
154
155
156
157 \subsection{I flag \texttt{suid} e \texttt{sgid}}
158 \label{sec:filedir_suid_sgid}
159
160 \subsection{La titolarità di nuovi files e directory}
161 \label{sec:filedir_ownership}
162
163 \subsection{La funzione \texttt{access}}
164 \label{sec:filedir_access}
165
166 \subsection{La funzione \texttt{umask}}
167 \label{sec:filedir_umask}
168
169 \subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
170 \label{sec:filedir_chmod}
171
172 \subsection{Il flag \texttt{sticky}}
173 \label{sec:filedir_sticky}
174
175 \subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
176 \label{sec:filedir_chown}
177
178
179 \section{La manipolazione delle directories}
180 \label{sec:filedir_dir_handling}
181
182 \subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}} 
183 \label{sec:filedir_dir_creat_rem}
184
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}.
188
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.
194   
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:
199   \begin{errlist}
200   \item \texttt{EACCESS} 
201     Non c'è il permesso di scrittura per la directory in cui si vuole inserire
202     la nuova directory.
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
210     la nuova directory.
211   \item \texttt{EROFS} La directory su cui si vuole inserire la nuova
212     directory è su un filesystem montato readonly.
213   \end{errlist}
214 \end{prototype}
215  
216
217 \subsection{Accesso alle directory}
218 \label{sec:filedir_dir_read}
219
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.
224
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}.
232
233
234 \subsection{La directory di lavoro}
235 \label{sec:filedir_work_dir}
236
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).
241
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.
248
249 Le funzioni qui descritte servono esaminare e cambiare la directory di lavoro
250 corrente. 
251
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.
261   
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:
265   \begin{errlist}
266   \item \texttt{EINVAL} L'argomento \texttt{size} è zero e \texttt{buffer} non
267     è nullo.
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
272     corrente).
273   \end{errlist}
274 \end{prototype}
275
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.
284
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.
290
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.
295
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}.
300 \end{prototype}
301   
302 \begin{prototype}{unistd.h}{int fchdir (int filedes)} 
303   Analoga alla precedente, ma usa un file descriptor invece del pathname.
304   
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
310   una directory.
311 \end{prototype}
312
313
314
315
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}).
321