Completato I/O binario
authorSimone Piccardi <piccardi@gnulinux.it>
Mon, 10 Dec 2001 22:54:27 +0000 (22:54 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Mon, 10 Dec 2001 22:54:27 +0000 (22:54 +0000)
filestd.tex
fileunix.tex
sources/Makefile

index a20d207aea09d97e4b69dfb9fd73ef0715b80d83..c8936db9b51950b41b290fd982215f245d171725 100644 (file)
@@ -46,11 +46,11 @@ di lettura e scrittura in blocchi di dimensioni appropriate all'ottenimento
 della massima efficienza.
 
 Per questo motivo l'interfaccia viene chiamata anche interfaccia dei
 della massima efficienza.
 
 Per questo motivo l'interfaccia viene chiamata anche interfaccia dei
-\textit{file stream}, dato che non è più necessario doversi preoccupare di dei
-dettagli della comunicazione con il tipo di hardware sottostante (come nel
-caso della dimensione dei blocchi del filesystem), ed un file può essere
-sempre considerato come composto da un flusso continuo (da cui il nome
-\textit{stream}) di dati.
+\textit{file stream}, dato che non è più necessario doversi preoccupare
+dei dettagli della comunicazione con il tipo di hardware sottostante
+(come nel caso della dimensione dei blocchi del filesystem), ed un file
+può essere sempre considerato come composto da un flusso continuo (da
+cui il nome \textit{stream}) di dati.
 
 A parte i dettagli legati alla gestione delle operazioni di lettura e
 scrittura (sia per quel che riguarda la bufferizzazione, che le
 
 A parte i dettagli legati alla gestione delle operazioni di lettura e
 scrittura (sia per quel che riguarda la bufferizzazione, che le
@@ -69,13 +69,12 @@ contengono tutte le informazioni necessarie a gestire le operazioni sugli
 stream, come la posizione corrente, lo stato del buffer e degli indicatori di
 stato e di fine del file.
 
 stream, come la posizione corrente, lo stato del buffer e degli indicatori di
 stato e di fine del file.
 
-Per questo motivo gli utenti non devono mai utilizzare direttamente o allocare
-queste strutture, ma usare sempre puntatori del tipo \type{FILE *} ottenuti
-dalla libreria stessa (tanto che in certi casi il termine di puntatore a file
-è diventato sinonimo di stream). 
-
-Tutte le funzioni della libreria che operano sui file accettano come parametri
-solo variabili di questo tipo, che diventa accessibile includendo l'header
+Per questo motivo gli utenti non devono mai utilizzare direttamente o
+allocare queste strutture, ma usare sempre puntatori del tipo \type{FILE
+  *} ottenuti dalla libreria stessa (tanto che in certi casi il termine
+di puntatore a file è diventato sinonimo di stream).  Tutte le funzioni
+della libreria che operano sui file accettano come parametri solo
+variabili di questo tipo, che diventa accessibile includendo l'header
 file \file{stdio.h}.
 
 
 file \file{stdio.h}.
 
 
@@ -111,9 +110,9 @@ dell'output di un programma con il semplice codice:
     fclose (stdout);
     stdout = fopen ("standard-output-file", "w");
 \end{lstlisting}
     fclose (stdout);
     stdout = fopen ("standard-output-file", "w");
 \end{lstlisting}
-ma in altri sistemi possono essere definite come macro, se si hanno
-problemi di portabilità e si vuole essere sicuri, diventa opportuno
-usare la funzione \func{freopen}.
+ma in altri sistemi queste variabili possono essere definite da macro, e
+se si hanno problemi di portabilità e si vuole essere sicuri, diventa
+opportuno usare la funzione \func{freopen}.
 
 
 \subsection{Le modalità di bufferizzazione}
 
 
 \subsection{Le modalità di bufferizzazione}
@@ -234,19 +233,22 @@ dello standard POSIX.1.}, i loro prototipi sono:
   \func{freopen}. 
 \end{functions}
 
   \func{freopen}. 
 \end{functions}
 
-Normalmente la funzione che si usa per aprire uno stream è \func{fopen}, essa
-apre il file specificato nella modalità specificata da \param{mode} che è una
-delle stringhe elencate in \tabref{tab:file_fopen_mode}. 
+Normalmente la funzione che si usa per aprire uno stream è \func{fopen},
+essa apre il file specificato nella modalità specificata da
+\param{mode}, che è una stringa che deve iniziare con almeno uno dei
+valori indicati in \tabref{tab:file_fopen_mode} (sono possibili varie
+estensioni che vedremo in seguito).
 
 
-L'uso di \func{freopen} è in genere per redirigere uno dei tre file standard
-(vedi \secref{sec:file_std_stream}): il file \param{path} viene associato a
-\param{stream} e se questo è uno stream aperto prima viene chiuso.  
+L'uso più comune di \func{freopen} è per redirigere uno dei tre file
+standard (vedi \secref{sec:file_std_stream}): il file \param{path} viene
+associato a \param{stream} e se questo è uno stream già aperto viene
+preventivamente chiuso.
 
 
-Infine \func{fdopen} viene usato per associare uno stream ad un file
-descriptor esistente ottenuto tramite una altra funzione (come \func{open},
-\func{dup}, \func{pipe}) e serve quando si vogliono usare gli stream con file
-speciali come le fifo od i socket, che non possono essere aperti con le
-funzioni delle librerie standard del C.
+Infine \func{fdopen} viene usata per associare uno stream ad un file
+descriptor esistente ottenuto tramite una altra funzione (ad esempio con
+una \func{open}, una \func{dup}, o una \func{pipe}) e serve quando si
+vogliono usare gli stream con file come le fifo o i socket, che non
+possono essere aperti con le funzioni delle librerie standard del C.
 
 \begin{table}[htb]
   \centering
 
 \begin{table}[htb]
   \centering
@@ -255,25 +257,26 @@ funzioni delle librerie standard del C.
     \textbf{Valore} & \textbf{Significato}\\
     \hline
     \hline
     \textbf{Valore} & \textbf{Significato}\\
     \hline
     \hline
-    \texttt{r} & Il file viene aperto in sola lettura; lo stream è posizionato
-    all'inizio del file.\\
-    \texttt{r+} & Il file viene aperto in lettura e scrittura; lo stream è
-    posizionato all'inizio del file. \\
+    \texttt{r} & Il file viene aperto, l'accesso viene posto in sola
+    lettura, lo stream è posizionato all'inizio del file.\\
+    \texttt{r+} & Il file viene aperto, l'accesso viene posto in lettura e
+    scrittura, lo stream è posizionato all'inizio del file. \\
 %    \hline
 %    \hline
-    \texttt{w} & Il file viene troncato a lunghezza nulla (o creato se non 
-    esiste), ed aperto in sola lettura; lo stream è posizionato all'inizio del
-    file.\\
-    \texttt{w+} & Il file viene troncato a lunghezza nulla (o creato se non
-    esiste), ed aperto in scrittura e lettura; lo stream è posizionato 
-    all'inizio del file.\\
+    \texttt{w} & Il file viene aperto e troncato a lunghezza nulla (o
+    creato se non esiste), l'accesso viene posto in sola scrittura, lo
+    stream è posizionato all'inizio del file.\\
+    \texttt{w+} & Il file viene aperto e troncato a lunghezza nulla (o
+    creato se non esiste), l'accesso viene posto in scrittura e lettura,
+    lo stream è posizionato all'inizio del file.\\
 %    \hline
 %    \hline
-    \texttt{a} & Il file è aperto in \textit{append mode} in sola scrittura
-    (o creato se non esiste). \\
-    \texttt{a+} & Il file è aperto in \textit{append mode} in lettura e 
-    scrittura (o creato se non esiste). \\
+    \texttt{a} & Il file viene aperto (o creato se non esiste) in
+    \textit{append mode}, l'accesso viene posto in sola scrittura. \\
+    \texttt{a+} & Il file viene aperto (o creato se non esiste) in
+    \textit{append mode}, l'accesso viene posto in lettura e scrittura. \\
     \hline
   \end{tabular}
     \hline
   \end{tabular}
-  \caption{Modalità di apertura di uno stream}
+  \caption{Modalità di apertura di uno stream dello standard ANSI C che
+    sono sempre presenti in qualunque sistema POSIX}
   \label{tab:file_fopen_mode}
 \end{table}
 
   \label{tab:file_fopen_mode}
 \end{table}
 
@@ -286,13 +289,27 @@ 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.
 
 distinzione non esiste e il valore viene accettato solo per
 compatibilità, ma non ha alcun effetto.
 
+Le \acr{glibc} supportano alcune estensioni, queste devono essere sempre
+indicate dopo aver specificato il \param{mode} con uno dei valori di
+\tabref{tab:file_fopen_mode}. L'uso del carattere \texttt{x} serve per
+evitare di sovrascrivere un file già esistente (è analoga all'uso
+dell'opzione \macro{O\_EXCL} in \func{open}), se il file specificato già
+esiste e si aggiunge questo carattere a \param{mode} la \func{fopen}
+fallisce. 
+
+Un'altra estensione serve a supportare la localizzazione, quando si
+aggiunge a \param{mode} una stringa della forma \verb|",ccs=STRING"| il
+valore \verb|STRING| è considerato il nome di una codifica dei caratteri
+e \func{fopen} marca il file per l'uso dei caratteri estesi e abilita le
+opportune funzioni di conversione in lettura e scrittura.
+
 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
 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.
+file (vedi \secref{sec:file_io}) 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
 
 I nuovi file saranno creati secondo quanto visto in
 \secref{sec:file_ownership} ed avranno i permessi di accesso settati al
@@ -305,7 +322,7 @@ 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
 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.
+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
 
 Per questo motivo è una buona pratica (e talvolta necessario) far seguire ad
 una scrittura una delle funzioni \func{fflush}, \func{fseek}, \func{fsetpos} o
@@ -329,11 +346,12 @@ Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo 
   funzione che è fallita (\func{close}, \func{write} o \func{fflush}).
 \end{prototype}
 
   funzione che è fallita (\func{close}, \func{write} o \func{fflush}).
 \end{prototype}
 
-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 occorrerà effettuare . 
+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 vuole essere sicuri che il kernel forzi la scrittura
+su disco occorrerà effettuare una \func{sync}.
 
 Linux supporta, come estensione implementata dalle \acr{glibc}, anche una
 altra funzione, \func{fcloseall}, che serve a chiudere tutti i file, il suo
 
 Linux supporta, come estensione implementata dalle \acr{glibc}, anche una
 altra funzione, \func{fcloseall}, che serve a chiudere tutti i file, il suo
@@ -358,7 +376,7 @@ Una delle caratteristiche pi
 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:
 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}
+\begin{enumerate*}
 \item\textsl{binario} in cui legge/scrive un blocco di dati alla
   volta, vedi \secref{sec:file_binary_io}.
 \item\textsl{di linea} in cui si legge/scrive una linea (terminata dal
 \item\textsl{binario} in cui legge/scrive un blocco di dati alla
   volta, vedi \secref{sec:file_binary_io}.
 \item\textsl{di linea} in cui si legge/scrive una linea (terminata dal
@@ -367,16 +385,16 @@ modalit
 \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}.
 \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}
+\end{enumerate*}
 ed inoltre la modalità di input/output formattato.
 
 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}.
+A differenza dell'interfaccia dei file descriptor, con gli stream 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
 
 Dato che le funzioni dell'interfaccia degli stream sono funzioni di libreria
 che si appoggiano a delle system call, esse non settano direttamente la
@@ -395,7 +413,7 @@ 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;
 \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:
+questi due flag possono essere riletti dalle funzioni:
 \begin{functions}
   \headdecl{stdio.h}
   \funcdecl{int feof(FILE *stream)}
 \begin{functions}
   \headdecl{stdio.h}
   \funcdecl{int feof(FILE *stream)}
@@ -425,8 +443,8 @@ cos
 \label{sec:file_binary_io}
 
 La prima modalità di input/output non formattato ricalca quella della
 \label{sec:file_binary_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. In generale
+interfaccia dei file descriptor, e provvede semplicemente la scrittura e
+la lettura dei dati da un buffer verso un file e viceversa. In generale
 questa è la modalità che si usa quando si ha a che fare con dati non
 formattati. Le due funzioni che si usano per l'I/O binario sono:
 \begin{functions}
 questa è la modalità che si usa quando si ha a che fare con dati non
 formattati. Le due funzioni che si usano per l'I/O binario sono:
 \begin{functions}
@@ -479,17 +497,67 @@ int WriteStruct(FILE * stream, struct histogram * histo, size_t nelem)
 }
 \end{lstlisting}
 in cui si specifica la dimensione dell'intera struttura ed un solo
 }
 \end{lstlisting}
 in cui si specifica la dimensione dell'intera struttura ed un solo
