\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
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} \\
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}}
\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.
\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}
\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}