2a22545a15e690ba79c4eeeefedda7601eb4c78e
[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'inglese 
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
275 diversi per \param{mode}, ma in \tabref{tab:file_fopen_mode} si sono
276 riportati solo i sei valori effettivi, ad essi può essere aggiunto pure
277 il carattere \func{b} (come ultimo carattere o nel mezzo agli altri per
278 le stringhe di due caratteri) che in altri sistemi operativi serve a
279 distinguere i file binari dai file di testo; in un sistema POSIX questa
280 distinzione non esiste e il valore viene accettato solo per
281 compatibilità, ma non ha alcun effetto.
282
283 Inoltre nel caso si usi \func{fdopen} i valori specificati da
284 \param{mode} devono essere compatibili con quelli con cui il file
285 descriptor è stato aperto. Inoltre i modi \cmd{w} e \cmd{w+} non
286 troncano il file. La posizione nello stream viene settata a quella
287 corrente nel file descriptor, e le variabili di errore e di fine del
288 file sono cancellate. Il file non viene duplicato e verrà chiuso alla
289 chiusura dello stream.
290
291 I nuovi file saranno creati secondo quanto visto in
292 \secref{sec:file_ownership} ed avranno i permessi di accesso settati al
293 valore \macro{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH}
294 (pari a \macro{0666}) modificato secondo il valore di \acr{umask} per il
295 processo (si veda \secref{sec:file_umask}).
296
297 In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
298 di messo una bufferizzazione; per questo motivo lo standard ANSI C
299 richiede che ci sia una operazione di posizionamento fra una operazione
300 di output ed una di input o viceversa (eccetto il caso in cui l'input ha
301 incontrato la fine del file), altrimenti una lettura può ritornare anche
302 il risultato di scritture precedenti l'ultima effettuata.
303
304 Per questo motivo è una buona pratica (e talvolta necessario) far seguire ad
305 una scrittura una delle funzioni \func{fflush}, \func{fseek}, \func{fsetpos} o
306 \func{rewind} prima di eseguire una rilettura; viceversa nel caso in cui si
307 voglia fare una scrittura subito dopo aver eseguito una lettura occorre prima
308 usare una delle funzioni \func{fseek}, \func{fsetpos} o \func{rewind}. Anche
309 una operazione nominalmente nulla come \func{fseek(file, 0, SEEK\_CUR)} è
310 sufficiente a garantire la sincronizzazione.
311
312 Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione
313 (vedi \secref{sec:file_buffering_ctrl}) fintanto che non si è effettuato
314 alcuna operazione di I/O sul file.
315
316 Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo è:
317 \begin{prototype}{stdio.h}{int fclose(FILE * stream)}
318   Chiude lo stream \param{stream}. 
319   
320   Restituisce 0 in caso di successo e \macro{EOF} in caso di errore, nel qual
321   caso setta \var{errno} a \macro{EBADF} se il file descriptor indicato da
322   \param{stream} non è valido, o uno dei valori specificati dalla sottostante
323   funzione che è fallita (\func{close}, \func{write} o \func{fflush}).
324 \end{prototype}
325
326 La funzione effettua uno scarico di tutti i dati presenti nei buffer di uscita
327 e scarta tutti i dati in ingresso, se era stato allocato un buffer per lo
328 stream questo verrà rilasciato. La funzione effettua lo scarico solo per i
329 dati presenti nei buffer in user space usati dalle \acr{glibc}; se si essere
330 sicuri che il kernel forzi la scrittura su disco occorrerà effettuare . 
331
332 Linux supporta, come estensione implementata dalle \acr{glibc}, anche una
333 altra funzione, \func{fcloseall}, che serve a chiudere tutti i file, il suo
334 prototipo è:
335 \begin{prototype}{stdio.h}{int fcloseall(void)}
336   Chiude tutti gli stream. 
337   
338   Restituisce 0 se non ci sono errori ed \macro{EOF} altrimenti.
339 \end{prototype}
340 la funzione esegue lo scarico dei dati bufferizzati in uscita e scarta quelli
341 in ingresso, chiudendo tutti i file. Questa funzione è provvista solo per i
342 casi di emergenza, quando si è verificato un errore ed il programma deve
343 essere abortito, ma si vuole compiere qualche altra operazione dopo aver
344 chiuso i file e prima di uscire (si ricordi quanto visto in
345 \secref{sec:proc_exit}).
346
347
348 \subsection{Lettura e scrittura su uno stream}
349 \label{sec:file_io}
350
351 Una delle caratteristiche più utili dell'interfaccia degli stream è la
352 ricchezza delle funzioni disponibili per le operazioni di lettura e
353 scrittura sui file. Sono infatti previste ben tre diverse modalità
354 modalità di input/output non formattato:
355 \begin{enumerate}
356 \item\textsl{binario} in cui legge/scrive un blocco di dati alla
357   volta, vedi \secref{sec:file_binary_io}.
358 \item\textsl{di linea} in cui si legge/scrive una linea (terminata dal
359   carattere di newline \verb|\n|) alla volta, vedi
360   \secref{sec:file_line_io}.
361 \item\textsl{a caratteri} in cui si legge/scrive un carattere alla
362   volta (con la bufferizzazione gestita automaticamente dalla libreria),
363   vedi \secref{sec:file_char_io}.
364 \end{enumerate}
365 ed inoltre la modalità di input/output formattato.
366
367 A differenza dell'interfaccia dei file descriptor il raggiungimento della fine
368 del file è considerato un errore, e viene notificato come tale dai valori di
369 uscita delle varie funzioni; nella maggior parte dei casi questo avviene con
370 la restituzione del valore intero (di tipo \type{int}) \macro{EOF}\footnote{la
371   costante deve essere negativa, le \acr{glibc} usano -1, altre
372   implementazioni possono avere valori diversi.}  definito anch'esso
373 nell'header \func{stdlib.h}.
374
375 Dato che le funzioni dell'interfaccia degli stream sono funzioni di libreria
376 che si appoggiano a delle system call, esse non settano direttamente la
377 variabile \var{errno}, che mantiene il valore settato dalla system call che ha
378 riportato l'errore. 
379
380 Siccome la condizione di end-of-file è anch'essa segnalata come errore, nasce
381 il problema di come distinguerla da un errore effettivo; basarsi solo sul
382 valore di ritorno della funzione e controllare il valore di \var{errno}
383 infatti non basta, dato che quest'ultimo potrebbe essere stato settato in una
384 altra occasione, (si veda \secref{sec:sys_errno} per i dettagli del
385 funzionamento di \var{errno}).
386
387 Per questo motivo tutte le implementazioni delle librerie standard
388 mantengono per ogni stream almeno due flag all'interno dell'oggetto
389 \type{FILE}, il flag di \textit{end-of-file}, che segnala che si è
390 raggiunta la fine del file in lettura, e quello di errore, che segnala
391 la presenza di un qualche errore nelle operazioni di input/output;
392 questi flag possono essere riletti dalle funzioni:
393 \begin{functions}
394   \headdecl{stdio.h}
395   \funcdecl{int feof(FILE *stream)}
396   Controlla il flag di end-of-file di \param{stream}.
397   \funcdecl{int ferror(FILE *stream)}
398   Controlla il flag di errore di \param{stream}.
399
400   Entrambe le funzioni ritornano un valore diverso da zero se i relativi
401   flag sono settati. 
402 \end{functions}
403 \noindent si tenga presente comunque che la lettura di questi flag segnala
404 soltanto che c'è stato un errore, o che si è raggiunta la fine del file in una
405 qualunque operazione sullo stream, il controllo quindi deve essere effettuato
406 ogni volta che si chiama una funzione di libreria.
407
408 Entrambi i flag (di errore e di end-of-file) possono essere cancellati usando
409 la funzione \func{clearerr}, il cui prototipo è:
410 \begin{prototype}{stdio.h}{void clearerr( FILE *stream)}
411   Cancella i flag di errore ed end-of-file di \param{stream}. 
412 \end{prototype}
413 \noindent in genere si usa questa funziona una volta che si sia identificata e
414 corretta la causa di un errore per evitare di mantenere i flag attivi,
415 così da poter rilevare una successiva ulteriore condizione di errore.
416
417
418 \subsection{Input/output binario}
419 \label{sec:file_binary_io}
420
421 La prima modalità di input/output non formattato ricalca quella della
422 intefaccia dei file descriptor, e provvede semplicemente la scrittura e
423 la lettura dei dati da un buffer verso un file e vicecersa. In generale
424 questa è la modalità che si usa quando si ha a che fare con dati non
425 formattati. Le due funzioni che si usano per l'I/O binario sono:
426 \begin{functions}
427   \headdecl{stdio.h} 
428   \funcdecl{size\_t fread(void * ptr, size\_t size,
429     size\_t nmemb, FILE * stream)} 
430   \funcdecl{size\_t fwrite(const void *
431     ptr, size\_t size, size\_t nmemb, FILE * stream)}
432   
433   Le funzioni rispettivamente leggono e scrivono \param{nmemb} elementi
434   di dimensione \param{size} dal buffer \param{ptr} al file \param{stream}.
435   
436   Entrambe le funzioni ritornano il numero di elementi letti o scritti,
437   in caso di errore o fine del file viene restituito un numero di
438   elementi inferiore al richiesto.
439 \end{functions}
440
441 In genere si usano queste funzioni quando si devono leggere o scrivere
442 un array o una struttura; un tipico esempio è quello in cui si salva una
443 parte di un vettore con una chiamata del tipo:
444 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
445 int WriteVect(FILE * stream, double * vec, size_t nelem) 
446 {
447     int size, nread;
448     size = sizeof(*vec);
449     if ( (nread = fwrite(vec, size, nelem, stream)) != nelem) {
450         perror("Write error");
451     }
452     return nread;
453 }
454 \end{lstlisting}
455 nel qual caso devono essere specificate dimensione e numero degli
456 elementi del vettore; nel caso di una struttura invece si avrà un
457 qualcosa tipo:
458 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
459 struct histogram {
460     int nbins; 
461     double max, min;
462     double * bin;
463 } histo; 
464 int WriteStruct(FILE * stream, struct histogram * histo, size_t nelem) 
465 {
466     if ( fwrite(vec, sizeof(*histo), 1, stream) !=1) {
467         perror("Write error");
468     }
469     return nread;
470 }
471 \end{lstlisting}
472
473
474
475
476 \subsection{Input/output a caratteri singoli}
477 \label{sec:file_char_io}
478
479
480
481
482 \subsection{Input/output di linea}
483 \label{sec:file_line_io}
484
485
486 \subsection{Input/output formattato}
487 \label{sec:file_formatted_io}
488
489
490 \subsection{Posizionamento su uno stream}
491 \label{sec:file_fseek}
492
493
494
495 \section{Funzioni avanzate}
496 \label{sec:file_stream_adv_func}
497
498 In questa sezione esamineremo le funzioni che permettono di controllare alcune
499 caratteristiche più particolari degli stream, come la lettura degli attributi,
500 le modalità di bufferizzazione, etc.
501
502
503 \subsection{Le funzioni di controllo}
504 \label{sec:file_stream_cntrl}
505
506 Al contrario di quanto avviene con i file descriptor le librerie standard del
507 C non prevedono nessuna funzione come la \func{fcntl} per la lettura degli
508 attributi degli stream; le \acr{glibc} però supportano alcune estensioni
509 derivate da Solaris, che permettono di ottenere informazioni utili.
510
511 In certi casi può essere necessario sapere se un certo stream è accessibile in
512 lettura o scrittura. In genere questa informazione non è disponibile, e si
513 deve ricordare come il file è stato aperto. La cosa può essere complessa se le
514 operazioni vengono effettuate un una subroutine, che a questo punto
515 necessiterà di informazioni aggiuntive rispetto al semplice puntatore allo
516 stream; questo può essere evitato con le due funzioni \func{\_\_freadable} e
517 \func{\_\_fwritable} i cui prototipi sono:
518 \begin{functions}
519   \headdecl{stdio\_ext.h}
520   \funcdecl{int \_\_freadable (FILE * stream)}
521   Restituisce un valore diverso da zero se \param{stream} consente la lettura.
522
523   \funcdecl{int \_\_fwritable(FILE * stream)}  
524   Restituisce un valore diverso da zero se \param{stream} consente la
525   scrittura.
526 \end{functions}
527
528 Altre due funzioni, \func{\_\_freading} e \func{\_\_fwriting} servono ad un
529 uso ancora più specialistico, il loro prototipo è: 
530 \begin{functions}
531   \headdecl{stdio\_ext.h}
532   \funcdecl{int \_\_freading (FILE * stream)}
533   Restituisce un valore diverso da zero se \param{stream} è aperto in sola
534   lettura o se l'ultima operazione è stata di lettura.
535
536   \funcdecl{int \_\_fwriting(FILE * stream)}  
537   Restituisce un valore diverso da zero se \param{stream} è aperto in sola
538   scrittura o se l'ultima operazione è stata di scrittura.
539 \end{functions}
540
541 Le due funzioni hanno lo scopo di determinare di che tipo è stata l'ultima
542 operazione eseguita su uno stream aperto in lettura/scrittura; ovviamente se
543 uno stream è aperto in sola lettura (o sola scrittura) la modalità dell'ultima
544 operazione è sempre determinata; l'unica ambiguità è quando non sono state
545 ancora eseguite operazioni, in questo caso le funzioni rispondono come se
546 una operazione ci fosse comunque stata.
547
548 La conoscenza dell'ultima operazione effettuata su uno stream aperto in
549 lettura/scrittura è utile in quanto permette di trarre conclusioni sullo stato
550 del buffer e del suo contenuto.
551
552
553 \subsection{Il controllo della bufferizzazione}
554 \label{sec:file_buffering_ctrl}
555
556 Come accennato in \secref{sec:file_buffering} le librerie definiscono una
557 serie di funzioni che permettono di controllare il comportamento degli
558 stream; se non si è 
559
560
561 \subsection{Dettagli dell'implementazione}
562 \label{sec:file_stream_details}
563
564
565 \subsection{File temporanei}
566 \label{sec:file_temp_file}
567
568
569 \subsection{Efficienza}
570 \label{sec:file_stream_efficiency}
571