Aggiunte altre estensioni Solaris
[gapil.git] / filestd.tex
index bbc7bc0ddf8fbece27978f3b4b85c4b606719fde..6730757a57cdb01d0fbea3d4153e3cf06cefaa89 100644 (file)
@@ -1,4 +1,4 @@
-\chapter{I file: l'interfaccia standard ANSI C}
+ \chapter{I file: l'interfaccia standard ANSI C}
 \label{cha:files_std_interface}
 
 Esamineremo in questo capitolo l'interfaccia standard ANSI C per i file,
@@ -126,7 +126,7 @@ riguarda l'aspetto della scrittura dei dati sul file.
 
 I caratteri che vengono scritti su uno stream normalmente vengono accumulati
 in un buffer e poi trasmessi in blocco in maniera asincrona rispetto alla
-scrittura (quello che viene chiamato lo \textsl{scarico}, dall'ingelese 
+scrittura (quello che viene chiamato lo \textsl{scarico}, dall'inglese 
 \textit{flush}, dei dati) tutte le volte che il buffer viene riempito. Un
 comportamento analogo avviene anche in lettura (cioè dal file viene letto un
 blocco di dati, anche se se ne sono richiesti una quantità inferiore), ma la
@@ -271,33 +271,35 @@ funzioni delle librerie standard del C.
   \label{tab:file_fopen_mode}
 \end{table}
 
-In realtà lo standard ANSI C prevede un totale di 15 possibili valori diversi
-per \param{mode}, ma in \tabref{tab:file_fopen_mode} si sono riportati solo i
-sei valori effettivi, ad essi può essere aggiunto pure il carattere \func{b}
-(come ultimo carattere o nel mezzo agli altri per le stringhe di due
-caratteri) che in altri sistemi operativi serve a distinguere i file binari
-dai file di testo; in un sistema POSIX questa distinzione non esiste e il
-valore viene accettato solo per compatibilità, ma non ha alcun effetto.
-
-Inoltre nel caso si usi \func{fdopen} i valori specificati da \param{mode}
-devono essere compatibili con quelli con cui il file descriptor è stato
-aperto. Inoltre i modi \cmd{w} e \cmd{w+} non troncano il file. La posizione
-nello stream viene settata a quella corrente nel file descriptor, e le
-variabili di errore e di fine del file sono cancellate. Il file non viene
-duplicato e verrà chiuso alla chiusura dello stream.
+In realtà lo standard ANSI C prevede un totale di 15 possibili valori
+diversi per \param{mode}, ma in \tabref{tab:file_fopen_mode} si sono
+riportati solo i sei valori effettivi, ad essi può essere aggiunto pure
+il carattere \func{b} (come ultimo carattere o nel mezzo agli altri per
+le stringhe di due caratteri) che in altri sistemi operativi serve a
+distinguere i file binari dai file di testo; in un sistema POSIX questa
+distinzione non esiste e il valore viene accettato solo per
+compatibilità, ma non ha alcun effetto.
+
+Inoltre nel caso si usi \func{fdopen} i valori specificati da
+\param{mode} devono essere compatibili con quelli con cui il file
+descriptor è stato aperto. Inoltre i modi \cmd{w} e \cmd{w+} non
+troncano il file. La posizione nello stream viene settata a quella
+corrente nel file descriptor, e le variabili di errore e di fine del
+file sono cancellate. Il file non viene duplicato e verrà chiuso alla
+chiusura dello stream.
 
 I nuovi file saranno creati secondo quanto visto in
-\secref{sec:file_ownership} ed avranno i permessi di accesso settati al valore
-\macro{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a
-\macro{0666}) modificato secondo il valore di \acr{umask} per il processo (si
-veda \secref{sec:file_umask}).
-
-In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è di
-messo una bufferizzazione; per questo motivo lo standard ANSI C richiede che
-ci sia una operazione di posizionamento fra una operazione di output ed una di
-input o viceversa (eccetto il caso in cui l'input ha incontrato la fine del
-file), altrimenti una lettura può ritornare anche il risultato di scritture
-precedenti l'ultima effettuata.
+\secref{sec:file_ownership} ed avranno i permessi di accesso settati al
+valore \macro{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH}
+(pari a \macro{0666}) modificato secondo il valore di \acr{umask} per il
+processo (si veda \secref{sec:file_umask}).
+
+In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
+di messo una bufferizzazione; per questo motivo lo standard ANSI C
+richiede che ci sia una operazione di posizionamento fra una operazione
+di output ed una di input o viceversa (eccetto il caso in cui l'input ha
+incontrato la fine del file), altrimenti una lettura può ritornare anche
+il risultato di scritture precedenti l'ultima effettuata.
 
 Per questo motivo è una buona pratica (e talvolta necessario) far seguire ad
 una scrittura una delle funzioni \func{fflush}, \func{fseek}, \func{fsetpos} o
@@ -325,7 +327,7 @@ La funzione effettua uno scarico di tutti i dati presenti nei buffer di uscita
 e scarta tutti i dati in ingresso, se era stato allocato un buffer per lo
 stream questo verrà rilasciato. La funzione effettua lo scarico solo per i
 dati presenti nei buffer in user space usati dalle \acr{glibc}; se si essere
-sicuri che il kernel forzi la scrittura su disco occorrà effettuare . 
+sicuri che il kernel forzi la scrittura su disco occorrerà effettuare . 
 
 Linux supporta, come estensione implementata dalle \acr{glibc}, anche una
 altra funzione, \func{fcloseall}, che serve a chiudere tutti i file, il suo
@@ -346,13 +348,74 @@ chiuso i file e prima di uscire (si ricordi quanto visto in
 \subsection{Lettura e scrittura su uno stream}
 \label{sec:file_io}
 
+Una delle caratteristiche più utili dell'interfaccia degli stream è la
+ricchezza delle funzioni disponibili per le operazioni di lettura e
+scrittura sui file. Sono infatti previste ben tre diverse modalità
+modalità di input/output non formattato:
+\begin{enumerate}
+\item\textsl{a blocchi} in cui legge/scrive un blocco di dati alla
+  volta, vedi \secref{sec:file_block_io}.
+\item\textsl{di linea} in cui si legge/scrive una linea (terminata dal
+  carattere di newline \verb|\n|) alla volta, vedi
+  \secref{sec:file_line_io}.
+\item\textsl{a caratteri} in cui si legge/scrive un carattere alla
+  volta (con la bufferizzazione gestita automaticamente dalla libreria),
+  vedi \secref{sec:file_char_io}.
+\end{enumerate}
+e una modalità di input/output formattato.
+
+A differenza dell'interfaccia dei file descriptor il raggiungimento
+della fine del file è considerato un errore, e viene notificato come
+tale dai valori di uscita delle varie funzioni; nella maggior parte dei
+casi questo avviene con la restituzione del valore intero (di tipo
+\type{int}) \macro{EOF}\footnote{la costante deve essere negativa, le
+  \acr{glibc} usano -1, altre implementazioni possono avere valori
+  diversi.}  definito anch'esso nell'header \func{stdlib.h}.
+
+Dato che le funzioni dell'interfaccia degli stream sono funzioni di
+libreria, esse non settano la variabile \var{errno}, che mantiene il
+valore settato dalla system call che ha riportato l'errore, ma siccome
+la condizione di end-of-file è anch'essa segnalata come errore, non
+esisterebbe alcuna possibilità di distinguerla da un errore (\var{errno}
+potrebbe essere stata settata in una altra occasione, vedi
+\secref{sec:sys_errno}). 
+
+Per questo motivo tutte le implementazioni delle librerie standard
+mantengono per ogni stream almeno due flag all'interno dell'oggetto
+\type{FILE}, il flag di \textit{end-of-file}, che segnala che si è
+raggiunta la fine del file in lettura, e quello di errore, che segnala
+la presenza di un qualche errore nelle operazioni di input/output;
+questi flag possono essere riletti dalle funzioni:
+\begin{functions}
+  \headdecl{stdio.h}
+  \funcdecl{int feof(FILE *stream)}
+  Controlla il flag di end-of-file di \param{stream}.
+  \funcdecl{int ferror(FILE *stream)}
+  Controlla il flag di errore di \param{stream}.
 
-\subsection{Posizionamento su uno stream}
-\label{sec:file_fseek}
+  Entrambe le funzioni ritornano un valore diverso da zero se i relativi
+  flag sono settati. 
+\end{functions}
+\noindent si tenga presente comunque che la lettura di questi flag segnala
+soltanto che si è avuto un errore, o si è raggiunta la fine del file, in
+una precedente operazione sullo stream.
+
+Entrambi i flag (di errore e di end-of-file) possono essere cancellati
+usando la funzione \func{clearerr}, il cui prototipo è:
+\begin{prototype}{stdio.h}{void clearerr( FILE *stream)}
+  Cancella i flag di errore ed end-of-file di \param{stream}. 
+\end{prototype}
+\noindent in genere si usa questa funziona una volta che si sia identificata e
+corretta la causa di un errore per evitare di mantenere i flag attivi,
+così da poter rilevare una successiva ulteriore condizione di errore.
+
+
+\subsection{Input/output a blocchi}
+\label{sec:file_block_io}
 
 
-\subsection{Input/output binario}
-\label{sec:file_binary_io}
+\subsection{Input/output a caratteri singoli}
+\label{sec:file_char_io}
 
 
 \subsection{Input/output di linea}
@@ -363,6 +426,11 @@ chiuso i file e prima di uscire (si ricordi quanto visto in
 \label{sec:file_formatted_io}
 
 
+\subsection{Posizionamento su uno stream}
+\label{sec:file_fseek}
+
+
+
 \section{Funzioni avanzate}
 \label{sec:file_stream_adv_func}
 
@@ -386,14 +454,17 @@ operazioni vengono effettuate un una subroutine, che a questo punto
 necessiterà di informazioni aggiuntive rispetto al semplice puntatore allo
 stream; questo può essere evitato con le due funzioni \func{\_\_freadable} e
 \func{\_\_fwritable} i cui prototipi sono:
-
 \begin{functions}
   \headdecl{stdio\_ext.h}
   \funcdecl{int \_\_freadable (FILE * stream)}
-  \funcdecl{int \_\_fwritable(FILE * stream)}
-\end{functions}
+  Restituisce un valore diverso da zero se \param{stream} consente la lettura.
 
+  \funcdecl{int \_\_fwritable(FILE * stream)}  
+  Restituisce un valore diverso da zero se \param{stream} consente la
+  scrittura.
+\end{functions}
 
+Altre due funzioni, \func{\_\_freading} e \func{\_\_fwriting} servono 
 
 \subsection{Il controllo della bufferizzazione}
 \label{sec:file_buffering_ctrl}