X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filestd.tex;h=15da6a791ca905e6b3849abb42896600675fdda7;hp=db18e5d454230071849b1a7776ca788747c48d57;hb=ff76d56c6a2c280cbe4f153173488871d7b12336;hpb=66e83c068629844f84fe4a0d44b382f756c9ef32 diff --git a/filestd.tex b/filestd.tex index db18e5d..15da6a7 100644 --- a/filestd.tex +++ b/filestd.tex @@ -1,6 +1,6 @@ %% filestd.tex %% -%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2007 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", @@ -8,6 +8,7 @@ %% license is included in the section entitled "GNU Free Documentation %% License". %% + \chapter{I file: l'interfaccia standard ANSI C} \label{cha:files_std_interface} @@ -37,12 +38,13 @@ costituire il nucleo\footnote{queste funzioni sono state implementate la prima \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. 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 @@ -69,24 +71,26 @@ formattazioni), i file stream restano del tutto equivalenti ai file descriptor (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 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}. @@ -113,14 +117,13 @@ definiti nell'header \file{stdio.h} che sono: 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} @@ -256,8 +259,8 @@ preventivamente chiuso. 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 @@ -268,21 +271,23 @@ possono essere aperti con le funzioni delle librerie standard del C. \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à. \\ @@ -324,10 +329,11 @@ di errore e di fine del file (vedi sez.~\ref{sec:file_io}) sono cancellate. Il 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 +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 \acr{umask} per il processo (si -veda sez.~\ref{sec:file_umask}). +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 @@ -422,7 +428,7 @@ funzionamento di \var{errno}). 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 @@ -585,11 +591,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 +642,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, @@ -746,20 +751,19 @@ dentro la stringa. Se la lettura incontra la fine del file (o c' 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 @@ -857,18 +861,18 @@ 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 -\index{\textit{value~result~argument}}\textit{value result argument}, passando -dei puntatori anziché i valori delle variabili, secondo la tecnica spiegata in +dimensione ed il nuovo puntatore vengono restituiti indietro (si noti infatti +come per entrambi gli argomenti si siano usati dei +\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 @@ -877,7 +881,7 @@ 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{\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 @@ -932,7 +936,7 @@ 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{\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} @@ -943,8 +947,8 @@ motivo 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 \index{variadic} \textit{variadic}, prendendo un numero di argomenti variabile che dipende appunto da quello che si è specificato in \param{format}). @@ -1103,9 +1107,9 @@ sez.~\ref{sec:proc_variadic}), sono \funcd{vprintf}, \funcd{vfprintf} e \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 +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 \param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un \code{va\_end(ap)} ma in Linux questo non è necessario). @@ -1118,8 +1122,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{\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 @@ -1141,14 +1145,15 @@ 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 \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 @@ -1165,7 +1170,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}. @@ -1189,11 +1194,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}. @@ -1230,9 +1235,9 @@ all'interno di un file per effettuare operazioni di lettura o scrittura in un 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 @@ -1244,7 +1249,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} @@ -1259,7 +1264,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 @@ -1420,7 +1425,7 @@ Dato che la procedura di allocazione manuale (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. @@ -1438,13 +1443,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 @@ -1617,3 +1622,27 @@ che pu %%% 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