-elemento. In realtà quello che conta nel trasferimento dei dati sono le
-dimensioni totali, che sono sempre pari al prodotto \func{size * nelem},
-la sola differenza è che le funzioni non ritornano il numero di bytes
-scritti, ma il numero di elementi. 
+elemento. 
 
 
-La funzione \func{fread} legge sempre un numero intero di elementi, se
-si ha un errore o si incontra la fine del file l'oggetto letto
-parzialmente viene scartato
+In realtà quello che conta nel trasferimento dei dati sono le dimensioni
+totali, che sono sempre pari al prodotto \func{size * nelem}; la sola
+differenza è che le funzioni non ritornano il numero di byte scritti,
+ma il numero di elementi.
 
 
+La funzione \func{fread} legge sempre un numero intero di elementi, se
+incontra la fine del file l'oggetto letto parzialmente viene scartato
+(lo stesso avviene in caso di errore). In questo caso la posizione dello
+stream viene settata alla fine del file (e non a quella corrispondente
+alla quantità di dati letti).
+
+In caso di errore (o fine del file per \func{fread}) entrambe le
+funzioni restituiscono il numero di oggetti effettivamente letti o
+scritti, che sarà inferiore a quello richiesto. Contrariamente a quanto
+avviene per i file descriptor, questo segnala una condizione di errore e
+occorrerà usare \func{feof} e \func{ferror} per stabilire la natura del
+problema.
+
+Benché queste funzioni assicurino la massima efficienza per il
+salvataggio dei dati, i dati memorizzati attraverso di esse presentano
+lo svantaggio di dipendere strettamente dalla piattaforma di sviluppo
+usata ed in genere possono essere riletti senza problemi solo dallo
+stesso programma che li ha prodotti.
+
+Infatti diversi compilatori possono eseguire ottimizzazioni diverse
+delle strutture dati e alcuni compilatori (come il \cmd{gcc}) possono
+anche scegliere se ottimizzare l'occupazione di spazio, impacchettando
+più strettamente i dati, o la velocità inserendo opportuni
+\textit{padding} per l'allineamento dei medesimi generando quindi output
+binari diversi. Inoltre altre incompatibilità si possono presentare
+quando entrano in gioco differenze di architettura hardware, come la
+dimensione del bus o la modalità di ordinamento dei bit o il formato
+delle variabili in floating point.
+
+Per questo motivo quando si usa l'input/output binario occorre sempre
+essere prendere le opportune precauzioni (in genere usare un formato di
+più alto livello che permetta di recuperare l'informazione completa),
+per assicurarsi che versioni diverse del programma siano in grado di
+rileggere i dati tenendo conto delle eventuali differenze.
+
+Le \acr{glibc} definiscono altre due funzioni per l'I/O binario, che
+evitano il lock implicito dello stream, usato per dalla librerie per la
+gestione delle applicazioni multi-thread (si veda
+\secref{sec:file_stream_thread} per i dettagli).
 
 
-Benché queste funzioni assicurino 
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{size\_t fread\_unlocked(void * ptr, size\_t size, size\_t
+    nmemb, FILE * stream)}
+  
+  \funcdecl{size\_t fwrite\_unlocked(const void * ptr, size\_t size,
+    size\_t nmemb, FILE * stream)}
+  
+  Le funzioni sono identiche alle analoghe \func{fread} e \func{fwrite}
+  ma non acquisiscono il lock implicito sullo stream.
+\end{functions}
+\noindent entrambe le funzioni sono estensioni GNU previste solo dalle
+  \acr{glibc}. 
 
 
 \subsection{Input/output a caratteri singoli}
 
 
 \subsection{Input/output a caratteri singoli}
@@ -514,9 +582,9 @@ Bench
 \section{Funzioni avanzate}
 \label{sec:file_stream_adv_func}
 
 \section{Funzioni avanzate}
 \label{sec:file_stream_adv_func}
 
-In questa sezione esamineremo le funzioni che permettono di controllare alcune
-caratteristiche più particolari degli stream, come la lettura degli attributi,
-le modalità di bufferizzazione, etc.
+In questa sezione esamineremo le funzioni che permettono di controllare
+alcune caratteristiche più particolari degli stream, come la lettura
+degli attributi, le modalità di bufferizzazione, etc.
 
 
 \subsection{Le funzioni di controllo}
 
 
 \subsection{Le funzioni di controllo}
@@ -530,7 +598,7 @@ derivate da Solaris, che permettono di ottenere informazioni utili.
 In certi casi può essere necessario sapere se un certo stream è accessibile in
 lettura o scrittura. In genere questa informazione non è disponibile, e si
 deve ricordare come il file è stato aperto. La cosa può essere complessa se le
 In certi casi può essere necessario sapere se un certo stream è accessibile in
 lettura o scrittura. In genere questa informazione non è disponibile, e si
 deve ricordare come il file è stato aperto. La cosa può essere complessa se le
-operazioni vengono effettuate un una subroutine, che a questo punto
+operazioni vengono effettuate in 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:
 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:
@@ -577,6 +645,34 @@ serie di funzioni che permettono di controllare il comportamento degli
 stream; se non si è 
 
 
 stream; se non si è 
 
 
+\subsection{Gli stream e i thread}
+\label{sec:file_stream_thread}
+
+Gli stream possono essere usati in applicazioni multi-thread allo stesso
+modo in cui sono usati nelle applicazioni normali, ma si deve essere
+consapovoli delle possibili complicazioni anche quando non si usano i
+thread, dato che l'implementazione delle librerie è influenzata
+pesantemente dalle richieste necessarie per garantirne l'uso coi thread.
+
+
+
+\begin{functions}
+  \headdecl{stdio.h}
+  
+  \funcdecl{void flockfile(FILE * stream)} Esegue l'acquisizione del
+  lock dello stream \param{stream}, bloccandosi in caso il lock non
+  disponibile. 
+  
+  \funcdecl{int ftrylockfile(FILE * stream)} Tenta l'acquisizione del
+  lock dello stream \param{stream}, senza bloccarsi in caso il lock non sia
+  disponibile. Ritorna zero in caso di acquisizione del lock, diverso da
+  zero altrimenti.
+  
+  \funcdecl{void funlockfile(FILE * stream)} Rilascia il lock dello
+  stream \param{stream}.
+\end{functions}
+
+
 \subsection{Dettagli dell'implementazione}
 \label{sec:file_stream_details}
 
 \subsection{Dettagli dell'implementazione}
 \label{sec:file_stream_details}
 
index ba83b4d8cebb48897e0089772923ab611e1a0188..17a68ed645e5a2fc4ad033a422e7ecaf9b40f105 100644 (file)
@@ -832,12 +832,12 @@ file specificato, ed attendono fino alla conclusione delle operazioni;
 di \var{fstat} come i tempi del file). 
 
 
 di \var{fstat} come i tempi del file). 
 
 
-Si tenga presente che questo non comporta la sincronizzazione della directory
-che contiene il file (e scrittura della relativa voce su disco) che deve
-essere effettuata esplicitamente\footnote{in realtà con il filesystem
-  \acr{ext2}, quando questo viene montato con l'opzione \cmd{sync}, il kernel
-  provvede anche alla sincronizzazione automatica delle voci delle
-  directory.}.
+Si tenga presente che questo non comporta la sincronizzazione della
+directory che contiene il file (e scrittura della relativa voce su
+disco) che deve essere effettuata esplicitamente\footnote{in realtà per
+  il filesystem \acr{ext2}, quando lo si monta con l'opzione \cmd{sync},
+  il kernel provvede anche alla sincronizzazione automatica delle voci
+  delle directory.}.
 
 
 \subsection{La funzioni \func{dup} e \func{dup2}}
 
 
 \subsection{La funzioni \func{dup} e \func{dup2}}
index 576771a01586e829f54b0d0feafa28b8d23b9b8f..dd605131addd66556779dc7cf52125702daea5d3 100644 (file)
@@ -10,6 +10,9 @@ OBJ = SockRead.o SockWrite.o
 
 all: forktest errcode echo echod daytimed iterdaytimed daytime
 
 
 all: forktest errcode echo echod daytimed iterdaytimed daytime
 
+testfopen: test_fopen.c
+       $(CC) $(CFLAGS) $^ -o $@
+
 testren: TestRen.c
        $(CC) $(CFLAGS) $^ -o $@
 
 testren: TestRen.c
        $(CC) $(CFLAGS) $^ -o $@