%% filestd.tex
%%
-%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2010 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
%% license is included in the section entitled "GNU Free Documentation
%% License".
%%
+
\chapter{I file: l'interfaccia standard ANSI C}
\label{cha:files_std_interface}
\label{sec:file_stream}
\index{file!stream|(}
+
Come più volte ribadito, l'interfaccia dei file descriptor è un'interfaccia di
basso livello, che non provvede nessuna forma di formattazione dei dati e
nessuna forma di bufferizzazione per ottimizzare le operazioni di I/O.
(sui quali sono basati), ed in particolare continua a valere quanto visto in
sez.~\ref{sec:file_sharing} a proposito dell'accesso condiviso ed in
sez.~\ref{sec:file_access_control} per il controllo di accesso.
+
\index{file!stream|)}
-\subsection{Gli oggetti \ctyp{FILE}}
+\subsection{Gli oggetti \type{FILE}}
\label{sec:file_FILE}
+
Per ragioni storiche la struttura di dati che rappresenta uno stream è stata
-chiamata \ctyp{FILE}, questi oggetti sono creati dalle funzioni di libreria e
+chiamata \type{FILE}, questi oggetti sono creati dalle funzioni di libreria e
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.
Per questo motivo gli utenti non devono mai utilizzare direttamente o allocare
-queste strutture (che sono dei \textsl{tipi opachi}\index{tipo!opaco}) ma
-usare sempre puntatori del tipo \ctyp{FILE *} ottenuti dalla libreria stessa
+queste strutture (che sono dei \index{tipo!opaco} \textsl{tipi opachi}) ma
+usare sempre puntatori del tipo \texttt{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 argomenti solo variabili di questo tipo, che diventa accessibile
sullo schermo.
\end{basedescript}
-Nelle \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono
-effettivamente tre variabili di tipo \ctyp{FILE *} che possono essere
-usate come tutte le altre, ad esempio si può effettuare una redirezione
-dell'output di un programma con il semplice codice:
-\includecodesnip{listati/redir_stdout.c}
-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}.
+Nelle \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono effettivamente
+tre variabili di tipo \type{FILE}\texttt{ *} che possono essere usate come
+tutte le altre, ad esempio si può effettuare una redirezione dell'output di un
+programma con il semplice codice: \includecodesnip{listati/redir_stdout.c} 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}
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\index{socket}, che non
-possono essere aperti con le funzioni delle librerie standard del C.
+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
\hline
\hline
\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. \\
+ 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
\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.\\
+ 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
\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. \\
+ \itindex{append~mode} \textit{append mode}, l'accesso viene
+ posto in sola scrittura.\\
+ \texttt{a+}& Il file viene aperto (o creato se non esiste) in
+ \itindex{append~mode} \textit{append mode}, l'accesso viene
+ posto in lettura e scrittura.\\
\hline
- \texttt{b} & specifica che il file è binario, non ha alcun effetto. \\
- \texttt{x} & l'apertura fallisce se il file esiste già. \\
+ \texttt{b} & Specifica che il file è binario, non ha alcun effetto. \\
+ \texttt{x} & L'apertura fallisce se il file esiste già. \\
\hline
\end{tabular}
\caption{Modalità di apertura di uno stream dello standard ANSI C che
file non viene duplicato e verrà chiuso alla chiusura dello stream.
I nuovi file saranno creati secondo quanto visto in
-sez.~\ref{sec:file_ownership} ed avranno i permessi di accesso impostati al
-valore \code{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a
-\val{0666}) modificato secondo il valore di \acr{umask} per il processo (si
-veda sez.~\ref{sec:file_umask}).
+sez.~\ref{sec:file_ownership_management} ed avranno i permessi di accesso
+impostati al valore
+\code{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a
+\val{0666}) modificato secondo il valore di \itindex{umask} \textit{umask} per
+il processo (si veda sez.~\ref{sec:file_perm_management}).
In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
di mezzo una bufferizzazione; per questo motivo lo standard ANSI C
Per questo motivo tutte le implementazioni delle librerie standard
mantengono per ogni stream almeno due flag all'interno dell'oggetto
-\ctyp{FILE}, il flag di \textit{end-of-file}, che segnala che si è
+\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 due flag possono essere riletti dalle funzioni \funcd{feof} e
Le \acr{glibc} definiscono altre due funzioni per l'I/O binario,
\funcd{fread\_unlocked} e \funcd{fwrite\_unlocked} che evitano il lock
implicito dello stream, usato per dalla librerie per la gestione delle
-applicazioni multi-thread (si veda sez.~\ref{sec:file_stream_thread} per i
-dettagli), i loro prototipi sono:
+applicazioni \itindex{thread} \textit{multi-thread} (si veda
+sez.~\ref{sec:file_stream_thread} per i dettagli), i loro prototipi sono:
\begin{functions}
\headdecl{stdio.h}
\param{stream}. In genere è implementata come una macro.
\funcdecl{wint\_t fgetwc(FILE *stream)} Legge un carattere esteso da
- \param{stream} È una sempre una funzione.
+ \param{stream}. È una sempre una funzione.
\funcdecl{wint\_t getwchar(void)} Equivalente a \code{getwc(stdin)}.
\funcdecl{int putc(int c, FILE *stream)} Scrive il carattere \param{c}
su \param{stream}. In genere è implementata come una macro.
- \funcdecl{int fputc(FILE *stream)} Scrive il carattere \param{c} su
+ \funcdecl{int fputc(int c, FILE *stream)} Scrive il carattere \param{c} su
\param{stream}. È una sempre una funzione.
- \funcdecl{int putchar(void)} Equivalente a \code{putc(stdin)}.
+ \funcdecl{int putchar(int c)} Equivalente a \code{putc(stdout)}.
\bodydesc{Le funzioni scrivono sempre un carattere alla volta, il cui
valore viene restituito in caso di successo; in caso di errore o
viene restituito un \val{NULL}, ed il buffer \param{buf} non viene toccato.
L'uso di \func{gets} è deprecato e deve essere assolutamente evitato; la
funzione infatti non controlla il numero di byte letti, per cui nel caso la
-stringa letta superi le dimensioni del buffer, si avrà un \textit{buffer
- overflow}\index{\textit{buffer~overflow}}, con sovrascrittura della memoria
-del processo adiacente al buffer.\footnote{questa tecnica è spiegata in
- dettaglio e con molta efficacia nell'ormai famoso articolo di Aleph1
+stringa letta superi le dimensioni del buffer, si avrà un
+\itindex{buffer~overflow} \textit{buffer overflow}, con sovrascrittura della
+memoria del processo adiacente al buffer.\footnote{questa tecnica è spiegata
+ in dettaglio e con molta efficacia nell'ormai famoso articolo di Aleph1
\cite{StS}.}
-Questa è una delle vulnerabilità più sfruttate per guadagnare accessi
-non autorizzati al sistema (i cosiddetti \textit{exploit}), basta
-infatti inviare una stringa sufficientemente lunga ed opportunamente
-forgiata per sovrascrivere gli indirizzi di ritorno nello stack
-(supposto che la \func{gets} sia stata chiamata da una subroutine), in
-modo da far ripartire l'esecuzione nel codice inviato nella stringa
-stessa (in genere uno \textit{shell code} cioè una sezione di programma
-che lancia una shell).
+Questa è una delle vulnerabilità più sfruttate per guadagnare accessi non
+autorizzati al sistema (i cosiddetti \textit{exploit}), basta infatti inviare
+una stringa sufficientemente lunga ed opportunamente forgiata per
+sovrascrivere gli indirizzi di ritorno nello \itindex{stack} \textit{stack}
+(supposto che la \func{gets} sia stata chiamata da una subroutine), in modo da
+far ripartire l'esecuzione nel codice inviato nella stringa stessa (in genere
+uno \textit{shell code} cioè una sezione di programma che lancia una shell).
La funzione \func{fgets} non ha i precedenti problemi di \func{gets} in quanto
prende in input la dimensione del buffer \param{size}, che non verrà mai
Se il buffer di destinazione è sufficientemente ampio la stringa viene scritta
subito, altrimenti il buffer viene allargato usando \func{realloc} e la nuova
-dimensione ed il nuovo puntatore vengono passata indietro (si noti infatti
+dimensione ed il nuovo puntatore vengono restituiti indietro (si noti infatti
come per entrambi gli argomenti si siano usati dei
-\index{\textit{value~result~argument}}\textit{value result argument}, passando
-dei puntatori anziché i valori delle variabili, secondo la tecnica spiegata in
+\itindex{value~result~argument} \textit{value result argument}, passando dei
+puntatori anziché i valori delle variabili, secondo la tecnica spiegata in
sez.~\ref{sec:proc_var_passing}).
Se si passa alla funzione l'indirizzo di un puntatore impostato a \val{NULL} e
puntatore all'inizio del testo della linea letta. Un esempio di codice può
essere il seguente:
\includecodesnip{listati/getline.c}
-e per evitare memory leak\index{\textit{memory~leak}} occorre ricordarsi di
+e per evitare \itindex{memory~leak} \textit{memory leak} occorre ricordarsi di
liberare \var{ptr} con una \func{free}.
Il valore di ritorno della funzione indica il numero di caratteri letti
l'uso di \func{sprintf} è sconsigliato in quanto è possibile, se non si ha la
sicurezza assoluta sulle dimensioni del risultato della stampa, eccedere le
dimensioni di \param{str}, con conseguente sovrascrittura di altre variabili e
-possibili \textit{buffer overflow}\index{\textit{buffer~overflow}}; per questo
+possibili \itindex{buffer~overflow} \textit{buffer overflow}; per questo
motivo si consiglia l'uso dell'alternativa \funcd{snprintf}, il cui prototipo
è:
\begin{prototype}{stdio.h}
La parte più complessa delle funzioni di scrittura formattata è il formato
della stringa \param{format} che indica le conversioni da fare, e da cui
deriva anche il numero degli argomenti che dovranno essere passati a seguire
-(si noti come tutte queste funzioni siano \textit{variadic}\index{variadic},
+(si noti come tutte queste funzioni siano \index{variadic} \textit{variadic},
prendendo un numero di argomenti variabile che dipende appunto da quello che
si è specificato in \param{format}).
\hline
\hline
\cmd{\%d} &\ctyp{int} & Stampa un numero intero in formato decimale
- con segno \\
- \cmd{\%i} &\ctyp{int} & Identico a \cmd{\%i} in output, \\
- \cmd{\%o} &\ctyp{unsigned int}& Stampa un numero intero come ottale\\
+ con segno.\\
+ \cmd{\%i} &\ctyp{int} & Identico a \cmd{\%i} in output.\\
+ \cmd{\%o} &\ctyp{unsigned int}& Stampa un numero intero come ottale.\\
\cmd{\%u} &\ctyp{unsigned int}& Stampa un numero intero in formato
- decimale senza segno \\
+ decimale senza segno.\\
\cmd{\%x},
\cmd{\%X} &\ctyp{unsigned int}& Stampano un intero in formato esadecimale,
rispettivamente con lettere minuscole e
- maiuscole. \\
+ maiuscole.\\
\cmd{\%f} &\ctyp{double} & Stampa un numero in virgola mobile con la
- notazione a virgola fissa \\
+ notazione a virgola fissa.\\
\cmd{\%e},
\cmd{\%E} &\ctyp{double} & Stampano un numero in virgola mobile con la
notazione esponenziale, rispettivamente con
- lettere minuscole e maiuscole. \\
+ lettere minuscole e maiuscole.\\
\cmd{\%g},
\cmd{\%G} &\ctyp{double} & Stampano un numero in virgola mobile con la
notazione più appropriate delle due precedenti,
rispettivamente con lettere minuscole e
- maiuscole. \\
+ maiuscole.\\
\cmd{\%a},
\cmd{\%A} &\ctyp{double} & Stampano un numero in virgola mobile in
- notazione esadecimale frazionaria\\
- \cmd{\%c} &\ctyp{int} & Stampa un carattere singolo\\
- \cmd{\%s} &\ctyp{char *} & Stampa una stringa \\
- \cmd{\%p} &\ctyp{void *} & Stampa il valore di un puntatore\\
- \cmd{\%n} &\ctyp{\&int} & Prende il numero di caratteri stampati finora\\
- \cmd{\%\%}& & Stampa un \% \\
+ notazione esadecimale frazionaria.\\
+ \cmd{\%c} &\ctyp{int} & Stampa un carattere singolo.\\
+ \cmd{\%s} &\ctyp{char *} & Stampa una stringa.\\
+ \cmd{\%p} &\ctyp{void *} & Stampa il valore di un puntatore.\\
+ \cmd{\%n} &\ctyp{\&int} & Prende il numero di caratteri stampati finora.\\
+ \cmd{\%\%}& & Stampa un \%.\\
\hline
\end{tabular}
\caption{Valori possibili per gli specificatori di conversione in una
\val{0} & La conversione è riempita con zeri alla sinistra del valore.\\
\val{-} & La conversione viene allineata a sinistra sul bordo del campo.\\
\val{' '}& Mette uno spazio prima di un numero con segno di valore
- positivo\\
+ positivo.\\
\val{+} & Mette sempre il segno ($+$ o $-$) prima di un numero.\\
\hline
\end{tabular}
\textbf{Valore} & \textbf{Significato} \\
\hline
\hline
- \cmd{hh} & una conversione intera corrisponde a un \ctyp{char} con o senza
+ \cmd{hh} & Una conversione intera corrisponde a un \ctyp{char} con o senza
segno, o il puntatore per il numero dei parametri \cmd{n} è di
tipo \ctyp{char}.\\
- \cmd{h} & una conversione intera corrisponde a uno \ctyp{short} con o
+ \cmd{h} & Una conversione intera corrisponde a uno \ctyp{short} con o
senza segno, o il puntatore per il numero dei parametri \cmd{n}
è di tipo \ctyp{short}.\\
- \cmd{l} & una conversione intera corrisponde a un \ctyp{long} con o
+ \cmd{l} & Una conversione intera corrisponde a un \ctyp{long} con o
senza segno, o il puntatore per il numero dei parametri \cmd{n}
è di tipo \ctyp{long}, o il carattere o la stringa seguenti
sono in formato esteso.\\
- \cmd{ll} & una conversione intera corrisponde a un \ctyp{long long} con o
+ \cmd{ll} & Una conversione intera corrisponde a un \ctyp{long long} con o
senza segno, o il puntatore per il numero dei parametri \cmd{n}
è di tipo \ctyp{long long}.\\
- \cmd{L} & una conversione in virgola mobile corrisponde a un
+ \cmd{L} & Una conversione in virgola mobile corrisponde a un
\ctyp{double}.\\
- \cmd{q} & sinonimo di \cmd{ll}.\\
- \cmd{j} & una conversione intera corrisponde a un \type{intmax\_t} o
+ \cmd{q} & Sinonimo di \cmd{ll}.\\
+ \cmd{j} & Una conversione intera corrisponde a un \type{intmax\_t} o
\type{uintmax\_t}.\\
- \cmd{z} & una conversione intera corrisponde a un \type{size\_t} o
+ \cmd{z} & Una conversione intera corrisponde a un \type{size\_t} o
\type{ssize\_t}.\\
- \cmd{t} & una conversione intera corrisponde a un \type{ptrdiff\_t}.\\
+ \cmd{t} & Una conversione intera corrisponde a un \type{ptrdiff\_t}.\\
\hline
\end{tabular}
\caption{Il modificatore di tipo di dato per il formato di \func{printf}}
\bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
\end{functions}
\noindent con queste funzioni diventa possibile selezionare gli argomenti che
-si vogliono passare ad una routine di stampa, passando direttamente la lista
+si vogliono passare ad una funzione di stampa, passando direttamente la lista
tramite l'argomento \param{ap}. Per poter far questo ovviamente la lista degli
argomenti dovrà essere opportunamente trattata (l'argomento è esaminato in
sez.~\ref{sec:proc_variadic}), e dopo l'esecuzione della funzione l'argomento
Identica a \func{vsprintf}, ma non scrive su \param{str} più di
\param{size} caratteri.
\end{prototype}
-\noindent in modo da evitare possibili buffer
-overflow\index{\textit{buffer~overflow}}.
+\noindent in modo da evitare possibili \itindex{buffer~overflow} buffer
+overflow.
Per eliminare alla radice questi problemi, le \acr{glibc} supportano una
\bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
\end{functions}
+
Entrambe le funzioni prendono come argomento \param{strptr} che deve essere
l'indirizzo di un puntatore ad una stringa di caratteri, in cui verrà
restituito (si ricordi quanto detto in sez.~\ref{sec:proc_var_passing} a
-proposito dei \index{\textit{value~result~argument}}\textit{value result
- argument}) l'indirizzo della stringa allocata automaticamente dalle
-funzioni. Occorre inoltre ricordarsi di invocare \func{free} per liberare
-detto puntatore quando la stringa non serve più, onde evitare memory
-leak\index{\textit{memory~leak}}.
+proposito dei \itindex{value~result~argument} \textit{value result argument})
+l'indirizzo della stringa allocata automaticamente dalle funzioni. Occorre
+inoltre ricordarsi di invocare \func{free} per liberare detto puntatore quando
+la stringa non serve più, onde evitare \itindex{memory~leak} \textit{memory
+ leak}.
Infine una ulteriore estensione GNU definisce le due funzioni \func{dprintf} e
\func{vdprintf}, che prendono un file descriptor al posto dello stream. Altre
sono varie differenze. Le funzioni di input infatti sono più orientate verso
la lettura di testo libero che verso un input formattato in campi fissi. Uno
spazio in \param{format} corrisponde con un numero qualunque di caratteri di
-separazione (che possono essere spazi, tabulatori, virgole etc.), mentre
+separazione (che possono essere spazi, tabulatori, virgole ecc.), mentre
caratteri diversi richiedono una corrispondenza esatta. Le direttive di
conversione sono analoghe a quelle di \func{printf} e si trovano descritte in
dettaglio nelle pagine di manuale e nel manuale delle \acr{glibc}.
punto prestabilito; sempre che l'operazione di riposizionamento sia supportata
dal file sottostante lo stream, quando cioè si ha a che fare con quello che
viene detto un file ad \textsl{accesso casuale}.\footnote{dato che in un
- sistema Unix esistono vari tipi di file, come le fifo ed i file di
- dispositivo\index{file!di~dispositivo}, non è scontato che questo sia sempre
- vero.}
+ sistema Unix esistono vari tipi di file, come le fifo ed i
+ \index{file!di~dispositivo} file di dispositivo, non è scontato che questo
+ sia sempre vero.}
In GNU/Linux ed in generale in ogni sistema unix-like la posizione nel file è
espressa da un intero positivo, rappresentato dal tipo \type{off\_t}, il
In Linux, a partire dalle glibc 2.1, sono presenti anche le due funzioni
\func{fseeko} e \func{ftello}, che sono assolutamente identiche alle
precedenti \func{fseek} e \func{ftell} ma hanno argomenti di tipo
-\type{off\_t} anziché di tipo \ctyp{long int}.
+\type{off\_t} anziché di tipo \ctyp{long int}. Dato che \ctyp{long} è nella
+gran parte dei casi un intero a 32 bit, questo diventa un problema quando la
+posizione sul file viene espressa con un valore a 64 bit come accade nei
+sistemi più moderni.
In questa sezione esamineremo alcune funzioni avanzate che permettono di
eseguire operazioni particolari sugli stream, come leggerne gli attributi,
controllarne le modalità di bufferizzazione, gestire direttamente i lock
-impliciti per la programmazione multi thread.
+impliciti per la programmazione \itindex{thread} \textit{multi-thread}.
\subsection{Le funzioni di controllo}
(come delle scritture accidentali sul buffer) e non assicura la scelta delle
dimensioni ottimali, è sempre meglio lasciare allocare il buffer alle funzioni
di libreria, che sono in grado di farlo in maniera ottimale e trasparente
-all'utente (in quanto la disallocazione avviene automaticamente). Inoltre
+all'utente (in quanto la deallocazione avviene automaticamente). Inoltre
siccome alcune implementazioni usano parte del buffer per mantenere delle
informazioni di controllo, non è detto che le dimensioni dello stesso
coincidano con quelle su cui viene effettuato l'I/O.
compresi gli eventuali caratteri rimandati indietro con \func{ungetc}.
-\subsection{Gli stream e i thread}
+\subsection{Gli \textit{stream} e i \textit{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
+\itindbeg{thread}
+
+Gli stream possono essere usati in applicazioni \textit{multi-thread} allo
+stesso modo in cui sono usati nelle applicazioni normali, ma si deve essere
consapevoli 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 con i thread.
+\textit{thread}, dato che l'implementazione delle librerie è influenzata
+pesantemente dalle richieste necessarie per garantirne l'uso con i
+\textit{thread}.
Lo standard POSIX richiede che le operazioni sui file siano atomiche rispetto
-ai thread, per questo le operazioni sui buffer effettuate dalle funzioni di
-libreria durante la lettura e la scrittura di uno stream devono essere
-opportunamente protette (in quanto il sistema assicura l'atomicità solo per le
-system call). Questo viene fatto associando ad ogni stream un opportuno blocco
-che deve essere implicitamente acquisito prima dell'esecuzione di qualunque
-operazione.
-
-Ci sono comunque situazioni in cui questo non basta, come quando un thread
-necessita di compiere più di una operazione sullo stream atomicamente, per
-questo motivo le librerie provvedono anche delle funzioni \funcd{flockfile},
-\funcd{ftrylockfile} e \funcd{funlockfile}, che permettono la gestione
-esplicita dei blocchi sugli stream; esse sono disponibili definendo
-\macro{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro prototipi sono:
+ai \textit{thread}, per questo le operazioni sui buffer effettuate dalle
+funzioni di libreria durante la lettura e la scrittura di uno stream devono
+essere opportunamente protette (in quanto il sistema assicura l'atomicità solo
+per le system call). Questo viene fatto associando ad ogni stream un opportuno
+blocco che deve essere implicitamente acquisito prima dell'esecuzione di
+qualunque operazione.
+
+Ci sono comunque situazioni in cui questo non basta, come quando un
+\textit{thread} necessita di compiere più di una operazione sullo stream
+atomicamente, per questo motivo le librerie provvedono anche delle funzioni
+\funcd{flockfile}, \funcd{ftrylockfile} e \funcd{funlockfile}, che permettono
+la gestione esplicita dei blocchi sugli stream; esse sono disponibili
+definendo \macro{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro prototipi sono:
\begin{functions}
\headdecl{stdio.h}
Ma, vista la complessità delle strutture di dati coinvolte, le operazioni di
blocco non sono del tutto indolori, e quando il locking dello stream non è
-necessario (come in tutti i programmi che non usano i thread), tutta la
-procedura può comportare dei costi pesanti in termini di prestazioni. Per
+necessario (come in tutti i programmi che non usano i \textit{thread}), tutta
+la procedura può comportare dei costi pesanti in termini di prestazioni. Per
questo motivo abbiamo visto come alle usuali funzioni di I/O non formattato
siano associate delle versioni \code{\_unlocked} (alcune previste dallo stesso
standard POSIX, altre aggiunte come estensioni dalle \acr{glibc}) che possono
accade per \func{getc} e \func{putc}) sono realizzate come macro.
La sostituzione di tutte le funzioni di I/O con le relative versioni
-\code{\_unlocked} in un programma che non usa i thread è però un lavoro
-abbastanza noioso; per questo motivo le \acr{glibc} forniscono al
+\code{\_unlocked} in un programma che non usa i \textit{thread} è però un
+lavoro abbastanza noioso; per questo motivo le \acr{glibc} forniscono al
programmatore pigro un'altra via\footnote{anche questa mutuata da estensioni
introdotte in Solaris.} da poter utilizzare per disabilitare in blocco il
locking degli stream: l'uso della funzione \funcd{\_\_fsetlocking}, il cui
di blocco dello stream.
\end{basedescript}
+\itindend{thread}
+
+
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
+
+% LocalWords: stream cap system call kernel Ritchie glibc descriptor Stevens
+% LocalWords: buf read write filesystem st blksize stat sez l'header stdio BSD
+% LocalWords: nell'header stdin shell stdout stderr error freopen flush line
+% LocalWords: unbuffered buffered newline fully SVr fopen fdopen POSIX const
+% LocalWords: char path int fildes NULL errno malloc fcntl fclose fflush tab
+% LocalWords: dup fifo socket append EXCL ccs STRING IRUSR IWUSR IRGRP IWGRP
+% LocalWords: IROTH IWOTH umask fseek fsetpos rewind SEEK CUR EOF EBADF close
+% LocalWords: sync fcloseall SOURCE void stdlib of feof ferror clearerr l'I ws
+% LocalWords: unlocked fread fwrite size ptr nmemb nelem gcc padding point str
+% LocalWords: lock thread fgetc getc getchar dell'overhead altresì unsigned ap
+% LocalWords: getwc fgetwc getwchar wint wchar WEOF putc fputc putchar dell'I
+% LocalWords: SVID getw putw parsing peeking ahead ungetc gets fgets string Di
+% LocalWords: overflow Aleph stack fputs puts fgetws fputws getline ssize leak
+% LocalWords: realloc value result argument memory getdelim delim printf short
+% LocalWords: fprintf sprintf format snprintf variadic long double intmax list
+% LocalWords: uintmax ptrdiff vprintf vfprintf vsprintf vsnprintf asprintf lex
+% LocalWords: vasprintf strptr dprintf vdprintf print scanf fscanf sscanf flex
+% LocalWords: vscanf vfscanf vsscanf bison parser yacc like off VMS whence pos
+% LocalWords: lseek ftell fgetpos fpos fseeko ftello fileno Solaris freadable
+% LocalWords: fwritable ext freading fwriting buffering setvbuf BUFSIZ setbuf
+% LocalWords: IONBF IOLBF IOFBF setbuffer setlinebuf flbf fbufsize flushlbf hh
+% LocalWords: fsync fpurge flockfile ftrylockfile funlockfile SAFE FUNCTIONS
+% LocalWords: locking fsetlocking type BYCALLER QUERY ll