bbc7bc0ddf8fbece27978f3b4b85c4b606719fde
[gapil.git] / filestd.tex
1 \chapter{I file: l'interfaccia standard ANSI C}
2 \label{cha:files_std_interface}
3
4 Esamineremo in questo capitolo l'interfaccia standard ANSI C per i file,
5 quella che viene comunemente detta interfaccia degli \textit{stream}.
6 Dopo una breve sezione introduttiva tratteremo le funzioni base per la
7 gestione dell'input/output, mentre tratteremo le caratteristiche più avanzate
8 dell'interfaccia nell'ultima sezione.
9
10
11 \section{Introduzione}
12 \label{sec:file_stream_intro}
13
14 Come visto in \capref{cap:file_unix_interface} le operazioni di I/O sui file
15 sono gestibili a basso livello con l'interfaccia standard unix, che ricorre
16 direttamente alle system call messe a disposizione dal kernel.
17
18 Questa interfaccia però non provvede le funzionalità previste dallo standard
19 ANSI C, che invece sono realizzate attraverso opportune funzioni di libreria,
20 queste, insieme alle altre funzioni definite dallo standard, vengono a
21 costituire il nucleo\footnote{queste funzioni sono state implementate la prima
22   volta da Ritchie nel 1976 e da allora sono rimaste sostanzialmente
23   immutate.} delle \acr{glibc}.
24
25
26 \subsection{I \textit{file stream}}
27 \label{sec:file_stream}
28
29 Come più volte ribadito l'interfaccia dei file descriptor è una interfaccia di
30 basso livello, che non provvede nessuna forma di formattazione dei dati e
31 nessuna forma di bufferizzazione per ottimizzare le operazioni di I/O.
32
33 In \textit{Advanced Programming in the Unix Environment} Stevens descrive una
34 serie di test sull'influenza delle dimensioni del blocco di dati (il parametro
35 \param{buf} di \func{read} e \func{write}) nell'efficienza nelle operazioni di
36 I/O con i file descriptor, evidenziando come le prestazioni ottimali si
37 ottengano a partire da dimensioni del buffer dei dati pari a quelle dei
38 blocchi del filesystem (il valore dato dal campo \var{st\_blksize} di
39 \var{fstat}).
40
41 Se il programmatore non si cura di effettuare le operazioni in blocchi di
42 dimensioni adeguate, le prestazioni sono inferiori.  La caratteristica
43 principale dell'interfaccia degli stream è che essa provvede da sola alla
44 gestione dei dettagli della bufferizzazione e all'esecuzione delle operazioni
45 di lettura e scrittura in blocchi di dimensioni appropriate all'ottenimento
46 della massima efficienza.
47
48 Per questo motivo l'interfaccia viene chiamata anche interfaccia dei
49 \textit{file stream}, dato che non è più necessario doversi preoccupare di dei
50 dettagli della comunicazione con il tipo di hardware sottostante (come nel
51 caso della dimensione dei blocchi del filesystem), ed un file può essere
52 sempre considerato come composto da un flusso continuo (da cui il nome
53 \textit{stream}) di dati.
54
55 A parte i dettagli legati alla gestione delle operazioni di lettura e
56 scrittura (sia per quel che riguarda la bufferizzazione, che le
57 formattazioni), i file stream restano del tutto equivalenti ai file descriptor
58 (sui quali sono basati), ed in particolare continua a valere quanto visto in
59 \secref{sec:file_sharing} a proposito dell'accesso condiviso ed in
60 \secref{sec:file_access_control} per il controllo di accesso.
61
62
63 \subsection{Gli oggetti \type{FILE}}
64 \label{sec:file_FILE}
65
66 Per ragioni storiche la struttura di dati che rappresenta uno stream è stata
67 chiamata \type{FILE}, questi oggetti sono creati dalle funzioni di libreria e
68 contengono tutte le informazioni necessarie a gestire le operazioni sugli
69 stream, come la posizione corrente, lo stato del buffer e degli indicatori di
70 stato e di fine del file.
71
72 Per questo motivo gli utenti non devono mai utilizzare direttamente o allocare
73 queste strutture, ma usare sempre puntatori del tipo \type{FILE *} ottenuti
74 dalla libreria stessa (tanto che in certi casi il termine di puntatore a file
75 è diventato sinonimo di stream). 
76
77 Tutte le funzioni della libreria che operano sui file accettano come parametri
78 solo variabili di questo tipo, che diventa accessibile includendo l'header
79 file \file{stdio.h}.
80
81
82
83 \subsection{Gli stream standard}
84 \label{sec:file_std_stream}
85
86 Ai tre file descriptor standard (vedi \secref{sec:file_std_descr}) aperti per
87 ogni processo, corrispondono altrettanti stream, che rappresentano i canali
88 standard di input/output prestabiliti; anche questi tre stream sono
89 identificabili attraverso dei nomi simbolici definiti nell'header
90 \file{stdio.h} che sono:
91
92 \begin{itemize}
93 \item \var{FILE * stdin} Lo \textit{standard input} cioè lo stream da cui
94   il processo riceve ordinariamente i dati in ingresso. Normalmente è associato
95   dalla shell all'input del terminale e prende i caratteri dalla tastiera.
96 \item \var{FILE * stdout} Lo \textit{standard input} cioè lo stream su cui
97   il processo invia ordinariamente i dati in uscita. Normalmente è associato
98   dalla shell all'output del terminale e scrive sullo schermo.
99 \item \var{FILE * stderr} Lo \textit{standard input} cioè lo stream su cui
100   il processo è supposto inviare i messaggi di errore. Normalmente anch'esso
101   è associato dalla shell all'output del terminale e scrive sullo schermo.
102 \end{itemize}
103
104 Nelle \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono effettivamente
105 tre variabili di tipo \type{FILE *} che possono essere usate come tutte le
106 altre, ad esempio si può effettuare una redirezione dell'output di un
107 programma con il semplice codice:
108 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
109     fclose (stdout);
110     stdout = fopen ("standard-output-file", "w");
111 \end{lstlisting}
112 ma in altri sistemi possono essere definite come macro, se si hanno problemi
113 di portabilità e si vuole essere sicuri, diventa opportuno usare la funzione
114 \func{freopen}.
115
116
117 \subsection{Le modalità di bufferizzazione}
118 \label{sec:file_buffering}
119
120 La bufferizzazione è una delle caratteristiche principali della interfaccia
121 degli stream; lo scopo è quello di ridurre al minimo il numero di system call
122 (\func{read} o \func{write}) eseguite nelle operazioni di input/output. Questa
123 funzionalità è assicurata automaticamente dalla libreria, ma costituisce anche
124 una degli aspetti più comunemente fraintesi, in particolare per quello che
125 riguarda l'aspetto della scrittura dei dati sul file.
126
127 I caratteri che vengono scritti su uno stream normalmente vengono accumulati
128 in un buffer e poi trasmessi in blocco in maniera asincrona rispetto alla
129 scrittura (quello che viene chiamato lo \textsl{scarico}, dall'ingelese 
130 \textit{flush}, dei dati) tutte le volte che il buffer viene riempito. Un
131 comportamento analogo avviene anche in lettura (cioè dal file viene letto un
132 blocco di dati, anche se se ne sono richiesti una quantità inferiore), ma la
133 cosa ovviamente ha rilevanza inferiore, dato che i dati letti sono sempre gli
134 stessi; in caso di scrittura invece, quando si ha un accesso contemporaneo
135 allo stesso file (ad esempio da parte di un altro processo) si potranno vedere
136 solo le parti effettivamente scritte, e non quelle ancora presenti nel buffer.
137
138 Allo stesso modo, se si sta facendo dell'input/output interattivo bisognerà
139 tenere presente le caratteristiche delle operazioni di scarico dei dati,
140 poiché non è detto che ad una scrittura sullo stream corrisponda una immediata
141 scrittura sul dispositivo.
142
143 Per rispondere ad esigenze diverse, lo standard definisce tre distinte modalità
144 in cui può essere eseguita la bufferizzazione, delle quali occorre essere ben
145 consapevoli, specie in caso di lettura e scrittura da dispositivi interattivi:
146 \begin{itemize}
147 \item \textit{unbuffered}: in questo caso non c'è bufferizzazione ed i
148   caratteri vengono trasmessi direttamente al file non appena possibile
149   (effettuando immediatamente una \func{write}).
150 \item \textit{line buffered}: in questo caso i caratteri vengono normalmente
151   trasmessi al file in blocco ogni volta che viene incontrato un carattere di
152   \textit{newline} (il carattere ASCII \verb|\n|).
153 \item \textit{fully buffered}: in questo caso i caratteri vengono trasmessi da
154   e verso il file in blocchi di dimensione opportuna.
155 \end{itemize}
156
157 Lo standard ANSI C specifica inoltre che lo standard output e lo standard
158 input siano aperti in modalità \textit{fully buffered} quando non fanno
159 riferimento ad un dispositivo interattivo, e che lo standard error non sia mai
160 aperto in modalità \textit{fully buffered}.
161
162 Linux, come BSD e SVr4, specifica il comportamento di default in maniera
163 ancora più precisa, e cioè impone che lo standard error sia sempre
164 \textit{unbuffered} (in modo che i messaggi di errore siano mostrati il più
165 rapidamente possibile) e che standard input e standard output siano aperti in
166 modalità \textit{line buffered} quando sono associati ad un terminale (od
167 altro dispositivo interattivo) ed in modalità \textit{fully buffered}
168 altrimenti.
169
170 Il comportamento specificato per standard input e standard output vale anche
171 per tutti i nuovi stream aperti da un processo; la selezione comunque avviene
172 automaticamente, e la libreria apre lo stream nella modalità più opportuna a
173 seconda del file o del dispositivo scelto.
174
175 La modalità \textit{line buffered} è quella che necessita di maggiori
176 chiarimenti e attenzioni per quel che concerne il suo funzionamento. Come già
177 accennato nella descrizione, \emph{di norma} i dati vengono inviati al kernel
178 alla ricezione di un carattere di a capo; questo non è vero in tutti i casi,
179 infatti, dato che le dimensioni del buffer usato dalle librerie sono fisse, se
180 le si eccedono si può avere uno scarico dei dati anche prima che sia stato
181 inviato un carattere di \textit{newline}.
182
183 Un secondo punto da tenere presente, particolarmente quando si ha a che fare
184 con I/O interattivo, è che quando si effettua una lettura su uno stream che
185 comporta l'accesso al kernel\footnote{questo vuol dire sempre se lo stream da
186   cui si legge è in modalità \textit{unbuffered}.} viene anche eseguito lo
187 scarico di tutti i buffer degli stream in scrittura.
188
189 In \secref{sec:file_buffering_ctrl} vedremo come la libreria definisca delle
190 opportune funzioni per controllare le modalità di bufferizzazione e lo scarico
191 dei dati.
192
193
194
195 \section{Funzioni base}
196 \label{sec:file_ansi_base_func}
197
198 Esamineremo in questa sezione le funzioni base dell'interfaccia degli stream,
199 analoghe a quelle di \secref{sec:file_base_func} per i file descriptor. In
200 particolare vedremo come aprire, leggere, scrivere e cambiare la posizione
201 corrente in uno stream.
202
203
204 \subsection{Apertura e chiusura di uno stream}
205 \label{sec:file_fopen}
206
207 Le funzioni che permettono di aprire uno stream sono tre\footnote{\func{fopen}
208   e \func{freopen} fanno parte dello standard ANSI C, \func{fdopen} è parte
209 dello standard POSIX.1.}, i loro prototipi sono:
210 \begin{functions}
211   \headdecl{stdio.h}
212   \funcdecl{FILE * fopen(const char * path, const char *mode)}
213   Apre il file specificato da \param{path}.
214   \funcdecl{FILE * fdopen(int fildes, const char * mode)}
215   Associa uno stream al file descriptor \param{fildes}.
216   \funcdecl{FILE * freopen(const char * path, const char * mode, FILE *
217   stream)}
218   Apre il file specificato da \param{path} associandolo allo stream
219   specificato da \param{stream}, se questo è già aperto prima lo chiude.
220
221   Le funzioni ritornano un puntatore valido in caso di successo e \macro{NULL}
222   in caso di errore, in tal caso \var{errno} viene settata al valore ricevuto
223   dalla funzione sottostante di cui è fallita l'esecuzione.
224   
225   Gli errori pertanto possono essere quelli di \func{malloc} per tutte e tre
226   le funzioni, quelli \func{open} per \func{fopen}, quelli di \func{fcntl} per
227   \func{fdopen} e quelli di \func{fopen}, \func{fclose} e \func{fflush} per
228   \func{freopen}. 
229 \end{functions}
230
231 Normalmente la funzione che si usa per aprire uno stream è \func{fopen}, essa
232 apre il file specificato nella modalità specificata da \param{mode} che è una
233 delle stringhe elencate in \tabref{tab:file_fopen_mode}. 
234
235 L'uso di \func{freopen} è in genere per redirigere uno dei tre file standard
236 (vedi \secref{sec:file_std_stream}): il file \param{path} viene associato a
237 \param{stream} e se questo è uno stream aperto prima viene chiuso.  
238
239 Infine \func{fdopen} viene usato per associare uno stream ad un file
240 descriptor esistente ottenuto tramite una altra funzione (come \func{open},
241 \func{dup}, \func{pipe}) e serve quando si vogliono usare gli stream con file
242 speciali come le fifo od i socket, che non possono essere aperti con le
243 funzioni delle librerie standard del C.
244
245 \begin{table}[htb]
246   \centering
247   \begin{tabular}[c]{|l|p{8cm}|}
248     \hline
249     \textbf{Valore} & \textbf{Significato}\\
250     \hline
251     \hline
252     \texttt{r} & Il file viene aperto in sola lettura; lo stream è posizionato
253     all'inizio del file.\\
254     \texttt{r+} & Il file viene aperto in lettura e scrittura; lo stream è
255     posizionato all'inizio del file. \\
256 %    \hline
257     \texttt{w} & Il file viene troncato a lunghezza nulla (o creato se non 
258     esiste), ed aperto in sola lettura; lo stream è posizionato all'inizio del
259     file.\\
260     \texttt{w+} & Il file viene troncato a lunghezza nulla (o creato se non
261     esiste), ed aperto in scrittura e lettura; lo stream è posizionato 
262     all'inizio del file.\\
263 %    \hline
264     \texttt{a} & Il file è aperto in \textit{append mode} in sola scrittura
265     (o creato se non esiste). \\
266     \texttt{a+} & Il file è aperto in \textit{append mode} in lettura e 
267     scrittura (o creato se non esiste). \\
268     \hline
269   \end{tabular}
270   \caption{Modalità di apertura di uno stream}
271   \label{tab:file_fopen_mode}
272 \end{table}
273
274 In realtà lo standard ANSI C prevede un totale di 15 possibili valori diversi
275 per \param{mode}, ma in \tabref{tab:file_fopen_mode} si sono riportati solo i
276 sei valori effettivi, ad essi può essere aggiunto pure il carattere \func{b}
277 (come ultimo carattere o nel mezzo agli altri per le stringhe di due
278 caratteri) che in altri sistemi operativi serve a distinguere i file binari
279 dai file di testo; in un sistema POSIX questa distinzione non esiste e il
280 valore viene accettato solo per compatibilità, ma non ha alcun effetto.
281
282 Inoltre nel caso si usi \func{fdopen} i valori specificati da \param{mode}
283 devono essere compatibili con quelli con cui il file descriptor è stato
284 aperto. Inoltre i modi \cmd{w} e \cmd{w+} non troncano il file. La posizione
285 nello stream viene settata a quella corrente nel file descriptor, e le
286 variabili di errore e di fine del file sono cancellate. Il file non viene
287 duplicato e verrà chiuso alla chiusura dello stream.
288
289 I nuovi file saranno creati secondo quanto visto in
290 \secref{sec:file_ownership} ed avranno i permessi di accesso settati al valore
291 \macro{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a
292 \macro{0666}) modificato secondo il valore di \acr{umask} per il processo (si
293 veda \secref{sec:file_umask}).
294
295 In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è di
296 messo una bufferizzazione; per questo motivo lo standard ANSI C richiede che
297 ci sia una operazione di posizionamento fra una operazione di output ed una di
298 input o viceversa (eccetto il caso in cui l'input ha incontrato la fine del
299 file), altrimenti una lettura può ritornare anche il risultato di scritture
300 precedenti l'ultima effettuata.
301
302 Per questo motivo è una buona pratica (e talvolta necessario) far seguire ad
303 una scrittura una delle funzioni \func{fflush}, \func{fseek}, \func{fsetpos} o
304 \func{rewind} prima di eseguire una rilettura; viceversa nel caso in cui si
305 voglia fare una scrittura subito dopo aver eseguito una lettura occorre prima
306 usare una delle funzioni \func{fseek}, \func{fsetpos} o \func{rewind}. Anche
307 una operazione nominalmente nulla come \func{fseek(file, 0, SEEK\_CUR)} è
308 sufficiente a garantire la sincronizzazione.
309
310 Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione
311 (vedi \secref{sec:file_buffering_ctrl}) fintanto che non si è effettuato
312 alcuna operazione di I/O sul file.
313
314 Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo è:
315 \begin{prototype}{stdio.h}{int fclose(FILE * stream)}
316   Chiude lo stream \param{stream}. 
317   
318   Restituisce 0 in caso di successo e \macro{EOF} in caso di errore, nel qual
319   caso setta \var{errno} a \macro{EBADF} se il file descriptor indicato da
320   \param{stream} non è valido, o uno dei valori specificati dalla sottostante
321   funzione che è fallita (\func{close}, \func{write} o \func{fflush}).
322 \end{prototype}
323
324 La funzione effettua uno scarico di tutti i dati presenti nei buffer di uscita
325 e scarta tutti i dati in ingresso, se era stato allocato un buffer per lo
326 stream questo verrà rilasciato. La funzione effettua lo scarico solo per i
327 dati presenti nei buffer in user space usati dalle \acr{glibc}; se si essere
328 sicuri che il kernel forzi la scrittura su disco occorrà effettuare . 
329
330 Linux supporta, come estensione implementata dalle \acr{glibc}, anche una
331 altra funzione, \func{fcloseall}, che serve a chiudere tutti i file, il suo
332 prototipo è:
333 \begin{prototype}{stdio.h}{int fcloseall(void)}
334   Chiude tutti gli stream. 
335   
336   Restituisce 0 se non ci sono errori ed \macro{EOF} altrimenti.
337 \end{prototype}
338 la funzione esegue lo scarico dei dati bufferizzati in uscita e scarta quelli
339 in ingresso, chiudendo tutti i file. Questa funzione è provvista solo per i
340 casi di emergenza, quando si è verificato un errore ed il programma deve
341 essere abortito, ma si vuole compiere qualche altra operazione dopo aver
342 chiuso i file e prima di uscire (si ricordi quanto visto in
343 \secref{sec:proc_exit}).
344
345
346 \subsection{Lettura e scrittura su uno stream}
347 \label{sec:file_io}
348
349
350 \subsection{Posizionamento su uno stream}
351 \label{sec:file_fseek}
352
353
354 \subsection{Input/output binario}
355 \label{sec:file_binary_io}
356
357
358 \subsection{Input/output di linea}
359 \label{sec:file_line_io}
360
361
362 \subsection{Input/output formattato}
363 \label{sec:file_formatted_io}
364
365
366 \section{Funzioni avanzate}
367 \label{sec:file_stream_adv_func}
368
369 In questa sezione esamineremo le funzioni che permettono di controllare alcune
370 caratteristiche più particolari degli stream, come la lettura degli attributi,
371 le modalità di bufferizzazione, etc.
372
373
374 \subsection{Le funzioni di controllo}
375 \label{sec:file_stream_cntrl}
376
377 Al contrario di quanto avviene con i file descriptor le librerie standard del
378 C non prevedono nessuna funzione come la \func{fcntl} per la lettura degli
379 attributi degli stream; le \acr{glibc} però supportano alcune estensioni
380 derivate da Solaris, che permettono di ottenere informazioni utili.
381
382 In certi casi può essere necessario sapere se un certo stream è accessibile in
383 lettura o scrittura. In genere questa informazione non è disponibile, e si
384 deve ricordare come il file è stato aperto. La cosa può essere complessa se le
385 operazioni vengono effettuate un una subroutine, che a questo punto
386 necessiterà di informazioni aggiuntive rispetto al semplice puntatore allo
387 stream; questo può essere evitato con le due funzioni \func{\_\_freadable} e
388 \func{\_\_fwritable} i cui prototipi sono:
389
390 \begin{functions}
391   \headdecl{stdio\_ext.h}
392   \funcdecl{int \_\_freadable (FILE * stream)}
393   \funcdecl{int \_\_fwritable(FILE * stream)}
394 \end{functions}
395
396
397
398 \subsection{Il controllo della bufferizzazione}
399 \label{sec:file_buffering_ctrl}
400
401 Come accennato in \secref{sec:file_buffering} le librerie definiscono una
402 serie di funzioni che permettono di controllare il comportamento degli
403 stream; se non si è 
404
405
406 \subsection{Dettagli dell'implementazione}
407 \label{sec:file_stream_details}
408
409
410 \subsection{File temporanei}
411 \label{sec:file_temp_file}
412
413
414 \subsection{Efficienza}
415 \label{sec:file_stream_efficiency}
416