Iniziato I/O a blocchi
[gapil.git] / filestd.tex
index c0a628312bc2a3d415a81c95cb2ad737d9825077..f93b9e03f3c5ed2d91629cebdd0a846ebd78f73a 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
@@ -327,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
@@ -358,27 +358,31 @@ modalit
 \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 catatteri} in cui si legge/scrive un carattere alla
+\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}). 
+ed inoltre la 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
+che si appoggiano a delle system call, esse non settano direttamente la
+variabile \var{errno}, che mantiene il valore settato dalla system call che ha
+riportato l'errore. 
+
+Siccome la condizione di end-of-file è anch'essa segnalata come errore, nasce
+il problema di come distinguerla da un errore effettivo; basarsi solo sul
+valore di ritorno della funzione e controllare il valore di \var{errno}
+infatti non basta, dato che quest'ultimo potrebbe essere stato settato in una
+altra occasione, (si veda \secref{sec:sys_errno} per i dettagli del
+funzionamento di \var{errno}).
 
 Per questo motivo tutte le implementazioni delle librerie standard
 mantengono per ogni stream almeno due flag all'interno dell'oggetto
@@ -397,11 +401,12 @@ questi flag possono essere riletti dalle funzioni:
   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.
+soltanto che c'è stato un errore, o che si è raggiunta la fine del file in una
+qualunque operazione sullo stream, il controllo quindi deve essere effettuato
+ogni volta che si chiama una funzione di libreria.
 
-Entrambi i flag (di errore e di end-of-file) possono essere cancellati
-usando la funzione \func{clearerr}, il cui prototipo è:
+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}
@@ -413,11 +418,17 @@ cos
 \subsection{Input/output a blocchi}
 \label{sec:file_block_io}
 
+La prima modalità di input/output non formattato ricalca quella della
+intefaccia dei file descriptor, e provvede semplicemente la scrittura e
+la lettura dei dati da un buffer verso un file e vicecersa.
+
 
 \subsection{Input/output a caratteri singoli}
 \label{sec:file_char_io}
 
 
+
+
 \subsection{Input/output di linea}
 \label{sec:file_line_io}
 
@@ -454,13 +465,39 @@ 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)}
+  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 ad un
+uso ancora più specialistico, il loro prototipo è: 
+\begin{functions}
+  \headdecl{stdio\_ext.h}
+  \funcdecl{int \_\_freading (FILE * stream)}
+  Restituisce un valore diverso da zero se \param{stream} è aperto in sola
+  lettura o se l'ultima operazione è stata di lettura.
+
+  \funcdecl{int \_\_fwriting(FILE * stream)}  
+  Restituisce un valore diverso da zero se \param{stream} è aperto in sola
+  scrittura o se l'ultima operazione è stata di scrittura.
+\end{functions}
+
+Le due funzioni hanno lo scopo di determinare di che tipo è stata l'ultima
+operazione eseguita su uno stream aperto in lettura/scrittura; ovviamente se
+uno stream è aperto in sola lettura (o sola scrittura) la modalità dell'ultima
+operazione è sempre determinata; l'unica ambiguità è quando non sono state
+ancora eseguite operazioni, in questo caso le funzioni rispondono come se
+una operazione ci fosse comunque stata.
+
+La conoscenza dell'ultima operazione effettuata su uno stream aperto in
+lettura/scrittura è utile in quanto permette di trarre conclusioni sullo stato
+del buffer e del suo contenuto.
 
 
 \subsection{Il controllo della bufferizzazione}