%% fileio.tex (merge fileunix.tex - filestd.tex)
%%
-%% Copyright (C) 2000-2013 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2014 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",
Come si può notare alla fine il collegamento che consente di porre in
relazione i file ed i processi è effettuato attraverso i dati mantenuti nella
-struttura \kstruct{files\_struct} essa infatti contiene alcune informazioni
+struttura \kstruct{files\_struct}, essa infatti contiene alcune informazioni
essenziali come:
\begin{itemize*}
\item i flag relativi ai file aperti dal processo.
\itindex{standard~output} \textit{standard
output}.\\
\const{STDERR\_FILENO} & \textit{file descriptor} dello \textit{standard
- error}.\\
+ error}.\\
\hline
\end{tabular}
\caption{Costanti definite in \headfile{unistd.h} per i file standard.}
\begin{errlist}
\item[\errcode{EINVAL}] \param{whence} non è un valore valido.
\item[\errcode{EOVERFLOW}] \param{offset} non può essere rappresentato nel
- \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo.
tipo \type{off\_t}.
+ \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo.
\end{errlist}
ed inoltre \errval{EBADF} nel suo significato generico.}
\end{funcproto}
{La funzione ritorna il numero di byte scritti in caso di successo e $-1$ per
un errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EAGAIN}] ci siq sarebbe bloccati, ma il file era aperto in
+ \item[\errcode{EAGAIN}] ci si sarebbe bloccati, ma il file era aperto in
modalità \const{O\_NONBLOCK}.
\item[\errcode{EFBIG}] si è cercato di scrivere oltre la dimensione massima
consentita dal filesystem o il limite per le dimensioni dei file del
avviene spesso per i database, è assicurarsi che i dati raggiungano il disco e
siano rileggibili immediatamente in maniera corretta, è sufficiente l'uso di
\func{fdatasync} che non comporta anche l'esecuzione di operazioni non
-necessarie all'integrità dei dati, come l'aggiornamento dei temi di ultima
+necessarie all'integrità dei dati, come l'aggiornamento dei tempi di ultima
modifica ed ultimo accesso.
Si tenga presente che l'uso di queste funzioni non comporta la
filesystem \textit{proc} con l'apertura del file attraverso il riferimento a
\textit{pathname} del tipo di \texttt{/proc/self/fd/dirfd/relative\_path}.}
Benché queste funzioni non siano presenti negli standard tradizionali esse
-sono state adottate da altri sistemi unix-like come Solaris i vari BSD, fino ad
+sono state adottate da altri sistemi unix-like come Solaris, i vari BSD, fino ad
essere incluse in una recente revisione (la POSIX.1-2008) dello standard
POSIX.1. Con la \acr{glibc} per l'accesso a queste funzioni è necessario
definire la macro \macro{\_ATFILE\_SOURCE}.
\item[\const{FIONREAD}] legge il numero di byte disponibili in lettura sul
file descriptor; questa operazione è disponibile solo su alcuni file
descriptor, in particolare sui socket (vedi sez.~\ref{sec:sock_ioctl_IP}) o
- sui file descriptor di \textit{epoll} (vedi sez.~\ref{sec:file_epoll}); il
+ sui file descriptor di \textit{epoll} (vedi sez.~\ref{sec:file_epoll}), il
terzo argomento deve essere un puntatore ad un intero (cioè di tipo
\texttt{int *}) su cui sarà restituito il valore.
\item[\const{FIOQSIZE}] restituisce la dimensione corrente di un file o di una
direttamente alle \textit{system call} messe a disposizione dal kernel.
Questa interfaccia però non provvede le funzionalità previste dallo standard
-ANSI C, che invece sono realizzate attraverso opportune funzioni di libreria,
-queste, insieme alle altre funzioni definite dallo standard (queste funzioni
-sono state implementate la prima volta da Ritchie nel 1976 e da allora sono
-rimaste sostanzialmente immutate), vengono a costituire il nucleo delle
-\acr{glibc} per la gestione dei file.
-
+ANSI C, che invece sono realizzate attraverso opportune funzioni di libreria.
+Queste funzioni di libreria, insieme alle altre funzioni definite dallo
+standard (che sono state implementate la prima volta da Ritchie nel 1976 e da
+allora sono rimaste sostanzialmente immutate), vengono a costituire il nucleo
+delle \acr{glibc} per la gestione dei file.
Esamineremo in questa sezione le funzioni base dell'interfaccia degli
\textit{stream}, analoghe a quelle di sez.~\ref{sec:file_unix_interface} per i
deriva appunto il nome \textit{stream}.
A parte i dettagli legati alla gestione delle operazioni di lettura e
-scrittura, sia per quel che riguarda la bufferizzazione, che le formattazioni,
+scrittura, sia per quel che riguarda la bufferizzazione che le formattazioni,
per tutto il resto i \textit{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_shared_access} a proposito dell'accesso
output} cioè il \textit{file 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 error} cioè il \textit{file
- 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.
+\item[\var{FILE *stderr}] Lo \textit{standard error} \textit{standard error}
+ cioè il \textit{file 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.
\end{basedescript}
Nella \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono effettivamente
un'operazione nominalmente nulla come \code{fseek(file, 0, SEEK\_CUR)} è
sufficiente a garantire la sincronizzazione.
-Una volta completate le operazioni su di esso \textit{stream} può essere
+Una volta completate le operazioni su di esso uno \textit{stream} può essere
chiuso con la funzione \funcd{fclose}, il cui prototipo è:
\begin{funcproto}{
\subsection{Gestione dell'I/O e posizionamento su uno \textit{stream}}
- \label{sec:file_io}
-
- Una delle caratteristiche più utili dell'interfaccia degli \textit{stream} è
- la ricchezza delle funzioni disponibili per le operazioni di lettura e
- scrittura sui file. Sono infatti previste ben tre diverse modalità modalità di
- input/output non formattato:
- \begin{itemize}
- \item\textsl{binario} in cui si leggono e scrivono blocchi di dati di
+\label{sec:file_io}
+
+Una delle caratteristiche più utili dell'interfaccia degli \textit{stream} è
+la ricchezza delle funzioni disponibili per le operazioni di lettura e
+scrittura sui file. Sono infatti previste ben tre diverse modalità modalità di
+input/output non formattato:
+\begin{itemize}
+\item\textsl{binario} in cui si leggono e scrivono blocchi di dati di
dimensione arbitraria, (analogo della modalità ordinaria dell'I/O sui file
descriptor), trattato in sez.~\ref{sec:file_binary_io}.
- \item\textsl{a caratteri} in cui si legge e scrive un carattere alla volta,
+\item\textsl{a caratteri} in cui si legge e scrive un carattere alla volta,
con la bufferizzazione che viene gestita automaticamente dalla libreria,
trattato in sez.~\ref{sec:file_char_io}.
- \item\textsl{di linea} in cui si legge e scrive una linea alla volta,
+\item\textsl{di linea} in cui si legge e scrive una linea alla volta,
(terminata dal carattere di newline \verb|'\n'|), trattato in
sez.~\ref{sec:file_line_io}.
- \end{itemize}
- a cui si aggiunge la modalità di input/output formattato, trattato in
- sez.~\ref{sec:file_formatted_io}.
-
- Ognuna di queste modalità utilizza per l'I/O delle funzioni specifiche che
- vedremo nelle sezioni citate, affronteremo qui tutte gli argomenti e le
- funzioni che si applicano in generale a tutte le modalità di I/O.
-
- A differenza di quanto avviene con l'interfaccia dei file descriptor, con gli
- \textit{stream} il raggiungimento della fine del file viene considerato un
- errore, e viene notificato come tale dai valori di uscita delle varie
- funzioni. Nella maggior parte dei casi questo avviene con la restituzione del
- valore intero (di tipo \ctyp{int}) \val{EOF} definito anch'esso nell'header
- \headfile{stdlib.h}. La costante deve essere negativa perché in molte
- funzioni un valore positivo indica la quantità di dati scritti, le
- \acr{glibc} usano il valore $-1$, ma altre implementazioni possono avere
- valori diversi.
-
- Dato che le funzioni dell'interfaccia degli \textit{stream} sono funzioni di
- libreria che si appoggiano a delle \textit{system call}, esse non impostano
- direttamente la variabile \var{errno}, che mantiene sempre il valore
- impostato dalla \textit{system call} invocata internamente che ha riportato
- l'errore.
-
- Siccome la condizione di \textit{end-of-file} è anch'essa segnalata come
- errore, nasce 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 sez.~\ref{sec:sys_errno} per i
- dettagli del funzionamento di \var{errno}).
-
- Per questo motivo tutte le implementazioni delle librerie standard mantengono
- per ogni \textit{stream} almeno due flag all'interno dell'oggetto \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 \funcd{ferror}, i cui prototipi sono:
+\end{itemize}
+a cui si aggiunge la modalità di input/output formattato, trattato in
+sez.~\ref{sec:file_formatted_io}.
+
+Ognuna di queste modalità utilizza per l'I/O delle funzioni specifiche che
+vedremo nelle sezioni citate, affronteremo qui tutte gli argomenti e le
+funzioni che si applicano in generale a tutte le modalità di I/O.
+
+A differenza di quanto avviene con l'interfaccia dei file descriptor, con gli
+\textit{stream} il raggiungimento della fine del file viene considerato un
+errore, e viene notificato come tale dai valori di uscita delle varie
+funzioni. Nella maggior parte dei casi questo avviene con la restituzione del
+valore intero (di tipo \ctyp{int}) \val{EOF} definito anch'esso nell'header
+\headfile{stdlib.h}. La costante deve essere negativa perché in molte funzioni
+un valore positivo indica la quantità di dati scritti, le \acr{glibc} usano il
+valore $-1$, ma altre implementazioni possono avere valori diversi.
+
+Dato che le funzioni dell'interfaccia degli \textit{stream} sono funzioni di
+libreria che si appoggiano a delle \textit{system call}, esse non impostano
+direttamente la variabile \var{errno}, che mantiene sempre il valore impostato
+dalla \textit{system call} invocata internamente che ha riportato l'errore.
+
+Siccome la condizione di \textit{end-of-file} è anch'essa segnalata come
+errore, nasce 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 sez.~\ref{sec:sys_errno} per i
+dettagli del funzionamento di \var{errno}).
+
+Per questo motivo tutte le implementazioni delle librerie standard mantengono
+per ogni \textit{stream} almeno due flag all'interno dell'oggetto \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 \funcd{ferror}, i cui prototipi sono:
\begin{funcproto}{
\fhead{stdio.h}
output} mentre \func{puts} la scrive sul file indicato da \param{stream}.
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 \itindex{standard~output} standard output; la funzione prende
-una stringa terminata da uno zero ed aggiunge automaticamente il ritorno a
-capo. La differenza con \func{fputs} (a parte la possibilità di specificare un
-file diverso da \var{stdout}) è che quest'ultima non aggiunge il
-\textit{newline}, che deve essere previsto esplicitamente.
+messaggi sullo \itindex{standard~output} \textit{standard output}; la funzione
+prende una stringa terminata da uno zero ed aggiunge automaticamente il
+ritorno a capo. La differenza con \func{fputs} (a parte la possibilità di
+specificare un file diverso da \var{stdout}) è che quest'ultima non aggiunge
+il \textit{newline}, che deve essere previsto esplicitamente.
Come per le analoghe funzioni di input/output a caratteri, anche per l'I/O di
linea esistono delle estensioni per leggere e scrivere linee di caratteri
Il valore di ritorno di \func{getline} indica il numero di caratteri letti
dallo \textit{stream}, quindi compreso il \textit{newline}, ma non lo zero di
-terminazione). Questo permette anche di distinguere anche gli eventuali zeri
+terminazione. Questo permette anche di distinguere anche gli eventuali zeri
letti come dati dallo \textit{stream} da quello inserito dalla funzione dopo
il \textit{newline} per terminare la stringa. Se si è alla fine del file e
non si è potuto leggere nulla o se c'è stato un errore la funzione restituisce
del carattere di \textit{newline} come separatore di linea. Il comportamento
di \func{getdelim} è identico a quello di \func{getline}, che può essere
implementata da \func{getdelim} passando ``\verb|\n|'' come valore
-dell'argomento
-\param{delim}.
+dell'argomento \param{delim}.
\subsection{Input/output formattato}
\fdesc{Scrive una stringa formattata sullo \itindex{standard~output}
\textit{standard output}.}
\fdecl{int vfprintf(FILE *stream, const char *format, va\_list ap)}
-\fdesc{Scrive una stringa formattata su un \textit{stream}.}
+\fdesc{Scrive una stringa formattata su uno \textit{stream}.}
\fdecl{int vsprintf(char *str, const char *format, va\_list ap)}
\fdesc{Scrive una stringa formattata su un buffer.}
}
\noindent anche di questa funzione esiste una analoga \func{fflush\_unlocked}
(accessibile definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE} o
-\macro{\_GNU\_SOURCE}) che non effettua il blocco dello stream.
+\macro{\_GNU\_SOURCE}) che non effettua il blocco dello \textit{stream}.
% TODO aggiungere prototipo \func{fflush\_unlocked}?
\textit{stream} aperti. Esistono però circostanze, ad esempio quando si vuole
essere sicuri che sia stato eseguito tutto l'output su terminale, in cui serve
poter effettuare lo scarico dei dati solo per gli \textit{stream} in modalità
-line buffered. Per fare questo le \acr{glibc} supportano una estensione di
-Solaris, la funzione \funcd{\_flushlbf}, il cui prototipo è:
+\textit{line buffered}. Per fare questo le \acr{glibc} supportano una
+estensione di Solaris, la funzione \funcd{\_flushlbf}, il cui prototipo è:
\begin{funcproto}{
\fhead{stdio-ext.h}