Completata revisione capitolo 2, aggiunte le variadic function e
[gapil.git] / filestd.tex
index 582f696764ce856da6a0a02263ea3dfb6473a1f1..2e9b05af38d47538260c57eb57836ead8850735e 100644 (file)
@@ -2,9 +2,9 @@
 \label{cha:files_std_interface}
 
 Esamineremo in questo capitolo l'interfaccia standard ANSI C per i file,
-quella che viene comunemente detta interfaccia degli \textit{stream}.
-Dopo una breve sezione introduttiva tratteremo le funzioni base per la
-gestione dell'input/output, mentre tratteremo le caratteristiche più avanzate
+quella che viene comunemente detta interfaccia degli \textit{stream}.  Dopo
+una breve sezione introduttiva tratteremo le funzioni base per la gestione
+dell'input/output, mentre tratteremo le caratteristiche più avanzate
 dell'interfaccia nell'ultima sezione.
 
 
@@ -334,7 +334,7 @@ una operazione nominalmente nulla come \func{fseek(file, 0, SEEK\_CUR)} 
 sufficiente a garantire la sincronizzazione.
 
 Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione
-(vedi \secref{sec:file_buffering_ctrl}) fintanto che non si è effettuato
+(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 è:
@@ -348,12 +348,12 @@ Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo 
     \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 vuole essere sicuri che il kernel forzi la scrittura
-su disco occorrerà effettuare una \func{sync}.
+La funzione effettua lo 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} (vedi \secref{sec:file_sync}).
 
 Linux supporta, come estensione implementata dalle \acr{glibc}, anche una
 altra funzione, \func{fcloseall}, che serve a chiudere tutti i file, il suo
@@ -940,13 +940,14 @@ famiglia \func{printf}; le tre pi
   \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
 \end{functions}
 \noindent le prime due servono per stampare su file (lo standard output
-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}; per questo motivo si
-consiglia l'uso dell'alternativa:
+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 varibili e
+possibili buffer overflow; per questo motivo si consiglia l'uso
+dell'alternativa:
 \begin{prototype}{stdio.h}
-{snprintf(char *str, size\_t size, const char *format, ...);
+{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}
@@ -1013,11 +1014,12 @@ generale essa 
 \end{center}
 in cui i valori opzionali sono indicati fra parentesi, e prevedono la
 presenza, in questo ordine, di: uno specificatore per il parametro da usare
-(terminato da un \cmd{\$}, uno o più flag (riassunti in \tabref{}) che
-controllano il formato di stampa della conversione (riassunti in \tabref{}),
-uno specificatore di larghezza, eventualmente seguito (per i numeri in virgola
-mobile) da un specificatore di precisione, uno specificatore del tipo di dato
-(che ne indica la lunghezza).
+(terminato da un \cmd{\$}, uno o più flag (riassunti in
+\tabref{tab:file_format_flag}) che controllano il formato di stampa della
+conversione (riassunti in \tabref{tab:file_format_type}), uno specificatore di
+larghezza, eventualmente seguito (per i numeri in virgola mobile) da un
+specificatore di precisione, uno specificatore del tipo di dato (che ne indica
+la lunghezza).
 
 \begin{table}[htb]
   \centering
@@ -1026,18 +1028,20 @@ mobile) da un specificatore di precisione, uno specificatore del tipo di dato
     \textbf{Valore} & \textbf{Significato}\\
     \hline
     \hline
-    \cmd{\#}  & \\
-    \cmd{0}   & \\
-    \cmd{-}   & \\
-    \cmd{' '} & \\
-    \cmd{+}   & \\
+    \cmd{\#} & Chiede la conversione in forma alternativa. \\
+    \cmd{0}  & La conversione è riempita con zeri alla sinistra del valore.\\
+    \cmd{-}  & La conversione viene allineata a sinistra sul bordo del campo.\\
+    \cmd{' '}& Mette uno spazio prima di un numero con segno di valore 
+               positivo\\
+    \cmd{+}  & Mette sempre il segno ($+$ o $-$) prima di un numero.\\
     \hline
   \end{tabular}
   \caption{I valori dei flag per il formato di \func{printf}}
   \label{tab:file_format_flag}
 \end{table}
 
-
+Dettagli ulteriori sulle varie opzioni possono essere trovati nella man page
+di \func{printf} e nella documentazione delle \acr{glibc}.
 
 \begin{table}[htb]
   \centering
@@ -1046,23 +1050,74 @@ mobile) da un specificatore di precisione, uno specificatore del tipo di dato
     \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    \cmd{hh} & \\
-    \cmd{h}  & \\
-    \cmd{l}  & \\
-    \cmd{ll} & \\
-    \cmd{L}  & \\
-    \cmd{q}  & \\
-    \cmd{j}  & \\
-    \cmd{z}  & \\
-    \cmd{t}  & \\
+    \cmd{hh} & una conversione intera corriponde a un \type{char} con o senza
+               segno, o il puntatore per il numero dei parametri \cmd{n} è di 
+               tipo \type{char}.\\
+    \cmd{h}  & una conversione intera corriponde a uno \type{short} con o 
+               senza segno, o il puntatore per il numero dei parametri \cmd{n}
+               è di tipo \type{short}.\\
+    \cmd{l}  & una conversione intera corriponde a un \type{long} con o 
+               senza segno, o il puntatore per il numero dei parametri \cmd{n}
+               è di tipo \type{long}, o il carattere o la stringa seguenti
+               sono in formato esteso.\\ 
+    \cmd{ll} & una conversione intera corriponde a un \type{long long} con o 
+               senza segno, o il puntatore per il numero dei parametri \cmd{n}
+               è di tipo \type{long long}.\\
+    \cmd{L}  & una conversione in virgola mobile corrisponde a un
+               \type{double}.\\
+    \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 
+               \type{ssize\_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}}
   \label{tab:file_format_type}
 \end{table}
 
+Una versione alternativa delle funzioni di output formattato, che permettono
+di usare il puntatore ad una lista di argomenti (vedi \secref{proc_variadic}),
+sono le seguenti:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int vprintf(const char *format, va\_list ap)} Stampa su
+  \var{stdout} gli argomenti della lista \param{ap}, secondo il formato
+  specificato da \param{format}.
+  
+  \funcdecl{int vfprintf(FILE *stream, const char *format, va\_list ap)}
+  Stampa su \param{stream} gli argomenti della lista \param{ap}, secondo il
+  formato specificato da \param{format}.
+  
+  \funcdecl{int vsprintf(char *str, const char *format, va\_list ap)} Stampa
+  sulla stringa \param{str} gli argomenti della lista \param{ap}, secondo il
+  formato specificato da \param{format}.
 
+  \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
+tramite il parametro \param{ap}. Per poter far questo ovviamente la lista dei
+parametri dovrà essere opportunamente trattata (l'argomento è esaminato in
+\secref{sec:proc_variadic}), e dopo l'esecuzione della funzione l'argomento
+\param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un
+\macro{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
+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}
 
+Per evitare questi problemi con la stampa su stringhe di lunghezza
+insuffciente le \acr{glibc} supportano una estensione specifica GNU che alloca
+dinamicamente tutto lo spazio necessario; l'estensione si attiva al solito
+definendo \macro{\_GNU\_SOURCE}, 
 
 
 \subsection{Posizionamento su uno stream}