Fatte fopen, freopen, fdopen
[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 il \textit{flush} dei dati) tutte le
130 volte che il buffer viene riempito. Un comportamento analogo avviene anche in
131 lettura (cioè dal file viene letto un blocco di dati, anche se se ne sono
132 richiesti una quantità inferiore), ma la cosa ovviamente ha rilevanza
133 inferiore, dato che i dati letti sono sempre gli stessi; in caso di scrittura
134 invece, quando si ha un accesso contemporaneo allo stesso file (ad esempio da
135 parte di un altro processo) si potranno vedere solo le parti effettivamente
136 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 \textit{flush} dei
140 dati, poiché non è detto che ad una scrittura sullo stream corrisponda una
141 immediata 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 un \textit{flush} dei dati anche prima che sia
181 stato 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 il
187 \textit{flush} 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 ed il
191 \textit{flush} 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
211 \begin{functions}
212   \headdecl{stdio.h}
213   \funcdecl{FILE * fopen(const char * path, const char *mode)}
214   Apre il file specificato da \param{path}.
215   \funcdecl{FILE * fdopen(int fildes, const char * mode)}
216   Associa uno stream al file descriptor \param{fildes}.
217   \funcdecl{FILE * freopen(const char * path, const char * mode, FILE *
218   stream)}
219   Apre il file specificato da \param{path} associandolo allo stream
220   specificato da \param{stream}, se questo è già aperto prima lo chiude.
221
222   Le funzioni ritornano un puntatore valido in caso di successo e \macro{NULL}
223   in caso di errore, in tal caso \var{errno} viene settata al valore ricevuto
224   dalla funzione sottostante di cui è fallita l'esecuzione.
225   
226   Gli errori pertanto possono essere quelli di \func{malloc} per tutte e tre
227   le funzioni, quelli \func{open} per \func{fopen}, quelli di \func{fcntl} per
228   \func{fdopen} e quelli di \func{fopen}, \func{fclose} e \func{fflush} per
229   \func{freopen}. 
230 \end{functions}
231
232 Normalmente la funzione che si usa per aprire uno stream è \func{fopen}, essa
233 apre il file specificato nella modalità specificata da \param{mode} che è una
234 delle stringhe elencate in \tabref{tab:file_fopen_mode}. 
235
236 L'uso di \func{freopen} è in genere per redirigere uno dei tre file standard
237 (vedi \secref{sec:file_std_stream}): il file \param{path} viene associato a
238 \param{stream} e se questo è uno stream aperto prima viene chiuso.  
239
240 Infine \func{fdopen} viene usato per associare uno stream ad un file
241 descriptor esistente ottenuto tramite una altra funzione (come \func{open},
242 \func{dup}, \func{pipe}) e serve quando si vogliono usare gli stream con file
243 speciali come le fifo od i socket, che non possono essere aperti con le
244 funzioni delle librerie standard del C.
245
246 \begin{table}[htb]
247   \centering
248   \begin{tabular}[c]{|l|p{8cm}|}
249     \hline
250     \textbf{Valore} & \textbf{Significato}\\
251     \hline
252     \hline
253     \texttt{r} & Il file viene aperto in sola lettura; lo stream è posizionato
254     all'inizio del file.\\
255     \texttt{r+} & Il file viene aperto in lettura e scrittura; lo stream è
256     posizionato all'inizio del file. \\
257 %    \hline
258     \texttt{w} & Il file viene troncato a lunghezza nulla (o creato se non 
259     esiste), ed aperto in sola lettura; lo stream è posizionato all'inizio del
260     file.\\
261     \texttt{w+} & Il file viene troncato a lunghezza nulla (o creato se non
262     esiste), ed aperto in scrittura e lettura; lo stream è posizionato 
263     all'inizio del file.\\
264 %    \hline
265     \texttt{a} & Il file è aperto in \textit{append mode} in sola scrittura
266     (o creato se non esiste). \\
267     \texttt{a+} & Il file è aperto in \textit{append mode} in lettura e 
268     scrittura (o creato se non esiste). \\
269     \hline
270   \end{tabular}
271   \caption{Modalità di apertura di uno stream}
272   \label{tab:file_fopen_mode}
273 \end{table}
274
275 In realtà lo standard ANSI C prevede un totale di 15 possibili valori diversi
276 per \param{mode}, ma in \tabref{tab:file_fopen_mode} si sono riportati solo i
277 sei valori effettivi, ad essi può essere aggiunto pure il carattere \func{b}
278 (come ultimo carattere o nel mezzo agli altri per le stringhe di due
279 caratteri) che in altri sistemi operativi serve a distinguere i file binari
280 dai file di testo; in un sistema POSIX questa distinzione non esiste e il
281 valore viene accettato solo per compatibilità, ma non ha alcun effetto.
282
283 Inoltre nel caso si usi \func{fdopen} i valori specificati da \param{mode}
284 devono essere compatibili con quelli con cui il file descriptor è stato
285 aperto. Inoltre i modi \cmd{w} e \cmd{w+} non troncano il file. La posizione
286 nello stream viene settata a quella corrente nel file descriptor, e le
287 variabili di errore e di fine del file sono cancellate. Il file non viene
288 duplicato e verrà chiuso alla chiusura dello stream.
289
290 I nuovi file saranno creati secondo quanto visto in
291 \secref{sec:file_ownership} ed avranno i permessi di accesso settati al valore
292 \macro{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a
293 \macro{0666}) modificato secondo il valore di \acr{umask} per il processo (si
294 veda \secref{sec:file_umask}).
295
296 In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è di
297 messo una bufferizzazione; per questo motivo lo standard ANSI C richiede che
298 ci sia una operazione di posizionamento fra una operazione di output ed una di
299 input o viceversa (eccetto il caso in cui l'input ha incontrato la fine del
300 file), altrimenti una lettura può ritornare anche il risultato di scritture
301 precedenti l'ultima effettuata.
302
303 Per questo motivo è una buona pratica (e talvolta necessario) far seguire ad
304 una scrittura una delle funzioni \func{fflush}, \func{fseek}, \func{fsetpos} o
305 \func{rewind} prima di eseguire una rilettura; viceversa nel caso in cui si
306 voglia fare una scrittura subito dopo aver eseguito una lettura occorre prima
307 usare una delle funzioni \func{fseek}, \func{fsetpos} o \func{rewind}. Anche
308 una operazione nominalmente nulla come \func{fseek(file, 0, SEEK\_CUR)} è
309 sufficiente a garantire la sincronizzazione.
310
311 Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo è:
312 \begin{prototype}{stdio.h}{int fclose(FILE * stream)}
313   Chiude lo stream \param{stream}. 
314   
315   Restituisce 0 in caso di successo e \macro{EOF} in caso di errore, nel qual
316   caso setta \var{errno} a \macro{EBADF} se il file descriptor indicato da
317   \param{stream} non è valido, o uno dei valori specificati dalla sottostante
318   funzione che è fallita (\func{close}, \func{write} o \func{fflush}).
319 \end{prototype}
320
321
322
323 \subsection{Lettura e scrittura su uno stream}
324 \label{sec:file_io}
325
326
327 \subsection{Posizionamento su uno stream}
328 \label{sec:file_fseek}
329
330
331 \subsection{Input/output binario}
332 \label{sec:file_binary_io}
333
334
335 \subsection{Input/output di linea}
336 \label{sec:file_line_io}
337
338
339 \subsection{Input/output formattato}
340 \label{sec:file_formatted_io}
341
342
343 \section{Funzioni avanzate}
344 \label{sec:file_stream_adv_func}
345
346
347 \subsection{Il controllo della bufferizzazione}
348 \label{sec:file_buffering_ctrl}
349
350 Come accennato in \secref{sec:file_buffering} le librerie definiscono una
351 serie di funzioni che permettono di controllare il comportamento degli
352 stream; se non si è 
353
354
355 \subsection{Dettagli dell'implementazione}
356 \label{sec:file_stream_details}
357
358
359 \subsection{File temporanei}
360 \label{sec:file_temp_file}
361
362
363 \subsection{Efficienza}
364 \label{sec:file_stream_efficiency}
365
366
367
368
369
370
371
372
373