Completata (rozzamente) open, creato nuovo capito sull'I/O avanzato (con
[gapil.git] / fileunix.tex
index bc50b420f643e21720941096110ad5b3e583bc6f..9f021143a7980fc473137d7a8ea88bd540987dd6 100644 (file)
@@ -63,7 +63,7 @@ che 
 \var{file}; in ciascuna di esse sono tenute varie informazioni relative al
 file, fra cui:
 \begin{itemize*}
-\item lo stato del file (lettura, scrittura, append, etc.).
+\item lo stato del file (nel campo \var{f\_flags}).
 \item il valore della posizione corrente (l'\textit{offset}) nel file.
 \item un puntatore all'inode\footnote{nel kernel 2.4.x si è in realtà passati
     ad un puntatore ad una struttura \var{dentry} che punta a sua volta
@@ -110,11 +110,11 @@ secondo file 
 si aspetta debbano essere inviati i dati in uscita (sempre nel caso della
 shell, è il terminale su cui si sta scrivendo), il terzo è lo \textit{standard
   error}, su cui viene inviato l'output relativo agli errori.
-
 Lo standard POSIX.1 provvede tre costanti simboliche, definite nell'header
 \file{unistd.h}, al posto di questi valori numerici: 
 \begin{table}[htb]
   \centering
+  \footnotesize
   \begin{tabular}[c]{|l|l|}
     \hline
     \textbf{Costante} & \textbf{Significato} \\
@@ -156,10 +156,9 @@ funzioni fondamentali \func{open}, \func{read}, \func{write}, \func{lseek} e
 chiudere un file. 
 
 La gran parte delle operazioni sui file si effettua attraverso queste cinque
-funzioni, esse vengono chiamate anche funzioni di I/O non bufferizzato, per
-contrapporle alle analoghe previste dallo standard ANSI C (che vedremo in
-\secref{sec:file_ansi_base_func}), dato che effettuano le operazioni di lettura
-e scrittura usando direttamente le system call del kernel.
+funzioni, esse vengono chiamate anche funzioni di I/O non bufferizzato dato
+che effettuano le operazioni di lettura e scrittura usando direttamente le
+system call del kernel.
 
 
 \subsection{La funzione \func{open}}
@@ -188,9 +187,8 @@ prototipo 
     \macro{O\_CREAT} e \macro{O\_EXCL}.  
   \item \macro{EISDIR} \var{pathname} indica una directory e si è tentato
     l'accesso in scrittura. 
-  \item \macro{ENOTDIR} un componente di \var{pathname} non è una directory o
-    si è specificato \macro{O\_DIRECTORY} e \var{pathname} non è una
-    directory.  
+  \item \macro{ENOTDIR} si è specificato \macro{O\_DIRECTORY} e \var{pathname}
+    non è una directory.
   \item \macro{ENXIO} si sono settati \macro{O\_NOBLOCK} o \macro{O\_WRONLY}
     ed il file è una fifo che non viene letta da nessun processo o
     \var{pathname} è un file di dispositivo ma il dispositivo è assente.
@@ -207,12 +205,159 @@ prototipo 
   \macro{EMFILE} e \macro{ENFILE}.
 \end{functions}
 
+La funzione apre il file, usando il primo file descriptor libero, e crea
+l'opportuna voce (cioè la struttura \var{file}) nella file table.  Viene usato
+sempre il file descriptor con il valore più basso, questa caratteritica
+permette di prevedere qual'è il valore che si otterrà e viene talvolta usata
+da alcune applicazioni per sostituire i file corrispondenti ai file standard
+di \secref{sec:file_std_descr}: se ad esempio si chiude lo standard input e si
+apre subito dopo un nuovo file questo diventerà il nuovo standard input (avrà
+cioè il file descriptor 0).
+
+Il nuovo file descriptor non è condiviso con nessun altro processo, (torneremo
+sulla condivisione dei file, in genere accessibile dopo una \func{fork}, in
+\secref{sec:file_sharing}). Il nuovo file descriptor è settato di default per
+restare aperto attraverso una \func{exec} (come accennato in
+\secref{sec:proc_exec}) ed l'offset è settato all'inizio del file. 
+
+Il parametro \var{mode} specifica i permessi con cui il file viene
+eventualmente creato; i valori possibili gli stessi già visti in
+\secref{sec:file_perm_overview} e possono essere specificati come OR binario
+delle costanti descritte in \tabref{tab:file_bit_perm}. Questi permessi
+filtrati dal valore di \file{umask} per il processo.
+
+La funzione prevede diverse opzioni, che vengono specificate usando vari bit
+del parametro \var{flags}.  Alcuni di questi vanno anche a costituire lo il
+flag di stato del file (o \textit{file status flag}), che è mantenuto nel
+campo \var{f\_flags} della struttura \var{file} (vedi \curfig).  Questi
+bit sono divisi in tre categorie principali:
+\begin{itemize}
+\item \textsl{i bit delle modalità di accesso}: specificano con quale modalità
+  si accede al file: i valori possibili sono lettura, scrittura o
+  lettura/scrittura.  Uno di questi bit deve essere sempre specificato quando
+  si apre un file.  Vengono settati alla chiamata da \func{open}, e possono
+  essere riletti con una \func{fcntl} (fanno parte del \textit{file status
+    flag}), ma non modificati.
+\item \textsl{i bit delle modalità di apertura}: permettono di specificare
+  alcuni dei modi di funzionamento di \func{open}. Hanno effetto solo al
+  momento della chiamata della funzione e non sono memorizzati nè possono
+  essere riletti.
+\item \textsl{i bit delle modalità di operazione}: permettono di specificare
+  alcuni effetti validi anche in seguito per il comportamento delle operazioni
+  sul file (come la \func{read} o la \func{write}). Anch'essi fanno parte del
+  \textit{file status flag}. Il loro valore è settato alla chiamata di
+  \func{open}, ma possono essere riletti e modificati con una \func{fcntl}.
+\end{itemize}
+
+In \ntab\ si sono riportate, ordinate e divise fra loro secondo le tre
+modalità appena elencate, le costanti che identificano i vari bit, queste
+possono essere combinate con un OR aritmetico per costruire il valore del
+parametro \var{flags} da passare alla \func{open} per specificarne il
+comportamento.
+
+\begin{table}[!htbp]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{12cm}|}
+    \hline
+    \textbf{Flag} & \textbf{Descrizione} \\
+    \hline
+    \hline % modailtà di accesso al file
+    \macro{O\_RDONLY} & apre il file in sola lettura\\
+    \macro{O\_WRONLY} & apre il file in sola scrittura\\
+    \macro{O\_RDWR} & apre il file lettura/scrittura\\
+    \hline % modalita di apertura del file
+    \hline
+    \macro{O\_CREAT} & se il file non esiste verrà creato, con le regole di
+    titolarità del file viste in \secref{sec:file_ownership}. Il parametro
+    \var{mode} deve essere specificato. \\
+    \macro{O\_EXCL} & usato in congiunzione con \macro{O\_CREAT} fa sì che
+    l'esistenza del file diventi un errore\footnote{la man page di \func{open}
+    segnala che questa opzione è difettosa su NFS, e che i programmi che la
+    usano per stabilire un file di lock possono incorrere in una race
+    condition.  Si consiglia come alternativa di usare un file con un nome
+    univoco e la funzione \func{link} per verificarne l'esistenza.} che fa
+    fallire \func{open} con \macro{EEXIST}.\\
+    \macro{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo
+    valore specifica anche una modalità di operazione (vedi sotto), e 
+    comporta che \func{open} ritorni immediatamente (torneremo su
+    questo in \secref{sec:file_noblocking}).  \\
+    \macro{O\_NOCTTY} & se \var{pathname} si riferisce ad un device di
+    terminale, questo non diventerà il terminale di controllo, anche se il
+    processo non ne ha ancora uno (si veda \secref{sec:sess_xxx}).\\
+    \macro{O\_SHLOCK} & opzione di BSD, acquisisce uno shared lock (vedi
+    \secref{sec:file_locking}) sul file. Non è disponibile in Linux.\\
+    \macro{O\_EXLOCK} & opzione di BSD, acquisisce uno lock esclusivo (vedi
+    \secref{sec:file_locking}) sul file. Non è disponibile in Linux.\\
+    \macro{O\_TRUNC} & se il file esiste ed è un file di dati e la modalità di
+    apertura consente la scrittura, allora la sua lunghezza verrà troncata a
+    zero. Se il file è un terminale o una fifo il flag verrà ignorato, negli
+    altri casi il comportamento non è specificato.\\
+    \macro{O\_NOFOLLOW} & se \var{pathname} è un link simbolico la chiamata
+    fallisce. Questa è una estensione BSD aggiunta in Linux dal kernel 2.1.126.
+    Nelle versioni precedenti i link simbolici sono sempre seguiti, e questa
+    opzione è ignorata.\\
+    \macro{O\_DIRECTORY} & se \var{pathname} non è una directory la chiamata
+    fallisce. Questo flag è specifico di Linux ed è stato introdotto con il
+    kernel 2.1.126 per evitare dei DoS\footnote{Denial of Service, si chiamano
+    così attacchi miranti ad impedire un servizio causando una qualche forma
+    di carico eccessivo per il sistema, che resta bloccato nelle risposte
+    all'attacco} quando \func{opendir} viene chiamata su una fifo o su un
+    device di unità a nastri, non deve essere utilizzato al di fuori
+    dell'implementazione di \func{opendir}. \\
+    \macro{O\_LARGEFILE} & nel caso di sistemi a 32 bit che supportano file di
+    grandi dimensioni consente di aprire file le cui dimensioni non possono
+    essere rappresentate da numeri a 31 bit.\\
+    \hline
+    \hline  % modalità di operazione col file
+    \macro{O\_APPEND} & il file viene aperto in append mode. Prima di ciascuna
+    scrittura la posizione corrente viene sempre settata alla fine del
+    file. Può causare corruzione del file con NFS se più di un processo scrive
+    allo stesso tempo\footnote{il problema è che NFS non supporta la scrittura
+    in append, ed il kernel deve simularla, ma questo comporta la possibilità
+    di una race condition}.\\
+    \macro{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per
+    le operazioni di I/O: questo significa il fallimento di una \func{read} in
+    assenza di dati da leggere e quello di una \func{write} in caso di 
+    impossibilità di scrivere immediatamente. L'opzione è effettiva solo per
+    le fifo e per alcuni file di dispositivo. \\
+    \macro{O\_NDELAY} & in Linux\footnote{l'opzione origina da SVr4, dove però
+    causava il ritorno da una \func{read} con un valore nullo e non con un
+    errore, questo introduce una ambiguità, dato che come vedremo in
+    \secref{sec:file_read} il ritorno di zero da parte di \func{read} ha il
+    significato di una end-of-file} è sinonimo di \macro{O\_NONBLOCK}\\
+    \macro{O\_ASYNC} & apre il file per l'input/output in modalità
+    asincrona. Non è supportato in Linux. \\
+    \macro{O\_FSYNC} & \\
+    \macro{O\_SYNC} & apre il file per l'input/output sincrono, ogni
+    \func{write} bloccherà fino al completamento della scrittura di tutti dati
+    sul sull'hardware sottostante\\
+    \macro{O\_NOATIME} & blocca l'aggiornamento dei tempi dei di accesso dei
+    file (vedi \secref{sec:file_file_times}). In Linux questa opzione non è
+    disponibile per il singolo file ma come opzione per il filesystem in fase
+    di montaggio.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti definite in \file{fcntl.h} per indicare i vari bit 
+    usabili per il specificare parametro \var{flags} di \func{open}.}
+  \label{tab:file_open_flags}
+\end{table}
+
+Nelle prime versioni di unix i flag specificabili per \func{open} erano solo
+quelli delle modalità di apertura. Per questo motivo per creare un file c'era
+una system call apposita, \func{creat}, il cui prototipo è:
+
+\begin{prototype}{fcntl.h}
+  {int creat(const char *pathname, mode\_t mode)}
+  Crea un nuovo file vuoto, con i permessi specificati da \var{mode}. É del
+  tutto equivalente a \func{open(filedes, O\_CREAT|O\_WRONLY|O\_TRUNC, mode)}. 
+\end{prototype}
+
+adesso questa funzione resta solo per compatibilità con i vecchi programmi.
 
 
 
 
-\subsection{La funzione \func{creat}}
-\label{sec:file_creat}
 
 \subsection{La funzione \func{close}}
 \label{sec:file_close}
@@ -233,6 +378,15 @@ prototipo 
 \subsection{La condivisione dei files}
 \label{sec:file_sharing}
 
+
+Si noti che i flag di stato del file, quelli settati dal parametro \var{flag}
+di \func{open}, essendo tenuti nella vode sulla file table, vengono condivisi,
+ai file sono però associati anche altri flag, (tenuti invece nella struttura
+\var{file\_struct} interna alla process table) che sono unici per ciascun file
+descriptor, e sono pertanto detti \textit{file descriptor flags} (l'unico
+usato al momento è \macro{FD\_CLOEXEC}).
+
+
 \subsection{Operazioni atomiche coi file}
 \label{sec:file_atomic}