X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filestd.tex;h=9d06757cd1d02302f4a8ff1c372a2c31913308f8;hp=0a623a06a95597bedffe165a74c99dcfe1bf7ca3;hb=c474f4307db945bc45287edd0ea4c2c29374d0ee;hpb=687f101ae37d793ffda23c39ca8735e127b5fc9d diff --git a/filestd.tex b/filestd.tex index 0a623a0..9d06757 100644 --- a/filestd.tex +++ b/filestd.tex @@ -21,7 +21,7 @@ dell'interfaccia nell'ultima sezione. \section{Introduzione} \label{sec:file_stream_intro} -Come visto in \capref{cha:file_unix_interface} le operazioni di I/O sui file +Come visto in cap.~\ref{cha:file_unix_interface} le operazioni di I/O sui file sono gestibili a basso livello con l'interfaccia standard unix, che ricorre direttamente alle system call messe a disposizione dal kernel. @@ -67,8 +67,8 @@ A parte i dettagli legati alla gestione delle operazioni di lettura e scrittura (sia per quel che riguarda la bufferizzazione, che le formattazioni), i file stream restano del tutto equivalenti ai file descriptor (sui quali sono basati), ed in particolare continua a valere quanto visto in -\secref{sec:file_sharing} a proposito dell'accesso condiviso ed in -\secref{sec:file_access_control} per il controllo di accesso. +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|)} @@ -93,7 +93,7 @@ includendo l'header file \file{stdio.h}. \subsection{Gli stream standard} \label{sec:file_std_stream} -Ai tre file descriptor standard (vedi \secref{sec:file_std_descr}) +Ai tre file descriptor standard (vedi sez.~\ref{sec:file_std_descr}) aperti per ogni processo, corrispondono altrettanti stream, che rappresentano i canali standard di input/output prestabiliti; anche questi tre stream sono identificabili attraverso dei nomi simbolici @@ -200,7 +200,7 @@ comporta l'accesso al kernel\footnote{questo vuol dire che lo stream da cui si legge è in modalità \textit{unbuffered}.} viene anche eseguito lo scarico di tutti i buffer degli stream in scrittura. -In \secref{sec:file_buffering_ctrl} vedremo come la libreria definisca delle +In sez.~\ref{sec:file_buffering_ctrl} vedremo come la libreria definisca delle opportune funzioni per controllare le modalità di bufferizzazione e lo scarico dei dati. @@ -210,7 +210,7 @@ dei dati. \label{sec:file_ansi_base_func} Esamineremo in questa sezione le funzioni base dell'interfaccia degli stream, -analoghe a quelle di \secref{sec:file_base_func} per i file descriptor. In +analoghe a quelle di sez.~\ref{sec:file_base_func} per i file descriptor. In particolare vedremo come aprire, leggere, scrivere e cambiare la posizione corrente in uno stream. @@ -245,11 +245,11 @@ Le funzioni che si possono usare per aprire uno stream sono solo tre: Normalmente la funzione che si usa per aprire uno stream è \func{fopen}, essa apre il file specificato nella modalità specificata da \param{mode}, che è una stringa che deve iniziare con almeno uno dei -valori indicati in \tabref{tab:file_fopen_mode} (sono possibili varie +valori indicati in tab.~\ref{tab:file_fopen_mode} (sono possibili varie estensioni che vedremo in seguito). L'uso più comune di \func{freopen} è per redirigere uno dei tre file -standard (vedi \secref{sec:file_std_stream}): il file \param{path} viene +standard (vedi sez.~\ref{sec:file_std_stream}): il file \param{path} viene associato a \param{stream} e se questo è uno stream già aperto viene preventivamente chiuso. @@ -294,7 +294,7 @@ possono essere aperti con le funzioni delle librerie standard del C. \end{table} In realtà lo standard ANSI C prevede un totale di 15 possibili valori -diversi per \param{mode}, ma in \tabref{tab:file_fopen_mode} si sono +diversi per \param{mode}, ma in tab.~\ref{tab:file_fopen_mode} si sono riportati solo i sei valori effettivi, ad essi può essere aggiunto pure il carattere \texttt{b} (come ultimo carattere o nel mezzo agli altri per le stringhe di due caratteri) che in altri sistemi operativi serve a @@ -304,7 +304,7 @@ compatibilit Le \acr{glibc} supportano alcune estensioni, queste devono essere sempre indicate dopo aver specificato il \param{mode} con uno dei valori di -\tabref{tab:file_fopen_mode}. L'uso del carattere \texttt{x} serve per +tab.~\ref{tab:file_fopen_mode}. L'uso del carattere \texttt{x} serve per evitare di sovrascrivere un file già esistente (è analoga all'uso dell'opzione \const{O\_EXCL} in \func{open}), se il file specificato già esiste e si aggiunge questo carattere a \param{mode} la \func{fopen} @@ -319,15 +319,15 @@ opportune funzioni di conversione in lettura e scrittura. Nel caso si usi \func{fdopen} i valori specificati da \param{mode} devono essere compatibili con quelli con cui il file descriptor è stato aperto. Inoltre i modi \cmd{w} e \cmd{w+} non troncano il file. La posizione nello -stream viene impostata a quella corrente nel file descriptor, e le variabili di -errore e di fine del file (vedi \secref{sec:file_io}) sono cancellate. Il file -non viene duplicato e verrà chiuso alla chiusura dello stream. +stream viene impostata a quella corrente nel file descriptor, e le variabili +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 -\secref{sec:file_ownership} ed avranno i permessi di accesso impostati al +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 \val{0666}) modificato secondo il valore di \acr{umask} per il processo (si -veda \secref{sec:file_umask}). +veda sez.~\ref{sec:file_umask}). In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è di mezzo una bufferizzazione; per questo motivo lo standard ANSI C @@ -345,7 +345,7 @@ un'operazione nominalmente nulla come \code{fseek(file, 0, SEEK\_CUR)} sufficiente a garantire la sincronizzazione. Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione -(si veda \secref{sec:file_buffering_ctrl}) fintanto che non si è effettuato +(si veda sez.~\ref{sec:file_buffering_ctrl}) fintanto che non si è effettuato alcuna operazione di I/O sul file. Uno stream viene chiuso con la funzione \funcd{fclose} il cui prototipo è: @@ -364,7 +364,7 @@ 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}). +una \func{sync} (vedi sez.~\ref{sec:file_sync}). Linux supporta anche una altra funzione, \funcd{fcloseall}, come estensione GNU implementata dalle \acr{glibc}, accessibile avendo definito @@ -379,7 +379,7 @@ 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}). +visto in sez.~\ref{sec:proc_exit}). \subsection{Lettura e scrittura su uno stream} @@ -391,12 +391,12 @@ scrittura sui file. Sono infatti previste ben tre diverse modalit modalità di input/output non formattato: \begin{enumerate*} \item\textsl{binario} in cui legge/scrive un blocco di dati alla - volta, vedi \secref{sec:file_binary_io}. + volta, vedi sez.~\ref{sec:file_binary_io}. \item\textsl{a caratteri} in cui si legge/scrive un carattere alla volta (con la bufferizzazione gestita automaticamente dalla libreria), - vedi \secref{sec:file_char_io}. + vedi sez.~\ref{sec:file_char_io}. \item\textsl{di linea} in cui si legge/scrive una linea alla volta (terminata - dal carattere di newline \verb|'\n'|), vedi \secref{sec:file_line_io}. + dal carattere di newline \verb|'\n'|), vedi sez.~\ref{sec:file_line_io}. \end{enumerate*} ed inoltre la modalità di input/output formattato. @@ -417,7 +417,7 @@ Siccome la condizione di end-of-file il problema di come distinguerla da un errore effettivo; basarsi solo sul valore di ritorno della funzione e controllare il valore di \var{errno} infatti non basta, dato che quest'ultimo potrebbe essere stato impostato in -una altra occasione, (si veda \secref{sec:sys_errno} per i dettagli del +una altra occasione, (si veda sez.~\ref{sec:sys_errno} per i dettagli del funzionamento di \var{errno}). Per questo motivo tutte le implementazioni delle librerie standard @@ -451,7 +451,7 @@ la funzione \funcd{clearerr}, il cui prototipo corretta la causa di un errore per evitare di mantenere i flag attivi, così da poter rilevare una successiva ulteriore condizione di errore. Di questa funzione esiste una analoga \func{clearerr\_unlocked} che non esegue il blocco -dello stream (vedi \secref{sec:file_stream_thread}). +dello stream (vedi sez.~\ref{sec:file_stream_thread}). \subsection{Input/output binario} @@ -535,7 +535,7 @@ eventuali differenze. 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 +applicazioni multi-thread (si veda sez.~\ref{sec:file_stream_thread} per i dettagli), i loro prototipi sono: \begin{functions} \headdecl{stdio.h} @@ -582,7 +582,7 @@ differenza viene implementata con una macro, per cui occorre stare attenti a cosa le si passa come argomento, infatti \param{stream} può essere valutato più volte nell'esecuzione, e non viene passato in copia con il -meccanismo visto in \secref{sec:proc_var_passing}; per questo motivo se +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 @@ -708,7 +708,7 @@ successivamente. Infine si tenga presente che \func{ungetc} non altera il contenuto del file, ma opera esclusivamente sul buffer interno. Se si esegue una qualunque delle operazioni di riposizionamento (vedi -\secref{sec:file_fseek}) i caratteri rimandati indietro vengono +sez.~\ref{sec:file_fseek}) i caratteri rimandati indietro vengono scartati. @@ -821,7 +821,7 @@ 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 +implicito dello stream (vedi sez.~\ref{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}. @@ -868,7 +868,7 @@ scritta subito, altrimenti il buffer viene allargato usando 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}). +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 @@ -994,7 +994,7 @@ La stringa vengono passati invariati all'output, e da direttive di conversione, in cui devono essere sempre presenti il carattere \texttt{\%}, che introduce la direttiva, ed uno degli specificatori di conversione (riportati in -\tabref{tab:file_format_spec}) che la conclude. +tab.~\ref{tab:file_format_spec}) che la conclude. \begin{table}[htb] \centering @@ -1031,13 +1031,13 @@ questo ordine: \begin{itemize*} \item uno specificatore del parametro da usare (terminato da un \val{\$}), \item uno o più flag (i cui valori possibili sono riassunti in - \tabref{tab:file_format_flag}) che controllano il formato di stampa della + tab.~\ref{tab:file_format_flag}) che controllano il formato di stampa della conversione, \item uno specificatore di larghezza (un numero decimale), eventualmente seguito (per i numeri in virgola mobile) da un specificatore di precisione (un altro numero decimale), \item uno specificatore del tipo di dato, che ne indica la dimensione (i cui - valori possibili sono riassunti in \tabref{tab:file_format_type}). + valori possibili sono riassunti in tab.~\ref{tab:file_format_type}). \end{itemize*} @@ -1081,7 +1081,7 @@ manuale di \func{printf} e nella documentazione delle \acr{glibc}. 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 \funcd{vprintf}, \funcd{vfprintf} e +sez.~\ref{sec:proc_variadic}), sono \funcd{vprintf}, \funcd{vfprintf} e \funcd{vsprintf}, i cui prototipi sono: \begin{functions} \headdecl{stdio.h} @@ -1104,7 +1104,7 @@ di usare il puntatore ad una lista di argomenti (vedi 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 +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). @@ -1140,7 +1140,7 @@ sono: \end{functions} Entrambe le funzioni prendono come parametro \param{strptr} che deve essere l'indirizzo di un puntatore ad una stringa di caratteri, in cui verrà -restituito (si ricordi quanto detto in \secref{sec:proc_var_passing} a +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 @@ -1257,7 +1257,7 @@ stream sono \funcd{fseek} e \funcd{rewind} i cui prototipi sono: 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 particolare \param{whence} assume gli stessi valori già visti in -\secref{sec:file_lseek}. La funzione restituisce 0 in caso di successo e -1 +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 posizione corrente all'inizio dello stream, ma non esattamente equivalente ad una \code{fseek(stream, 0L, SEEK\_SET)} in quanto vengono cancellati anche i @@ -1376,7 +1376,7 @@ operazione ci fosse comunque stata. \subsection{Il controllo della bufferizzazione} \label{sec:file_buffering_ctrl} -Come accennato in \secref{sec:file_buffering} le librerie definiscono una +Come accennato in sez.~\ref{sec:file_buffering} le librerie definiscono una serie di funzioni che permettono di controllare il comportamento degli stream; se non si è specificato nulla, la modalità di buffering viene decisa autonomamente sulla base del tipo di file sottostante, ed i buffer vengono @@ -1443,7 +1443,7 @@ 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} 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 \tabref{tab:file_stream_buf_mode}. Qualora si +opportuni valori elencati in tab.~\ref{tab:file_stream_buf_mode}. Qualora si specifichi la modalità non bufferizzata i valori di \param{buf} e \param{size} vengono sempre ignorati. @@ -1511,7 +1511,7 @@ funzione \funcd{\_flushlbf}, il cui prototipo Si ricordi comunque che lo scarico dei dati dai buffer effettuato da queste funzioni non comporta la scrittura di questi su disco; se si vuole che il kernel dia effettivamente avvio alle operazioni di scrittura su disco occorre -usare \func{sync} o \func{fsync} (si veda~\secref{sec:file_sync}). +usare \func{sync} o \func{fsync} (si veda~sez.~\ref{sec:file_sync}). Infine esistono anche circostanze in cui si vuole scartare tutto l'output pendente; per questo si può usare \funcd{fpurge}, il cui prototipo è: