Iniziato I/O formattato (finito quello di linea).
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 16 Dec 2001 15:35:02 +0000 (15:35 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 16 Dec 2001 15:35:02 +0000 (15:35 +0000)
filestd.tex
intro.tex
process.tex

index 14867d51305f3577f41127638d4698390ee0e167..92ad0a562bef15a366b2697065defef102d50fa8 100644 (file)
@@ -89,14 +89,14 @@ questi tre stream sono identificabili attraverso dei nomi simbolici
 definiti nell'header \file{stdio.h} che sono:
 
 \begin{itemize}
-\item \var{FILE * stdin} Lo \textit{standard input} cioè lo stream da
+\item \var{FILE *stdin} Lo \textit{standard input} cioè lo stream da
   cui il processo riceve ordinariamente i dati in ingresso. Normalmente
   è associato dalla shell all'input del terminale e prende i caratteri
   dalla tastiera.
-\item \var{FILE * stdout} Lo \textit{standard input} cioè lo stream su
+\item \var{FILE *stdout} Lo \textit{standard input} cioè lo stream su
   cui il processo invia ordinariamente i dati in uscita. Normalmente è
   associato dalla shell all'output del terminale e scrive sullo schermo.
-\item \var{FILE * stderr} Lo \textit{standard input} cioè lo stream su
+\item \var{FILE *stderr} Lo \textit{standard input} cioè lo stream su
   cui il processo è supposto inviare i messaggi di errore. Normalmente
   anch'esso è associato dalla shell all'output del terminale e scrive
   sullo schermo.
@@ -215,12 +215,11 @@ tre\footnote{\func{fopen} e \func{freopen} fanno parte dello standard
 prototipi sono:
 \begin{functions}
   \headdecl{stdio.h}
-  \funcdecl{FILE * fopen(const char * path, const char *mode)}
+  \funcdecl{FILE *fopen(const char *path, const char *mode)}
   Apre il file specificato da \param{path}.
-  \funcdecl{FILE * fdopen(int fildes, const char * mode)}
+  \funcdecl{FILE *fdopen(int fildes, const char *mode)}
   Associa uno stream al file descriptor \param{fildes}.
-  \funcdecl{FILE * freopen(const char * path, const char * mode, FILE *
-  stream)}
+  \funcdecl{FILE *freopen(const char *path, const char *mode, FILE *stream)}
   Apre il file specificato da \param{path} associandolo allo stream
   specificato da \param{stream}, se questo è già aperto prima lo chiude.
   
@@ -339,7 +338,7 @@ Una volta aperto lo stream, si pu
 alcuna operazione di I/O sul file.
 
 Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo è:
-\begin{prototype}{stdio.h}{int fclose(FILE * stream)}
+\begin{prototype}{stdio.h}{int fclose(FILE *stream)}
   Chiude lo stream \param{stream}. 
   
   \bodydesc{Restituisce 0 in caso di successo e \macro{EOF} in caso di errore,
@@ -364,12 +363,12 @@ prototipo 
   
   \bodydesc{Restituisce 0 se non ci sono errori ed \macro{EOF} altrimenti.}
 \end{prototype}
-la funzione esegue lo scarico dei dati bufferizzati in uscita e scarta quelli
-in ingresso, chiudendo tutti i file. Questa funzione è provvista solo per i
-casi di emergenza, quando si è verificato un errore ed il programma deve
-essere abortito, ma si vuole compiere qualche altra operazione dopo aver
-chiuso i file e prima di uscire (si ricordi quanto visto in
-\secref{sec:proc_exit}).
+\noindent la funzione esegue lo scarico dei dati bufferizzati in uscita
+e scarta quelli in ingresso, chiudendo tutti i file. Questa funzione è
+provvista solo per i casi di emergenza, quando si è verificato un errore
+ed il programma deve essere abortito, ma si vuole compiere qualche altra
+operazione dopo aver chiuso i file e prima di uscire (si ricordi quanto
+visto in \secref{sec:proc_exit}).
 
 
 \subsection{Lettura e scrittura su uno stream}
@@ -423,9 +422,9 @@ questi due flag possono essere riletti dalle funzioni:
   Controlla il flag di end-of-file di \param{stream}.
   \funcdecl{int ferror(FILE *stream)}
   Controlla il flag di errore di \param{stream}.
-
-  Entrambe le funzioni ritornano un valore diverso da zero se i relativi
-  flag sono settati. 
+  
+  \bodydesc{Entrambe le funzioni ritornano un valore diverso da zero se
+    i relativi flag sono settati.}
 \end{functions}
 \noindent si tenga presente comunque che la lettura di questi flag segnala
 soltanto che c'è stato un errore, o che si è raggiunta la fine del file in una
@@ -453,11 +452,11 @@ formattati. Le due funzioni che si usano per l'I/O binario sono:
 \begin{functions}
   \headdecl{stdio.h} 
   
-  \funcdecl{size\_t fread(void * ptr, size\_t size, size\_t nmemb, FILE
-    * stream)}
+  \funcdecl{size\_t fread(void *ptr, size\_t size, size\_t nmemb, FILE
+    *stream)}
   
-  \funcdecl{size\_t fwrite(const void * ptr, size\_t size, size\_t
-    nmemb, FILE * stream)}
+  \funcdecl{size\_t fwrite(const void *ptr, size\_t size, size\_t
+    nmemb, FILE *stream)}
   
   Rispettivamente leggono e scrivono \param{nmemb} elementi di dimensione
   \param{size} dal buffer \param{ptr} al file \param{stream}.
@@ -472,7 +471,7 @@ blocchi di dati binari in maniera compatta e veloce; un primo caso di uso
 tipico è quello in cui si salva un vettore (o un certo numero dei suoi
 elementi) con una chiamata del tipo:
 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-int WriteVect(FILE * stream, double * vec, size_t nelem) 
+int WriteVect(FILE *stream, double *vec, size_t nelem) 
 {
     int size, nread;
     size = sizeof(*vec);
@@ -552,11 +551,11 @@ gestione delle applicazioni multi-thread (si veda
 \begin{functions}
   \headdecl{stdio.h} 
   
-  \funcdecl{size\_t fread\_unlocked(void * ptr, size\_t size, size\_t
-    nmemb, FILE * stream)}
+  \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)}
+  \funcdecl{size\_t fwrite\_unlocked(const void *ptr, size\_t size,
+    size\_t nmemb, FILE *stream)}
   
   \bodydesc{Le funzioni sono identiche alle analoghe \func{fread} e
     \func{fwrite} ma non acquisiscono il lock implicito sullo stream.}
@@ -614,6 +613,7 @@ byte restituiscono un carattere in formato esteso (cio
 \type{wint\_t}, il loro prototipo è:
 \begin{functions}
   \headdecl{stdio.h} 
+  \headdecl{wchar.h} 
   
   \funcdecl{wint\_t getwc(FILE *stream)} Legge un carattere esteso da
   \param{stream}. In genere è implementata come una macro.
@@ -653,9 +653,10 @@ sempre un intero; in caso di errore o fine del file il valore di ritorno
 è \macro{EOF}.
 
 Come nel caso dell'I/O binario le \acr{glibc} provvedono per ciascuna
-delle funzioni precedenti una seconda funzione, il cui nome è ottenuto
-aggiungendo un \func{\_unlocked}, che esegue esattamente le stesse
-operazioni evitando però il lock implicito dello stream.
+delle funzioni precedenti, come estensione GNU, una seconda funzione, il
+cui nome è ottenuto aggiungendo un \func{\_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 \type{int}); i
@@ -692,11 +693,11 @@ lettura si chiama \func{ungetc} ed il suo prototipo 
   \bodydesc{La funzione ritorna \param{c} in caso di successo e
   \macro{EOF} in caso di errore.}
 \end{prototype}
-benché lo standard ANSI C preveda che l'operazione possa essere ripetuta
-per un numero arbitrario di caratteri, alle implementazioni è richiesto
-di garantire solo un livello; questo è quello che fa la \acr{glibc}, che
-richiede che avvenga un'altra operazione fra due \func{ungetc}
-successive.
+\noindent benché lo standard ANSI C preveda che l'operazione possa
+essere ripetuta per un numero arbitrario di caratteri, alle
+implementazioni è richiesto di garantire solo un livello; questo è
+quello che fa la \acr{glibc}, che richiede che avvenga un'altra
+operazione fra due \func{ungetc} successive.
 
 Non è necessario che il carattere che si manda indietro sia l'ultimo che
 si è letto, e non è necessario neanche avere letto nessun carattere
@@ -722,36 +723,281 @@ scartati.
 \subsection{Input/output di linea}
 \label{sec:file_line_io}
 
-La terza ed ultima modalità di input/output non formattato è quello di
+La terza ed ultima modalità di input/output non formattato è quella di
 linea, in cui legge o scrive una riga alla volta; questa è una modalità
 molto usata per l'I/O da terminale, ma che presenta le caratteristiche
 più controverse.
 
-Le funzioni per leggere una linea sono sostanzialmente due, \func{gets} e
-\func{fgets}, i cui rispettivi prototipi sono:
+Le funzioni previste dallo standard ANSI C per leggere una linea sono
+sostanzialmente due, \func{gets} e \func{fgets}, i cui rispettivi
+prototipi sono:
 \begin{functions}
   \headdecl{stdio.h} 
   
-  \funcdecl{char * gets(char * string)} Scrive su \param{string} una
+  \funcdecl{char *gets(char *string)} Scrive su \param{string} una
   linea letta da \var{stdin}.
   
-  \funcdecl{char * fgets(char * string, int size, FILE *stream)}
+  \funcdecl{char *fgets(char *string, int size, FILE *stream)}
   Scrive su \param{string} la linea letta da \param{stream} per un
   massimo di \param{size} byte.
   
-  \bodydesc{Le funzioni restituiscono della stringa letta o \macro{NULL}
-    in caso di errore.}
+  \bodydesc{Le funzioni restituiscono l'indirizzo \param{string} in caso
+    di successo o \macro{NULL} in caso di errore.}
 \end{functions}
 
+Entrambe le funzioni effettuano la lettura (dal file specificato
+\func{fgets}, dallo standard input \func{gets}) di una linea di
+caratteri (terminata dal carattere \textit{newline}, \verb|\n|), ma
+\func{gets} sostituisce \verb|\n| con uno zero, mentre \func{fgets}
+aggiunge uno zero dopo il \textit{newline}, che resta dentro la
+stringa. Se la lettura incontra la fine del file (o c'è un errore) viene
+restituito un \macro{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}, con sovrascrittura della memoria del processo
+adiacente al buffer. 
+
+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
+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 ecceduta in lettura. La funzione legge fino ad un massimo di
+\param{size} caratteri (newline compreso), ed aggiunge uno zero di
+terminazione; questo comporta che la stringa possa essere al massimo di
+\var{size-1} caratteri.  Se la linea eccede la dimensione del buffer
+verranno letti solo \var{size-1} caratteri, ma la stringa sarà sempre
+terminata correttamente con uno zero finale; sarà possibile leggere i
+restanti caratteri in una chiamata 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
+rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int puts(const char *string)} Scrive su \var{stdout} la
+  linea \param{string}.
+  
+  \funcdecl{int fputs(const char *string, FILE *stream)} Scrive su
+  \param{stream} la linea \param{string}.
+  
+  \bodydesc{Le funzioni restituiscono un valore non negativo in caso di
+    successo o \macro{EOF} in caso di errore.}
+\end{functions}
+
+Dato che in questo caso si scrivono i dati in uscita \func{puts} non ha
+i problemi di \func{gets} ed è in genere la forma più immediata per
+scrivere messaggi sullo standard output; la funzione prende una stringa
+terminata da uno zero ed aggiunge automaticamente un newline. La
+differenza con \func{fputs} (a parte la possibilità di specificare un
+file diverso da \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:
+\begin{functions}
+  \headdecl{whar.h} 
+  \funcdecl{wchar\_t *fgetws(wchar\_t *ws, int n, FILE *stream)}
+  Legge un massimo di \param{n} caratteri estesi dal file
+  \param{stream} al buffer \param{ws}.
+  
+  \funcdecl{int fputws(const wchar\_t *ws, FILE *stream)} Scrive la
+  linea \param{ws} di caratteri estesi sul file \param{stream}.
+  
+  \bodydesc{Le funzioni ritornano rispettivamente \param{ws} o un numero
+    non negativo in caso di successo e \macro{NULL} o \macro{EOF} in
+    caso di errore o fine del file.}
+\end{functions}
+\noindent il comportamento è identico a quello di \func{fgets} e
+\func{fputs} solo che tutto (numero di caratteri massimo, terminatore
+della stringa, newline) è espresso in termini di caratteri estesi
+anziché di 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 \func{\_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 abbiamo visto, le funzioni di lettura per l'input/output di linea
+previste dallo standard ANSI C presentano svariati inconvenienti. Benché
+\func{fgets} non abbia i gravissimi problemi di \func{gets}, può
+comunque dare risultati ambigui se l'input contiene degli zeri; questi
+infatti saranno scritti sul buffer di uscita e la stringa in output
+apparirà come più corta dei bytes effettivamente letti. Questa è una
+condizione che è sempre possibile controllare (deve essere presente un
+newline prima della effettiva conclusione della stringa presente nel
+buffer), ma a costo di una complicazione ulteriore della logica del
+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 è:
+\begin{prototype}{stdio.h}
+  {ssize\_t getline(char **buffer, size\_t *n, FILE *stream)} Legge una
+  linea dal file \param{stream} sul buffer indicato da \param{buffer}
+  riallocandolo se necessario (l'indirizzo del buffer e la sua
+  dimensione vengono sempre riscritte).
+
+  \bodydesc{La funzione ritorna il numero di caratteri letti in caso di
+  successo e -1 in caso di errore o di raggiungimento della fine del
+  file.}
+\end{prototype}
+
+La funzione permette di eseguire una lettura senza doversi preoccupare
+della eventuale lunghezza eccessiva della stringa da leggere. Essa
+prende come primo parametro l'indirizzo del puntatore al buffer su cui
+si vuole leggere la linea. Quest'ultimo \emph{deve} essere stato
+allocato in precedenza con una \func{malloc} (non si può passare
+l'indirizzo di un puntatore ad una variabile locale); come secondo
+parametro la funzione vuole l'indirizzo della variabile contenente le
+dimensioni del buffer suddetto.
+
+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 come per entrambi i parametri si siano
+usati dei \textit{value result argument}, passando dei puntatori anzichè
+i valori delle variabili, secondo la tecnica spiegata in
+\secref{sec:proc_var_passing}).
+
+Se si passa alla funzione l'indirizzo ad un puntatore settato a
+\macro{NULL} e \var{*n} è zero, la funzione provvede da sola
+all'allocazione della memoria necessaria a contenere la linea. In tutti
+i casi si ottiene dalla funzione un puntatore all'inizio del testo della
+linea. Un esempio di codice può essere il seguente:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+    size_t n = 0; 
+    char *ptr = NULL;
+    int nread;
+    FILE * file;
+    ...    
+    nread = getline(&ptr, &n, file);
+\end{lstlisting}
+e per evitare 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
+terminazione); questo permette anche di distinguere eventuali zeri letti
+dallo stream da quello inserito dalla funzione per terminare la linea.
+Se si è alla fine del file e non si è potuto leggere nulla o c'è stato
+un errore la funzione restituisce -1.
+
+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 è:
+\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
+  carattere di newline come separatore di linea.
+\end{prototype}
+
+Il comportamento di \func{getdelim} è identico a quello di
+\func{getline} (che può essere implementata da questa passando
+\verb|'\n'| come valore di \param{delim}).
 
 
 \subsection{Input/output formattato}
 \label{sec:file_formatted_io}
 
+L'ultima modalità di input/output è quella formattata, che è una delle
+caratteristiche più utilizzate delle librerie standard del C; in genere
+questa è la modalità in cui si esegue normalmente l'output su terminale
+poichè 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:
+\begin{functions}
+  \headdecl{stdio.h} 
+  \funcdecl{int printf(const char *format, ...)} Stampa su \var{stdout}
+  gli argomenti, secondo il formato specificato da \param{format}.
+  
+  \funcdecl{int fprintf(FILE *stream, const char *format, ...)}  Stampa
+  su \param{stream} gli argomenti, secondo il formato specificato da
+  \param{format}.
+  
+  \funcdecl{int sprintf(char *str, const char *format, ...)} Stampa
+  sulla stringa \param{str} gli argomenti, secondo il formato
+  specificato da \param{format}.
+
+  \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
+\end{functions}
+\noindent le prime due servono per stampare su file (lo standard output
+o quallo 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:
+\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 variabile
+\param{format} che indica le conversioni da fare ed il numero di
+parametri che dovranno essere specificati a seguire.
+
+
+
+
+
+
+
+
+
+
 
 \subsection{Posizionamento su uno stream}
 \label{sec:file_fseek}
 
+Come per i file descriptor è possibile spostarsi all'interno del file
+anche con gli stream. 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 problema è alcune delle funzioni
+usate per il riposizionamento sugli stream (come \func{ftell} e
+\func{fseek}) originano dalle prime versioni di unix in cui questo tipo
+non era ancora stato definito, e che in altri sistemi non è detto che la
+posizione su un file venga sempre rappresentata con un numero di
+caratteri (ad esempio in VMS può essere rappresentata come numero di
+record, e offset rispetto al record corrente).
+
+Tutto questo comporta la presenza di diverse funzioni che seguono
+sostanzialmente le stesse operazioni, ma usano parametri di tipo
+diverso. Le funzioni tradizionali usate per il riposizionamento della
+posizione in uno stream sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int fseek(FILE *stream, long offset, int whence)} Sposta la
+  posizione nello stream secondo quanto specicato tramite \param{offset}
+  e \param{whence}.  
+
+  \funcdecl{long ftell(FILE *stream)} Legge la posizione attuale nello stream.
+  
+  \funcdecl{void rewind(FILE *stream)} Riporta la posizione nello stream
+  all'inizio del file.
+\end{functions}
+
+
+
 
 
 \section{Funzioni avanzate}
@@ -779,10 +1025,10 @@ stream; questo pu
 \func{\_\_fwritable} i cui prototipi sono:
 \begin{functions}
   \headdecl{stdio\_ext.h}
-  \funcdecl{int \_\_freadable (FILE * stream)}
+  \funcdecl{int \_\_freadable (FILE *stream)}
   Restituisce un valore diverso da zero se \param{stream} consente la lettura.
 
-  \funcdecl{int \_\_fwritable(FILE * stream)}  
+  \funcdecl{int \_\_fwritable(FILE *stream)}  
   Restituisce un valore diverso da zero se \param{stream} consente la
   scrittura.
 \end{functions}
@@ -791,11 +1037,11 @@ 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)}
+  \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)}  
+  \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}
@@ -834,16 +1080,16 @@ pesantemente dalle richieste necessarie per garantirne l'uso coi thread.
 \begin{functions}
   \headdecl{stdio.h}
   
