X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filestd.tex;h=4526eb060e876555a25d3b878ad9470d86636332;hp=9d06757cd1d02302f4a8ff1c372a2c31913308f8;hb=388493a5b44babce8434148b87562aea0f046db7;hpb=c474f4307db945bc45287edd0ea4c2c29374d0ee diff --git a/filestd.tex b/filestd.tex index 9d06757..4526eb0 100644 --- a/filestd.tex +++ b/filestd.tex @@ -1,9 +1,9 @@ %% filestd.tex %% -%% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2005 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 "Prefazione", +%% Free Software Foundation; with the Invariant Sections being "Un preambolo", %% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the %% license is included in the section entitled "GNU Free Documentation %% License". @@ -42,7 +42,7 @@ basso livello, che non provvede nessuna forma di formattazione dei dati e nessuna forma di bufferizzazione per ottimizzare le operazioni di I/O. In \cite{APUE} Stevens descrive una serie di test sull'influenza delle -dimensioni del blocco di dati (il parametro \param{buf} di \func{read} e +dimensioni del blocco di dati (l'argomento \param{buf} di \func{read} e \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 @@ -86,7 +86,7 @@ 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 +come argomenti solo variabili di questo tipo, che diventa accessibile includendo l'header file \file{stdio.h}. @@ -585,11 +585,11 @@ pi meccanismo visto in sez.~\ref{sec:proc_var_passing}; per questo motivo se si passa un'espressione si possono avere effetti indesiderati. -Invece \func{fgetc} è assicurata essere sempre una funzione, per questo -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 nel tipo di argomento). +Invece \func{fgetc} è assicurata essere sempre una funzione, per questo motivo +la sua esecuzione normalmente è più lenta per via dell'overhead della +chiamata, ma è altresì possibile ricavarne l'indirizzo, che può essere passato +come argomento ad un altra funzione (e non si hanno i 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 @@ -636,11 +636,10 @@ loro prototipi sono: fine del file il valore di ritorno è \val{EOF}.} \end{functions} -Tutte queste funzioni scrivono sempre un byte alla volta, anche se -prendono come parametro un \ctyp{int} (che pertanto deve essere ottenuto -con un cast da un \ctyp{unsigned char}). Anche il valore di ritorno è -sempre un intero; in caso di errore o fine del file il valore di ritorno -è \val{EOF}. +Tutte queste funzioni scrivono sempre un byte alla volta, anche se prendono +come argomento un \ctyp{int} (che pertanto deve essere ottenuto con un cast da +un \ctyp{unsigned char}). Anche il valore di ritorno è sempre un intero; in +caso di errore o fine del file il valore di ritorno è \val{EOF}. Come nel caso dell'I/O binario con \func{fread} e \func{fwrite} le \acr{glibc} provvedono come estensione, per ciascuna delle funzioni precedenti, @@ -747,9 +746,10 @@ 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{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}.} + 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 + \cite{StS}.} Questa è una delle vulnerabilità più sfruttate per guadagnare accessi non autorizzati al sistema (i cosiddetti \textit{exploit}), basta @@ -856,28 +856,28 @@ newline, esattamente allo stesso modo di \func{fgets}, il suo prototipo 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 copiare la +argomento l'indirizzo del puntatore al buffer su cui si vuole copiare 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 +locale); come secondo argomento 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 +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 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 sez.~\ref{sec:proc_var_passing}). -Se si passa alla funzione l'indirizzo di un puntatore impostato a \val{NULL} -e \var{*n} è zero, la funzione provvede da sola all'allocazione della memoria +Se si passa alla funzione l'indirizzo di un puntatore impostato a \val{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 letta. Un esempio di codice può -essere il seguente: -\includecodesnip{listati/getline.c} -e per evitare memory leak\index{memory leak} occorre ricordarsi di liberare -\var{ptr} con una \func{free}. +essere il seguente: +\includecodesnip{listati/getline.c} +e per evitare memory leak\index{\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 dallo stream (quindi compreso il newline, ma non lo zero di @@ -926,13 +926,14 @@ L'output formattato viene eseguito con una delle 13 funzioni della famiglia \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 +\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}, 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 è: +possibili \textit{buffer overflow}\index{\textit{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 @@ -941,8 +942,8 @@ si consiglia l'uso dell'alternativa \funcd{snprintf}, il cui prototipo 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}, +deriva anche il numero degli argomenti 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}). @@ -1102,8 +1103,8 @@ sez.~\ref{sec:proc_variadic}), sono \funcd{vprintf}, \funcd{vfprintf} e \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 +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 \param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un \code{va\_end(ap)} ma in Linux questo non è necessario). @@ -1116,7 +1117,8 @@ scritti sulla stringa di destinazione: 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{buffer overflow}. +\noindent in modo da evitare possibili buffer +overflow\index{\textit{buffer~overflow}}. Per eliminare alla radice questi problemi, le \acr{glibc} supportano una @@ -1138,13 +1140,14 @@ sono: \bodydesc{Le funzioni ritornano il numero di caratteri stampati.} \end{functions} -Entrambe le funzioni prendono come parametro \param{strptr} che deve essere +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 \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{memory leak}. +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}}. Infine una ulteriore estensione GNU definisce le due funzioni \func{dprintf} e \func{vdprintf}, che prendono un file descriptor al posto dello stream. Altre @@ -1161,7 +1164,7 @@ famiglia \func{scanf}; fra queste le tre pi \headdecl{stdio.h} \funcdecl{int scanf(const char *format, ...)} Esegue una scansione di \file{stdin} cercando una corrispondenza di quanto letto con il formato dei dati specificato da \param{format}, ed effettua le relative - conversione memorizzando il risultato nei parametri seguenti. + conversione memorizzando il risultato negli argomenti seguenti. \funcdecl{int fscanf(FILE *stream, const char *format, ...)} Analoga alla precedente, ma effettua la scansione su \param{stream}. @@ -1185,11 +1188,11 @@ caratteristica. Le funzioni leggono i caratteri dallo stream (o dalla stringa) di input ed eseguono un confronto con quanto indicato in \param{format}, la sintassi di -questo parametro è simile a quella usata per l'analogo di \func{printf}, ma ci +questo argomento è simile a quella usata per l'analogo di \func{printf}, ma ci 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}. @@ -1227,7 +1230,7 @@ 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 + dispositivo\index{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 è @@ -1240,7 +1243,7 @@ esempio in VMS pu 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 +sostanzialmente le stesse operazioni, ma usano argomenti 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} @@ -1255,7 +1258,7 @@ stream sono \funcd{fseek} e \funcd{rewind} i cui prototipi sono: \end{functions} L'uso di \func{fseek} è del tutto analogo a quello di \func{lseek} per i file -descriptor, ed i parametri, a parte il tipo, hanno lo stesso significato; in +descriptor, e gli argomenti, a parte il tipo, hanno lo stesso significato; in particolare \param{whence} assume gli stessi valori già visti in sez.~\ref{sec:file_lseek}. La funzione restituisce 0 in caso di successo e -1 in caso di errore. La funzione \func{rewind} riporta semplicemente la @@ -1434,13 +1437,13 @@ coincidano con quelle su cui viene effettuato l'I/O. \const{\_IOFBF} & \textit{fully buffered}\\ \hline \end{tabular} - \caption{Valori del parametro \param{mode} di \func{setvbuf} - per l'impostazione delle modalità di bufferizzazione.} + \caption{Valori dell'argomento \param{mode} di \func{setvbuf} + per l'impostazione delle modalità di bufferizzazione.} \label{tab:file_stream_buf_mode} \end{table} Per evitare che \func{setvbuf} imposti il buffer basta passare un valore -\val{NULL} per \param{buf} e la funzione ignorerà il parametro \param{size} +\val{NULL} per \param{buf} e la funzione ignorerà l'argomento \param{size} usando il buffer allocato automaticamente dal sistema. Si potrà comunque modificare la modalità di bufferizzazione, passando in \param{mode} uno degli opportuni valori elencati in tab.~\ref{tab:file_stream_buf_mode}. Qualora si