From dfec603c0424b6ec1e0f8d630dd4303acf2e35a7 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 9 Nov 2001 23:09:10 +0000 Subject: [PATCH 1/1] Completata lseek, iniziata write. --- fileunix.tex | 74 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/fileunix.tex b/fileunix.tex index 39bbba9..bc94a0e 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -15,7 +15,8 @@ ANSI C. In questa sezione faremo una breve introduzione sulla architettura su cui è basata dell'interfaccia dei \textit{file descriptor}, che, sia pure con -differenze di implementazione, è comune ad ogni implementazione di unix. +differenze nella realizzazione pratica, resta sostanzialmente la stessa in +ogni implementazione di unix. \subsection{L'architettura dei \textit{file descriptor}} @@ -179,7 +180,6 @@ prototipo La funzione ritorna il file descriptor in caso di successo e -1 in caso di errore. In questo caso la variabile \var{errno} viene settata ad uno dei valori: - \begin{errlist} \item \macro{EEXIST} \var{pathname} esiste e si è specificato \macro{O\_CREAT} e \macro{O\_EXCL}. @@ -417,13 +417,11 @@ un valore qualsiasi con la funzione \func{lseek}, il cui prototipo \begin{functions} \headdecl{sys/types.h} \headdecl{unistd.h} - \funcdecl{off_t lseek(int fd, off_t offset, int whence)} - La funzione setta - + \funcdecl{off\_t lseek(int fd, off\_t offset, int whence)} + La funzione setta la posizione attuale nel file. La funzione ritorna valore della posizione corrente in caso di successo e -1 - in caso di errore. In questo caso la variabile \var{errno} viene settata ad - uno dei valori: + in caso di errore nel qual caso \var{errno} viene settata ad uno dei valori: \begin{errlist} \item \macro{ESPIPE} \var{fd} è una pipe, un socket o una fifo. \item \macro{EINVAL} \var{whence} non è un valore valido. @@ -431,12 +429,72 @@ un valore qualsiasi con la funzione \func{lseek}, il cui prototipo e \macro{EBADF}. \end{functions} - +La nuova posizione è settata usando il valore specificato da \var{offset}, +sommato al riferimento dato da \var{whence}; quest'ultimo può assumere i +seguenti valori\footnote{per compatibilità con alcune vecchie notazioni + questi valori possono essere rimpiazzati rispettivamente con 0, 1 e 2 o con + \macro{L\_SET}, \macro{L\_INCR} e \macro{L\_XTND}}: +\begin{description} +\item \macro{SEEK\_SET} si fa riferimento all'inizio del file: il valore di + \var{offset} è la nuova posizione. +\item \macro{SEEK\_CUR} si fa riferimento alla posizione corrente del file: + \var{offset} che può essere negativo e positivo. +\item \macro{SEEK\_END} si fa riferimento alla fine del file: il valore di + \var{offset} può essere negativo e positivo. +\end{description} + +Come accennato in \secref{sec:file_file_size} con \func{lseek} è possibile +settare la posizione corrente anche al di la della fine del file, e alla +successiva scrittura il file sarà esteso. La chiamata non causa nessuna +attività di input/output, si limita a modificare la posizione corrente nel +kernel (cioè \var{f\_pos} in \var{file}, vedi \figref{fig:file_proc_file}). + +Dato che la funzione ritorna la nuova posizione, usando il valore zero per +\func{offset} si può riottenere la posizione corrente nel file chiamando la +funzione con \func{lseek(fd, 0, SEEK\_CUR}. + +Si tenga presente inoltre che usare \macro{SEEK\_END} non assicura affatto che +successiva scrittura avvenga alla fine del file, infatti se questo è stato +aperto anche da un altro processo che vi ha scritto, la fine del file può +essersi spostata, ma noi scriveremo alla posizione settata in precedenza. +Questa è una potenziale sorgente di \textit{race condition}, e quando si vuole +essere sicuri di scrivere alla fine del file questo deve essere posto in +modalità \macro{O\_APPEND}. + +Non tutti i file supportano la capacità di eseguire una \func{lseek}, in +questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per +i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che non +supportano questa funzione, come ad esempio per le \acr{tty}\footnote{altri + sistemi, usando \macro{SEEK\_SET} in questo caso ritornano il numero di + caratteri che vi sono stati scritti}. Lo standard POSIX però non specifica +niente al proposito. Infine alcuni device, ad esempio \file{/dev/null}, non +causano un errore ma restituiscono un valore indefinito. \subsection{La funzione \func{read}} \label{sec:file_read} +Per leggere da un file precedentemente aperto, si può la funzione \func{read}, +il cui prototipo è: +\begin{prototype} + \headdecl{unistd.h} + \funcdecl{ssize\_t read(int fd, void * buf, size\_t count)} + + La funzione cerca di leggere \var{count} bytes dal file \var{fd} al buffer + \var{buf}. + + La funzione ritorna il numero di byte letti in caso di successo e -1 in + caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori: + \begin{errlist} + \item \macro{EINTR} la funzione è stata interrotta da un segnale prima di + aver letto quasiasi dato. + \item \macro{EAGAIN} la funzione non aveva nessun dato da restituire e si + era aperto il file in modalità \macro{O\_NONBLOCK}. + \end{errlist} + ed inoltre \macro{EBADF}, \macro{EIO}, \macro{EISDIR}, \macro{EBADF}, + \macro{EINVAL} e \macro{EFAULT}. +\end{prototype} + \subsection{La funzione \func{write}} \label{sec:file_write} -- 2.30.2