-  \funcdecl{void flockfile(FILE * stream)} Esegue l'acquisizione del
+  \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
+  \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
+  \funcdecl{void funlockfile(FILE *stream)} Rilascia il lock dello
   stream \param{stream}.
 \end{functions}
 
index f352fd7cd9f76a68cccdedf54256e003524df07e..0e6ce76fe013b5c52387e6e36d0c814cf399a8eb 100644 (file)
--- a/intro.tex
+++ b/intro.tex
@@ -497,6 +497,13 @@ Le macro disponibili per i vari standard sono le seguenti:
   data la precedenza a POSIX.
 \end{basedescript}
 
+In particolare è da sottolineare che le \acr{glibc} supportano alcune
+estensioni specifiche GNU, che non sono comprese in nessuno degli
+standard citati. Per poterle utilizzare esse devono essere attivate
+esplicitamente definendo la macro \macro{\_GNU\_SOURCE} prima di
+includere i vari header file.
+
+
 \subsection{Gli standard di Linux}
 \label{sec:intro_linux_std}
 
index d7d22ccf329b1e7724503646517451a47384d7a9..f29f993320cbda410a2f40761726231514c56fad 100644 (file)
@@ -603,14 +603,14 @@ analoghe system call a cui fanno da interfaccia (ad esempio per implementare
 una propria versione di \func{malloc}. Le funzioni sono:
 \begin{functions}
   \headdecl{unistd.h}
-  \funcdecl{int brk(void * end\_data\_segment)}
+  \funcdecl{int brk(void *end\_data\_segment)}
   Sposta la fine del segmento dei dati all'indirizzo specificato da
   \var{end\_data\_segment}.
   
   La funzione restituisce 0 in caso di successo e -1 in caso di
     fallimento, nel qual caso \var{errno} viene settata a \macro{ENOMEM}.
 
-  \funcdecl{void * sbrk(ptrdiff\_t increment)} Incrementa lo spazio dati di un
+  \funcdecl{void *sbrk(ptrdiff\_t increment)} Incrementa lo spazio dati di un
   programma di \var{increment}. Un valore zero restituisce l'attuale posizione
   della fine del segmento dati.
   
@@ -1168,6 +1168,17 @@ informazioni sulle dimensioni delle strutture degli indirizzi utilizzate,
 viene usato questo meccanismo.
 
 
+\subsection{Il passaggio di un numero variabile di argomenti}
+\label{sec:proc_variadic}
+
+Come vedremo nei capitoli successivi, non sempre è possibile specificare
+un numero fisso di parametri per una funzione.  Lo standard ISO C
+prevede la possibilità di definire delle \textit{varadic function} che
+abbiano un numero variabile di argomenti, ma non provvede nessun
+meccanismo con cui queste funzioni possono accedere a questi argomenti.
+
+(NdT il resto è da fare).
+
 \subsection{Potenziali problemi con le variabili automatiche}
 \label{sec:proc_auto_var}