\func{write}) nell'efficienza nelle operazioni di I/O con i file descriptor,
evidenziando come le prestazioni ottimali si ottengano a partire da dimensioni
del buffer dei dati pari a quelle dei blocchi del filesystem (il valore dato
-dal campo \var{st\_blksize} di \struct{stat}).
+dal campo \var{st\_blksize} di \struct{stat}), che di norma corrispondono alle
+dimensioni dei settori fisici in cui è suddiviso il disco.
Se il programmatore non si cura di effettuare le operazioni in blocchi di
dimensioni adeguate, le prestazioni sono inferiori. La caratteristica
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 \ctyp{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}.
-
+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
+(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}.
\subsection{Gli stream standard}
uno degli aspetti più comunemente fraintesi, in particolare per quello che
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} dei dati,
-dall'inglese \textit{flush}) 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 ne sono richiesti una quantità inferiore), ma la cosa
-ovviamente ha rilevanza inferiore, dato che i dati letti sono sempre gli
-stessi; in caso di scrittura invece, quando si ha un accesso contemporaneo
-allo stesso file (ad esempio da parte di un altro processo) si potranno vedere
-solo le parti effettivamente scritte, e non quelle ancora presenti nel buffer.
-
-Allo stesso modo, se si sta facendo dell'input/output interattivo
-bisognerà tenere presente le caratteristiche delle operazioni di scarico
-dei dati, poiché non è detto che ad una scrittura sullo stream
-corrisponda una immediata scrittura sul dispositivo.
+I caratteri che vengono scritti su di uno stream normalmente vengono
+accumulati in un buffer e poi trasmessi in blocco\footnote{questa operazione
+ viene usualmente chiamata \textsl{scaricamento} dei dati, dal termine
+ inglese \textit{flush}.} tutte le volte che il buffer viene riempito, in
+maniera asincrona rispetto alla scrittura. Un comportamento analogo avviene
+anche in lettura (cioè dal file viene letto un blocco di dati, anche se ne
+sono richiesti una quantità inferiore), ma la cosa ovviamente ha rilevanza
+inferiore, dato che i dati letti sono sempre gli stessi. In caso di scrittura
+invece, quando si ha un accesso contemporaneo allo stesso file (ad esempio da
+parte di un altro processo) si potranno vedere solo le parti effettivamente
+scritte, e non quelle ancora presenti nel buffer.
+
+Per lo stesso motivo, in tutte le situazioni in cui si sta facendo
+dell'input/output interattivo, bisognerà tenere presente le caratteristiche
+delle operazioni di scaricamento dei dati, poiché non è detto che ad una
+scrittura sullo stream corrisponda una immediata scrittura sul dispositivo (la
+cosa è particolarmente evidente quando con le operazioni di input/output su
+terminale).
Per rispondere ad esigenze diverse, lo standard definisce tre distinte
modalità in cui può essere eseguita la bufferizzazione, delle quali
\label{sec:file_fopen}
Le funzioni che si possono usare per aprire uno stream sono solo tre:
-\func{fopen}, \func{fdopen} e \func{freopen},\footnote{\func{fopen} e
+\funcd{fopen}, \funcd{fdopen} e \funcd{freopen},\footnote{\func{fopen} e
\func{freopen} fanno parte dello standard ANSI C, \func{fdopen} è parte
dello standard POSIX.1.} i loro prototipi sono:
\begin{functions}
(si veda \secref{sec:file_buffering_ctrl}) fintanto che non si è effettuato
alcuna operazione di I/O sul file.
-Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo è:
+Uno stream viene chiuso con la funzione \funcd{fclose} il cui prototipo è:
\begin{prototype}{stdio.h}{int fclose(FILE *stream)}
Chiude lo stream \param{stream}.
essere sicuri che il kernel forzi la scrittura su disco occorrerà effettuare
una \func{sync} (vedi \secref{sec:file_sync}).
-Linux supporta anche una altra funzione, \func{fcloseall}, come estensione GNU
-implementata dalle \acr{glibc}, accessibile avendo definito
+Linux supporta anche una altra funzione, \funcd{fcloseall}, come estensione
+GNU implementata dalle \acr{glibc}, accessibile avendo definito
\macro{\_GNU\_SOURCE}, il suo prototipo è:
\begin{prototype}{stdio.h}{int fcloseall(void)}
Chiude tutti gli stream.
\ctyp{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:
+questi due flag possono essere riletti dalle funzioni \funcd{feof} e
+\funcd{ferror}, i cui prototipi sono:
\begin{functions}
\headdecl{stdio.h}
\funcdecl{int feof(FILE *stream)}
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 è:
+la funzione \funcd{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}
\label{sec:file_binary_io}
La prima modalità di input/output non formattato ricalca quella della
-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:
+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 \funcd{fread} ed \funcd{fwrite};
+i loro prototipi sono:
\begin{functions}
\headdecl{stdio.h}
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):
+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 \secref{sec:file_stream_thread} per i
+dettagli), i loro prototipi sono:
\begin{functions}
\headdecl{stdio.h}
La seconda modalità di input/output è quella a caratteri, in cui si
trasferisce un carattere alla volta. Le funzioni per la lettura a
-caratteri sono tre, \func{fgetc}, \func{getc} e \func{getchar}, i
+caratteri sono tre, \funcd{fgetc}, \funcd{getc} e \funcd{getchar}, i
rispettivi prototipi sono:
\begin{functions}
\headdecl{stdio.h}
motivo la sua esecuzione normalmente è più lenta per via dell'overhead
della chiamata, ma è altresì possibile ricavarne l'indirizzo, che può
essere passato come parametro ad un altra funzione (e non si hanno i
-problemi accennati in precedenza con \param{stream}).
+problemi accennati in precedenza nel tipo di argomento).
Le tre funzioni restituiscono tutte un \ctyp{unsigned char} convertito
ad \ctyp{int} (si usa \ctyp{unsigned char} in modo da evitare
positivo, tranne in caso di errore o fine del file.
Nelle estensioni GNU che provvedono la localizzazione sono definite tre
-funzioni equivalenti alle precedenti che invece di un carattere di un
-byte restituiscono un carattere in formato esteso (cioè di tipo
-\ctyp{wint\_t}), il loro prototipo è:
+funzioni equivalenti alle precedenti, \funcd{getwc}, \funcd{fgetwc} e
+\funcd{getwchar}, che invece di un carattere di un byte restituiscono un
+carattere in formato esteso (cioè di tipo \ctyp{wint\_t}), il loro prototipo
+è:
\begin{functions}
\headdecl{stdio.h}
\headdecl{wchar.h}
caso di errore o fine del file il valore di ritorno è \const{WEOF}.}
\end{functions}
-Per scrivere un carattere si possono usare tre funzioni analoghe alle
-precedenti usate per leggere: \func{putc}, \func{fputc} e
-\func{putchar}; i loro prototipi sono:
+Per scrivere un carattere si possono usare tre funzioni, analoghe alle
+precedenti usate per leggere: \funcd{putc}, \funcd{fputc} e \funcd{putchar}; i
+loro prototipi sono:
\begin{functions}
\headdecl{stdio.h}
sempre un intero; in caso di errore o fine del file il valore di ritorno
è \val{EOF}.
-Come nel caso dell'I/O binario le \acr{glibc} provvedono per ciascuna
-delle funzioni precedenti, come estensione GNU, una seconda funzione, il
-cui nome è ottenuto aggiungendo un \code{\_unlocked}, che esegue
-esattamente le stesse operazioni evitando però il lock implicito dello
-stream.
+Come nel caso dell'I/O binario con \func{fread} e \func{fwrite} le \acr{glibc}
+provvedono come estensione, per ciascuna delle funzioni precedenti,
+un'ulteriore funzione, il cui nome è ottenuto aggiungendo un
+\code{\_unlocked}, che esegue esattamente le stesse operazioni, evitando però
+il lock implicito dello stream.
-Per compatibilità con SVID sono provviste anche due funzioni per leggere
-e scrivere una \textit{word} (che è sempre definita come \ctyp{int}); i
-loro prototipi sono:
+Per compatibilità con SVID sono inoltre provviste anche due funzioni,
+\funcd{getw} e \funcd{putw}, da usare per leggere e scrivere una \textit{word}
+(cioè due byte in una volta); i loro prototipi sono:
\begin{functions}
\headdecl{stdio.h}
\bodydesc{Le funzioni restituiscono la parola \param{w}, o \val{EOF}
in caso di errore o di fine del file.}
\end{functions}
-\noindent l'uso di queste funzioni è deprecato in favore dell'uso di
-\func{fread} e \func{fwrite}, in quanto non è possibile distinguere il
+
+Le funzioni leggono e scrivono una \textit{word} di due byte, usando comunque
+una variabile di tipo \ctyp{int}; il loro uso è deprecato in favore dell'uso
+di \func{fread} e \func{fwrite}, in quanto non è possibile distinguere il
valore -1 da una condizione di errore che restituisce \val{EOF}.
Uno degli usi più frequenti dell'input/output a caratteri è nei programmi di
Nel nostro caso questo tipo di comportamento può essere realizzato prima
leggendo il carattere, e poi rimandandolo indietro, cosicché ridiventi
disponibile per una lettura successiva; la funzione che inverte la
-lettura si chiama \func{ungetc} ed il suo prototipo è:
+lettura si chiama \funcd{ungetc} ed il suo prototipo è:
\begin{prototype}{stdio.h}{int ungetc(int c, FILE *stream)}
Rimanda indietro il carattere \param{c}, con un cast a \ctyp{unsigned
char}, sullo stream \param{stream}.
La terza ed ultima modalità di input/output non formattato è quella di linea,
in cui si legge o si scrive una riga alla volta; questa è una modalità molto
-usata per l'I/O da terminale, ma che presenta le caratteristiche più
-controverse.
+usata per l'I/O da terminale, ma è anche quella che presenta le
+caratteristiche più controverse.
Le funzioni previste dallo standard ANSI C per leggere una linea sono
-sostanzialmente due, \func{gets} e \func{fgets}, i cui rispettivi
+sostanzialmente due, \funcd{gets} e \funcd{fgets}, i cui rispettivi
prototipi sono:
\begin{functions}
\headdecl{stdio.h}
successiva.
Per la scrittura di una linea lo standard ANSI C prevede altre due
-funzioni, \func{fputs} e \func{puts}, analoghe a quelle di lettura, i
+funzioni, \funcd{fputs} e \funcd{puts}, analoghe a quelle di lettura, i
rispettivi prototipi sono:
\begin{functions}
\headdecl{stdio.h}
\var{stdout}) è che quest'ultima non aggiunge il newline, che deve essere
previsto esplicitamente.
-Come per le funzioni di input/output a caratteri esistono le estensioni
-per leggere e scrivere caratteri estesi, i loro prototipi sono:
+Come per le analoghe funzioni di input/output a caratteri, anche per l'I/O di
+linea esistono delle estensioni per leggere e scrivere linee di caratteri
+estesi, le funzioni in questione sono \funcd{fgetws} e \funcd{fputws} ed i
+loro prototipi sono:
\begin{functions}
\headdecl{wchar.h}
\funcdecl{wchar\_t *fgetws(wchar\_t *ws, int n, FILE *stream)}
non negativo in caso di successo e \val{NULL} o \val{EOF} in
caso di errore o fine del file.}
\end{functions}
-\noindent il cui comportamento è identico a quello di \func{fgets} e
-\func{fputs} a parte il fatto che tutto (numero di caratteri massimo,
+
+Il comportamento di queste due funzioni è identico a quello di \func{fgets} e
+\func{fputs}, a parte il fatto che tutto (numero di caratteri massimo,
terminatore della stringa, newline) è espresso in termini di caratteri estesi
-anziché di caratteri ASCII.
+anziché di normali caratteri ASCII.
-Come nel caso dell'I/O binario e a caratteri nelle \acr{glibc} sono
-previste una serie di altre funzioni, estensione di tutte quelle
-illustrate finora (eccetto \func{gets} e \func{puts}), il cui nome si
-ottiene aggiungendo un \code{\_unlocked}, e che eseguono esattamente le
-stesse operazioni delle loro equivalenti, evitando però il lock
-implicito dello stream (vedi \secref{sec:file_stream_thread}).
+Come per l'I/O binario e quello a caratteri, anche per l'I/O di linea le
+\acr{glibc} supportano una serie di altre funzioni, estensioni di tutte quelle
+illustrate finora (eccetto \func{gets} e \func{puts}), che eseguono
+esattamente le stesse operazioni delle loro equivalenti, evitando però il lock
+implicito dello stream (vedi \secref{sec:file_stream_thread}). Come per le
+altre forma di I/O, dette funzioni hanno lo stesso nome della loro analoga
+normale, con l'aggiunta dell'estensione \code{\_unlocked}.
Come abbiamo visto, le funzioni di lettura per l'input/output di linea
previste dallo standard ANSI C presentano svariati inconvenienti. Benché
programma. Lo stesso dicasi quando si deve gestire il caso di stringa
che eccede le dimensioni del buffer.
-Per questo motivo le \acr{glibc} prevedono, come estensione GNU, due
-nuove funzioni per la gestione dell'input/output di linea, il cui uso
-permette di risolvere questi problemi. L'uso di queste funzioni deve
-essere attivato definendo la macro \macro{\_GNU\_SOURCE} prima di
-includere \file{stdio.h}. La prima delle due, \func{getline}, serve per
-leggere una linea terminata da un newline esattamente allo stesso modo
-di \func{fgets}, il suo prototipo è:
+Per questo motivo le \acr{glibc} prevedono, come estensione GNU, due nuove
+funzioni per la gestione dell'input/output di linea, il cui uso permette di
+risolvere questi problemi. L'uso di queste funzioni deve essere attivato
+definendo la macro \macro{\_GNU\_SOURCE} prima di includere \file{stdio.h}. La
+prima delle due, \funcd{getline}, serve per leggere una linea terminata da un
+newline, esattamente allo stesso modo di \func{fgets}, il suo prototipo è:
\begin{prototype}{stdio.h}
{ssize\_t getline(char **buffer, size\_t *n, FILE *stream)} Legge una linea
dal file \param{stream} copiandola sul buffer indicato da \param{buffer}
...
nread = getline(&ptr, &n, file);
\end{lstlisting}
-e per evitare memory leak occorre ricordarsi di liberare \var{ptr} con
-una \func{free}.
+e per evitare memory leak\index{memory leak} occorre ricordarsi di liberare
+\var{ptr} con una \func{free}.
Il valore di ritorno della funzione indica il numero di caratteri letti
dallo stream (quindi compreso il newline, ma non lo zero di
La seconda estensione GNU è una generalizzazione di \func{getline} per
poter usare come separatore un carattere qualsiasi, la funzione si
-chiama \func{getdelim} ed il suo prototipo è:
+chiama \funcd{getdelim} ed il suo prototipo è:
\begin{prototype}{stdio.h}
{ssize\_t getdelim(char **buffer, size\_t *n, int delim, FILE *stream)}
Identica a \func{getline} solo che usa \param{delim} al posto del
permette di stampare in maniera facile e veloce dati, tabelle e messaggi.
L'output formattato viene eseguito con una delle 13 funzioni della famiglia
-\func{printf}; le tre più usate sono le seguenti:
+\func{printf}; le tre più usate sono \funcd{printf}, \funcd{fprintf} e
+\funcd{sprintf}, i cui prototipi sono:
\begin{functions}
\headdecl{stdio.h}
\funcdecl{int printf(const char *format, ...)} Stampa su \file{stdout}
o quello specificato) la terza permette di stampare su una stringa, in genere
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 buffer overflow; per questo motivo si consiglia l'uso
-dell'alternativa:
+dimensioni di \param{str}, con conseguente sovrascrittura di altre variabili e
+possibili \textit{buffer overflow}\index{buffer overflow}; per questo motivo
+si consiglia l'uso dell'alternativa \funcd{snprintf}, il cui prototipo è:
\begin{prototype}{stdio.h}
{snprintf(char *str, size\_t size, const char *format, ...)}
Identica a \func{sprintf}, ma non scrive su \param{str} più di
\param{size} caratteri.
\end{prototype}
-La parte più complessa di queste funzioni è il formato della stringa
-\param{format} che indica le conversioni da fare, da cui poi deriva il numero
-dei parametri che dovranno essere passati a seguire.
+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 dei parametri che dovranno essere passati a seguire (si
+noti come tutte queste funzioni siano \textit{variadic}\index{variadic},
+prendendo un numero di argomenti variabile che dipende appunto da quello che
+si è specificato in \param{format}).
\begin{table}[htb]
\centering
Una versione alternativa delle funzioni di output formattato, che permettono
di usare il puntatore ad una lista di argomenti (vedi
-\secref{sec:proc_variadic}), sono le seguenti:
+\secref{sec:proc_variadic}), sono \funcd{vprintf}, \funcd{vfprintf} e
+\funcd{vsprintf}, i cui prototipi sono:
\begin{functions}
\headdecl{stdio.h}
\code{va\_end(ap)} ma in Linux questo non è necessario).
Come per \func{sprintf} anche per \func{vsprintf} esiste una analoga
-\func{vsnprintf} che pone un limite sul numero di caratteri che vengono
+\funcd{vsnprintf} che pone un limite sul numero di caratteri che vengono
scritti sulla stringa di destinazione:
\begin{prototype}{stdio.h}
{vsnprintf(char *str, size\_t size, const char *format, va\_list ap)}
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.
+\noindent in modo da evitare possibili buffer overflow\index{buffer overflow}.
Per eliminare alla radice questi problemi, le \acr{glibc} supportano una
specifica estensione GNU che alloca dinamicamente tutto lo spazio necessario;
l'estensione si attiva al solito definendo \macro{\_GNU\_SOURCE}, le due
-funzioni sono:
+funzioni sono \funcd{asprintf} e \funcd{vasprintf}, ed i rispettivi prototipi
+sono:
\begin{functions}
\headdecl{stdio.h}
proposito dei \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.
+più, onde evitare memory leak\index{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
In corrispondenza alla famiglia di funzioni \func{printf} che si usano per
l'output formattato, l'input formattato viene eseguito con le funzioni della
-famiglia \func{scanf}; fra queste le tre più importanti sono:
+famiglia \func{scanf}; fra queste le tre più importanti sono \funcd{scanf},
+\funcd{fscanf} e \funcd{sscanf}, i cui prototipi sono:
\begin{functions}
\headdecl{stdio.h} \funcdecl{int scanf(const char *format, ...)} Esegue una
scansione di \file{stdin} cercando una corrispondenza di quanto letto con il
conversione delle stringhe; se invece il formato è più complesso diventa più
facile utilizzare uno strumento come \cmd{flex}\footnote{il programma
\cmd{flex}, è una implementazione libera di \cmd{lex} un generatore di
- analizzatori lessicali, per i dettagli si può fare riferimento al manuale
+ analizzatori lessicali. Per i dettagli si può fare riferimento al manuale
\cite{flex}.} per generare un analizzatore lessicale o il
\cmd{bison}\footnote{il programma \cmd{bison} è un clone del generatore di
parser \cmd{yacc}, maggiori dettagli possono essere trovati nel relativo
rispetto al record corrente).
Tutto questo comporta la presenza di diverse funzioni che eseguono
-sostanzialmente le stesse operazioni, ma usano parametri di tipo
-diverso. Le funzioni tradizionali usate per il riposizionamento della
-posizione in uno stream sono:
+sostanzialmente le stesse operazioni, ma usano parametri di tipo diverso. Le
+funzioni tradizionali usate per il riposizionamento della posizione in uno
+stream sono \funcd{fseek} e \funcd{rewind} i cui prototipi sono:
\begin{functions}
\headdecl{stdio.h}
una \code{fseek(stream, 0L, SEEK\_SET)} in quanto vengono cancellati anche i
flag di errore e fine del file.
-Per ottenere la posizione corrente si usa invece la funzione \func{ftell}, il
+Per ottenere la posizione corrente si usa invece la funzione \funcd{ftell}, il
cui prototipo è:
\begin{prototype}{stdio.h}{long ftell(FILE *stream)}
Legge la posizione attuale nello stream \param{stream}.
Queste funzioni esprimono tutte la posizione nel file come un \ctyp{long int}.
Dato che (ad esempio quando si usa un filesystem indicizzato a 64 bit) questo
può non essere possibile lo standard POSIX ha introdotto le nuove funzioni
-\func{fgetpos} e \func{fsetpos}, che invece usano il nuovo tipo
+\funcd{fgetpos} e \funcd{fsetpos}, che invece usano il nuovo tipo
\type{fpos\_t}, ed i cui prototipi sono:
\begin{functions}
\headdecl{stdio.h}
Al contrario di quanto avviene con i file descriptor, le librerie standard del
C non prevedono nessuna funzione come la \func{fcntl} per il controllo degli
attributi dei file. Però, dato che ogni stream si appoggia ad un file
-descriptor, si può usare la funzione \func{fileno} per ottenere quest'ultimo,
+descriptor, si può usare la funzione \funcd{fileno} per ottenere quest'ultimo,
il prototipo della funzione è:
\begin{prototype}{stdio.h}{int fileno(FILE *stream)}
Legge il file descriptor sottostante lo stream \param{stream}.
essere complessa se le 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:
+\funcd{\_\_freadable} e \funcd{\_\_fwritable} i cui prototipi sono:
\begin{functions}
\headdecl{stdio\_ext.h}
\funcdecl{int \_\_freadable(FILE *stream)}
La conoscenza dell'ultima operazione effettuata su uno stream aperto è utile
in quanto permette di trarre conclusioni sullo stato del buffer e del suo
-contenuto. Altre due funzioni, \func{\_\_freading} e \func{\_\_fwriting}
+contenuto. Altre due funzioni, \funcd{\_\_freading} e \funcd{\_\_fwriting}
servono a tale scopo, il loro prototipo è:
\begin{functions}
\headdecl{stdio\_ext.h}
Però una volta che si sia aperto lo stream (ma prima di aver compiuto
operazioni su di esso) è possibile intervenire sulle modalità di buffering; la
-funzione che permette di controllare la bufferizzazione è \func{setvbuf}, il
+funzione che permette di controllare la bufferizzazione è \funcd{setvbuf}, il
suo prototipo è:
\begin{prototype}{stdio.h}{int setvbuf(FILE *stream, char *buf, int mode,
size\_t size)}
vengono sempre ignorati.
Oltre a \func{setvbuf} le \acr{glibc} definiscono altre tre funzioni per la
-gestione della bufferizzazione di uno stream: \func{setbuf}, \func{setbuffer}
-e \func{setlinebuf}; i loro prototipi sono:
+gestione della bufferizzazione di uno stream: \funcd{setbuf}, \funcd{setbuffer}
+e \funcd{setlinebuf}; i loro prototipi sono:
\begin{functions}
\headdecl{stdio.h}
\noindent tutte queste funzioni sono realizzate con opportune chiamate a
\func{setvbuf} e sono definite solo per compatibilità con le vecchie librerie
BSD. Infine le \acr{glibc} provvedono le funzioni non standard\footnote{anche
- queste funzioni sono originarie di Solaris.} \func{\_\_flbf} e
-\func{\_\_fbufsize} che permettono di leggere le proprietà di bufferizzazione
+ queste funzioni sono originarie di Solaris.} \funcd{\_\_flbf} e
+\funcd{\_\_fbufsize} che permettono di leggere le proprietà di bufferizzazione
di uno stream; i cui prototipi sono:
\begin{functions}
\headdecl{stdio\_ext.h}
Come già accennato, indipendentemente dalla modalità di bufferizzazione
scelta, si può forzare lo scarico dei dati sul file con la funzione
-\func{fflush}, il suo prototipo è:
+\funcd{fflush}, il suo prototipo è:
\begin{prototype}{stdio.h}{int fflush(FILE *stream)}
Forza la scrittura di tutti i dati bufferizzati dello stream \param{stream}.
sicuri che sia stato eseguito tutto l'output su terminale, in cui serve poter
effettuare lo scarico dei dati solo per gli stream in modalità line buffered;
per questo motivo le \acr{glibc} supportano una estensione di Solaris, la
-funzione \func{\_flushlbf}, il cui prototipo è:
+funzione \funcd{\_flushlbf}, il cui prototipo è:
\begin{prototype}{stdio-ext.h}{void \_flushlbf(void)}
Forza la scrittura di tutti i dati bufferizzati degli stream in modalità
line buffered.
usare \func{sync} o \func{fsync} (si veda~\secref{sec:file_sync}).
Infine esistono anche circostanze in cui si vuole scartare tutto l'output
-pendente; per questo si può usare \func{fpurge}, il cui prototipo è:
+pendente; per questo si può usare \funcd{fpurge}, il cui prototipo è:
\begin{prototype}{stdio.h}{int fpurge(FILE *stream)}
Cancella i buffer di input e di output dello stream \param{stream}.
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 che permettono la
-gestione esplicita dei blocchi sugli stream; queste funzioni sono disponibili
-definendo \macro{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro prototipi sono:
+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}
abbastanza noioso; per questo motivo le \acr{glibc} provvedono 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 \func{\_\_fsetlocking}, il cui
+locking degli stream: l'uso della funzione \funcd{\_\_fsetlocking}, il cui
prototipo è:
\begin{prototype}{stdio\_ext.h}{int \_\_fsetlocking (FILE *stream, int type)}
Specifica o richiede a seconda del valore di \param{type} la modalità in cui