per \param{size} o si è usato \const{O\_DIRECT} ed il buffer non è
allineato.
\item[\errval{EIO}] si è tentata la lettura dal terminale di controllo
- essendo in background (vedi sez.~\ref{sec:term_io_design}).
+ essendo in background ignorando o bloccando \const{SIGTTIN} (vedi
+ sez.~\ref{sec:term_io_design}) o per errori di basso livello sul supporto.
\end{errlist}
ed inoltre \errval{EBADF}, \errval{EFAULT} e \errval{EISDIR}, nel loro
significato generico.}
\end{funcproto}
La funzione tenta di leggere \param{count} byte dal file \param{fd} a partire
-dalla posizione corrente, scrivendoli nel buffer \param{buf}. Dopo la lettura
-la posizione sul file è spostata automaticamente in avanti del numero di byte
-letti. Se \param{count} è zero la funzione restituisce zero senza nessun altro
-risultato. Inoltre che non è detto che la funzione \func{read} restituisca il
-numero di byte richiesto, ci sono infatti varie ragioni per cui la funzione
-può restituire un numero di byte inferiore: questo è un comportamento normale,
-e non un errore, che bisogna sempre tenere presente.
+dalla posizione corrente, scrivendoli nel buffer \param{buf}.\footnote{fino ad
+ un massimo di \const{0x7ffff000} bytes, indipendentemente che l'architettura
+ sia a 32 o 64 bit.} Dopo la lettura la posizione sul file è spostata
+automaticamente in avanti del numero di byte letti. Se \param{count} è zero la
+funzione restituisce zero senza nessun altro risultato. Inoltre che non è
+detto che la funzione \func{read} restituisca il numero di byte richiesto, ci
+sono infatti varie ragioni per cui la funzione può restituire un numero di
+byte inferiore: questo è un comportamento normale, e non un errore, che
+bisogna sempre tenere presente.
La prima e più ovvia di queste ragioni è che si è chiesto di leggere più byte
di quanto il file ne contenga. In questo caso il file viene letto fino alla
di dispositivo, come le unità a nastro, che restituiscono sempre i dati ad un
singolo blocco alla volta, o come le linee seriali, che restituiscono solo i
dati ricevuti fino al momento della lettura, o i terminali, per i quali si
-applicano inoltre ulteriori condizioni che approfondiremo in
+applicano anche ulteriori condizioni che approfondiremo in
sez.~\ref{sec:sess_terminal_io}.
Infine anche le due condizioni segnalate dagli errori \errcode{EINTR} ed
La funzione prende esattamente gli stessi argomenti di \func{read} con lo
stesso significato, a cui si aggiunge l'argomento \param{offset} che indica
-una posizione sul file. Identico è il comportamento ed il valore di
-ritorno. La funzione serve quando si vogliono leggere dati dal file senza
-modificare la posizione corrente.
-
-L'uso di \func{pread} è equivalente all'esecuzione di una \func{read} seguita
-da una \func{lseek} che riporti al valore precedente la posizione corrente sul
-file, ma permette di eseguire l'operazione atomicamente. Questo può essere
+una posizione sul file a partire dalla quale verranno i \param{count}
+bytes. Identico è il comportamento ed il valore di ritorno, ma la posizione
+corrente sul file resterà invariata. Il valore di \param{offset} fa sempre
+riferimento all'inizio del file.
+
+L'uso di \func{pread} è equivalente all'esecuzione di una \func{lseek} alla
+posizione indicata da \param{offset} seguita da una \func{read}, seguita da
+un'altra \func{lseek} che riporti al valore iniziale della posizione corrente
+sul file, ma permette di eseguire l'operazione atomicamente. Questo può essere
importante quando la posizione sul file viene condivisa da processi diversi
-(vedi sez.~\ref{sec:file_shared_access}). Il valore di \param{offset} fa
-sempre riferimento all'inizio del file.
+(vedi sez.~\ref{sec:file_shared_access}) ed è particolarmente utile in caso di
+programmazione \textit{multi-thread} (vedi sez.~\ref{cha:threads}) quando
+all'interno di un processo si vuole che le operazioni di un \textit{thread}
+non possano essere influenzata da eventuali variazioni della posizione sul
+file effettuate da altri \textit{thread}.
La funzione \func{pread} è disponibile anche in Linux, però diventa
accessibile solo attivando il supporto delle estensioni previste dalle
-\textit{Single Unix Specification} con la definizione della macro:
-\begin{Example}
-#define _XOPEN_SOURCE 500
-\end{Example}
-e si ricordi di definire questa macro prima dell'inclusione del file di
-dichiarazioni \headfile{unistd.h}.
-
+\textit{Single Unix Specification} con un valore della macro
+\macro{\_XOPEN\_SOURCE} maggiore o uguale a 500 o a partire dalla \acr{glibc}
+2.12 con un valore dalla macro \macro{\_POSIX\_C\_SOURCE} maggiore o uguale al
+varore \val{200809L}. Si ricordi di definire queste macro prima
+dell'inclusione del file di dichiarazione \headfile{unistd.h}.
\subsection{Le funzioni per la scrittura di un file}
indicato da \param{count}, a meno di un errore. Negli altri casi si ha lo
stesso comportamento di \func{read}.
-Anche per \func{write} lo standard Unix98 definisce un'analoga \funcd{pwrite}
-per scrivere alla posizione indicata senza modificare la posizione corrente
-nel file, il suo prototipo è:
+Anche per \func{write} lo standard Unix98 (ed i successivi POSIX.1-2001 e
+POSIX.1-2008) definiscono un'analoga \funcd{pwrite} per scrivere alla
+posizione indicata senza modificare la posizione corrente nel file, il suo
+prototipo è:
\begin{funcproto}{
\fhead{unistd.h}
\func{write} e \func{lseek}.}
\end{funcproto}
-\noindent e per essa valgono le stesse considerazioni fatte per \func{pread}.
+\noindent per questa funzione valgono le stesse considerazioni fatte per
+\func{pread}, a cui si aggiunge il fatto che su Linux, a differenza di quanto
+previsto dallo standard POSIX che richiederebbe di ignorarlo, se si è aperto
+il file con \const{O\_APPEND} i dati saranno comunque scritti in coda al file,
+ignorando il valore di \param{offset}.
\section{Caratteristiche avanzate}
\begin{figure}[!htb]
\centering
- \includegraphics[width=12cm]{img/filemultacc}
+ \includegraphics[width=11cm]{img/filemultacc}
\caption{Schema dell'accesso allo stesso file da parte di due processi
diversi}
\label{fig:file_mult_acc}
vengono mantenute nella sua voce della \textit{file table}. Questo ha
conseguenze specifiche sugli effetti della possibile azione simultanea sullo
stesso file, in particolare occorre tenere presente che:
-\begin{itemize}
+\begin{itemize*}
\item ciascun processo può scrivere indipendentemente, dopo ciascuna
\func{write} la posizione corrente sarà cambiata solo nel processo
scrivente. Se la scrittura eccede la dimensione corrente del file questo
\item se un file è in modalità \const{O\_APPEND} tutte le volte che viene
effettuata una scrittura la posizione corrente viene prima impostata alla
dimensione corrente del file letta dalla struttura \kstruct{inode}. Dopo la
- scrittura il file viene automaticamente esteso.
+ scrittura il file viene automaticamente esteso. Questa operazione avviene
+ atomicamente, ogni altro processo che usi \const{O\_APPEND} vedrà la
+ dimensione estesa e continuerà a scrivere in coda al file.
\item l'effetto di \func{lseek} è solo quello di cambiare il campo
\var{f\_pos} nella struttura \kstruct{file} della \textit{file table}, non
c'è nessuna operazione sul file su disco. Quando la si usa per porsi alla
- fine del file la posizione viene impostata leggendo la dimensione corrente
- dalla struttura \kstruct{inode}.
-\end{itemize}
+ fine del file la posizione viene impostata leggendo la attuale dimensione
+ corrente dalla struttura \kstruct{inode}.
+\end{itemize*}
\begin{figure}[!htb]
\centering
- \includegraphics[width=12cm]{img/fileshar}
+ \includegraphics[width=11cm]{img/fileshar}
\caption{Schema dell'accesso ai file da parte di un processo figlio}
\label{fig:file_acc_child}
\end{figure}
da cui il nome della funzione.
\begin{figure}[!htb]
- \centering \includegraphics[width=12cm]{img/filedup}
+ \centering \includegraphics[width=11cm]{img/filedup}
\caption{Schema dell'accesso ai file duplicati}
\label{fig:file_dup}
\end{figure}