sono gestibili a basso livello con l'interfaccia standard unix, che ricorre
direttamente alle system call messe a disposizione dal kernel.
sono gestibili a basso livello con l'interfaccia standard unix, che ricorre
direttamente alle system call messe a disposizione dal kernel.
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
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.
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
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
legge è in modalità \textit{unbuffered}.} viene anche eseguito lo scarico di
tutti i buffer degli stream in scrittura.
legge è in modalità \textit{unbuffered}.} viene anche eseguito lo scarico di
tutti i buffer degli stream in scrittura.
\label{sec:file_ansi_base_func}
Esamineremo in questa sezione le funzioni base dell'interfaccia degli stream,
\label{sec:file_ansi_base_func}
Esamineremo in questa sezione le funzioni base dell'interfaccia degli stream,
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
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
estensioni che vedremo in seguito).
L'uso più comune di \func{freopen} è per redirigere uno dei tre file
estensioni che vedremo in seguito).
L'uso più comune di \func{freopen} è per redirigere uno dei tre file
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
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
Le \acr{glibc} supportano alcune estensioni, queste devono essere sempre
indicate dopo aver specificato il \param{mode} con uno dei valori di
Le \acr{glibc} supportano alcune estensioni, queste devono essere sempre
indicate dopo aver specificato il \param{mode} con uno dei valori di
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}
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}
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
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.
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
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
In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
di mezzo una bufferizzazione; per questo motivo lo standard ANSI C
In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
di mezzo una bufferizzazione; per questo motivo lo standard ANSI C
sufficiente a garantire la sincronizzazione.
Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione
sufficiente a garantire la sincronizzazione.
Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione
alcuna operazione di I/O sul file.
Uno stream viene chiuso con la funzione \funcd{fclose} il cui prototipo è:
alcuna operazione di I/O sul file.
Uno stream viene chiuso con la funzione \funcd{fclose} il cui prototipo è:
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
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
Linux supporta anche una altra funzione, \funcd{fcloseall}, come estensione
GNU implementata dalle \acr{glibc}, accessibile avendo definito
Linux supporta anche una altra funzione, \funcd{fcloseall}, come estensione
GNU implementata dalle \acr{glibc}, accessibile avendo definito
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
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
modalità di input/output non formattato:
\begin{enumerate*}
\item\textsl{binario} in cui legge/scrive un blocco di dati alla
modalità di input/output non formattato:
\begin{enumerate*}
\item\textsl{binario} in cui legge/scrive un blocco di dati alla
\item\textsl{a caratteri} in cui si legge/scrive un carattere alla
volta (con la bufferizzazione gestita automaticamente dalla libreria),
\item\textsl{a caratteri} in cui si legge/scrive un carattere alla
volta (con la bufferizzazione gestita automaticamente dalla libreria),
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
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
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
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
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
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
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
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
si passa un'espressione si possono avere effetti indesiderati.
Invece \func{fgetc} è assicurata essere sempre una funzione, per questo
si passa un'espressione si possono avere effetti indesiderati.
Invece \func{fgetc} è assicurata essere sempre una funzione, per questo
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
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
\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
\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
altre forma di I/O, dette funzioni hanno lo stesso nome della loro analoga
normale, con l'aggiunta dell'estensione \code{\_unlocked}.
altre forma di I/O, dette funzioni hanno lo stesso nome della loro analoga
normale, con l'aggiunta dell'estensione \code{\_unlocked}.
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
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 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
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
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
\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
\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
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
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
Una versione alternativa delle funzioni di output formattato, che permettono
di usare il puntatore ad una lista di argomenti (vedi
Una versione alternativa delle funzioni di output formattato, che permettono
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
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
\param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un
\code{va\_end(ap)} ma in Linux questo non è necessario).
\param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un
\code{va\_end(ap)} ma in Linux questo non è necessario).
\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à
\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à
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
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
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
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
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
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
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
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
\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
\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
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
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
Infine esistono anche circostanze in cui si vuole scartare tutto l'output
pendente; per questo si può usare \funcd{fpurge}, il cui prototipo è:
Infine esistono anche circostanze in cui si vuole scartare tutto l'output
pendente; per questo si può usare \funcd{fpurge}, il cui prototipo è: