Inizio accorpamento dei capitoli 5 e 6 (ex 6 e 7) nel nuovo capitolo 5.
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 29 Jan 2012 00:38:13 +0000 (00:38 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 29 Jan 2012 00:38:13 +0000 (00:38 +0000)
12 files changed:
errors.tex
fileadv.tex
filedir.tex
fileio.tex [new file with mode: 0644]
gapil.tex
img/procfile.dia
intro.tex
ipc.tex
process.tex
prochand.tex
session.tex
system.tex

index 60b4bde027cb967545994899f0165b01fdb5b3b6..e10acc27678128f4c0db46de92b8ca8250084740 100644 (file)
@@ -394,7 +394,7 @@ messaggio.
 \item[\errcode{ENOSR} \textit{Out of streams resources}.] Errore relativo agli
   \textit{STREAMS}, che indica l'assenza di risorse sufficienti a completare
   l'operazione richiesta. Quella degli \textit{STREAMS}\footnote{che non vanno
 \item[\errcode{ENOSR} \textit{Out of streams resources}.] Errore relativo agli
   \textit{STREAMS}, che indica l'assenza di risorse sufficienti a completare
   l'operazione richiesta. Quella degli \textit{STREAMS}\footnote{che non vanno
-    confusi con gli \textit{stream} di cap.~\ref{cha:files_std_interface}.}  è
+    confusi con gli \textit{stream} di sez.~\ref{sec:files_std_interface}.}  è
   interfaccia di programmazione originaria di System V, che non è implementata
   da Linux, per cui questo errore non viene utilizzato.
 
   interfaccia di programmazione originaria di System V, che non è implementata
   da Linux, per cui questo errore non viene utilizzato.
 
index d145833fe2e18b8713086b23dda398f76e2aa501..240c0582524d1d7eab149b336df1cde0276a4106 100644 (file)
@@ -901,7 +901,7 @@ possibilità di modificare il file.
 
 Uno dei problemi che si presentano quando si deve operare contemporaneamente
 su molti file usando le funzioni illustrate in
 
 Uno dei problemi che si presentano quando si deve operare contemporaneamente
 su molti file usando le funzioni illustrate in
-cap.~\ref{cha:file_unix_interface} e cap.~\ref{cha:files_std_interface} è che
+sez.~\ref{sec:file_unix_interface} e sez.~\ref{sec:files_std_interface} è che
 si può essere bloccati nelle operazioni su un file mentre un altro potrebbe
 essere disponibile. L'\textit{I/O multiplexing} nasce risposta a questo
 problema. In questa sezione forniremo una introduzione a questa problematica
 si può essere bloccati nelle operazioni su un file mentre un altro potrebbe
 essere disponibile. L'\textit{I/O multiplexing} nasce risposta a questo
 problema. In questa sezione forniremo una introduzione a questa problematica
@@ -1547,7 +1547,7 @@ maschera binaria in fase di creazione del file descriptor. Al momento l'unico
 valore legale per \param{flags} (a parte lo zero) è \const{EPOLL\_CLOEXEC},
 che consente di impostare in maniera atomica sul file descriptor il flag di
 \itindex{close-on-exec} \textit{close-on-exec} (si veda il significato di
 valore legale per \param{flags} (a parte lo zero) è \const{EPOLL\_CLOEXEC},
 che consente di impostare in maniera atomica sul file descriptor il flag di
 \itindex{close-on-exec} \textit{close-on-exec} (si veda il significato di
-\const{O\_CLOEXEC} in tab.~\ref{tab:file_open_flags}), senza che sia
+\const{O\_CLOEXEC} in sez.~\ref{sec:file_open}), senza che sia
 necessaria una successiva chiamata a \func{fcntl}.
 
 Una volta ottenuto un file descriptor per \textit{epoll} il passo successivo è
 necessaria una successiva chiamata a \func{fcntl}.
 
 Una volta ottenuto un file descriptor per \textit{epoll} il passo successivo è
@@ -3653,9 +3653,10 @@ per il campo \var{aio\_sigevent} di \struct{aiocb}.
 Oltre alle precedenti modalità di \textit{I/O multiplexing} e \textsl{I/O
   asincrono}, esistono altre funzioni che implementano delle modalità di
 accesso ai file più evolute rispetto alle normali funzioni di lettura e
 Oltre alle precedenti modalità di \textit{I/O multiplexing} e \textsl{I/O
   asincrono}, esistono altre funzioni che implementano delle modalità di
 accesso ai file più evolute rispetto alle normali funzioni di lettura e
-scrittura che abbiamo esaminato in sez.~\ref{sec:file_base_func}. In questa
-sezione allora prenderemo in esame le interfacce per l'\textsl{I/O mappato in
-  memoria}, per l'\textsl{I/O vettorizzato} e altre funzioni di I/O avanzato.
+scrittura che abbiamo esaminato in sez.~\ref{sec:file_unix_interface}. In
+questa sezione allora prenderemo in esame le interfacce per l'\textsl{I/O
+  mappato in memoria}, per l'\textsl{I/O vettorizzato} e altre funzioni di I/O
+avanzato.
 
 
 \subsection{File mappati in memoria}
 
 
 \subsection{File mappati in memoria}
@@ -3663,7 +3664,7 @@ sezione allora prenderemo in esame le interfacce per l'\textsl{I/O mappato in
 
 \itindbeg{memory~mapping}
 Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
 
 \itindbeg{memory~mapping}
 Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
-rispetto a quella classica vista in cap.~\ref{cha:file_unix_interface}, è il
+rispetto a quella classica vista in sez.~\ref{sec:file_unix_interface}, è il
 cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della
 \textsl{paginazione} \index{paginazione} usato dalla memoria virtuale (vedi
 sez.~\ref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un
 cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della
 \textsl{paginazione} \index{paginazione} usato dalla memoria virtuale (vedi
 sez.~\ref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un
@@ -3975,12 +3976,12 @@ consentita la scrittura sul file (cioè per un file mappato con
 o in corrispondenza di una eventuale \func{msync}.
 
 Dato per i file mappati in memoria le operazioni di I/O sono gestite
 o in corrispondenza di una eventuale \func{msync}.
 
 Dato per i file mappati in memoria le operazioni di I/O sono gestite
-direttamente dalla \index{memoria~virtuale}memoria virtuale, occorre essere
+direttamente dalla \index{memoria~virtuale} memoria virtuale, occorre essere
 consapevoli delle interazioni che possono esserci con operazioni effettuate
 consapevoli delle interazioni che possono esserci con operazioni effettuate
-con l'interfaccia standard dei file di cap.~\ref{cha:file_unix_interface}. Il
-problema è che una volta che si è mappato un file, le operazioni di lettura e
-scrittura saranno eseguite sulla memoria, e riportate su disco in maniera
-autonoma dal sistema della memoria virtuale.
+con l'interfaccia dei file di sez.~\ref{sec:file_unix_interface}. Il problema
+è che una volta che si è mappato un file, le operazioni di lettura e scrittura
+saranno eseguite sulla memoria, e riportate su disco in maniera autonoma dal
+sistema della memoria virtuale.
 
 Pertanto se si modifica un file con l'interfaccia standard queste modifiche
 potranno essere visibili o meno a seconda del momento in cui la memoria
 
 Pertanto se si modifica un file con l'interfaccia standard queste modifiche
 potranno essere visibili o meno a seconda del momento in cui la memoria
@@ -4506,7 +4507,7 @@ ma si perderà l'atomicità del trasferimento da e verso la destinazione finale.
 Si tenga presente infine che queste funzioni operano sui file con
 l'interfaccia dei file descriptor, e non è consigliabile mescolarle con
 l'interfaccia classica dei \textit{file stream} di
 Si tenga presente infine che queste funzioni operano sui file con
 l'interfaccia dei file descriptor, e non è consigliabile mescolarle con
 l'interfaccia classica dei \textit{file stream} di
-cap.~\ref{cha:files_std_interface}; a causa delle bufferizzazioni interne di
+sez.~\ref{sec:files_std_interface}; a causa delle bufferizzazioni interne di
 quest'ultima infatti si potrebbero avere risultati indefiniti e non
 corrispondenti a quanto aspettato.
 
 quest'ultima infatti si potrebbero avere risultati indefiniti e non
 corrispondenti a quanto aspettato.
 
index bfcd9cadb457e0446fb9f89f0a7bc4fd522ea120..0bae59c04094304df39739d08d4c0fe8c9cecec7 100644 (file)
@@ -260,13 +260,13 @@ tab.~\ref{tab:file_file_operations}.\footnote{essa può essere comunque
   detta funzione.} Questo avviene perché su Linux l'apertura di un file
 richiede comunque un'altra operazione che mette in gioco l'omonimo oggetto del
 VFS: l'allocazione di una struttura di tipo \kstruct{file} che viene associata
   detta funzione.} Questo avviene perché su Linux l'apertura di un file
 richiede comunque un'altra operazione che mette in gioco l'omonimo oggetto del
 VFS: l'allocazione di una struttura di tipo \kstruct{file} che viene associata
-ad ogni file aperto nel sistema.
-
-I motivi per cui viene usata una struttura a parte sono diversi, anzitutto,
-come illustrato in sez.~\ref{sec:file_fd}, questa è necessaria per le
-operazioni eseguite dai processi con l'interfaccia dei file descriptor; ogni
-processo infatti mantiene il riferimento ad una struttura \kstruct{file} per
-ogni file che ha aperto, ed è tramite essa che esegue le operazioni di I/O.
+ad ogni file aperto nel sistema.  I motivi per cui viene usata una struttura a
+parte sono diversi, anzitutto, come illustrato in sez.~\ref{sec:file_fd},
+questa è necessaria per le operazioni eseguite dai processi con l'interfaccia
+dei file descriptor. Ogni processo infatti mantiene il riferimento ad una
+struttura \kstruct{file} per ogni file che ha aperto, ed è tramite essa che
+esegue le operazioni di I/O. Inoltre il kernel mantiene un elenco di tutti i
+file aperti nella \itindex{file~table} \textit{file table}.
 
 Inoltre se le operazioni relative agli \textit{inode} fanno riferimento ad
 oggetti posti all'interno di un filesystem e vi si applicano quindi le
 
 Inoltre se le operazioni relative agli \textit{inode} fanno riferimento ad
 oggetti posti all'interno di un filesystem e vi si applicano quindi le
@@ -1722,7 +1722,7 @@ sono stati cancellati: solo quando il numero di collegamenti mantenuto
 lo spazio occupato su disco viene liberato. Si tenga presente comunque che a
 questo si aggiunge sempre un'ulteriore condizione e cioè che non ci siano
 processi che abbiano il suddetto file aperto.\footnote{come vedremo in
 lo spazio occupato su disco viene liberato. Si tenga presente comunque che a
 questo si aggiunge sempre un'ulteriore condizione e cioè che non ci siano
 processi che abbiano il suddetto file aperto.\footnote{come vedremo in
-  cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei
+  sez.~\ref{sec:file_unix_interface} il kernel mantiene anche una tabella dei
   file aperti nei vari processi, che a sua volta contiene i riferimenti agli
   \itindex{inode} \textit{inode} ad essi relativi; prima di procedere alla
   cancellazione dello spazio occupato su disco dal contenuto di un file il
   file aperti nei vari processi, che a sua volta contiene i riferimenti agli
   \itindex{inode} \textit{inode} ad essi relativi; prima di procedere alla
   cancellazione dello spazio occupato su disco dal contenuto di un file il
@@ -2001,7 +2001,7 @@ Tutto questo si riflette nello standard POSIX\footnote{le funzioni erano
 che ha introdotto una apposita interfaccia per la lettura delle directory,
 basata sui cosiddetti \textit{directory stream}, chiamati così per l'analogia
 con i \textit{file stream} dell'interfaccia standard ANSI C che vedremo in
 che ha introdotto una apposita interfaccia per la lettura delle directory,
 basata sui cosiddetti \textit{directory stream}, chiamati così per l'analogia
 con i \textit{file stream} dell'interfaccia standard ANSI C che vedremo in
-cap.~\ref{cha:files_std_interface}. La prima funzione di questa interfaccia è
+sez.~\ref{sec:files_std_interface}. La prima funzione di questa interfaccia è
 \funcd{opendir}, il cui prototipo è:
 
 \begin{funcproto}{
 \funcd{opendir}, il cui prototipo è:
 
 \begin{funcproto}{
@@ -3057,11 +3057,11 @@ In OpenBSD è stata introdotta un'altra funzione simile alle precedenti,
   più gli altri eventuali codici di errore di \func{mkdir}.}
 \end{funcproto}
 
   più gli altri eventuali codici di errore di \func{mkdir}.}
 \end{funcproto}
 
-La funzione genera una directory il cui nome è ottenuto sostituendo le
-\code{XXXXXX} finali di \param{template} con permessi \code{0700} (al solito
-si veda cap.~\ref{cha:file_unix_interface} per i dettagli). Dato che la
-creazione della directory è sempre esclusiva i precedenti problemi di
-\itindex{race~condition} \textit{race condition} non si pongono.
+La funzione crea una directory temporanea il cui nome è ottenuto sostituendo
+le \code{XXXXXX} finali di \param{template} con permessi \code{0700} (si veda
+sez.~\ref{sec:file_perm_overview} per i dettagli). Dato che la creazione della
+directory è sempre esclusiva i precedenti problemi di \itindex{race~condition}
+\textit{race condition} non si pongono.
 
 
 
 
 
 
@@ -3984,8 +3984,8 @@ crearlo o rinominarlo o cancellarlo invece occorrerà avere anche il permesso
 di scrittura per la directory.
 
 Avere il permesso di lettura per un file consente di aprirlo con le opzioni
 di scrittura per la directory.
 
 Avere il permesso di lettura per un file consente di aprirlo con le opzioni
-(si veda quanto riportato in tab.~\ref{tab:file_open_flags}) di sola lettura o
-di lettura/scrittura e leggerne il contenuto. Avere il permesso di scrittura
+(si veda quanto riportato in sez.~\ref{sec:file_open}) di sola lettura o di
+lettura/scrittura e leggerne il contenuto. Avere il permesso di scrittura
 consente di aprire un file in sola scrittura o lettura/scrittura e modificarne
 il contenuto, lo stesso permesso è necessario per poter troncare il file o per
 aggiornare il suo tempo di ultima modifica al tempo corrente, ma non per
 consente di aprire un file in sola scrittura o lettura/scrittura e modificarne
 il contenuto, lo stesso permesso è necessario per poter troncare il file o per
 aggiornare il suo tempo di ultima modifica al tempo corrente, ma non per
@@ -4517,8 +4517,8 @@ utenti non hanno motivi per modificarlo.
 \subsection{La gestione della titolarità dei file}
 \label{sec:file_ownership_management}
 
 \subsection{La gestione della titolarità dei file}
 \label{sec:file_ownership_management}
 
-Vedremo in sez.~\ref{sec:file_base_func} con quali funzioni si possono creare
-nuovi file, in tale occasione vedremo che è possibile specificare in sede di
+Vedremo in sez.~\ref{sec:file_open} con quali funzioni si possono creare nuovi
+file, in tale occasione vedremo che è possibile specificare in sede di
 creazione quali permessi applicare ad un file, però non si può indicare a
 quale utente e gruppo esso deve appartenere.  Lo stesso problema si presenta
 per la creazione di nuove directory (procedimento descritto in
 creazione quali permessi applicare ad un file, però non si può indicare a
 quale utente e gruppo esso deve appartenere.  Lo stesso problema si presenta
 per la creazione di nuove directory (procedimento descritto in
diff --git a/fileio.tex b/fileio.tex
new file mode 100644 (file)
index 0000000..f7bfdec
--- /dev/null
@@ -0,0 +1,3459 @@
+%% fileio.tex (merge fileunix.tex - filestd.tex)
+%%
+%% Copyright (C) 2000-2012 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",
+%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
+%% license is included in the section entitled "GNU Free Documentation
+%% License".
+%%
+
+\chapter{La gestione dei contenuti dei file}
+\label{cha:file_IO_interface}
+
+
+Esamineremo in questo capitolo le due interfacce di programmazione che
+consentono di gestire i dati mantenuti nei file. Cominceremo con quella nativa
+del sistema, detta dei \itindex{file~descriptor} \textit{file descriptor}, che
+viene fornita direttamente dalle \textit{system call} e che non prevede
+funzionalità evolute come la bufferizzazione o funzioni di lettura o scrittura
+formattata. Esamineremo poi anche l'interfaccia definita dallo standard ANSI
+C, che viene chiamata dei \textit{file stream} o anche più brevemente degli
+\textit{stream}. Per entrambe dopo una introduzione alle caratteristiche
+generali tratteremo le funzioni base per la gestione dell'I/O, lasciando per
+ultime le caratteristiche più avanzate.
+
+
+\section{L'interfaccia dei \textit{file descriptor}}
+\label{sec:file_unix_interface}
+
+
+Come visto in sez.~\ref{sec:file_vfs_work} il kernel mette a disposione
+tramite il \itindex{Virtual~File~System} \textit{Virtual File System} una
+serie di \textit{system call} che consentono di operare sui file in maniera
+generale. Abbiamo trattato quelle relative alla gestione delle proprietà dei
+file nel precedente capitolo, vedremo quelle che si applicano al contenuto dei
+file in questa sezione, iniziando con una breve introduzione sull'architettura
+dei \textit{file descriptor} per poi trattare le funzioni di base e le
+modalità con cui consentono di gestire i dati memorizzati sui file.
+
+
+\subsection{I \textit{file descriptor}}
+\label{sec:file_fd}
+
+\itindbeg{file~descriptor} 
+
+L'accesso al contenuto dei file viene effettuato, sia pure con differenze
+nella realizzazione pratica, in maniera sostanzialmente identica in tutte le
+implementazioni di un sistema unix-like, ricorrendo a quella che viene
+chiamata l'interfaccia dei \textit{file descriptor}.
+
+Per poter accedere al contenuto di un file occorre creare un canale di
+comunicazione con il kernel che renda possibile operare su di esso. Questo si
+fa aprendo il file con la funzione \func{open} (vedi sez.~\ref{sec:file_open})
+che provvederà a localizzare \itindex{inode} l'inode del file e inizializzare
+i puntatori che rendono disponibili le funzioni che il
+\itindex{Virtual~File~System} VFS mette a disposizione (quelle di
+tab.~\ref{tab:file_file_operations}). Una volta terminate le operazioni, il
+file dovrà essere chiuso, e questo chiuderà il canale di comunicazione
+impedendo ogni ulteriore operazione.
+
+All'interno di ogni processo i file aperti sono identificati da un numero
+intero non negativo, che viene chiamato \textit{file descriptor}.  Quando un
+file viene aperto la funzione \func{open} restituisce questo numero, tutte le
+ulteriori operazioni dovranno essere compiute specificando questo stesso
+numero come argomento alle varie funzioni dell'interfaccia.
+
+Per capire come funziona il meccanismo occorre spiegare a grandi linee come il
+kernel gestisce l'interazione fra processi e file.  Abbiamo già accennato in
+sez.~\ref{sec:proc_hierarchy} come il kernel mantenga un elenco di tutti
+processi nella cosiddetta \itindex{process~table} \textit{process table}. Lo
+stesso, come accennato in sez.~\ref{sec:file_vfs_work}, vale anche per tutti i
+file che sono stati aperti, il cui elenco viene mantenuto nella cosiddetta
+\itindex{file~table} \textit{file table}.
+
+La \itindex{process~table} \textit{process table} è una tabella che contiene
+una voce per ciascun processo attivo nel sistema. Ciascuna voce è costituita
+da una struttura di tipo \kstruct{task\_struct} nella quale sono raccolte
+tutte le informazioni relative al processo, fra queste informazioni c'è anche
+il puntatore ad una ulteriore struttura di tipo
+\kstruct{files\_struct},\footnote{la definizione corrente di questa struttura
+  si trova nel file \texttt{include/linux/fdtable.h} dei sorgenti del kernel,
+  quella mostrata in fig.~\ref{fig:file_proc_file} è una versione pesantemente
+  semplificata.} in cui sono contenute le informazioni relative ai file che il
+processo ha aperto.
+
+La \itindex{file~table} \textit{file table} è invece una tabella che contiene
+una voce per ciascun file che è stato aperto nel sistema. Come accennato in
+sez.~\ref{sec:file_vfs_work} per ogni file aperto viene allocata una struttura
+\kstruct{file} e la \textit{file table} è costituita da un elenco di puntatori
+a ciascuna di queste strutture, che come illustrato in
+fig.~\ref{fig:kstruct_file}, contengono le informazioni necessario per la
+gestione dei contenuti del file, fra cui:
+\begin{itemize*}
+\item lo stato del file nel campo \var{f\_flags}.
+\item la posizione corrente nel file, il cosiddetto \textit{offset}, nel campo
+  \var{f\_pos}.
+\item un puntatore alla struttura \kstruct{inode} che identifica
+  \itindex{inode} l'\textit{inode} del file.\footnote{nel kernel 2.4.x si è in
+    realtà passati ad un puntatore ad una struttura \kstruct{dentry} che punta
+    a sua volta \itindex{inode} all'\textit{inode} passando per la nuova
+    struttura del VFS.}
+\item un puntatore \var{f\_op} alla tabella delle funzioni che si possono
+  usare sul file.\footnote{quelle della struttura \kstruct{file\_operation},
+    descritte sommariamente in tab.~\ref{tab:file_file_operations}.}
+\end{itemize*}
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=13cm]{img/procfile}
+  \caption{Schema della architettura dell'accesso ai file attraverso
+  l'interfaccia dei \textit{file descriptor}.}
+  \label{fig:file_proc_file}
+\end{figure}
+
+In fig.~\ref{fig:file_proc_file} si è riportato uno schema semplificato in cui
+è illustrata questa architettura, ed in cui si sono evidenziate le
+interrelazioni fra la \itindex{file~table} \textit{file table}, la
+\itindex{process~table} \textit{process table} e le varie strutture di dati
+che il kernel mantiene per ciascun file e ciascun processo.
+
+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
+essenziali come:
+\begin{itemize*}
+\item i flag relativi ai file aperti dal processo.
+\item il numero di file aperti dal processo.
+\item una tabella di puntatori alla relativa voce nella \itindex{file~table}
+  \textit{file table} per ciascun file aperto.
+\end{itemize*}
+
+In questa infrastruttura un \textit{file descriptor} non è altro che l'intero
+positivo che indicizza quest'ultima tabella, grazie al quale si può recuperare
+il puntatore alla struttura \kstruct{file} nella \itindex{file~table}
+\textit{file table} corrispondente al file che è stato aperto dal processo e a
+cui era stato assegnato questo indice. Ma una volta indicato col \textit{file
+  descriptor} qual'è la struttura \kstruct{file} nella \textit{file table}
+corrispondente al file voluto, il kernel potrà usare le funzioni messe
+disposizione dal VFS per eseguire sul file tutte le operazioni necessarie.
+
+Il meccanismo dell'apertura dei file prevede che venga sempre fornito il primo
+\textit{file descriptor} libero nella tabella, e per questo motivo essi
+vengono assegnati in successione tutte le volte che si apre un nuovo file,
+posto che non ne sia stato chiuso nessuno in precedenza.
+
+In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
+processo viene lanciato dalla shell con almeno tre file aperti. Questi, per
+quanto appena detto, avranno come \itindex{file~descriptor} \textit{file
+  descriptor} i valori 0, 1 e 2.  Benché questa sia soltanto una convenzione,
+essa è seguita dalla gran parte delle applicazioni, e non aderirvi potrebbe
+portare a gravi problemi di interoperabilità.
+
+Il primo file è sempre associato al cosiddetto \textit{standard input}; è cioè
+il file da cui un processo si aspetta di ricevere i dati in ingresso. Il
+secondo file è il cosiddetto \textit{standard output}, cioè quello su cui ci
+si aspetta debbano essere inviati i dati in uscita. Il terzo è lo
+\textit{standard error}, su cui viene inviata l'uscita relativa agli errori.
+Nel caso della shell tutti questi file sono associati al terminale di
+controllo, e corrispondono quindi alla lettura della tastiera per l'ingresso e
+alla scrittura sul terminale per l'uscita.  Lo standard POSIX.1 provvede, al
+posto dei valori numerici, tre costanti simboliche, definite in
+tab.~\ref{tab:file_std_files}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{File} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{STDIN\_FILENO}  & \textit{file descriptor} dello \textit{standard
+      input} \\
+    \const{STDOUT\_FILENO} & \textit{file descriptor} dello \textit{standard
+      output} \\
+    \const{STDERR\_FILENO} & \textit{file descriptor} dello \textit{standard
+      error}\\
+    \hline
+  \end{tabular}
+  \caption{Costanti definite in \headfile{unistd.h} per i file standard aperti 
+    alla creazione di ogni processo.}
+  \label{tab:file_std_files}
+\end{table}
+
+In fig.~\ref{fig:file_proc_file} si è rappresentata una situazione diversa
+rispetto a quella usuale della shell, in cui tutti e tre questi file fanno
+riferimento al terminale su cui si opera. Nell'esempio invece viene illustrata
+la situazione di un programma in cui lo \textit{standard input} è associato ad
+un certo file mentre lo \textit{standard output} e lo \textit{standard error}
+sono entrambi associati ad un altro file. 
+
+Si noti come questi ultimi, pur utilizzando strutture \kstruct{file} diverse,
+essendo il file che è stato aperto lo stesso, fanno a loro volta riferimento
+allo stesso \itindex{inode} \textit{inode}. Questo è quello che avviene
+normalmente quando si apre più volte lo stesso file.
+
+Si ritrova quindi anche con le voci della \itindex{file~table} \textit{file
+  table} una situazione analoga di quella delle voci di una directory, con la
+possibilità di avere più voci che fanno riferimento allo stesso
+\itindex{inode} \textit{inode}. L'analogia è in realtà molto stretta perché
+quando si cancella un file, il kernel verifica anche che non resti nessun
+riferimento in una una qualunque voce della \itindex{file~table} \textit{file
+  table} prima di liberare le risorse ad esso associate e disallocare il
+relativo \itindex{inode} \textit{inode}.
+
+Nelle vecchie versioni di Unix (ed anche in Linux fino al kernel 2.0.x) il
+numero di file aperti era anche soggetto ad un limite massimo dato dalle
+dimensioni del vettore di puntatori con cui era realizzata la tabella dei file
+descriptor dentro \kstruct{files\_struct}; questo limite intrinseco nei kernel
+più recenti non sussiste più, dato che si è passati da un vettore ad una
+lista, ma restano i limiti imposti dall'amministratore (vedi
+sez.~\ref{sec:sys_limits}).
+
+
+
+\subsection{Apertura e creazione di un file}
+\label{sec:file_open}
+
+La funzione di sistema \funcd{open} è la funzione fondamentale
+dell'interfaccia di gestione dei file su Unix, ed è quella che dato un
+\textit{pathname} consente di ottenere un file descriptor ``\textsl{aprendo}''
+il file corrispondente,\footnote{è questa funzione che alloca la struttura
+  \kstruct{file}, la inserisce nella \itindex{file~table} \textit{file table}
+  e crea il riferimento nella \kstruct{files\_struct} del processo.} il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fhead{fcntl.h}
+\fdecl{int open(const char *pathname, int flags)}
+\fdecl{int open(const char *pathname, int flags, mode\_t mode)}
+
+\fdesc{Apre un file.} 
+}
+
+{La funzione ritorna il file descriptor in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EEXIST}] \param{pathname} esiste e si è specificato
+    \const{O\_CREAT} e \const{O\_EXCL}.  
+  \item[\errcode{EISDIR}] \param{pathname} indica una directory e si è tentato
+    l'accesso in scrittura. 
+  \item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e
+    \param{pathname} non è una directory.
+  \item[\errcode{ENXIO}] si sono impostati \const{O\_NOBLOCK} o
+    \const{O\_WRONLY} ed il file è una fifo che non viene letta da nessun
+    processo o \param{pathname} è un file di dispositivo ma il dispositivo è
+    assente.
+  \item[\errcode{ENODEV}] \param{pathname} si riferisce a un file di
+    dispositivo che non esiste.
+  \item[\errcode{ETXTBSY}] si è cercato di accedere in scrittura all'immagine
+    di un programma in esecuzione.
+  \item[\errcode{ELOOP}] si sono incontrati troppi link simbolici nel
+    risolvere il \textit{pathname} o si è indicato \const{O\_NOFOLLOW} e
+    \param{pathname} è un link simbolico.
+  \end{errlist}
+  ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+  \errval{EROFS}, \errval{EFAULT}, \errval{ENOSPC}, \errval{ENOMEM},
+  \errval{EMFILE} e \errval{ENFILE} nel loro significato generico.}
+\end{funcproto}
+
+La funzione apre il file indicato da \param{pathname} nella modalità indicata da
+\param{flags}. Essa può essere invocata in due modi diversi, specificando
+opzionalmente un terzo argomento \param{mode}. Qualora il file non esista e
+venga creato, questo argomento consente di indicare quali permessi dovranno
+essergli assegnati.  La funzione restituisce il primo file descriptor libero.
+
+Quest'ultima caratteristica permette di prevedere sempre qual è il valore del
+file descriptor che si otterrà al ritorno di \func{open}, e viene talvolta
+usata da alcune applicazioni per sostituire i file corrispondenti ai file
+standard visti in tab.~\ref{tab:file_std_files}. 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).
+
+Al momento dell'apertura il nuovo file descriptor non è condiviso con nessun
+altro processo (torneremo sulla condivisione dei file, in genere accessibile
+dopo una \func{fork}, in sez.~\ref{sec:file_sharing}) ed è impostato per
+restare aperto attraverso una \func{exec} (come accennato in
+sez.~\ref{sec:proc_exec}). L'\textit{offset} è impostato all'inizio del file.
+
+L'argomento opzionale \param{mode} indica i permessi con cui il file viene
+creato ed i valori possibili sono gli stessi già visti in
+sez.~\ref{sec:file_perm_overview} e possono essere specificati come OR binario
+delle costanti descritte in tab.~\ref{tab:file_bit_perm}. Questi permessi sono
+filtrati dal valore di \itindex{umask} \textit{umask} (vedi
+sez.~\ref{sec:file_perm_management}) per il processo.
+
+La funzione prevede diverse opzioni, che vengono specificate usando vari bit
+dell'argomento \param{flags}.  Alcuni di questi bit vanno anche a costituire
+il cosiddetto flag di stato del file (o \textit{file status flag}), che è
+mantenuto nel campo \var{f\_flags} della struttura \kstruct{file} (al solito
+si veda lo schema di fig.~\ref{fig:file_proc_file}).  Essi sono divisi in tre
+categorie principali:
+\begin{itemize*}
+\item \textsl{i bit delle modalità di accesso}: specificano con quale modalità
+  si accederà 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 impostati alla chiamata da \func{open}, e possono
+  essere riletti con \func{fcntl} (fanno parte del \textit{file status flag}),
+  ma non possono essere modificati.
+\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{O\_RDONLY}] Apre il file in sola lettura, le \acr{glibc}
+  definiscono anche \const{O\_READ} come sinonimo.
+\item[\const{O\_WRONLY}] Apre il file in sola scrittura, le \acr{glibc}
+  definiscono anche \const{O\_WRITE} come sinonimo.
+\item[\const{O\_RDWR}] Apre il file sia in lettura che in scrittura.
+\end{basedescript}
+\item \textsl{i bit delle modalità di operazione}: permettono di specificare
+  alcune caratteristiche del comportamento delle future operazioni sul file
+  (come \func{read} o \func{write}). Anch'essi fan parte del \textit{file
+    status flag}. Il loro valore è impostato alla chiamata di \func{open}, ma
+  possono essere riletti e modificati (insieme alle caratteristiche operative
+  che controllano) con una \func{fcntl}.
+\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\const{O\_CREAT}] Se il file non esiste verrà creato, con le regole di
+  titolarità del file viste in sez.~\ref{sec:file_ownership_management}. Con
+  questa opzione l'argomento \param{mode} deve essere specificato.
+
+\item[\const{O\_EXCL}] Usato in congiunzione con \const{O\_CREAT} fa sì che la
+  precedente esistenza del file diventi un errore\footnote{la pagina di
+    manuale di \func{open} segnala che questa opzione è difettosa su NFS, e
+    che i programmi che la usano per stabilire un \index{file!di lock}
+    \textsl{file di lock} possono incorrere in una \itindex{race~condition}
+    \textit{race condition}.  Si consiglia come alternativa di usare un file
+    con un nome univoco e la funzione \func{link} per verificarne l'esistenza
+    (vedi sez.~\ref{sec:ipc_file_lock}).} che fa fallire \func{open} con
+  \errcode{EEXIST}.
+
+\item[\const{O\_NONBLOCK}] Apre il file in modalità non bloccante, e comporta
+  che \func{open} ritorni immediatamente anche quando dovrebbe bloccarsi
+  (l'opzione ha senso solo per le fifo, vedi sez.~\ref{sec:ipc_named_pipe}).
+
+\item[\const{O\_NOCTTY}] Se \param{pathname} si riferisce ad un dispositivo di
+  terminale, questo non diventerà il terminale di controllo, anche se il
+  processo non ne ha ancora uno (si veda sez.~\ref{sec:sess_ctrl_term}).
+
+\item[\const{O\_SHLOCK}] Apre il file con uno shared lock (vedi
+  sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux.
+
+\item[\const{O\_EXLOCK}] Apre il file con un lock esclusivo (vedi
+  sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux.
+
+\item[\const{O\_TRUNC}] Se usato su un file di dati aperto in scrittura, ne
+  tronca la lunghezza a zero; con un terminale o una fifo viene ignorato,
+  negli altri casi il comportamento non è specificato.
+
+\item[\const{O\_NOFOLLOW}] Se \param{pathname} è un link simbolico la chiamata
+  fallisce. Questa è un'estensione BSD aggiunta in Linux dal kernel
+  2.1.126. Nelle versioni precedenti i link simbolici sono sempre seguiti, e
+  questa opzione è ignorata.
+
+\item[\const{O\_DIRECTORY}] Se \param{pathname} non è una directory la
+  chiamata fallisce. Questo flag è specifico di Linux ed è stato introdotto
+  con il kernel 2.1.126 per evitare dei \itindex{Denial~of~Service~(DoS)}
+  \textit{DoS}\footnote{acronimo di \itindex{Denial~of~Service~(DoS)}
+    \textit{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 dispositivo associato ad una unità a
+  nastri, non deve dispositivo a nastri; non deve essere utilizzato
+  al di fuori dell'implementazione di \func{opendir}.
+
+\item[\const{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.
+\end{basedescript}
+\item \textsl{i bit delle modalità di apertura}: permettono di specificare
+  alcune delle caratteristiche del comportamento di \func{open} quando viene
+  eseguita. Hanno effetto solo al momento della chiamata della funzione e non
+  sono memorizzati né possono essere riletti.
+\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\const{O\_APPEND}] Il file viene aperto in \itindex{append~mode}
+  \textit{append mode}. Prima di ciascuna scrittura la posizione corrente
+  viene sempre impostata alla fine del file. Con NFS si può avere una
+  corruzione del file se più di un processo scrive allo stesso
+  tempo.\footnote{il problema è che NFS non supporta la scrittura in
+    \itindex{append~mode} \textit{append}, ed il kernel deve simularla, ma
+    questo comporta la possibilità di una \itindex{race~condition}
+    \textit{race condition}, vedi sez.~\ref{sec:file_atomic}.}
+
+\item[\const{O\_NONBLOCK}] Il file viene aperto in modalità non bloccante per
+  le operazioni di I/O (che tratteremo in sez.~\ref{sec:file_noblocking}):
+  questo significa il fallimento di \func{read} in assenza di dati da leggere
+  e quello di \func{write} in caso di impossibilità di scrivere
+  immediatamente. Questa modalità ha senso solo per le fifo e per alcuni file
+  di dispositivo.
+
+\item[\const{O\_NDELAY}] In Linux è sinonimo di
+  \const{O\_NONBLOCK}.\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 un'ambiguità, dato che come vedremo in
+    sez.~\ref{sec:file_read} il ritorno di zero da parte di \func{read} ha il
+    significato di una \textit{end-of-file}.}
+
+\item[\const{O\_ASYNC}] Apre il file per l'I/O in modalità asincrona (vedi
+  sez.~\ref{sec:file_asyncronous_io}). Quando è impostato viene generato il
+  segnale \signal{SIGIO} tutte le volte che sono disponibili dati in input sul
+  file.
+
+\item[\const{O\_SYNC}] Apre il file per l'input/output sincrono: ogni
+  \func{write} bloccherà fino al completamento della scrittura di tutti i dati
+  sull'hardware sottostante.
+
+\item[\const{O\_FSYNC}] Sinonimo di \const{O\_SYNC}, usato da BSD.
+
+\item[\const{O\_DSYNC}] Variante di I/O sincrono definita da POSIX; presente
+  dal kernel 2.1.130 come sinonimo di \const{O\_SYNC}.
+
+\item[\const{O\_RSYNC}] Variante analoga alla precedente, trattata allo stesso
+  modo.
+
+\item[\const{O\_NOATIME}] Blocca l'aggiornamento dei tempi di accesso dei file
+  (vedi sez.~\ref{sec:file_file_times}). Per molti filesystem questa
+  funzionalità non è disponibile per il singolo file ma come opzione generale
+  da specificare in fase di montaggio.
+
+\item[\const{O\_DIRECT}] Esegue l'I/O direttamente dai buffer in user space in
+  maniera sincrona, in modo da scavalcare i meccanismi di caching del
+  kernel. In genere questo peggiora le prestazioni tranne quando le
+  applicazioni ottimizzano il proprio caching.\footnote{l'opzione è stata
+    introdotta dalla SGI in IRIX, e serve sostanzialmente a permettere ad
+    alcuni programmi (in genere database) la gestione diretta della
+    bufferizzazione dell'I/O in quanto essi sono in grado di ottimizzarla al
+    meglio per le loro prestazioni; l'opzione è presente anche in FreeBSD,
+    senza limiti di allineamento dei buffer. In Linux è stata introdotta con
+    il kernel 2.4.10, le versioni precedenti la ignorano.}  Per i kernel della
+  serie 2.4 si deve garantire che i buffer in user space siano allineati alle
+  dimensioni dei blocchi del filesystem; per il kernel 2.6 basta che siano
+  allineati a multipli di 512 byte.
+
+\item[\const{O\_CLOEXEC}] Attiva la modalità di \itindex{close-on-exec}
+  \textit{close-on-exec} (vedi sez.~\ref{sec:file_sharing} e
+  \ref{sec:file_fcntl}).\footnote{introdotto con il kernel 2.6.23, per evitare
+    una \itindex{race~condition} \textit{race condition} che si può verificare
+    con i \itindex{thread} \textit{thread}, fra l'apertura del file e
+    l'impostazione della suddetta modalità con \func{fcntl}.}
+\end{basedescript}
+\end{itemize*}
+
+
+%TODO trattare le differenze fra O_DSYNC, O_SYNC e O_RSYNC introdotte nella  
+% nello sviluppo del kernel 2.6.33, vedi http://lwn.net/Articles/350219/
+
+
+In tab.~\ref{tab:file_open_flags} sono riportate, ordinate e divise fra loro
+secondo le tre modalità appena elencate, le costanti mnemoniche associate a
+ciascuno di questi bit. Dette costanti possono essere combinate fra loro con
+un OR aritmetico per costruire il valore (in forma di maschera binaria)
+dell'argomento \param{flags} da passare alla \func{open}. I due flag
+\const{O\_NOFOLLOW} e \const{O\_DIRECTORY} sono estensioni specifiche di
+Linux, e deve essere definita la macro \macro{\_GNU\_SOURCE} per poterli
+usare.
+
+Nelle prime versioni di Unix i valori di \param{flag} specificabili per
+\func{open} erano solo quelli relativi alle modalità di accesso del file.  Per
+questo motivo per creare un nuovo file c'era una system call apposita,
+\funcd{creat}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{fcntl.h}
+\fdecl{int creat(const char *pathname, mode\_t mode)}
+\fdesc{Crea un nuovo file vuoto.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà gli stessi valori che si otterebbero con
+  \func{open}.}
+\end{funcproto}
+
+
+La funzione crea un nuovo file vuoto, con i permessi specificati
+dall'argomento \param{mode}. È del tutto equivalente a \code{open(filedes,
+  O\_CREAT|O\_WRONLY|O\_TRUNC, mode)} e resta solo per compatibilità con i
+vecchi programmi.
+
+
+\subsection{La funzione \func{close}}
+\label{sec:file_close}
+
+La funzione \funcd{close} permette di chiudere un file, in questo modo il file
+descriptor ritorna disponibile; il suo prototipo è:
+\begin{prototype}{unistd.h}{int close(int fd)}
+  Chiude il descrittore \param{fd}. 
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+    errore, con \var{errno} che assume i valori:
+  \begin{errlist}
+    \item[\errcode{EBADF}]  \param{fd} non è un descrittore valido.
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+  \end{errlist}
+  ed inoltre \errval{EIO}.}
+\end{prototype}
+
+La chiusura di un file rilascia ogni blocco (il \textit{file locking}
+\itindex{file~locking} è trattato in sez.~\ref{sec:file_locking}) che il
+processo poteva avere acquisito su di esso; se \param{fd} è l'ultimo
+riferimento (di eventuali copie) ad un file aperto, tutte le risorse nella
+\itindex{file~table} \textit{file table} vengono rilasciate. Infine se il file
+descriptor era l'ultimo riferimento ad un file su disco quest'ultimo viene
+cancellato.
+
+Si ricordi che quando un processo termina anche tutti i suoi file descriptor
+vengono chiusi, molti programmi sfruttano questa caratteristica e non usano
+esplicitamente \func{close}. In genere comunque chiudere un file senza
+controllarne lo stato di uscita è errore; infatti molti filesystem
+implementano la tecnica del \textit{write-behind}, per cui una \func{write}
+può avere successo anche se i dati non sono stati scritti, un eventuale errore
+di I/O allora può sfuggire, ma verrà riportato alla chiusura del file: per
+questo motivo non effettuare il controllo può portare ad una perdita di dati
+inavvertita.\footnote{in Linux questo comportamento è stato osservato con NFS
+  e le quote su disco.}
+
+In ogni caso una \func{close} andata a buon fine non garantisce che i dati
+siano stati effettivamente scritti su disco, perché il kernel può decidere di
+ottimizzare l'accesso a disco ritardandone la scrittura. L'uso della funzione
+\func{sync} (vedi sez.~\ref{sec:file_sync}) effettua esplicitamente il
+\emph{flush} dei dati, ma anche in questo caso resta l'incertezza dovuta al
+comportamento dell'hardware (che a sua volta può introdurre ottimizzazioni
+dell'accesso al disco che ritardano la scrittura dei dati, da cui l'abitudine
+di ripetere tre volte il comando prima di eseguire lo shutdown).
+
+
+\subsection{La gestione della posizione nel file}
+\label{sec:file_lseek}
+
+Come già accennato in sez.~\ref{sec:file_fd} a ciascun file aperto è associata
+una \textsl{posizione corrente nel file} (il cosiddetto \textit{file offset},
+mantenuto nel campo \var{f\_pos} di \kstruct{file}) espressa da un numero intero
+positivo come numero di byte dall'inizio del file. Tutte le operazioni di
+lettura e scrittura avvengono a partire da questa posizione che viene
+automaticamente spostata in avanti del numero di byte letti o scritti.
+
+In genere (a meno di non avere richiesto la modalità \itindex{append~mode}
+\const{O\_APPEND}) questa posizione viene impostata a zero all'apertura del
+file. È possibile impostarla ad un valore qualsiasi con la funzione
+\funcd{lseek}, il cui prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h}
+  \headdecl{unistd.h}
+  \funcdecl{off\_t lseek(int fd, off\_t offset, int whence)}
+  Imposta la posizione attuale nel file. 
+  
+  \bodydesc{La funzione ritorna il valore della posizione corrente in caso di
+    successo e $-1$ in caso di errore nel qual caso \var{errno} assumerà uno
+    dei valori:
+  \begin{errlist}
+    \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo.
+    \item[\errcode{EINVAL}] \param{whence} non è un valore valido.
+    \item[\errcode{EOVERFLOW}] \param{offset} non può essere rappresentato nel
+      tipo \type{off\_t}.
+  \end{errlist}
+  ed inoltre \errval{EBADF}.}
+\end{functions}
+
+La nuova posizione è impostata usando il valore specificato da \param{offset},
+sommato al riferimento dato da \param{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
+  \const{L\_SET}, \const{L\_INCR} e \const{L\_XTND}.}:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\const{SEEK\_SET}] si fa riferimento all'inizio del file: il valore
+  (sempre positivo) di \param{offset} indica direttamente la nuova posizione
+  corrente.
+\item[\const{SEEK\_CUR}] si fa riferimento alla posizione corrente del file:
+  ad essa viene sommato \param{offset} (che può essere negativo e positivo)
+  per ottenere la nuova posizione corrente.
+\item[\const{SEEK\_END}] si fa riferimento alla fine del file: alle dimensioni
+  del file viene sommato \param{offset} (che può essere negativo e positivo)
+  per ottenere la nuova posizione corrente.
+\end{basedescript}
+
+% TODO, trattare, SEEK_HOLE e SEEK_DATA, inclusi nel kernel 3.1, vedi
+% http://lwn.net/Articles/439623/ 
+
+
+Si tenga presente che la chiamata a \func{lseek} non causa nessun accesso al
+file, si limita a modificare la posizione corrente (cioè il valore
+\var{f\_pos} in \param{file}, vedi fig.~\ref{fig:file_proc_file}).  Dato che
+la funzione ritorna la nuova posizione, usando il valore zero
+per \param{offset} si può riottenere la posizione corrente nel file chiamando
+la funzione con \code{lseek(fd, 0, SEEK\_CUR)}.
+
+Si tenga presente inoltre che usare \const{SEEK\_END} non assicura affatto che
+la 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 impostata in precedenza
+(questa è una potenziale sorgente di \itindex{race~condition} \textit{race
+  condition}, vedi sez.~\ref{sec:file_atomic}).
+
+Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
+questo caso la funzione ritorna l'errore \errcode{ESPIPE}. 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 i file di
+terminale.\footnote{altri sistemi, usando \const{SEEK\_SET}, in questo caso
+  ritornano il numero di caratteri che vi sono stati scritti.} Lo standard
+POSIX però non specifica niente in proposito. Inoltre alcuni
+\index{file!speciali} file speciali, ad esempio \file{/dev/null}, non causano
+un errore ma restituiscono un valore indefinito.
+
+\itindbeg{sparse~file} 
+
+Infine si tenga presente che, come accennato in sez.~\ref{sec:file_file_size},
+con \func{lseek} è possibile impostare una posizione anche oltre la corrente
+fine del file; ed in tal caso alla successiva scrittura il file sarà esteso a
+partire da detta posizione. In questo caso si ha quella che viene chiamata la
+creazione di un \index{file!\textit{hole}} \textsl{buco} nel file, accade cioè
+che nonostante la dimensione del file sia cresciuta in seguito alla scrittura
+effettuata, lo spazio vuoto fra la precedente fine del file ed la nuova parte
+scritta dopo lo spostamento, non corrisponda ad una allocazione effettiva di
+spazio su disco, che sarebbe inutile dato che quella zona è effettivamente
+vuota.
+
+Questa è una delle caratteristiche spcifiche della gestione dei file di un
+sistema unix-like, ed in questo caso si ha appunto quello che in gergo si
+chiama un \index{file!\textit{hole}} \textit{hole} nel file e si dice che il
+file in questione è uno \textit{sparse file}. In sostanza, se si ricorda la
+struttura di un filesystem illustrata in fig.~\ref{fig:file_filesys_detail},
+quello che accade è che nell'\textit{inode} del file viene segnata
+l'allocazione di un blocco di dati a partire dalla nuova posizione, ma non
+viene allocato nulla per le posizioni intermedie; in caso di lettura
+sequenziale del contenuto del file il kernel si accorgerà della presenza del
+buco, e restituirà degli zeri come contenuto di quella parte del file.
+
+Questa funzionalità comporta una delle caratteristiche della gestione dei file
+su Unix che spesso genera più confusione in chi non la conosce, per cui
+sommando le dimensioni dei file si può ottenere, se si hanno molti
+\textit{sparse file}, un totale anche maggiore della capacità del proprio
+disco e comunque maggiore della dimensione che riporta un comando come
+\cmd{du}, che calcola lo spazio disco occupato in base al numero dei blocchi
+effettivamente allocati per il file.
+
+Questo avviene proprio perché in un sistema unix-like la dimensione di un file
+è una caratteristica del tutto indipendente dalla quantità di spazio disco
+effettivamente allocato, e viene registrata sull'\textit{inode} come le altre
+proprietà del file. La dimensione viene aggiornata automaticamente quando si
+estende un file scrivendoci, e viene riportata dal campo \var{st\_size} di una
+struttura \struct{stat} quando si effettua chiamata ad una delle funzioni
+\texttt{*stat} viste in sez.~\ref{sec:file_stat}.
+
+Questo comporta che in generale, fintanto che lo si è scritto sequenzialmente,
+la dimensione di un file sarà più o meno corrispondente alla quantità di
+spazio disco da esso occupato, ma esistono dei casi, come questo in cui ci si
+sposta in una posizione oltre la fine corrente del file, o come quello
+accennato in in sez.~\ref{sec:file_file_size} in cui si estende la dimensione
+di un file con una \func{truncate}, in cui in sostanza di modifica il valore
+della dimensione di \var{st\_size} senza allocare spazio su disco. Questo
+consente di creare inizialmente file di dimensioni anche molto grandi, senza
+dover occupare da subito dello spazio disco che in realtà sarebbe
+inutilizzato.
+
+\itindend{sparse~file}
+
+
+\subsection{Le funzioni per la lettura}
+\label{sec:file_read}
+
+Una volta che un file è stato aperto (con il permesso in lettura) si possono
+leggere i dati che contiene utilizzando la funzione \funcd{read}, il cui
+prototipo è:
+\begin{prototype}{unistd.h}{ssize\_t read(int fd, void * buf, size\_t count)}
+  
+  Cerca di leggere \param{count} byte dal file \param{fd} al buffer
+  \param{buf}.
+  
+  \bodydesc{La funzione ritorna il numero di byte letti in caso di successo e
+    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale prima di
+    aver potuto leggere qualsiasi dato.
+  \item[\errcode{EAGAIN}] la funzione non aveva nessun dato da restituire e si
+    era aperto il file in modalità \const{O\_NONBLOCK}.
+  \end{errlist}
+  ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF},
+  \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori dipendenti dalla
+  natura dell'oggetto connesso a \param{fd}.}
+\end{prototype}
+
+La funzione tenta di leggere \param{count} byte a partire dalla posizione
+corrente nel file. 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.  Si deve sempre tener
+presente che non è detto che la funzione \func{read} restituisca sempre 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
+sua fine, e la funzione ritorna regolarmente il numero di byte letti
+effettivamente. Raggiunta la fine del file, alla ripetizione di un'operazione
+di lettura, otterremmo il ritorno immediato di \func{read} con uno zero.  La
+condizione di raggiungimento della fine del file non è un errore, e viene
+segnalata appunto da un valore di ritorno di \func{read} nullo. Ripetere
+ulteriormente la lettura non avrebbe nessun effetto se non quello di
+continuare a ricevere zero come valore di ritorno.
+
+Con i \textsl{file regolari} questa è l'unica situazione in cui si può avere
+un numero di byte letti inferiore a quello richiesto, ma questo non è vero
+quando si legge da un terminale, da una fifo o da una pipe. In tal caso
+infatti, se non ci sono dati in ingresso, la \func{read} si blocca (a meno di
+non aver selezionato la modalità non bloccante, vedi
+sez.~\ref{sec:file_noblocking}) e ritorna solo quando ne arrivano; se il numero
+di byte richiesti eccede quelli disponibili la funzione ritorna comunque, ma
+con un numero di byte inferiore a quelli richiesti.
+
+Lo stesso comportamento avviene caso di lettura dalla rete (cioè su un socket,
+come vedremo in sez.~\ref{sec:sock_io_behav}), o per la lettura da certi file
+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.
+
+Infine anche le due condizioni segnalate dagli errori \errcode{EINTR} ed
+\errcode{EAGAIN} non sono propriamente degli errori. La prima si verifica
+quando la \func{read} è bloccata in attesa di dati in ingresso e viene
+interrotta da un segnale; in tal caso l'azione da intraprendere è quella di
+rieseguire la funzione.  Torneremo in dettaglio sull'argomento in
+sez.~\ref{sec:sig_gen_beha}.  La seconda si verifica quando il file è aperto
+in modalità non bloccante (vedi sez.~\ref{sec:file_noblocking}) e non ci sono
+dati in ingresso: la funzione allora ritorna immediatamente con un errore
+\errcode{EAGAIN}\footnote{in BSD si usa per questo errore la costante
+  \errcode{EWOULDBLOCK}, in Linux, con le \acr{glibc}, questa è sinonima di
+  \errcode{EAGAIN}.} che indica soltanto che non essendoci al momento dati
+disponibili occorre provare a ripetere la lettura in un secondo tempo.
+
+La funzione \func{read} è una delle system call fondamentali, esistenti fin
+dagli albori di Unix, ma nella seconda versione delle \textit{Single Unix
+  Specification}\footnote{questa funzione, e l'analoga \func{pwrite} sono
+  state aggiunte nel kernel 2.1.60, il supporto nelle \acr{glibc}, compresa
+  l'emulazione per i vecchi kernel che non hanno la system call, è stato
+  aggiunto con la versione 2.1, in versioni precedenti sia del kernel che
+  delle librerie la funzione non è disponibile.} (quello che viene chiamato
+normalmente Unix98, vedi sez.~\ref{sec:intro_xopen}) è stata introdotta la
+definizione di un'altra funzione di lettura, \funcd{pread}, il cui prototipo è:
+\begin{prototype}{unistd.h}
+{ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)}
+
+Cerca di leggere \param{count} byte dal file \param{fd}, a partire dalla
+posizione \param{offset}, nel buffer \param{buf}.
+  
+\bodydesc{La funzione ritorna il numero di byte letti in caso di successo e
+  $-1$ in caso di errore, nel qual caso \var{errno} assumerà i valori già
+  visti per \func{read} e \func{lseek}.}
+\end{prototype}
+
+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
+importante quando la posizione sul file viene condivisa da processi diversi
+(vedi sez.~\ref{sec:file_sharing}).  Il valore di
+\param{offset} fa sempre riferimento all'inizio del file.
+
+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{verbatim}
+#define _XOPEN_SOURCE 500
+\end{verbatim}
+e si ricordi di definire questa macro prima dell'inclusione del file di
+dichiarazioni \headfile{unistd.h}.
+
+
+
+\subsection{Le funzioni per la scrittura}
+\label{sec:file_write}
+
+Una volta che un file è stato aperto (con il permesso in scrittura) si può
+scrivere su di esso utilizzando la funzione \funcd{write}, il cui prototipo è:
+\begin{prototype}{unistd.h}{ssize\_t write(int fd, void * buf, size\_t count)}
+  
+  Scrive \param{count} byte dal buffer \param{buf} sul file \param{fd}.
+  
+  \bodydesc{La funzione ritorna il numero di byte scritti in caso di successo
+    e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei
+    valori:
+  \begin{errlist}
+  \item[\errcode{EINVAL}] \param{fd} è connesso ad un oggetto che non consente
+    la scrittura.
+  \item[\errcode{EFBIG}] si è cercato di scrivere oltre la dimensione massima
+    consentita dal filesystem o il limite per le dimensioni dei file del
+    processo o su una posizione oltre il massimo consentito.
+  \item[\errcode{EPIPE}] \param{fd} è connesso ad una pipe il cui altro capo è
+    chiuso in lettura; in questo caso viene anche generato il segnale
+    \signal{SIGPIPE}, se questo viene gestito (o bloccato o ignorato) la
+    funzione ritorna questo errore.
+  \item[\errcode{EINTR}] si è stati interrotti da un segnale prima di aver
+    potuto scrivere qualsiasi dato.
+  \item[\errcode{EAGAIN}] ci si sarebbe bloccati, ma il file era aperto in
+    modalità \const{O\_NONBLOCK}.
+  \end{errlist}
+  ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF},
+  \errval{ENOSPC}, \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori
+  dipendenti dalla natura dell'oggetto connesso a \param{fd}.}
+\end{prototype}
+
+Come nel caso di \func{read} la funzione tenta di scrivere \param{count} byte
+a partire dalla posizione corrente nel file e sposta automaticamente la
+posizione in avanti del numero di byte scritti. Se il file è aperto in
+modalità \itindex{append~mode} \const{O\_APPEND} i dati vengono sempre scritti
+alla fine del file.  Lo standard POSIX richiede che i dati scritti siano
+immediatamente disponibili ad una \func{read} chiamata dopo che la
+\func{write} che li ha scritti è ritornata; ma dati i meccanismi di caching
+non è detto che tutti i filesystem supportino questa capacità.
+
+Se \param{count} è zero la funzione restituisce zero senza fare nient'altro.
+Per i file ordinari il numero di byte scritti è sempre uguale a quello
+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 è:
+\begin{prototype}{unistd.h}
+{ssize\_t pwrite(int fd, void * buf, size\_t count, off\_t offset)}
+  
+Cerca di scrivere sul file \param{fd}, a partire dalla posizione
+\param{offset}, \param{count} byte dal buffer \param{buf}.
+  
+\bodydesc{La funzione ritorna il numero di byte letti in caso di successo e
+  $-1$ in caso di errore, nel qual caso \var{errno} assumerà i valori già
+  visti per \func{write} e \func{lseek}.}
+\end{prototype}
+\noindent e per essa valgono le stesse considerazioni fatte per \func{pread}.
+
+
+\section{Caratteristiche avanzate}
+\label{sec:file_adv_func}
+
+In questa sezione approfondiremo alcune delle caratteristiche più sottili
+della gestione file in un sistema unix-like, esaminando in dettaglio il
+comportamento delle funzioni base, inoltre tratteremo le funzioni che
+permettono di eseguire alcune operazioni avanzate con i file (il grosso
+dell'argomento sarà comunque affrontato in cap.~\ref{cha:file_advanced}).
+
+
+\subsection{La condivisione dei files}
+\label{sec:file_sharing}
+
+In sez.~\ref{sec:file_fd} abbiamo descritto brevemente l'architettura
+dell'interfaccia con i file da parte di un processo, mostrando in
+fig.~\ref{fig:file_proc_file} le principali strutture usate dal kernel;
+esamineremo ora in dettaglio le conseguenze che questa architettura ha nei
+confronti dell'accesso allo stesso file da parte di processi diversi.
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=15cm]{img/filemultacc}
+  \caption{Schema dell'accesso allo stesso file da parte di due processi 
+    diversi}
+  \label{fig:file_mult_acc}
+\end{figure}
+
+Il primo caso è quello in cui due processi diversi aprono lo stesso file su
+disco; sulla base di quanto visto in sez.~\ref{sec:file_fd} avremo una
+situazione come quella illustrata in fig.~\ref{fig:file_mult_acc}: ciascun
+processo avrà una sua voce nella \textit{file table} referenziata da un
+diverso file descriptor nella sua \kstruct{file\_struct}. Entrambe le voci
+nella \itindex{file~table} \textit{file table} faranno però riferimento allo
+stesso \itindex{inode} inode su disco.
+
+Questo significa che ciascun processo avrà la sua posizione corrente sul file,
+la sua modalità di accesso e versioni proprie di tutte le proprietà che
+vengono mantenute nella sua voce della \itindex{file~table} \textit{file
+  table}. Questo ha conseguenze specifiche sugli effetti della possibile
+azione simultanea sullo stesso file, in particolare occorre tenere presente
+che:
+\begin{itemize}
+\item ciascun processo può scrivere indipendentemente; dopo ciascuna
+  \func{write} la posizione corrente sarà cambiata solo nel processo. Se la
+  scrittura eccede la dimensione corrente del file questo verrà esteso
+  automaticamente con l'aggiornamento del campo \var{i\_size} \itindex{inode}
+  nell'inode.
+\item se un file è in modalità \itindex{append~mode} \const{O\_APPEND} tutte
+  le volte che viene effettuata una scrittura la posizione corrente viene
+  prima impostata alla dimensione corrente del file letta \itindex{inode}
+  dall'inode. Dopo la scrittura il file viene automaticamente esteso.
+\item l'effetto di \func{lseek} è solo quello di cambiare il campo
+  \var{f\_pos} nella struttura \kstruct{file} della \itindex{file~table}
+  \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 \itindex{inode} dall'inode.
+\end{itemize}
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=15cm]{img/fileshar}
+  \caption{Schema dell'accesso ai file da parte di un processo figlio}
+  \label{fig:file_acc_child}
+\end{figure}
+
+Il secondo caso è quello in cui due file descriptor di due processi diversi
+puntino alla stessa voce nella \itindex{file~table} \textit{file table};
+questo è ad esempio il caso dei file aperti che vengono ereditati dal processo
+figlio all'esecuzione di una \func{fork} (si ricordi quanto detto in
+sez.~\ref{sec:proc_fork}). La situazione è illustrata in
+fig.~\ref{fig:file_acc_child}; dato che il processo figlio riceve una copia
+dello spazio di indirizzi del padre, riceverà anche una copia di
+\kstruct{file\_struct} e relativa tabella dei file aperti.
+
+In questo modo padre e figlio avranno gli stessi file descriptor che faranno
+riferimento alla stessa voce nella \textit{file table}, condividendo così la
+posizione corrente sul file. Questo ha le conseguenze descritte a suo tempo in
+sez.~\ref{sec:proc_fork}: in caso di scrittura contemporanea la posizione
+corrente nel file varierà per entrambi i processi (in quanto verrà modificato
+\var{f\_pos} che è lo stesso per entrambi).
+
+Si noti inoltre che anche i flag di stato del file (quelli impostati
+dall'argomento \param{flag} di \func{open}) essendo tenuti nella voce della
+\textit{file table}\footnote{per la precisione nel campo \var{f\_flags} di
+  \kstruct{file}.}, vengono in questo caso condivisi. Ai file però sono
+associati anche altri flag, dei quali l'unico usato al momento è
+\const{FD\_CLOEXEC}, detti \textit{file descriptor flags}. Questi ultimi sono
+tenuti invece in \kstruct{file\_struct}, e perciò sono specifici di ciascun
+processo e non vengono modificati dalle azioni degli altri anche in caso di
+condivisione della stessa voce della \textit{file table}.
+
+
+
+\subsection{Operazioni atomiche con i file}
+\label{sec:file_atomic}
+
+Come si è visto in un sistema unix-like è sempre possibile per più processi
+accedere in contemporanea allo stesso file, e che le operazioni di lettura e
+scrittura possono essere fatte da ogni processo in maniera autonoma in base
+ad una posizione corrente nel file che è locale a ciascuno di essi.
+
+Se dal punto di vista della lettura dei dati questo non comporta nessun
+problema, quando si andrà a scrivere le operazioni potranno mescolarsi in
+maniera imprevedibile.  Il sistema però fornisce in alcuni casi la possibilità
+di eseguire alcune operazioni di scrittura in maniera coordinata anche senza
+utilizzare meccanismi di sincronizzazione più complessi (come il
+\itindex{file~locking} \textit{file locking}, che esamineremo in
+sez.~\ref{sec:file_locking}).
+
+Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
+vari processi devono scrivere alla fine di un file (ad esempio un file di
+log). Come accennato in sez.~\ref{sec:file_lseek} impostare la posizione alla
+fine del file e poi scrivere può condurre ad una \itindex{race~condition}
+\textit{race condition}: infatti può succedere che un secondo processo scriva
+alla fine del file fra la \func{lseek} e la \func{write}; in questo caso, come
+abbiamo appena visto, il file sarà esteso, ma il nostro primo processo avrà
+ancora la posizione corrente impostata con la \func{lseek} che non corrisponde
+più alla fine del file, e la successiva \func{write} sovrascriverà i dati del
+secondo processo.
+
+Il problema è che usare due system call in successione non è un'operazione
+atomica; il problema è stato risolto introducendo la modalità
+\itindex{append~mode} \const{O\_APPEND}. In questo caso infatti, come abbiamo
+descritto in precedenza, è il kernel che aggiorna automaticamente la posizione
+alla fine del file prima di effettuare la scrittura, e poi estende il file.
+Tutto questo avviene all'interno di una singola system call (la \func{write})
+che non essendo interrompibile da un altro processo costituisce un'operazione
+atomica.
+
+Un altro caso tipico in cui è necessaria l'atomicità è quello in cui si vuole
+creare un \textsl{file di lock} \index{file!di lock}, bloccandosi se il file
+esiste. In questo caso la sequenza logica porterebbe a verificare prima
+l'esistenza del file con una \func{stat} per poi crearlo con una \func{creat};
+di nuovo avremmo la possibilità di una \itindex{race~condition} \textit{race
+  condition} da parte di un altro processo che crea lo stesso file fra il
+controllo e la creazione.
+
+Per questo motivo sono stati introdotti per \func{open} i due flag
+\const{O\_CREAT} e \const{O\_EXCL}. In questo modo l'operazione di controllo
+dell'esistenza del file (con relativa uscita dalla funzione con un errore) e
+creazione in caso di assenza, diventa atomica essendo svolta tutta all'interno
+di una singola system call (per i dettagli sull'uso di questa caratteristica
+si veda sez.~\ref{sec:ipc_file_lock}).
+
+
+\subsection{Le funzioni \func{sync} e \func{fsync}}
+\label{sec:file_sync}
+
+% TODO, aggiungere syncfs, introdotta con il 2.6.39
+
+Come accennato in sez.~\ref{sec:file_close} tutte le operazioni di scrittura
+sono in genere bufferizzate dal kernel, che provvede ad effettuarle in maniera
+asincrona (ad esempio accorpando gli accessi alla stessa zona del disco) in un
+secondo tempo rispetto al momento della esecuzione della \func{write}.
+
+Per questo motivo, quando è necessaria una sincronizzazione dei dati, il
+sistema mette a disposizione delle funzioni che provvedono a forzare lo
+scarico dei dati dai buffer del kernel.\footnote{come già accennato neanche
+  questo dà la garanzia assoluta che i dati siano integri dopo la chiamata,
+  l'hardware dei dischi è in genere dotato di un suo meccanismo interno di
+  ottimizzazione per l'accesso al disco che può ritardare ulteriormente la
+  scrittura effettiva.} La prima di queste funzioni è \funcd{sync} il cui
+prototipo è:
+\begin{prototype}{unistd.h}{int sync(void)}
+  
+  Sincronizza il buffer della cache dei file col disco.
+  
+  \bodydesc{La funzione ritorna sempre zero.}
+\end{prototype}
+\noindent  i vari standard prevedono che la funzione si limiti a far partire
+le operazioni, ritornando immediatamente; in Linux (dal kernel 1.3.20) invece
+la funzione aspetta la conclusione delle operazioni di sincronizzazione del
+kernel.
+
+La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
+esplicitamente lo scarico dei dati su disco, o dal demone di sistema
+\cmd{update} che esegue lo scarico dei dati ad intervalli di tempo fissi: il
+valore tradizionale, usato da BSD, per l'update dei dati è ogni 30 secondi, ma
+in Linux il valore utilizzato è di 5 secondi; con le nuove versioni\footnote{a
+  partire dal kernel 2.2.8} poi, è il kernel che si occupa direttamente di
+tutto quanto attraverso il demone interno \cmd{bdflush}, il cui comportamento
+può essere controllato attraverso il file \sysctlfile{vm/bdflush} (per
+il significato dei valori si può leggere la documentazione allegata al kernel
+in \file{Documentation/sysctl/vm.txt}).
+
+Quando si vogliono scaricare soltanto i dati di un file (ad esempio essere
+sicuri che i dati di un database sono stati registrati su disco) si possono
+usare le due funzioni \funcd{fsync} e \funcd{fdatasync}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{unistd.h}
+  \funcdecl{int fsync(int fd)}
+  Sincronizza dati e meta-dati del file \param{fd}
+  \funcdecl{int fdatasync(int fd)}
+  Sincronizza i dati del file \param{fd}.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+    errore, nel qual caso \var{errno} assume i valori:
+  \begin{errlist}
+  \item[\errcode{EINVAL}] \param{fd} è un \index{file!speciali} file speciale
+    che non supporta la sincronizzazione.
+  \end{errlist}
+  ed inoltre \errval{EBADF}, \errval{EROFS} e \errval{EIO}.}
+\end{functions}
+
+Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
+file specificato, ed attendono fino alla conclusione delle operazioni;
+\func{fsync} forza anche la sincronizzazione dei meta-dati del file (che
+riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli
+altri dati contenuti \itindex{inode} nell'inode che si leggono con \func{fstat},
+come i tempi del file).
+
+Si tenga presente che questo non comporta la sincronizzazione della
+directory che contiene il file (e scrittura della relativa voce su
+disco) che deve essere effettuata esplicitamente.\footnote{in realtà per
+  il filesystem \acr{ext2}, quando lo si monta con l'opzione \cmd{sync},
+  il kernel provvede anche alla sincronizzazione automatica delle voci
+  delle directory.}
+
+
+\subsection{Le funzioni \func{dup} e \func{dup2}}
+\label{sec:file_dup}
+
+Abbiamo già visto in sez.~\ref{sec:file_sharing} come un processo figlio
+condivida gli stessi file descriptor del padre; è possibile però ottenere un
+comportamento analogo all'interno di uno stesso processo \textit{duplicando}
+un file descriptor. Per far questo si usa la funzione \funcd{dup} il cui
+prototipo è:
+\begin{prototype}{unistd.h}{int dup(int oldfd)}
+  Crea una copia del file descriptor \param{oldfd}.
+  
+  \bodydesc{La funzione ritorna il nuovo file descriptor in caso di successo e
+    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei
+    valori:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{oldfd} non è un file aperto.
+  \item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
+    descriptor aperti.
+  \end{errlist}}
+\end{prototype}
+
+La funzione ritorna, come \func{open}, il primo file descriptor libero. Il
+file descriptor è una copia esatta del precedente ed entrambi possono essere
+interscambiati nell'uso. Per capire meglio il funzionamento della funzione si
+può fare riferimento a fig.~\ref{fig:file_dup}: l'effetto della funzione è
+semplicemente quello di copiare il valore nella struttura
+\kstruct{file\_struct}, cosicché anche il nuovo file descriptor fa riferimento
+alla stessa voce nella \textit{file table}; per questo si dice che il nuovo
+file descriptor è \textsl{duplicato}, da cui il nome della funzione.
+
+\begin{figure}[!htb]
+  \centering \includegraphics[width=14cm]{img/filedup}
+  \caption{Schema dell'accesso ai file duplicati}
+  \label{fig:file_dup}
+\end{figure}
+
+Si noti che per quanto illustrato in fig.~\ref{fig:file_dup} i file descriptor
+duplicati condivideranno eventuali lock, \textit{file status flag}, e
+posizione corrente. Se ad esempio si esegue una \func{lseek} per modificare la
+posizione su uno dei due file descriptor, essa risulterà modificata anche
+sull'altro (dato che quello che viene modificato è lo stesso campo nella voce
+della \textit{file table} a cui entrambi fanno riferimento). L'unica
+differenza fra due file descriptor duplicati è che ciascuno avrà il suo
+\textit{file descriptor flag}; a questo proposito va specificato che nel caso
+di \func{dup} il flag di \textit{close-on-exec} \itindex{close-on-exec} (vedi
+sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl}) viene sempre cancellato
+nella copia.
+
+L'uso principale di questa funzione è per la redirezione dell'input e
+dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec};
+diventa così possibile associare un file (o una pipe) allo standard input o
+allo standard output (torneremo sull'argomento in sez.~\ref{sec:ipc_pipe_use},
+quando tratteremo le pipe). Per fare questo in genere occorre prima chiudere
+il file che si vuole sostituire, cosicché il suo file descriptor possa esser
+restituito alla chiamata di \func{dup}, come primo file descriptor
+disponibile.
+
+Dato che questa è l'operazione più comune, è prevista una diversa versione
+della funzione, \funcd{dup2}, che permette di specificare esplicitamente
+qual è il valore di file descriptor che si vuole avere come duplicato; il suo
+prototipo è:
+\begin{prototype}{unistd.h}{int dup2(int oldfd, int newfd)}
+  
+  Rende \param{newfd} una copia del file descriptor \param{oldfd}.
+  
+  \bodydesc{La funzione ritorna il nuovo file descriptor in caso di successo e
+    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{oldfd} non è un file aperto o \param{newfd} ha
+    un valore fuori dall'intervallo consentito per i file descriptor.
+  \item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
+    descriptor aperti.
+  \end{errlist}}
+\end{prototype}
+\noindent e qualora il file descriptor \param{newfd} sia già aperto (come
+avviene ad esempio nel caso della duplicazione di uno dei file standard) esso
+sarà prima chiuso e poi duplicato (così che il file duplicato sarà connesso
+allo stesso valore per il file descriptor).
+
+La duplicazione dei file descriptor può essere effettuata anche usando la
+funzione di controllo dei file \func{fcntl} (che esamineremo in
+sez.~\ref{sec:file_fcntl}) con il parametro \const{F\_DUPFD}.  L'operazione ha
+la sintassi \code{fcntl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per
+\param{newfd} diventa equivalente a \func{dup}. 
+
+La sola differenza fra le due funzioni\footnote{a parte la sintassi ed i
+  diversi codici di errore.} è che \func{dup2} chiude il file descriptor
+\param{newfd} se questo è già aperto, garantendo che la duplicazione sia
+effettuata esattamente su di esso, invece \func{fcntl} restituisce il primo
+file descriptor libero di valore uguale o maggiore di \param{newfd} (e se
+\param{newfd} è aperto la duplicazione avverrà su un altro file descriptor).
+
+
+
+\subsection{Le funzioni \func{openat}, \func{mkdirat} e affini}
+\label{sec:file_openat}
+
+\itindbeg{at-functions}
+
+Un problema che si pone con l'uso della funzione \func{open}, così come per
+molte altre funzioni che accettano come argomenti dei
+\itindsub{pathname}{relativo} \textit{pathname} relativi, è che, quando un
+\textit{pathname} relativo non fa riferimento alla \index{directory~di~lavoro}
+directory di lavoro corrente, è possibile che alcuni dei suoi componenti
+vengano modificati in parallelo alla chiamata a \func{open}, e questo lascia
+aperta la possibilità di una \itindex{race~condition} \textit{race condition}.
+
+Inoltre come già accennato, la \index{directory~di~lavoro} directory di lavoro
+corrente è una proprietà del singolo processo; questo significa che quando si
+lavora con i \itindex{thread} \textit{thread} essa sarà la stessa per tutti,
+ma esistono molti casi in cui sarebbe invece utile che ogni singolo
+\itindex{thread} \textit{thread} avesse la sua \index{directory~di~lavoro}
+directory di lavoro.
+
+Per risolvere questi problemi, riprendendo una interfaccia già presente in
+Solaris, a fianco delle normali funzioni che operano sui file (come
+\func{open}, \func{mkdir}, ecc.) sono state introdotte delle ulteriori
+funzioni, dette anche funzioni ``\textit{at}'' in quanto contraddistinte dal
+suffisso \texttt{at}, che permettono l'apertura di un file (o le rispettive
+altre operazioni) usando un \itindsub{pathname}{relativo} \textit{pathname}
+relativo ad una directory specificata.\footnote{l'introduzione è avvenuta su
+  proposta dello sviluppatore principale delle \acr{glibc} Urlich Drepper; le
+  corrispondenti system call sono state inserite nel kernel ufficiale a
+  partire dalla versione 2.6.16, in precedenza era disponibile una emulazione
+  che, sia pure con prestazioni inferiori, funzionava facendo ricorso all'uso
+  del 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 vari
+Unix\footnote{oltre a Linux e Solaris sono presenti in vari BSD.} fino ad
+essere incluse nella recente revisione (la POSIX.1-2008) dello standard
+POSIX.1; con le \acr{glibc} per l'accesso a queste funzioni è necessario
+definire la macro \macro{\_ATFILE\_SOURCE}.
+
+L'uso di queste funzioni prevede una apertura iniziale della directory che
+sarà la base della risoluzione dei \itindsub{pathname}{relativo}
+\textit{pathname} relativi che verranno usati in seguito, dopo di che si dovrà
+passare il relativo file descriptor alle varie funzioni che useranno quella
+directory come punto di partenza per la risoluzione.\footnote{in questo modo,
+  anche quando si lavora con i \itindex{thread} \textit{thread}, si può
+  mantenere una \index{directory~di~lavoro} directory di lavoro diversa per
+  ciascuno di essi.}
+
+Questo metodo, oltre a risolvere i problemi di \itindex{race~condition}
+\textit{race condition}, consente anche di ottenere aumenti di prestazioni
+significativi quando si devono eseguire molte operazioni su sezioni
+dell'albero dei file che prevedono delle gerarchie di sottodirectory molto
+profonde; infatti in questo caso basta eseguire la risoluzione del
+\textit{pathname} della directory di partenza una sola volta (nell'apertura
+iniziale) e non tutte le volte che si deve accedere a ciascun file che essa
+contiene.
+
+La sintassi generale di queste nuove funzioni è che esse prevedono come primo
+argomento il file descriptor della directory da usare come base, mentre gli
+argomenti successivi restano identici a quelli della corrispondente funzione
+ordinaria; ad esempio nel caso di \funcd{openat} avremo che essa è definita
+come:
+\begin{functions}
+  \headdecl{fcntl.h}
+  \funcdecl{int openat(int dirfd, const char *pathname, int flags)}
+  \funcdecl{int openat(int dirfd, const char *pathname, int flags,  mode\_t
+    mode))} 
+
+  Apre un file usando come directory di \index{directory~di~lavoro} lavoro
+  corrente \param{dirfd}.
+  
+  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
+    errore di \func{open}, ed in più:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
+    \textit{pathname} relativo, ma
+    \param{dirfd} fa riferimento ad un file. 
+  \end{errlist}}
+\end{functions}
+
+Il comportamento delle nuove funzioni è del tutto analogo a quello delle
+corrispettive classiche, con la sola eccezione del fatto che se fra i loro
+argomenti si utilizza un \itindsub{pathname}{relativo} \textit{pathname}
+relativo questo sarà risolto rispetto alla directory indicata
+da \param{dirfd}; qualora invece si usi un \itindsub{pathname}{assoluto}
+\textit{pathname} assoluto \param{dirfd} verrà semplicemente ignorato. Infine
+se per
+\param{dirfd} si usa il valore speciale \const{AT\_FDCWD},\footnote{questa,
+  come le altre costanti \texttt{AT\_*}, è definita in \headfile{fcntl.h},
+  pertanto se la si vuole usare occorrerà includere comunque questo file,
+  anche per le funzioni che non sono definite in esso.} la risoluzione sarà
+effettuata rispetto alla directory di \index{directory~di~lavoro} lavoro
+corrente del processo.
+
+Così come il comportamento, anche i valori di ritorno e le condizioni di
+errore delle nuove funzioni sono gli stessi delle funzioni classiche, agli
+errori si aggiungono però quelli dovuti a valori errati per \param{dirfd}; in
+particolare si avrà un errore di \errcode{EBADF} se esso non è un file
+descriptor valido, ed un errore di \errcode{ENOTDIR} se esso non fa
+riferimento ad una directory.\footnote{tranne il caso in cui si sia
+  specificato un \itindsub{pathname}{assoluto} \textit{pathname} assoluto, nel
+  qual caso, come detto, il valore di \param{dirfd} sarà completamente
+  ignorato.}
+
+In tab.~\ref{tab:file_atfunc_corr} si sono riportate le funzioni introdotte
+con questa nuova interfaccia, con a fianco la corrispondente funzione
+classica.\footnote{in realtà, come visto in sez.~\ref{sec:file_temp_file}, le
+  funzioni \func{utimes} e \func{lutimes} non sono propriamente le
+  corrispondenti di \func{utimensat}, dato che questa ha una maggiore
+  precisione nella indicazione dei tempi dei file.} La gran parte di queste
+seguono la convenzione appena vista per \func{openat}, in cui agli argomenti
+della corrispondente funzione classica viene anteposto
+l'argomento \param{dirfd}.\footnote{non staremo pertanto a riportarle una per
+  una.} Per una parte di queste, indicate dal contenuto della omonima colonna
+di tab.~\ref{tab:file_atfunc_corr}, oltre al nuovo argomento iniziale, è
+prevista anche l'aggiunta di un ulteriore argomento finale, \param{flags}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|c|l|}
+    \hline
+    \textbf{Funzione} &\textbf{Flags} &\textbf{Corrispondente} \\
+    \hline
+    \hline
+     \func{faccessat} &$\bullet$&\func{access}  \\
+     \func{fchmodat}  &$\bullet$&\func{chmod}   \\
+     \func{fchownat}  &$\bullet$&\func{chown},\func{lchown}\\
+     \func{fstatat}   &$\bullet$&\func{stat},\func{lstat}  \\
+     \func{utimensat} &$\bullet$&\func{utimes},\func{lutimes}\\
+     \func{linkat}    &$\bullet$\footnotemark&\func{link}    \\
+     \funcm{mkdirat}  & --      &\func{mkdir}   \\
+     \funcm{mknodat}  & --      &\func{mknod}   \\
+     \func{openat}    & --      &\func{open}    \\
+     \funcm{readlinkat}& --     &\func{readlink}\\
+     \funcm{renameat} & --      &\func{rename}  \\
+     \funcm{symlinkat}& --      &\func{symlink} \\
+     \func{unlinkat}  &$\bullet$&\func{unlink},\func{rmdir}  \\
+     \funcm{mkfifoat} & --      &\func{mkfifo}  \\
+    \hline
+  \end{tabular}
+  \caption{Corrispondenze fra le nuove funzioni ``\textit{at}'' e le
+    corrispettive funzioni classiche.}
+  \label{tab:file_atfunc_corr}
+\end{table}
+
+\footnotetext{in questo caso l'argomento \param{flags} è disponibile ed
+  utilizzabile solo a partire dal kernel 2.6.18.}
+
+% TODO manca prototipo di fchmodat, verificare se metterlo o metter menzione
+% TODO manca prototipo di fstatat, verificare se metterlo o metter menzione
+% TODO manca prototipo di linkat, verificare se metterlo o metter menzione
+% TODO manca prototipo di utimensat, verificare se metterlo o metter menzione
+
+Per tutte le funzioni che lo prevedono, a parte \func{unlinkat} e
+\funcd{faccessat}, l'ulteriore argomento è stato introdotto solo per fornire
+un meccanismo con cui modificarne il comportamento nel caso si stia operando
+su un link simbolico, così da poter scegliere se far agire la funzione
+direttamente sullo stesso o sul file da esso referenziato. Dato che in certi
+casi esso può fornire ulteriori indicazioni per modificare il comportamento
+delle funzioni, \param{flags} deve comunque essere passato come maschera
+binaria, ed impostato usando i valori delle appropriate costanti
+\texttt{AT\_*}, definite in \headfile{fcntl.h}.
+
+Come esempio di questo secondo tipo di funzioni possiamo considerare
+\funcd{fchownat}, che può essere usata per sostituire sia \func{chown}
+che \func{lchown}; il suo prototipo è:
+\begin{functions}
+  \headdecl{unistd.h} \headdecl{fcntl.h} 
+
+  \funcdecl{int fchownat(int dirfd, const char *pathname, uid\_t owner, gid\_t
+    group, int flags)}
+
+  Modifica la proprietà di un file.
+  
+  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
+    errore di \func{chown}, ed in più:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
+  \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
+    \textit{pathname} relativo, ma \param{dirfd} fa riferimento ad un file. 
+  \end{errlist}}
+\end{functions}
+
+In questo caso il valore di \param{flags} stabilisce il comportamento della
+funzione quando la si applica ad un link simbolico, e l'unico valore
+utilizzabile è \const{AT\_SYMLINK\_NOFOLLOW}\footnote{in \headfile{fcntl.h} è
+  definito anche \const{AT\_SYMLINK\_FOLLOW}, che richiede di dereferenziare i
+  link simbolici, essendo questo però il comportamento adottato per un valore
+  nullo di \param{flags} questo valore non viene mai usato.} che se impostato
+indica alla funzione di non eseguire la dereferenziazione di un eventuale link
+simbolico, facendo comportare \func{fchownat} come \func{lchown} invece che
+come \func{chown}.
+
+Come accennato fra tutte quelle marcate in tab.~\ref{tab:file_atfunc_corr}
+solo due funzioni possono usare l'argomento \param{flags} con valori diversi
+da \const{AT\_SYMLINK\_NOFOLLOW}, la prima di queste è \funcd{faccessat}, ed
+il suo prototipo è:
+\begin{functions}
+  \headdecl{unistd.h}
+  \funcdecl{int faccessat(int dirfd, const char *path, int mode, int flags)}
+
+  Controlla i permessi di accesso.
+  
+  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
+    errore di \func{access}, ed in più:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
+  \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
+    \textit{pathname} relativo, ma \param{dirfd} fa riferimento ad un file. 
+  \end{errlist}}
+\end{functions}
+
+La funzione esegue lo stesso controllo di accesso effettuabile con
+\func{access}, ma si può utilizzare l'argomento \param{flags} per modificarne
+il comportamento rispetto a quello ordinario di \func{access}. In questo caso
+esso può essere specificato come maschera binaria di due valori:
+\begin{basedescript}{\desclabelwidth{3.0cm}}
+\item[\const{AT\_EACCES}] se impostato \funcd{faccessat} esegue il controllo
+  dei permessi usando l'\ids{UID} effettivo invece di quello reale (il
+  comportamento di default, che riprende quello di \func{access}).
+\item[\const{AT\_SYMLINK\_NOFOLLOW}] se impostato \funcd{faccessat} non esegue
+  la dereferenziazione dei link simbolici, effettuando il controllo dei
+  permessi direttamente sugli stessi.
+\end{basedescript}
+
+La seconda eccezione è \func{unlinkat}, in questo caso l'ulteriore
+argomento \param{flags} viene utilizzato perché tramite esso la funzione possa
+comportarsi sia come analogo di \func{unlink} che di \func{rmdir}; il suo
+prototipo è:
+\begin{functions}
+  \headdecl{fcntl.h}
+  \funcdecl{int unlinkat(int dirfd, const char *pathname, int flags)}
+
+  Rimuove una voce da una directory.
+  
+  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
+    errore di \func{unlink} o di \func{rmdir} a seconda del valore di
+    \param{flags}, ed in più:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
+  \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
+    \textit{pathname} relativo, ma \param{dirfd} fa riferimento ad un file.
+  \end{errlist}}
+\end{functions}
+
+Di default il comportamento di \func{unlinkat} è equivalente a quello che
+avrebbe \func{unlink} applicata a \param{pathname}, fallendo in tutti i casi
+in cui questo è una directory, se però si imposta \param{flags} al valore di
+\const{AT\_REMOVEDIR},\footnote{anche se \param{flags} è una maschera binaria,
+  essendo questo l'unico flag disponibile per questa funzione, lo si può
+  assegnare direttamente.}  essa si comporterà come \func{rmdir}, in tal
+caso \param{pathname} deve essere una directory, che sarà rimossa qualora
+risulti vuota.
+
+\itindend{at-functions}
+
+
+% TODO manca prototipo e motivazione di fexecve, da trattare qui in quanto
+% inserita nello stesso standard e da usare con openat, vedi 
+% http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
+
+
+
+
+\subsection{La funzione \func{fcntl}}
+\label{sec:file_fcntl}
+
+Oltre alle operazioni base esaminate in sez.~\ref{sec:file_unix_interface}
+esistono tutta una serie di operazioni ausiliarie che è possibile eseguire su
+un file descriptor, che non riguardano la normale lettura e scrittura di dati,
+ma la gestione sia delle loro proprietà, che di tutta una serie di ulteriori
+funzionalità che il kernel può mettere a disposizione.\footnote{ad esempio si
+  gestiscono con questa funzione varie modalità di I/O asincrono (vedi
+  sez.~\ref{sec:file_asyncronous_operation}) e il \itindex{file~locking}
+  \textit{file locking} (vedi sez.~\ref{sec:file_locking}).}
+
+Per queste operazioni di manipolazione e di controllo delle varie proprietà e
+caratteristiche di un file descriptor, viene usata la funzione \funcd{fcntl},
+il cui prototipo è:
+\begin{functions}
+  \headdecl{unistd.h}
+  \headdecl{fcntl.h}
+  \funcdecl{int fcntl(int fd, int cmd)}
+  \funcdecl{int fcntl(int fd, int cmd, long arg)}
+  \funcdecl{int fcntl(int fd, int cmd, struct flock * lock)}
+  Esegue una delle possibili operazioni specificate da \param{cmd}
+  sul file \param{fd}.
+  
+  \bodydesc{La funzione ha valori di ritorno diversi a seconda
+    dell'operazione. In caso di errore il valore di ritorno è sempre $-1$ ed
+    il codice dell'errore è restituito nella variabile \var{errno}; i codici
+    possibili dipendono dal tipo di operazione, l'unico valido in generale è:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{fd} non è un file aperto.
+  \end{errlist}}
+\end{functions}
+
+
+Il primo argomento della funzione è sempre il numero di file descriptor
+\var{fd} su cui si vuole operare. Il comportamento di questa funzione, il
+numero e il tipo degli argomenti, il valore di ritorno e gli eventuali errori
+sono determinati dal valore dell'argomento \param{cmd} che in sostanza
+corrisponde all'esecuzione di un determinato \textsl{comando}; in
+sez.~\ref{sec:file_dup} abbiamo incontrato un esempio dell'uso di \func{fcntl}
+per la duplicazione dei file descriptor, una lista di tutti i possibili valori
+per \var{cmd} è riportata di seguito:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\const{F\_DUPFD}] trova il primo file descriptor disponibile di valore
+  maggiore o uguale ad \param{arg} e ne fa una copia di \param{fd}. Ritorna il
+  nuovo file descriptor in caso di successo e $-1$ in caso di errore. Gli
+  errori possibili sono \errcode{EINVAL} se \param{arg} è negativo o maggiore
+  del massimo consentito o \errcode{EMFILE} se il processo ha già raggiunto il
+  massimo numero di descrittori consentito.
+\item[\const{F\_SETFD}] imposta il valore del \textit{file descriptor flag} al
+  valore specificato con \param{arg}. Al momento l'unico bit usato è quello di
+  \itindex{close-on-exec} \textit{close-on-exec}, identificato dalla costante
+  \const{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella
+  esecuzione di una \func{exec} (vedi sez.~\ref{sec:proc_exec}).  Ritorna un
+  valore nullo in caso di successo e $-1$ in caso di errore.
+\item[\const{F\_GETFD}] ritorna il valore del \textit{file descriptor flag} di
+  \param{fd} o $-1$ in caso di errore; se \const{FD\_CLOEXEC} è impostato i
+  file descriptor aperti vengono chiusi attraverso una \func{exec} altrimenti
+  (il comportamento predefinito) restano aperti.
+\item[\const{F\_GETFL}] ritorna il valore del \textit{file status flag} in
+  caso di successo o $-1$ in caso di errore; permette cioè di rileggere quei
+  bit impostati da \func{open} all'apertura del file che vengono memorizzati
+  (quelli riportati nella prima e terza sezione di
+  tab.~\ref{tab:file_open_flags}).
+% TODO toglire riferimeto a tabella flag e mettere altro
+
+\item[\const{F\_SETFL}] imposta il \textit{file status flag} al valore
+  specificato da \param{arg}, ritorna un valore nullo in caso di successo o
+  $-1$ in caso di errore. Possono essere impostati solo i bit riportati nella
+  terza sezione di tab.~\ref{tab:file_open_flags}.\footnote{la pagina di
+    manuale riporta come impostabili solo \const{O\_APPEND},
+    \const{O\_NONBLOCK} e \const{O\_ASYNC}.}
+% TODO toglire riferimeto a tabella flag e mettere altro
+
+\item[\const{F\_GETLK}] richiede un controllo sul file lock specificato da
+  \param{lock}, sovrascrivendo la struttura da esso puntata con il risultato;
+  ritorna un valore nullo in caso di successo o $-1$ in caso di errore.  Questa
+  funzionalità è trattata in dettaglio in sez.~\ref{sec:file_posix_lock}.
+\item[\const{F\_SETLK}] richiede o rilascia un file lock a seconda di quanto
+  specificato nella struttura puntata da \param{lock}. Se il lock è tenuto da
+  qualcun altro ritorna immediatamente restituendo $-1$ e imposta \var{errno} a
+  \errcode{EACCES} o \errcode{EAGAIN}, in caso di successo ritorna un valore
+  nullo. Questa funzionalità è trattata in dettaglio in
+  sez.~\ref{sec:file_posix_lock}.
+\item[\const{F\_SETLKW}] identica a \const{F\_SETLK} eccetto per il fatto che
+  la funzione non ritorna subito ma attende che il blocco sia rilasciato. Se
+  l'attesa viene interrotta da un segnale la funzione restituisce $-1$ e
+  imposta \var{errno} a \errcode{EINTR}, in caso di successo ritorna un valore
+  nullo.  Questa funzionalità è trattata in dettaglio in
+  sez.~\ref{sec:file_posix_lock}.
+\item[\const{F\_GETOWN}] restituisce il \ids{PID} del processo o
+  l'identificatore del \itindex{process~group} \textit{process
+    group}\footnote{i \itindex{process~group} \textit{process group} sono
+    (vedi sez.~\ref{sec:sess_proc_group}) raggruppamenti di processi usati nel
+    controllo di sessione; a ciascuno di essi è associato un identificatore
+    (un numero positivo analogo al \ids{PID}).} che è preposto alla ricezione
+  dei segnali \signal{SIGIO}\footnote{o qualunque altro segnale alternativo
+    impostato con \const{F\_FSETSIG}.} per gli eventi associati al file
+  descriptor \param{fd}\footnote{il segnale viene usato sia per il
+    \textit{Signal Drive I/O}, che tratteremo in
+    sez.~\ref{sec:file_asyncronous_operation}, e dai vari meccanismi di
+    notifica asincrona, che tratteremo in
+    sez.~\ref{sec:file_asyncronous_lease}.} e \signal{SIGURG} per la notifica
+  dei dati urgenti di un socket.\footnote{vedi
+    sez.~\ref{sec:TCP_urgent_data}.} Nel caso di un \textit{process group}
+  viene restituito un valore negativo il cui valore assoluto corrisponde
+  all'identificatore del \itindex{process~group} \textit{process group}.  In
+  caso di errore viene restituito $-1$.
+\item[\const{F\_SETOWN}] imposta, con il valore dell'argomento \param{arg},
+  l'identificatore del processo o del \itindex{process~group} \textit{process
+    group} che riceverà i segnali \signal{SIGIO}  e \signal{SIGURG} per gli
+  eventi associati al file descriptor \param{fd}, ritorna un valore nullo in
+  caso di successo o $-1$ in caso di errore.  Come per \const{F\_GETOWN}, per
+  impostare un \itindex{process~group} \textit{process group} si deve usare
+  per \param{arg} un valore negativo, il cui valore assoluto corrisponde
+  all'identificatore del \itindex{process~group} \textit{process group}.
+\item[\const{F\_GETSIG}] restituisce il valore del segnale inviato quando ci
+  sono dati disponibili in ingresso su un file descriptor aperto ed impostato
+  per l'I/O asincrono (si veda sez.~\ref{sec:file_asyncronous_io}). Il valore 0
+  indica il valore predefinito (che è \signal{SIGIO}), un valore diverso da
+  zero indica il segnale richiesto, (che può essere anche lo stesso
+  \signal{SIGIO}). In caso di errore ritorna $-1$.
+\item[\const{F\_SETSIG}] imposta il segnale da inviare quando diventa
+  possibile effettuare I/O sul file descriptor in caso di I/O asincrono,
+  ritorna un valore nullo in caso di successo o $-1$ in caso di errore. Il
+  valore zero indica di usare il segnale predefinito, \signal{SIGIO}. Un altro
+  valore diverso da zero (compreso lo stesso \signal{SIGIO}) specifica il
+  segnale voluto; l'uso di un valore diverso da zero permette inoltre, se si è
+  installato il gestore del segnale come \var{sa\_sigaction} usando
+  \const{SA\_SIGINFO}, (vedi sez.~\ref{sec:sig_sigaction}), di rendere
+  disponibili al gestore informazioni ulteriori riguardo il file che ha
+  generato il segnale attraverso i valori restituiti in \struct{siginfo\_t}
+  (come vedremo in sez.~\ref{sec:file_asyncronous_io}).\footnote{i due comandi
+    \const{F\_SETSIG} e \const{F\_GETSIG} sono una estensione specifica di
+    Linux.}
+\item[\const{F\_SETLEASE}] imposta o rimuove un \itindex{file~lease}
+  \textit{file lease}\footnote{questa è una nuova funzionalità, specifica di
+    Linux, e presente solo a partire dai kernel della serie 2.4.x, in cui il
+    processo che detiene un \textit{lease} su un file riceve una notifica
+    qualora un altro processo cerca di eseguire una \func{open} o una
+    \func{truncate} su di esso.} sul file descriptor \var{fd} a seconda del
+  valore del terzo argomento, che in questo caso è un \ctyp{int}, ritorna un
+  valore nullo in caso di successo o $-1$ in caso di errore. Questa
+  funzionalità avanzata è trattata in dettaglio in
+  sez.~\ref{sec:file_asyncronous_lease}.
+\item[\const{F\_GETLEASE}] restituisce il tipo di \itindex{file~lease}
+  \textit{file lease} che il processo detiene nei confronti del file
+  descriptor \var{fd} o $-1$ in caso di errore. Con questo comando il terzo
+  argomento può essere omesso. Questa funzionalità avanzata è trattata in
+  dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
+\item[\const{F\_NOTIFY}] attiva un meccanismo di notifica per cui viene
+  riportata al processo chiamante, tramite il segnale \signal{SIGIO} (o altro
+  segnale specificato con \const{F\_SETSIG}) ogni modifica eseguita o
+  direttamente sulla directory cui \var{fd} fa riferimento, o su uno dei file
+  in essa contenuti; ritorna un valore nullo in caso di successo o $-1$ in caso
+  di errore. Questa funzionalità avanzata, disponibile dai kernel della serie
+  2.4.x, è trattata in dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
+\end{basedescript}
+
+La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per
+poter essere affrontate in tutti i loro aspetti a questo punto; saranno
+pertanto riprese più avanti quando affronteremo le problematiche ad esse
+relative. In particolare le tematiche relative all'I/O asincrono e ai vari
+meccanismi di notifica saranno trattate in maniera esaustiva in
+sez.~\ref{sec:file_asyncronous_access} mentre quelle relative al
+\itindex{file~locking} \textit{file locking} saranno esaminate in
+sez.~\ref{sec:file_locking}). L'uso di questa funzione con i socket verrà
+trattato in sez.~\ref{sec:sock_ctrl_func}.
+
+Si tenga presente infine che quando si usa la funzione per determinare le
+modalità di accesso con cui è stato aperto il file (attraverso l'uso del
+comando \const{F\_GETFL}) è necessario estrarre i bit corrispondenti nel
+\textit{file status flag} che si è ottenuto.  Infatti la definizione corrente
+di quest'ultimo non assegna bit separati alle tre diverse modalità
+\const{O\_RDONLY}, \const{O\_WRONLY} e \const{O\_RDWR}.\footnote{in Linux
+  queste costanti sono poste rispettivamente ai valori 0, 1 e 2.} Per questo
+motivo il valore della modalità di accesso corrente si ottiene eseguendo un
+AND binario del valore di ritorno di \func{fcntl} con la maschera
+\const{O\_ACCMODE} (anch'essa definita in \headfile{fcntl.h}), che estrae i
+bit di accesso dal \textit{file status flag}.
+
+
+
+\subsection{La funzione \func{ioctl}}
+\label{sec:file_ioctl}
+
+Benché il concetto di \textit{everything is a file} si sia dimostrato molto
+valido anche per l'interazione con i dispositivi più vari, fornendo una
+interfaccia che permette di interagire con essi tramite le stesse funzioni
+usate per i normali file di dati, esisteranno sempre caratteristiche
+peculiari, specifiche dell'hardware e della funzionalità che ciascun
+dispositivo può provvedere, che non possono venire comprese in questa
+interfaccia astratta (un caso tipico è l'impostazione della velocità di una
+porta seriale, o le dimensioni di un framebuffer).
+
+Per questo motivo nell'architettura del sistema è stata prevista l'esistenza
+di una funzione apposita, \funcd{ioctl}, con cui poter compiere le operazioni
+specifiche di ogni dispositivo particolare, usando come riferimento il solito
+file descriptor.  Il prototipo di questa funzione è:
+\begin{prototype}{sys/ioctl.h}{int ioctl(int fd, int request, ...)}  
+
+  Esegue l'operazione di controllo specificata da \param{request} sul file
+  descriptor \param{fd}.
+  
+  \bodydesc{La funzione nella maggior parte dei casi ritorna 0, alcune
+    operazioni usano però il valore di ritorno per restituire informazioni. In
+    caso di errore viene sempre restituito $-1$ ed \var{errno} assumerà uno dei
+    valori:
+  \begin{errlist}
+  \item[\errcode{ENOTTY}] il file \param{fd} non è associato con un
+    dispositivo, o la richiesta non è applicabile all'oggetto a cui fa
+    riferimento \param{fd}.
+  \item[\errcode{EINVAL}] gli argomenti \param{request} o \param{argp} non sono
+    validi.
+  \end{errlist}
+  ed inoltre \errval{EBADF} e \errval{EFAULT}.}
+\end{prototype}
+
+La funzione serve in sostanza come meccanismo generico per fare tutte quelle
+operazioni che non rientrano nell'interfaccia ordinaria della gestione dei
+file e che non è possibile effettuare con le funzioni esaminate finora. La
+funzione richiede che si passi come primo argomento un file descriptor
+regolarmente aperto, e l'operazione da compiere viene selezionata attraverso
+il valore dell'argomento \param{request}. Il terzo argomento dipende
+dall'operazione prescelta; tradizionalmente è specificato come \code{char *
+  argp}, da intendersi come puntatore ad un area di memoria
+generica,\footnote{all'epoca della creazione di questa funzione infatti ancora
+  non era stato introdotto il tipo \ctyp{void}.} ma per certe operazioni può
+essere omesso, e per altre è un semplice intero.
+
+Normalmente la funzione ritorna zero in caso di successo e $-1$ in caso di
+errore, ma per alcune operazione il valore di ritorno, che nel caso viene
+impostato ad un valore positivo, può essere utilizzato come parametro di
+uscita. È più comune comunque restituire i risultati all'indirizzo puntato dal
+terzo argomento.
+
+Data la genericità dell'interfaccia non è possibile classificare in maniera
+sistematica le operazioni che si possono gestire con \func{ioctl}, un breve
+elenco di alcuni esempi di esse è il seguente:
+\begin{itemize*}
+\item il cambiamento dei font di un terminale.
+\item l'esecuzione di una traccia audio di un CDROM.
+\item i comandi di avanti veloce e riavvolgimento di un nastro.
+\item il comando di espulsione di un dispositivo rimovibile.
+\item l'impostazione della velocità trasmissione di una linea seriale.
+\item l'impostazione della frequenza e della durata dei suoni emessi dallo
+  speaker.
+\item l'impostazione degli attributi dei file su un filesystem
+  ext2.\footnote{i comandi \texttt{lsattr} e \texttt{chattr} fanno questo con
+    delle \func{ioctl} dedicate, usabili solo su questo filesystem e derivati
+    successivi (come ext3).}
+\end{itemize*}
+
+In generale ogni dispositivo ha un suo insieme di operazioni specifiche
+effettuabili attraverso \func{ioctl}, tutte queste sono definite nell'header
+file \headfile{sys/ioctl.h}, e devono essere usate solo sui dispositivi cui
+fanno riferimento. Infatti anche se in genere i valori di \param{request} sono
+opportunamente differenziati a seconda del dispositivo\footnote{il kernel usa
+  un apposito \textit{magic number} per distinguere ciascun dispositivo nella
+  definizione delle macro da usare per \param{request}, in modo da essere
+  sicuri che essi siano sempre diversi, ed il loro uso per dispositivi diversi
+  causi al più un errore.  Si veda il capitolo quinto di \cite{LinDevDri} per
+  una trattazione dettagliata dell'argomento.} così che la richiesta di
+operazioni relative ad altri dispositivi usualmente provoca il ritorno della
+funzione con una condizione di errore, in alcuni casi, relativi a valori
+assegnati prima che questa differenziazione diventasse pratica corrente, si
+potrebbero usare valori validi anche per il dispositivo corrente, con effetti
+imprevedibili o indesiderati.
+
+Data la assoluta specificità della funzione, il cui comportamento varia da
+dispositivo a dispositivo, non è possibile fare altro che dare una descrizione
+sommaria delle sue caratteristiche; torneremo ad esaminare in
+seguito\footnote{per l'uso di \func{ioctl} con i socket si veda
+  sez.~\ref{sec:sock_ctrl_func}.} quelle relative ad alcuni casi specifici (ad
+esempio la gestione dei terminali è effettuata attraverso \func{ioctl} in
+quasi tutte le implementazioni di Unix), qui riportiamo solo l'elenco delle
+operazioni che sono predefinite per qualunque file,\footnote{in particolare
+  queste operazioni sono definite nel kernel a livello generale, e vengono
+  sempre interpretate per prime, per cui, come illustrato in \cite{LinDevDri},
+  eventuali operazioni specifiche che usino lo stesso valore verrebbero
+  ignorate.}  caratterizzate dal prefisso \texttt{FIO}:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\const{FIOCLEX}] imposta il flag di \itindex{close-on-exec}
+  \textit{close-on-exec} sul file, in questo caso, essendo usata come
+  operazione logica, \func{ioctl} non richiede un terzo argomento, il cui
+  eventuale valore viene ignorato.
+\item[\const{FIONCLEX}] cancella il flag di \itindex{close-on-exec}
+  \textit{close-on-exec} sul file, in questo caso, essendo usata come
+  operazione logica, \func{ioctl} non richiede un terzo argomento, il cui
+  eventuale valore viene ignorato.
+\item[\const{FIOASYNC}] abilita o disabilita la modalità di I/O asincrono sul
+  file (vedi sez.~\ref{sec:file_asyncronous_operation}); il terzo argomento
+  deve essere un puntatore ad un intero (cioè di tipo \texttt{const int *})
+  che contiene un valore logico (un valore nullo disabilita, un valore non
+  nullo abilita).
+\item[\const{FIONBIO}] abilita o disabilita sul file l'I/O in modalità non
+  bloccante; il terzo argomento deve essere un puntatore ad un intero (cioè di
+  tipo \texttt{const int *}) che contiene un valore logico (un valore nullo
+  disabilita, un valore non nullo abilita).
+\item[\const{FIOSETOWN}] imposta il processo che riceverà i segnali
+  \signal{SIGURG} e \signal{SIGIO} generati sul file; il terzo argomento deve
+  essere un puntatore ad un intero (cioè di tipo \texttt{const int *}) il cui
+  valore specifica il PID del processo.
+\item[\const{FIOGETOWN}] legge il processo che riceverà i segnali
+  \signal{SIGURG} e \signal{SIGIO} generati sul file; il terzo argomento deve
+  essere un puntatore ad un intero (cioè di tipo \texttt{int *}) su cui sarà
+  scritto il PID del processo.
+\item[\const{FIONREAD}] legge il numero di byte disponibili in lettura sul
+  file descriptor;\footnote{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 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
+  directory, mentre se applicata ad un dispositivo fallisce con un errore di
+  \errcode{ENOTTY}; il terzo argomento deve essere un puntatore ad un intero
+  (cioè di tipo \texttt{int *}) su cui sarà restituito il valore.
+\end{basedescript}
+
+% TODO aggiungere FIBMAP e FIEMAP, vedi http://lwn.net/Articles/260832
+
+Si noti però come la gran parte di queste operazioni specifiche dei file (per
+essere precisi le prime sei dell'elenco) siano effettuabili in maniera
+generica anche tramite l'uso di \func{fcntl}. Le due funzioni infatti sono
+molto simili e la presenza di questa sovrapposizione è principalmente dovuta
+al fatto che alle origini di Unix i progettisti considerarono che era
+necessario trattare diversamente rispetto alle operazione di controllo delle
+modalità di I/O file e dispositivi usando \func{fcntl} per i primi e
+\func{ioctl} per i secondi;\footnote{all'epoca tra l'altro i dispositivi che
+  usavano \func{ioctl} erano sostanzialmente solo i terminali, il che spiega
+  l'uso comune di \errcode{ENOTTY} come codice di errore.} oggi non è più così
+ma le due funzioni sono rimaste.
+
+% TODO trovare qualche posto per la eventuale documentazione delle seguenti
+% (bassa/bassissima priorità)
+% EXT4_IOC_MOVE_EXT (dal 2.6.31)
+
+
+
+
+% \chapter{}
+
+\section{L'interfaccia standard ANSI C}
+\label{sec:files_std_interface}
+
+
+Come visto in sez.~\ref{sec:file_unix_interface} le operazioni di I/O sui file
+sono gestibili a basso livello con l'interfaccia standard unix, che ricorre
+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, vengono a
+costituire il nucleo\footnote{queste funzioni sono state implementate la prima
+  volta da Ritchie nel 1976 e da allora sono rimaste sostanzialmente
+  immutate.} delle \acr{glibc}.
+
+
+Esamineremo in questa sezione le funzioni base dell'interfaccia degli
+\textit{stream}, analoghe a quelle di sez.~\ref{sec:file_unix_interface} per i
+file descriptor. In particolare vedremo come aprire, leggere, scrivere e
+cambiare la posizione corrente in uno \textit{stream}.
+
+
+\subsection{I \textit{file stream}}
+\label{sec:file_stream}
+
+\itindbeg{file~stream}
+
+Come più volte ribadito, l'interfaccia dei file descriptor è un'interfaccia di
+basso livello, che non provvede nessuna forma di formattazione dei dati e
+nessuna forma di bufferizzazione per ottimizzare le operazioni di I/O.
+
+In \cite{APUE} Stevens descrive una serie di test sull'influenza delle
+dimensioni del blocco di dati (l'argomento \param{buf} di \func{read} e
+\func{write}) nell'efficienza nelle operazioni di I/O con i file descriptor,
+evidenziando come le prestazioni ottimali si ottengano a partire da dimensioni
+del buffer dei dati pari a quelle dei blocchi del filesystem (il valore dato
+dal campo \var{st\_blksize} di \struct{stat}), che di norma corrispondono alle
+dimensioni dei settori fisici in cui è suddiviso il disco.
+
+Se il programmatore non si cura di effettuare le operazioni in blocchi di
+dimensioni adeguate, le prestazioni sono inferiori.  La caratteristica
+principale dell'interfaccia degli \textit{stream} è che essa provvede da sola
+alla gestione dei dettagli della bufferizzazione e all'esecuzione delle
+operazioni di lettura e scrittura in blocchi di dimensioni appropriate
+all'ottenimento della massima efficienza.
+
+Per questo motivo l'interfaccia viene chiamata anche interfaccia dei
+\textit{file stream}, dato che non è più necessario doversi preoccupare
+dei dettagli della comunicazione con il tipo di hardware sottostante
+(come nel caso della dimensione dei blocchi del filesystem), ed un file
+può essere sempre considerato come composto da un flusso continuo (da
+cui il nome \textit{stream}) di dati.
+
+A parte i dettagli legati alla gestione delle operazioni di lettura e
+scrittura (sia per quel che riguarda la bufferizzazione, che le
+formattazioni), 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_sharing} a proposito dell'accesso condiviso ed in
+sez.~\ref{sec:file_access_control} per il controllo di accesso.
+
+\itindend{file~stream}
+
+
+\subsection{Gli oggetti \type{FILE}}
+\label{sec:file_FILE}
+
+
+Per ragioni storiche la struttura di dati che rappresenta uno \textit{stream}
+è stata chiamata \type{FILE}, questi oggetti sono creati dalle funzioni di
+libreria e contengono tutte le informazioni necessarie a gestire le operazioni
+sugli \textit{stream}, come la posizione corrente, lo stato del buffer e degli
+indicatori di stato e di fine del file.
+
+Per questo motivo gli utenti non devono mai utilizzare direttamente o allocare
+queste strutture (che sono dei \index{tipo!opaco} \textsl{tipi opachi}) ma
+usare sempre puntatori del tipo \texttt{FILE *} ottenuti dalla libreria stessa
+(tanto che in certi casi il termine di puntatore a file è diventato sinonimo
+di \textit{stream}).  Tutte le funzioni della libreria che operano sui file
+accettano come argomenti solo variabili di questo tipo, che diventa
+accessibile includendo l'header file \headfile{stdio.h}.
+
+
+\subsection{Gli \textit{stream standard}}
+\label{sec:file_std_stream}
+
+Ai tre file descriptor standard (vedi tab.~\ref{tab:file_std_files}) aperti
+per ogni processo, corrispondono altrettanti \textit{stream}, che
+rappresentano i canali standard di input/output prestabiliti; anche questi tre
+\textit{stream} sono identificabili attraverso dei nomi simbolici definiti
+nell'header \headfile{stdio.h} che sono:
+
+\begin{basedescript}{\desclabelwidth{3.0cm}}
+\item[\var{FILE *stdin}] Lo \textit{standard input} cioè il \textit{file
+    stream} da cui il processo riceve ordinariamente i dati in
+  ingresso. Normalmente è associato dalla shell all'input del terminale e
+  prende i caratteri dalla tastiera.
+\item[\var{FILE *stdout}] Lo \textit{standard 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.
+\end{basedescript}
+
+Nella \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono effettivamente
+tre variabili di tipo \type{FILE}\texttt{ *} che possono essere usate come
+tutte le altre, ad esempio si può effettuare una redirezione dell'output di un
+programma con il semplice codice: \includecodesnip{listati/redir_stdout.c} ma
+in altri sistemi queste variabili possono essere definite da macro, e se si
+hanno problemi di portabilità e si vuole essere sicuri, diventa opportuno
+usare la funzione \func{freopen}.
+
+
+\subsection{Le modalità di bufferizzazione}
+\label{sec:file_buffering}
+
+La bufferizzazione è una delle caratteristiche principali dell'interfaccia
+degli \textit{stream}; lo scopo è quello di ridurre al minimo il numero di
+system call (\func{read} o \func{write}) eseguite nelle operazioni di
+input/output. Questa funzionalità è assicurata automaticamente dalla libreria,
+ma costituisce anche uno degli aspetti più comunemente fraintesi, in
+particolare per quello che riguarda l'aspetto della scrittura dei dati sul
+file.
+
+I caratteri che vengono scritti su di uno \textit{stream} normalmente vengono
+accumulati in un buffer e poi trasmessi in blocco\footnote{questa operazione
+  viene usualmente chiamata \textsl{scaricamento} dei dati, dal termine
+  inglese \textit{flush}.} tutte le volte che il buffer viene riempito, in
+maniera asincrona rispetto alla scrittura. Un comportamento analogo avviene
+anche in lettura (cioè dal file viene letto un blocco di dati, anche se ne
+sono richiesti una quantità inferiore), ma la cosa ovviamente ha rilevanza
+inferiore, dato che i dati letti sono sempre gli stessi. In caso di scrittura
+invece, quando si ha un accesso contemporaneo allo stesso file (ad esempio da
+parte di un altro processo) si potranno vedere solo le parti effettivamente
+scritte, e non quelle ancora presenti nel buffer.
+
+Per lo stesso motivo, in tutte le situazioni in cui si sta facendo
+dell'input/output interattivo, bisognerà tenere presente le caratteristiche
+delle operazioni di scaricamento dei dati, poiché non è detto che ad una
+scrittura sullo \textit{stream} corrisponda una immediata scrittura sul
+dispositivo (la cosa è particolarmente evidente quando con le operazioni di
+input/output su terminale).
+
+Per rispondere ad esigenze diverse, lo standard definisce tre distinte
+modalità in cui può essere eseguita la bufferizzazione, delle quali
+occorre essere ben consapevoli, specie in caso di lettura e scrittura da
+dispositivi interattivi:
+\begin{itemize}
+\item \textit{unbuffered}: in questo caso non c'è bufferizzazione ed i
+  caratteri vengono trasmessi direttamente al file non appena possibile
+  (effettuando immediatamente una \func{write}).
+\item \textit{line buffered}: in questo caso i caratteri vengono
+  normalmente trasmessi al file in blocco ogni volta che viene
+  incontrato un carattere di \textit{newline} (il carattere ASCII
+  \verb|\n|).
+\item \textit{fully buffered}: in questo caso i caratteri vengono
+  trasmessi da e verso il file in blocchi di dimensione opportuna.
+\end{itemize}
+
+Lo standard ANSI C specifica inoltre che lo standard output e lo
+standard input siano aperti in modalità \textit{fully buffered} quando
+non fanno riferimento ad un dispositivo interattivo, e che lo standard
+error non sia mai aperto in modalità \textit{fully buffered}.
+
+Linux, come BSD e SVr4, specifica il comportamento predefinito in maniera
+ancora più precisa, e cioè impone che lo standard error sia sempre
+\textit{unbuffered} (in modo che i messaggi di errore siano mostrati il più
+rapidamente possibile) e che standard input e standard output siano aperti in
+modalità \textit{line buffered} quando sono associati ad un terminale (od
+altro dispositivo interattivo) ed in modalità \textit{fully buffered}
+altrimenti.
+
+Il comportamento specificato per standard input e standard output vale anche
+per tutti i nuovi \textit{stream} aperti da un processo; la selezione comunque
+avviene automaticamente, e la libreria apre lo \textit{stream} nella modalità
+più opportuna a seconda del file o del dispositivo scelto.
+
+La modalità \textit{line buffered} è quella che necessita di maggiori
+chiarimenti e attenzioni per quel che concerne il suo funzionamento. Come già
+accennato nella descrizione, \emph{di norma} i dati vengono inviati al kernel
+alla ricezione di un carattere di \textsl{a capo} (\textit{newline}); questo
+non è vero in tutti i casi, infatti, dato che le dimensioni del buffer usato
+dalle librerie sono fisse, se le si eccedono si può avere uno scarico dei dati
+anche prima che sia stato inviato un carattere di \textit{newline}.
+
+Un secondo punto da tenere presente, particolarmente quando si ha a che fare
+con I/O interattivo, è che quando si effettua una lettura da uno
+\textit{stream} che comporta l'accesso al kernel\footnote{questo vuol dire che
+  lo \textit{stream} da cui si legge è in modalità \textit{unbuffered}.} viene
+anche eseguito lo scarico di tutti i buffer degli \textit{stream} in
+scrittura.
+
+In sez.~\ref{sec:file_buffering_ctrl} vedremo come la libreria definisca delle
+opportune funzioni per controllare le modalità di bufferizzazione e lo scarico
+dei dati.
+
+
+
+
+\subsection{Apertura e chiusura di uno \textit{stream}}
+\label{sec:file_fopen}
+
+Le funzioni che si possono usare per aprire uno \textit{stream} sono solo tre:
+\funcd{fopen}, \funcd{fdopen} e \funcd{freopen},\footnote{\func{fopen} e
+  \func{freopen} fanno parte dello standard ANSI C, \func{fdopen} è parte
+  dello standard POSIX.1.} i loro prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h}
+  \funcdecl{FILE *fopen(const char *path, const char *mode)}
+  Apre il file specificato da \param{path}.
+  \funcdecl{FILE *fdopen(int fildes, const char *mode)}
+  Associa uno \textit{stream} al file descriptor \param{fildes}.
+  \funcdecl{FILE *freopen(const char *path, const char *mode, FILE *stream)}
+  Apre il file specificato da \param{path} associandolo allo \textit{stream}
+  specificato da \param{stream}, se questo è già aperto prima lo chiude.
+  
+  \bodydesc{Le funzioni ritornano un puntatore valido in caso di successo e
+    \val{NULL} in caso di errore, in tal caso \var{errno} assumerà il valore
+    ricevuto dalla funzione sottostante di cui è fallita l'esecuzione.
+  
+    Gli errori pertanto possono essere quelli di \func{malloc} per tutte
+    e tre le funzioni, quelli \func{open} per \func{fopen}, quelli di
+    \func{fcntl} per \func{fdopen} e quelli di \func{fopen},
+    \func{fclose} e \func{fflush} per \func{freopen}.}
+\end{functions}
+
+Normalmente la funzione che si usa per aprire uno \textit{stream} è
+\func{fopen}, essa apre il file specificato nella modalità specificata da
+\param{mode}, che è una stringa che deve iniziare con almeno uno dei valori
+indicati in tab.~\ref{tab:file_fopen_mode} (sono possibili varie estensioni
+che vedremo in seguito).
+
+L'uso più comune di \func{freopen} è per redirigere uno dei tre file
+standard (vedi sez.~\ref{sec:file_std_stream}): il file \param{path} viene
+associato a \param{stream} e se questo è uno \textit{stream} già aperto viene
+preventivamente chiuso.
+
+Infine \func{fdopen} viene usata per associare uno \textit{stream} ad un file
+descriptor esistente ottenuto tramite una altra funzione (ad esempio con una
+\func{open}, una \func{dup}, o una \func{pipe}) e serve quando si vogliono
+usare gli \textit{stream} con file come le fifo o i socket, che non possono
+essere aperti con le funzioni delle librerie standard del C.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato}\\
+    \hline
+    \hline
+    \texttt{r} & Il file viene aperto, l'accesso viene posto in sola
+                 lettura, lo \textit{stream} è posizionato all'inizio del
+                 file.\\ 
+    \texttt{r+}& Il file viene aperto, l'accesso viene posto in lettura e
+                 scrittura, lo \textit{stream} è posizionato all'inizio del
+                 file.\\ 
+%    \hline
+    \texttt{w} & Il file viene aperto e troncato a lunghezza nulla (o
+                 creato se non esiste), l'accesso viene posto in sola
+                 scrittura, lo stream\textit{} è posizionato all'inizio del
+                 file.\\ 
+    \texttt{w+}& Il file viene aperto e troncato a lunghezza nulla (o
+                 creato se non esiste), l'accesso viene posto in scrittura e
+                 lettura, lo \textit{stream} è posizionato all'inizio del
+                 file.\\ 
+%    \hline
+    \texttt{a} & Il file viene aperto (o creato se non esiste) in
+                 \itindex{append~mode} \textit{append mode}, l'accesso viene
+                 posto in sola scrittura.\\
+    \texttt{a+}& Il file viene aperto (o creato se non esiste) in
+                 \itindex{append~mode} \textit{append mode}, l'accesso viene
+                 posto in lettura e scrittura.\\
+    \hline
+    \texttt{b} & Specifica che il file è binario, non ha alcun effetto. \\
+    \texttt{x} & L'apertura fallisce se il file esiste già. \\
+    \hline
+  \end{tabular}
+  \caption{Modalità di apertura di uno \textit{stream} dello standard ANSI C
+    che sono sempre presenti in qualunque sistema POSIX.}
+  \label{tab:file_fopen_mode}
+\end{table}
+
+In realtà lo standard ANSI C prevede un totale di 15 possibili valori
+diversi per \param{mode}, ma in tab.~\ref{tab:file_fopen_mode} si sono
+riportati solo i sei valori effettivi, ad essi può essere aggiunto pure
+il carattere \texttt{b} (come ultimo carattere o nel mezzo agli altri per
+le stringhe di due caratteri) che in altri sistemi operativi serve a
+distinguere i file binari dai file di testo; in un sistema POSIX questa
+distinzione non esiste e il valore viene accettato solo per
+compatibilità, ma non ha alcun effetto.
+
+Le \acr{glibc} supportano alcune estensioni, queste devono essere sempre
+indicate dopo aver specificato il \param{mode} con uno dei valori di
+tab.~\ref{tab:file_fopen_mode}. L'uso del carattere \texttt{x} serve per
+evitare di sovrascrivere un file già esistente (è analoga all'uso
+dell'opzione \const{O\_EXCL} in \func{open}), se il file specificato già
+esiste e si aggiunge questo carattere a \param{mode} la \func{fopen}
+fallisce. 
+
+Un'altra estensione serve a supportare la localizzazione, quando si
+aggiunge a \param{mode} una stringa della forma \verb|",ccs=STRING"| il
+valore \verb|STRING| è considerato il nome di una codifica dei caratteri
+e \func{fopen} marca il file per l'uso dei caratteri estesi e abilita le
+opportune funzioni di conversione in lettura e scrittura.
+
+Nel caso si usi \func{fdopen} i valori specificati da \param{mode} devono
+essere compatibili con quelli con cui il file descriptor è stato aperto.
+Inoltre i modi \cmd{w} e \cmd{w+} non troncano il file. La posizione nello
+\textit{stream} viene impostata a quella corrente nel file descriptor, e le
+variabili di errore e di fine del file (vedi sez.~\ref{sec:file_io}) sono
+cancellate. Il file non viene duplicato e verrà chiuso alla chiusura dello
+\textit{stream}.
+
+I nuovi file saranno creati secondo quanto visto in
+sez.~\ref{sec:file_ownership_management} ed avranno i permessi di accesso
+impostati al valore
+\code{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a
+\val{0666}) modificato secondo il valore di \itindex{umask} \textit{umask} per
+il processo (si veda sez.~\ref{sec:file_perm_management}).
+
+In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
+di mezzo una bufferizzazione; per questo motivo lo standard ANSI C
+richiede che ci sia un'operazione di posizionamento fra un'operazione
+di output ed una di input o viceversa (eccetto il caso in cui l'input ha
+incontrato la fine del file), altrimenti una lettura può ritornare anche
+il risultato di scritture precedenti l'ultima effettuata. 
+
+Per questo motivo è una buona pratica (e talvolta necessario) far seguire ad
+una scrittura una delle funzioni \func{fflush}, \func{fseek}, \func{fsetpos} o
+\func{rewind} prima di eseguire una rilettura; viceversa nel caso in cui si
+voglia fare una scrittura subito dopo aver eseguito una lettura occorre prima
+usare una delle funzioni \func{fseek}, \func{fsetpos} o \func{rewind}. Anche
+un'operazione nominalmente nulla come \code{fseek(file, 0, SEEK\_CUR)} è
+sufficiente a garantire la sincronizzazione.
+
+Una volta aperto lo \textit{stream}, si può cambiare la modalità di
+bufferizzazione (si veda sez.~\ref{sec:file_buffering_ctrl}) fintanto che non
+si è effettuato alcuna operazione di I/O sul file.
+
+Uno \textit{stream} viene chiuso con la funzione \funcd{fclose} il cui
+prototipo è:
+\begin{prototype}{stdio.h}{int fclose(FILE *stream)}
+  Chiude lo \textit{stream} \param{stream}. 
+  
+  \bodydesc{Restituisce 0 in caso di successo e \val{EOF} in caso di errore,
+    nel qual caso imposta \var{errno} a \errval{EBADF} se il file descriptor
+    indicato da \param{stream} non è valido, o uno dei valori specificati
+    dalla sottostante funzione che è fallita (\func{close}, \func{write} o
+    \func{fflush}).}
+\end{prototype}
+
+La funzione effettua lo scarico di tutti i dati presenti nei buffer di uscita
+e scarta tutti i dati in ingresso; se era stato allocato un buffer per lo
+\textit{stream} questo verrà rilasciato. La funzione effettua lo scarico solo
+per i dati presenti nei buffer in user space usati dalle \acr{glibc}; se si
+vuole essere sicuri che il kernel forzi la scrittura su disco occorrerà
+effettuare una \func{sync} (vedi sez.~\ref{sec:file_sync}).
+
+Linux supporta anche una altra funzione, \funcd{fcloseall}, come estensione
+GNU implementata dalle \acr{glibc}, accessibile avendo definito
+\macro{\_GNU\_SOURCE}, il suo prototipo è:
+\begin{prototype}{stdio.h}{int fcloseall(void)}
+  Chiude tutti gli \textit{stream}. 
+  
+  \bodydesc{Restituisce 0 se non ci sono errori ed \val{EOF} altrimenti.}
+\end{prototype}
+\noindent la funzione esegue lo scarico dei dati bufferizzati in uscita
+e scarta quelli in ingresso, chiudendo tutti i file. Questa funzione è
+provvista solo per i casi di emergenza, quando si è verificato un errore
+ed il programma deve essere abortito, ma si vuole compiere qualche altra
+operazione dopo aver chiuso i file e prima di uscire (si ricordi quanto
+visto in sez.~\ref{sec:proc_conclusion}).
+
+
+\subsection{Lettura e scrittura 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{enumerate*}
+\item\textsl{binario} in cui legge/scrive un blocco di dati alla
+  volta, vedi sez.~\ref{sec:file_binary_io}.
+\item\textsl{a caratteri} in cui si legge/scrive un carattere alla
+  volta (con la bufferizzazione gestita automaticamente dalla libreria),
+  vedi sez.~\ref{sec:file_char_io}.
+\item\textsl{di linea} in cui si legge/scrive una linea alla volta (terminata
+  dal carattere di newline \verb|'\n'|), vedi sez.~\ref{sec:file_line_io}.
+\end{enumerate*}
+ed inoltre la modalità di input/output formattato.
+
+A differenza dell'interfaccia dei file descriptor, con gli \textit{stream} il
+raggiungimento della fine del file è 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}\footnote{la costante deve essere
+  negativa, le \acr{glibc} usano -1, altre implementazioni possono avere
+  valori diversi.}  definito anch'esso nell'header \headfile{stdlib.h}.
+
+Dato che le funzioni dell'interfaccia degli \textit{stream} sono funzioni di
+libreria che si appoggiano a delle system call, esse non impostano
+direttamente la variabile \var{errno}, che mantiene il valore impostato dalla
+system call che ha riportato l'errore.
+
+Siccome la condizione di 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{functions}
+  \headdecl{stdio.h}
+  \funcdecl{int feof(FILE *stream)}
+  Controlla il flag di end-of-file di \param{stream}.
+  \funcdecl{int ferror(FILE *stream)}
+  Controlla il flag di errore di \param{stream}.
+  
+  \bodydesc{Entrambe le funzioni ritornano un valore diverso da zero se
+    i relativi flag sono impostati.}
+\end{functions}
+\noindent si tenga presente comunque che la lettura di questi flag segnala
+soltanto che c'è stato un errore, o che si è raggiunta la fine del file in una
+qualunque operazione sullo \textit{stream}, il controllo quindi deve essere
+effettuato ogni volta che si chiama una funzione di libreria.
+
+Entrambi i flag (di errore e di end-of-file) possono essere cancellati usando
+la funzione \funcd{clearerr}, il cui prototipo è:
+\begin{prototype}{stdio.h}{void clearerr(FILE *stream)}
+  Cancella i flag di errore ed \textit{end-of-file} di \param{stream}.
+\end{prototype}
+\noindent in genere si usa questa funzione una volta che si sia identificata e
+corretta la causa di un errore per evitare di mantenere i flag attivi, così da
+poter rilevare una successiva ulteriore condizione di errore. Di questa
+funzione esiste una analoga \funcm{clearerr\_unlocked} che non esegue il
+blocco dello \textit{stream} (vedi sez.~\ref{sec:file_stream_thread}).
+
+
+\subsection{Input/output binario}
+\label{sec:file_binary_io}
+
+La prima modalità di input/output non formattato ricalca quella della
+interfaccia dei file descriptor, e provvede semplicemente la scrittura e la
+lettura dei dati da un buffer verso un file e viceversa. In generale questa è
+la modalità che si usa quando si ha a che fare con dati non formattati. Le due
+funzioni che si usano per l'I/O binario sono \funcd{fread} ed \funcd{fwrite};
+i loro prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{size\_t fread(void *ptr, size\_t size, size\_t nmemb, FILE
+    *stream)}
+  
+  \funcdecl{size\_t fwrite(const void *ptr, size\_t size, size\_t
+    nmemb, FILE *stream)}
+  
+  Rispettivamente leggono e scrivono \param{nmemb} elementi di dimensione
+  \param{size} dal buffer \param{ptr} al file \param{stream}.
+  
+  \bodydesc{Entrambe le funzioni ritornano il numero di elementi letti o
+    scritti, in caso di errore o fine del file viene restituito un numero di
+    elementi inferiore al richiesto.}
+\end{functions}
+
+In genere si usano queste funzioni quando si devono trasferire su file
+blocchi di dati binari in maniera compatta e veloce; un primo caso di uso
+tipico è quello in cui si salva un vettore (o un certo numero dei suoi
+elementi) con una chiamata del tipo:
+\includecodesnip{listati/WriteVect.c}
+in questo caso devono essere specificate le dimensioni di ciascun
+elemento ed il numero di quelli che si vogliono scrivere. Un secondo
+caso è invece quello in cui si vuole trasferire su file una struttura;
+si avrà allora una chiamata tipo:
+\includecodesnip{listati/WriteStruct.c}
+in cui si specifica la dimensione dell'intera struttura ed un solo
+elemento. 
+
+In realtà quello che conta nel trasferimento dei dati sono le dimensioni
+totali, che sono sempre pari al prodotto \code{size * nelem}; la sola
+differenza è che le funzioni non ritornano il numero di byte scritti,
+ma il numero di elementi.
+
+La funzione \func{fread} legge sempre un numero intero di elementi, se
+incontra la fine del file l'oggetto letto parzialmente viene scartato (lo
+stesso avviene in caso di errore). In questo caso la posizione dello
+\textit{stream} viene impostata alla fine del file (e non a quella
+corrispondente alla quantità di dati letti).
+
+In caso di errore (o fine del file per \func{fread}) entrambe le
+funzioni restituiscono il numero di oggetti effettivamente letti o
+scritti, che sarà inferiore a quello richiesto. Contrariamente a quanto
+avviene per i file descriptor, questo segnala una condizione di errore e
+occorrerà usare \func{feof} e \func{ferror} per stabilire la natura del
+problema.
+
+Benché queste funzioni assicurino la massima efficienza per il
+salvataggio dei dati, i dati memorizzati attraverso di esse presentano
+lo svantaggio di dipendere strettamente dalla piattaforma di sviluppo
+usata ed in genere possono essere riletti senza problemi solo dallo
+stesso programma che li ha prodotti.
+
+Infatti diversi compilatori possono eseguire ottimizzazioni diverse delle
+strutture dati e alcuni compilatori (come il \cmd{gcc}) possono anche
+scegliere se ottimizzare l'occupazione di spazio, impacchettando più
+strettamente i dati, o la velocità inserendo opportuni \textit{padding} per
+l'allineamento dei medesimi generando quindi output binari diversi. Inoltre
+altre incompatibilità si possono presentare quando entrano in gioco differenze
+di architettura hardware, come la dimensione del bus o la modalità di
+ordinamento dei bit o il formato delle variabili in floating point.
+
+Per questo motivo quando si usa l'input/output binario occorre sempre prendere
+le opportune precauzioni (in genere usare un formato di più alto livello che
+permetta di recuperare l'informazione completa), per assicurarsi che versioni
+diverse del programma siano in grado di rileggere i dati tenendo conto delle
+eventuali differenze.
+
+Le \acr{glibc} definiscono altre due funzioni per l'I/O binario,
+\funcd{fread\_unlocked} e \funcd{fwrite\_unlocked} che evitano il lock
+implicito dello \textit{stream}, usato per dalla librerie per la gestione delle
+applicazioni \itindex{thread} \textit{multi-thread} (si veda
+sez.~\ref{sec:file_stream_thread} per i dettagli), i loro prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h}
+  
+  \funcdecl{size\_t fread\_unlocked(void *ptr, size\_t size, size\_t
+    nmemb, FILE *stream)}
+  
+  \funcdecl{size\_t fwrite\_unlocked(const void *ptr, size\_t size,
+    size\_t nmemb, FILE *stream)}
+  
+  \bodydesc{Le funzioni sono identiche alle analoghe \func{fread} e
+    \func{fwrite} ma non acquisiscono il lock implicito sullo \textit{stream}.}
+\end{functions}
+\noindent entrambe le funzioni sono estensioni GNU previste solo dalle
+\acr{glibc}.
+
+
+\subsection{Input/output a caratteri}
+\label{sec:file_char_io}
+
+La seconda modalità di input/output è quella a caratteri, in cui si
+trasferisce un carattere alla volta.  Le funzioni per la lettura a
+caratteri sono tre, \funcd{fgetc}, \funcd{getc} e \funcd{getchar}, i
+rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+
+  \funcdecl{int getc(FILE *stream)} Legge un byte da \param{stream} e lo
+  restituisce come intero. In genere è implementata come una macro. 
+  
+  \funcdecl{int fgetc(FILE *stream)} Legge un byte da \param{stream} e lo
+  restituisce come intero. È sempre una funzione.
+  
+  \funcdecl{int getchar(void)} Equivalente a \code{getc(stdin)}.
+  
+  \bodydesc{Tutte queste funzioni leggono un byte alla volta, che viene
+    restituito come intero; in caso di errore o fine del file il valore
+    di ritorno è \val{EOF}.}
+\end{functions}
+
+A parte \func{getchar}, che si usa in genere per leggere un carattere da
+tastiera, le altre due funzioni sono sostanzialmente equivalenti. La
+differenza è che \func{getc} è ottimizzata al massimo e normalmente
+viene implementata con una macro, per cui occorre stare attenti a cosa
+le si passa come argomento, infatti \param{stream} può essere valutato
+più volte nell'esecuzione, e non viene passato in copia con il
+meccanismo visto in sez.~\ref{sec:proc_var_passing}; per questo motivo se
+si passa un'espressione si possono avere effetti indesiderati.
+
+Invece \func{fgetc} è assicurata essere sempre una funzione, per questo motivo
+la sua esecuzione normalmente è più lenta per via dell'overhead della
+chiamata, ma è altresì possibile ricavarne l'indirizzo, che può essere passato
+come argomento ad un altra funzione (e non si hanno i problemi accennati in
+precedenza nel tipo di argomento).
+
+Le tre funzioni restituiscono tutte un \ctyp{unsigned char} convertito
+ad \ctyp{int} (si usa \ctyp{unsigned char} in modo da evitare
+l'espansione del segno). In questo modo il valore di ritorno è sempre
+positivo, tranne in caso di errore o fine del file.
+
+Nelle estensioni GNU che provvedono la localizzazione sono definite tre
+funzioni equivalenti alle precedenti, \funcd{getwc}, \funcd{fgetwc} e
+\funcd{getwchar}, che invece di un carattere di un byte restituiscono un
+carattere in formato esteso (cioè di tipo \ctyp{wint\_t}), il loro prototipo
+è:
+\begin{functions}
+  \headdecl{stdio.h} 
+  \headdecl{wchar.h} 
+  
+  \funcdecl{wint\_t getwc(FILE *stream)} Legge un carattere esteso da
+  \param{stream}. In genere è implementata come una macro.
+  
+  \funcdecl{wint\_t fgetwc(FILE *stream)} Legge un carattere esteso da
+  \param{stream}. È una sempre una funzione.
+  
+  \funcdecl{wint\_t getwchar(void)} Equivalente a \code{getwc(stdin)}.
+  
+  \bodydesc{Tutte queste funzioni leggono un carattere alla volta, in
+    caso di errore o fine del file il valore di ritorno è \const{WEOF}.}
+\end{functions}
+
+Per scrivere un carattere si possono usare tre funzioni, analoghe alle
+precedenti usate per leggere: \funcd{putc}, \funcd{fputc} e \funcd{putchar}; i
+loro prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int putc(int c, FILE *stream)} Scrive il carattere \param{c}
+  su \param{stream}. In genere è implementata come una macro.
+  
+  \funcdecl{int fputc(int c, FILE *stream)} Scrive il carattere \param{c} su
+  \param{stream}. È una sempre una funzione.
+  
+  \funcdecl{int putchar(int c)} Equivalente a \code{putc(stdout)}.
+  
+  \bodydesc{Le funzioni scrivono sempre un carattere alla volta, il cui
+    valore viene restituito in caso di successo; in caso di errore o
+    fine del file il valore di ritorno è \val{EOF}.}
+\end{functions}
+
+Tutte queste funzioni scrivono sempre un byte alla volta, anche se prendono
+come argomento un \ctyp{int} (che pertanto deve essere ottenuto con un cast da
+un \ctyp{unsigned char}). Anche il valore di ritorno è sempre un intero; in
+caso di errore o fine del file il valore di ritorno è \val{EOF}.
+
+Come nel caso dell'I/O binario con \func{fread} e \func{fwrite} le \acr{glibc}
+provvedono come estensione, per ciascuna delle funzioni precedenti,
+un'ulteriore funzione, il cui nome è ottenuto aggiungendo un
+\code{\_unlocked}, che esegue esattamente le stesse operazioni, evitando però
+il lock implicito dello \textit{stream}.
+
+Per compatibilità con SVID sono inoltre provviste anche due funzioni,
+\funcd{getw} e \funcd{putw}, da usare per leggere e scrivere una \textit{word}
+(cioè due byte in una volta); i loro prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int getw(FILE *stream)} Legge una parola da \param{stream}.
+  \funcdecl{int putw(int w, FILE *stream)} Scrive la parola \param{w} su
+  \param{stream}.
+  
+  \bodydesc{Le funzioni restituiscono la parola \param{w}, o \val{EOF}
+    in caso di errore o di fine del file.}
+\end{functions}
+
+Le funzioni leggono e scrivono una \textit{word} di due byte, usando comunque
+una variabile di tipo \ctyp{int}; il loro uso è deprecato in favore dell'uso
+di \func{fread} e \func{fwrite}, in quanto non è possibile distinguere il
+valore -1 da una condizione di errore che restituisce \val{EOF}.
+
+Uno degli usi più frequenti dell'input/output a caratteri è nei programmi di
+\textit{parsing} in cui si analizza il testo; in questo contesto diventa utile
+poter analizzare il carattere successivo da uno \textit{stream} senza estrarlo
+effettivamente (la tecnica è detta \textit{peeking ahead}) in modo che il
+programma possa regolarsi avendo dato una \textsl{sbirciatina} a quello che
+viene dopo.
+
+Nel nostro caso questo tipo di comportamento può essere realizzato prima
+leggendo il carattere, e poi rimandandolo indietro, cosicché ridiventi
+disponibile per una lettura successiva; la funzione che inverte la
+lettura si chiama \funcd{ungetc} ed il suo prototipo è:
+\begin{prototype}{stdio.h}{int ungetc(int c, FILE *stream)}
+  Rimanda indietro il carattere \param{c}, con un cast a \ctyp{unsigned
+    char}, sullo \textit{stream} \param{stream}.
+
+  \bodydesc{La funzione ritorna \param{c} in caso di successo e
+  \val{EOF} in caso di errore.}
+\end{prototype}
+\noindent benché lo standard ANSI C preveda che l'operazione possa
+essere ripetuta per un numero arbitrario di caratteri, alle
+implementazioni è richiesto di garantire solo un livello; questo è
+quello che fa la \acr{glibc}, che richiede che avvenga un'altra
+operazione fra due \func{ungetc} successive.
+
+Non è necessario che il carattere che si manda indietro sia l'ultimo che
+si è letto, e non è necessario neanche avere letto nessun carattere
+prima di usare \func{ungetc}, ma di norma la funzione è intesa per
+essere usata per rimandare indietro l'ultimo carattere letto.
+
+Nel caso \param{c} sia un \val{EOF} la funzione non fa nulla, e
+restituisce sempre \val{EOF}; così si può usare \func{ungetc} anche
+con il risultato di una lettura alla fine del file.
+
+Se si è alla fine del file si può comunque rimandare indietro un
+carattere, il flag di end-of-file verrà automaticamente cancellato
+perché c'è un nuovo carattere disponibile che potrà essere riletto
+successivamente.
+
+Infine si tenga presente che \func{ungetc} non altera il contenuto del
+file, ma opera esclusivamente sul buffer interno. Se si esegue una
+qualunque delle operazioni di riposizionamento (vedi
+sez.~\ref{sec:file_fseek}) i caratteri rimandati indietro vengono
+scartati.
+
+
+\subsection{Input/output di linea}
+\label{sec:file_line_io}
+
+La terza ed ultima modalità di input/output non formattato è quella di linea,
+in cui si legge o si scrive una riga alla volta; questa è una modalità molto
+usata per l'I/O da terminale, ma è anche quella che presenta le
+caratteristiche più controverse.
+
+Le funzioni previste dallo standard ANSI C per leggere una linea sono
+sostanzialmente due, \funcd{gets} e \funcd{fgets}, i cui rispettivi
+prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{char *gets(char *string)} Scrive su \param{string} una
+  linea letta da \var{stdin}.
+  
+  \funcdecl{char *fgets(char *string, int size, FILE *stream)}
+  Scrive su \param{string} la linea letta da \param{stream} per un
+  massimo di \param{size} byte.
+  
+  \bodydesc{Le funzioni restituiscono l'indirizzo \param{string} in caso
+    di successo o \val{NULL} in caso di errore.}
+\end{functions}
+
+Entrambe le funzioni effettuano la lettura (dal file specificato \func{fgets},
+dallo standard input \func{gets}) di una linea di caratteri (terminata dal
+carattere \textit{newline}, \verb|'\n'|, quello mappato sul tasto di ritorno a
+capo della tastiera), ma \func{gets} sostituisce \verb|'\n'| con uno zero,
+mentre \func{fgets} aggiunge uno zero dopo il \textit{newline}, che resta
+dentro la stringa. Se la lettura incontra la fine del file (o c'è un errore)
+viene restituito un \val{NULL}, ed il buffer \param{buf} non viene toccato.
+L'uso di \func{gets} è deprecato e deve essere assolutamente evitato; la
+funzione infatti non controlla il numero di byte letti, per cui nel caso la
+stringa letta superi le dimensioni del buffer, si avrà un
+\itindex{buffer~overflow} \textit{buffer overflow}, con sovrascrittura della
+memoria del processo adiacente al buffer.\footnote{questa tecnica è spiegata
+  in dettaglio e con molta efficacia nell'ormai famoso articolo di Aleph1
+  \cite{StS}.}
+
+Questa è una delle vulnerabilità più sfruttate per guadagnare accessi non
+autorizzati al sistema (i cosiddetti \textit{exploit}), basta infatti inviare
+una stringa sufficientemente lunga ed opportunamente forgiata per
+sovrascrivere gli indirizzi di ritorno nello \itindex{stack} \textit{stack}
+(supposto che la \func{gets} sia stata chiamata da una subroutine), in modo da
+far ripartire l'esecuzione nel codice inviato nella stringa stessa (in genere
+uno \textit{shell code} cioè una sezione di programma che lancia una shell).
+
+La funzione \func{fgets} non ha i precedenti problemi di \func{gets} in quanto
+prende in input la dimensione del buffer \param{size}, che non verrà mai
+ecceduta in lettura. La funzione legge fino ad un massimo di \param{size}
+caratteri (newline compreso), ed aggiunge uno zero di terminazione; questo
+comporta che la stringa possa essere al massimo di \code{size-1} caratteri.  Se
+la linea eccede la dimensione del buffer verranno letti solo \code{size-1}
+caratteri, ma la stringa sarà sempre terminata correttamente con uno zero
+finale; sarà possibile leggere i rimanenti caratteri in una chiamata
+successiva.
+
+Per la scrittura di una linea lo standard ANSI C prevede altre due
+funzioni, \funcd{fputs} e \funcd{puts}, analoghe a quelle di lettura, i
+rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int puts(const char *string)} Scrive su \var{stdout} la
+  linea \param{string}.
+  
+  \funcdecl{int fputs(const char *string, FILE *stream)} Scrive su
+  \param{stream} la linea \param{string}.
+  
+  \bodydesc{Le funzioni restituiscono un valore non negativo in caso di
+    successo o \val{EOF} in caso di errore.}
+\end{functions}
+
+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 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 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
+estesi, le funzioni in questione sono \funcd{fgetws} e \funcd{fputws} ed i
+loro prototipi sono:
+\begin{functions}
+  \headdecl{wchar.h} 
+  \funcdecl{wchar\_t *fgetws(wchar\_t *ws, int n, FILE *stream)}
+  Legge un massimo di \param{n} caratteri estesi dal file
+  \param{stream} al buffer \param{ws}.
+  
+  \funcdecl{int fputws(const wchar\_t *ws, FILE *stream)} Scrive la
+  linea \param{ws} di caratteri estesi sul file \param{stream}.
+  
+  \bodydesc{Le funzioni ritornano rispettivamente \param{ws} o un numero
+    non negativo in caso di successo e \val{NULL} o \val{EOF} in
+    caso di errore o fine del file.}
+\end{functions}
+
+Il comportamento di queste due funzioni è identico a quello di \func{fgets} e
+\func{fputs}, a parte il fatto che tutto (numero di caratteri massimo,
+terminatore della stringa, newline) è espresso in termini di caratteri estesi
+anziché di normali caratteri ASCII.
+
+Come per l'I/O binario e quello a caratteri, anche per l'I/O di linea le
+\acr{glibc} supportano una serie di altre funzioni, estensioni di tutte quelle
+illustrate finora (eccetto \func{gets} e \func{puts}), che eseguono
+esattamente le stesse operazioni delle loro equivalenti, evitando però il lock
+implicito dello \textit{stream} (vedi sez.~\ref{sec:file_stream_thread}). Come
+per le altre forma di I/O, dette funzioni hanno lo stesso nome della loro
+analoga normale, con l'aggiunta dell'estensione \code{\_unlocked}.
+
+Come abbiamo visto, le funzioni di lettura per l'input/output di linea
+previste dallo standard ANSI C presentano svariati inconvenienti. Benché
+\func{fgets} non abbia i gravissimi problemi di \func{gets}, può
+comunque dare risultati ambigui se l'input contiene degli zeri; questi
+infatti saranno scritti sul buffer di uscita e la stringa in output
+apparirà come più corta dei byte effettivamente letti. Questa è una
+condizione che è sempre possibile controllare (deve essere presente un
+newline prima della effettiva conclusione della stringa presente nel
+buffer), ma a costo di una complicazione ulteriore della logica del
+programma. Lo stesso dicasi quando si deve gestire il caso di stringa
+che eccede le dimensioni del buffer.
+
+Per questo motivo le \acr{glibc} prevedono, come estensione GNU, due nuove
+funzioni per la gestione dell'input/output di linea, il cui uso permette di
+risolvere questi problemi. L'uso di queste funzioni deve essere attivato
+definendo la macro \macro{\_GNU\_SOURCE} prima di includere
+\headfile{stdio.h}. La prima delle due, \funcd{getline}, serve per leggere una
+linea terminata da un newline, esattamente allo stesso modo di \func{fgets},
+il suo prototipo è:
+\begin{prototype}{stdio.h}
+  {ssize\_t getline(char **buffer, size\_t *n, FILE *stream)} Legge una linea
+  dal file \param{stream} copiandola sul buffer indicato da \param{buffer}
+  riallocandolo se necessario (l'indirizzo del buffer e la sua dimensione
+  vengono sempre riscritte).
+
+  \bodydesc{La funzione ritorna il numero di caratteri letti in caso di
+  successo e -1 in caso di errore o di raggiungimento della fine del
+  file.}
+\end{prototype}
+
+La funzione permette di eseguire una lettura senza doversi preoccupare della
+eventuale lunghezza eccessiva della stringa da leggere. Essa prende come primo
+argomento l'indirizzo del puntatore al buffer su cui si vuole copiare la
+linea. Quest'ultimo \emph{deve} essere stato allocato in precedenza con una
+\func{malloc} (non si può passare l'indirizzo di un puntatore ad una variabile
+locale); come secondo argomento la funzione vuole l'indirizzo della variabile
+contenente le dimensioni del buffer suddetto.
+
+Se il buffer di destinazione è sufficientemente ampio la stringa viene scritta
+subito, altrimenti il buffer viene allargato usando \func{realloc} e la nuova
+dimensione ed il nuovo puntatore vengono restituiti indietro (si noti infatti
+come per entrambi gli argomenti si siano usati dei
+\itindex{value~result~argument} \textit{value result argument}, passando dei
+puntatori anziché i valori delle variabili, secondo la tecnica spiegata in
+sez.~\ref{sec:proc_var_passing}).
+
+Se si passa alla funzione l'indirizzo di un puntatore impostato a \val{NULL} e
+\var{*n} è zero, la funzione provvede da sola all'allocazione della memoria
+necessaria a contenere la linea. In tutti i casi si ottiene dalla funzione un
+puntatore all'inizio del testo della linea letta. Un esempio di codice può
+essere il seguente: 
+\includecodesnip{listati/getline.c} 
+e per evitare  \itindex{memory~leak} \textit{memory leak} occorre ricordarsi di
+liberare \var{ptr} con una \func{free}.
+
+Il valore di ritorno della funzione indica il numero di caratteri letti
+dallo \textit{stream} (quindi compreso il newline, ma non lo zero di
+terminazione); questo permette anche di distinguere eventuali zeri letti
+dallo \textit{stream} da quello inserito dalla funzione per terminare la linea.
+Se si è alla fine del file e non si è potuto leggere nulla o c'è stato
+un errore la funzione restituisce -1.
+
+La seconda estensione GNU è una generalizzazione di \func{getline} per
+poter usare come separatore un carattere qualsiasi, la funzione si
+chiama \funcd{getdelim} ed il suo prototipo è:
+\begin{prototype}{stdio.h}
+{ssize\_t getdelim(char **buffer, size\_t *n, int delim, FILE *stream)} 
+  Identica a \func{getline} solo che usa \param{delim} al posto del
+  carattere di newline come separatore di linea.
+\end{prototype}
+
+Il comportamento di \func{getdelim} è identico a quello di \func{getline} (che
+può essere implementata da questa passando \verb|'\n'| come valore di
+\param{delim}).
+
+
+\subsection{L'input/output formattato}
+\label{sec:file_formatted_io}
+
+L'ultima modalità di input/output è quella formattata, che è una delle
+caratteristiche più utilizzate delle librerie standard del C; in genere questa
+è la modalità in cui si esegue normalmente l'output su terminale poiché
+permette di stampare in maniera facile e veloce dati, tabelle e messaggi.
+
+L'output formattato viene eseguito con una delle 13 funzioni della famiglia
+\func{printf}; le tre più usate sono \funcd{printf}, \funcd{fprintf} e
+\funcd{sprintf}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  \funcdecl{int printf(const char *format, ...)} Stampa su \file{stdout}
+  gli argomenti, secondo il formato specificato da \param{format}.
+  
+  \funcdecl{int fprintf(FILE *stream, const char *format, ...)}  Stampa
+  su \param{stream} gli argomenti, secondo il formato specificato da
+  \param{format}.
+  
+  \funcdecl{int sprintf(char *str, const char *format, ...)} Stampa
+  sulla stringa \param{str} gli argomenti, secondo il formato
+  specificato da \param{format}.
+
+  \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
+\end{functions}
+\noindent le prime due servono per stampare su file (lo standard output o
+quello specificato) la terza permette di stampare su una stringa, in genere
+l'uso di \func{sprintf} è sconsigliato in quanto è possibile, se non si ha la
+sicurezza assoluta sulle dimensioni del risultato della stampa, eccedere le
+dimensioni di \param{str}, con conseguente sovrascrittura di altre variabili e
+possibili \itindex{buffer~overflow} \textit{buffer overflow}; per questo
+motivo si consiglia l'uso dell'alternativa \funcd{snprintf}, il cui prototipo
+è:
+\begin{prototype}{stdio.h}
+{snprintf(char *str, size\_t size, const char *format, ...)} 
+  Identica a \func{sprintf}, ma non scrive su \param{str} più di
+  \param{size} caratteri.
+\end{prototype}
+
+La parte più complessa delle funzioni di scrittura formattata è il formato
+della stringa \param{format} che indica le conversioni da fare, e da cui
+deriva anche il numero degli argomenti che dovranno essere passati a seguire
+(si noti come tutte queste funzioni siano \index{funzioni!variadic}
+\textit{variadic}, prendendo un numero di argomenti variabile che dipende
+appunto da quello che si è specificato in \param{format}).
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|p{10cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Tipo} & \textbf{Significato} \\
+    \hline
+    \hline
+   \cmd{\%d} &\ctyp{int}         & Stampa un numero intero in formato decimale
+                                   con segno.\\
+   \cmd{\%i} &\ctyp{int}         & Identico a \cmd{\%i} in output.\\
+   \cmd{\%o} &\ctyp{unsigned int}& Stampa un numero intero come ottale.\\
+   \cmd{\%u} &\ctyp{unsigned int}& Stampa un numero intero in formato
+                                   decimale senza segno.\\
+   \cmd{\%x}, 
+   \cmd{\%X} &\ctyp{unsigned int}& Stampano un intero in formato esadecimale,
+                                   rispettivamente con lettere minuscole e
+                                   maiuscole.\\
+   \cmd{\%f} &\ctyp{double}      & Stampa un numero in virgola mobile con la
+                                   notazione a virgola fissa.\\
+   \cmd{\%e}, 
+   \cmd{\%E} &\ctyp{double} & Stampano un numero in virgola mobile con la
+                              notazione esponenziale, rispettivamente con
+                              lettere minuscole e maiuscole.\\
+   \cmd{\%g}, 
+   \cmd{\%G} &\ctyp{double} & Stampano un numero in virgola mobile con la
+                              notazione più appropriate delle due precedenti,
+                              rispettivamente con lettere minuscole e
+                              maiuscole.\\
+   \cmd{\%a}, 
+   \cmd{\%A} &\ctyp{double} & Stampano un numero in virgola mobile in
+                              notazione esadecimale frazionaria.\\
+   \cmd{\%c} &\ctyp{int}    & Stampa un carattere singolo.\\
+   \cmd{\%s} &\ctyp{char *} & Stampa una stringa.\\
+   \cmd{\%p} &\ctyp{void *} & Stampa il valore di un puntatore.\\
+   \cmd{\%n} &\ctyp{\&int}  & Prende il numero di caratteri stampati finora.\\
+   \cmd{\%\%}&              & Stampa un \%.\\
+    \hline
+  \end{tabular}
+  \caption{Valori possibili per gli specificatori di conversione in una
+    stringa di formato di \func{printf}.} 
+  \label{tab:file_format_spec}
+\end{table}
+
+La stringa è costituita da caratteri normali (tutti eccetto \texttt{\%}), che
+vengono passati invariati all'output, e da direttive di conversione, in cui
+devono essere sempre presenti il carattere \texttt{\%}, che introduce la
+direttiva, ed uno degli specificatori di conversione (riportati in
+tab.~\ref{tab:file_format_spec}) che la conclude.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato}\\
+    \hline
+    \hline
+    \val{\#} & Chiede la conversione in forma alternativa. \\
+    \val{0}  & La conversione è riempita con zeri alla sinistra del valore.\\
+    \val{-}  & La conversione viene allineata a sinistra sul bordo del campo.\\
+    \val{' '}& Mette uno spazio prima di un numero con segno di valore 
+               positivo.\\
+    \val{+}  & Mette sempre il segno ($+$ o $-$) prima di un numero.\\
+    \hline
+  \end{tabular}
+  \caption{I valori dei flag per il formato di \func{printf}}
+  \label{tab:file_format_flag}
+\end{table}
+
+Il formato di una direttiva di conversione prevede una serie di possibili
+elementi opzionali oltre al \cmd{\%} e allo specificatore di conversione. In
+generale essa è sempre del tipo:
+\begin{center}
+\begin{verbatim}
+% [n. parametro $] [flag] [[larghezza] [. precisione]] [tipo] conversione
+\end{verbatim}
+\end{center}
+in cui tutti i valori tranne il \val{\%} e lo specificatore di conversione
+sono opzionali (e per questo sono indicati fra parentesi quadre); si possono
+usare più elementi opzionali, nel qual caso devono essere specificati in
+questo ordine:
+\begin{itemize*}
+\item uno specificatore del parametro da usare (terminato da un \val{\$}),
+\item uno o più flag (i cui valori possibili sono riassunti in
+  tab.~\ref{tab:file_format_flag}) che controllano il formato di stampa della
+  conversione,
+\item uno specificatore di larghezza (un numero decimale), eventualmente
+  seguito (per i numeri in virgola mobile) da un specificatore di precisione
+  (un altro numero decimale),
+\item uno specificatore del tipo di dato, che ne indica la dimensione (i cui
+  valori possibili sono riassunti in tab.~\ref{tab:file_format_type}).
+\end{itemize*}
+
+
+Dettagli ulteriori sulle varie opzioni possono essere trovati nella pagina di
+manuale di \func{printf} e nella documentazione delle \acr{glibc}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \cmd{hh} & Una conversione intera corrisponde a un \ctyp{char} con o senza
+               segno, o il puntatore per il numero dei parametri \cmd{n} è di 
+               tipo \ctyp{char}.\\
+    \cmd{h}  & Una conversione intera corrisponde a uno \ctyp{short} con o 
+               senza segno, o il puntatore per il numero dei parametri \cmd{n}
+               è di tipo \ctyp{short}.\\
+    \cmd{l}  & Una conversione intera corrisponde a un \ctyp{long} con o 
+               senza segno, o il puntatore per il numero dei parametri \cmd{n}
+               è di tipo \ctyp{long}, o il carattere o la stringa seguenti
+               sono in formato esteso.\\ 
+    \cmd{ll} & Una conversione intera corrisponde a un \ctyp{long long} con o 
+               senza segno, o il puntatore per il numero dei parametri \cmd{n}
+               è di tipo \ctyp{long long}.\\
+    \cmd{L}  & Una conversione in virgola mobile corrisponde a un
+               \ctyp{double}.\\
+    \cmd{q}  & Sinonimo di \cmd{ll}.\\
+    \cmd{j}  & Una conversione intera corrisponde a un \type{intmax\_t} o 
+               \type{uintmax\_t}.\\
+    \cmd{z}  & Una conversione intera corrisponde a un \type{size\_t} o 
+               \type{ssize\_t}.\\
+    \cmd{t}  & Una conversione intera corrisponde a un \type{ptrdiff\_t}.\\
+    \hline
+  \end{tabular}
+  \caption{Il modificatore di tipo di dato per il formato di \func{printf}}
+  \label{tab:file_format_type}
+\end{table}
+
+Una versione alternativa delle funzioni di output formattato, che permettono
+di usare il puntatore ad una lista variabile \index{funzioni!variadic} di
+argomenti (vedi sez.~\ref{sec:proc_variadic}), sono \funcd{vprintf},
+\funcd{vfprintf} e \funcd{vsprintf}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int vprintf(const char *format, va\_list ap)} Stampa su
+  \var{stdout} gli argomenti della lista \param{ap}, secondo il formato
+  specificato da \param{format}.
+  
+  \funcdecl{int vfprintf(FILE *stream, const char *format, va\_list ap)}
+  Stampa su \param{stream} gli argomenti della lista \param{ap}, secondo il
+  formato specificato da \param{format}.
+  
+  \funcdecl{int vsprintf(char *str, const char *format, va\_list ap)} Stampa
+  sulla stringa \param{str} gli argomenti della lista \param{ap}, secondo il
+  formato specificato da \param{format}.
+
+  \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
+\end{functions}
+\noindent con queste funzioni diventa possibile selezionare gli argomenti che
+si vogliono passare ad una funzione di stampa, passando direttamente la lista
+tramite l'argomento \param{ap}. Per poter far questo ovviamente la lista
+variabile\index{funzioni!variadic} degli argomenti dovrà essere opportunamente
+trattata (l'argomento è esaminato in sez.~\ref{sec:proc_variadic}), e dopo
+l'esecuzione della funzione l'argomento
+\param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un
+\code{va\_end(ap)} ma in Linux questo non è necessario). 
+
+Come per \func{sprintf} anche per \func{vsprintf} esiste una analoga
+\funcd{vsnprintf} che pone un limite sul numero di caratteri che vengono
+scritti sulla stringa di destinazione:
+\begin{prototype}{stdio.h}
+{vsnprintf(char *str, size\_t size, const char *format, va\_list ap)} 
+  Identica a \func{vsprintf}, ma non scrive su \param{str} più di
+  \param{size} caratteri.
+\end{prototype}
+\noindent in modo da evitare possibili \itindex{buffer~overflow} buffer
+overflow.
+
+
+Per eliminare alla radice questi problemi, le \acr{glibc} supportano una
+specifica estensione GNU che alloca dinamicamente tutto lo spazio necessario;
+l'estensione si attiva al solito definendo \macro{\_GNU\_SOURCE}, le due
+funzioni sono \funcd{asprintf} e \funcd{vasprintf}, ed i rispettivi prototipi
+sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+    
+  \funcdecl{int asprintf(char **strptr, const char *format, ...)}  Stampa gli
+  argomenti specificati secondo il formato specificato da \param{format} su
+  una stringa allocata automaticamente all'indirizzo \param{*strptr}.
+  
+  \funcdecl{int vasprintf(char **strptr, const char *format, va\_list ap)}
+  Stampa gli argomenti della lista \param{ap} secondo il formato specificato
+  da \param{format} su una stringa allocata automaticamente all'indirizzo
+  \param{*strptr}.
+
+  \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
+\end{functions}
+
+Entrambe le funzioni prendono come argomento \param{strptr} che deve essere
+l'indirizzo di un puntatore ad una stringa di caratteri, in cui verrà
+restituito (si ricordi quanto detto in sez.~\ref{sec:proc_var_passing} a
+proposito dei \itindex{value~result~argument} \textit{value result argument})
+l'indirizzo della stringa allocata automaticamente dalle funzioni. Occorre
+inoltre ricordarsi di invocare \func{free} per liberare detto puntatore quando
+la stringa non serve più, onde evitare \itindex{memory~leak} \textit{memory
+  leak}.
+
+% TODO verificare se mettere prototipi di \func{dprintf} e \func{vdprintf}
+
+Infine una ulteriore estensione GNU definisce le due funzioni \funcm{dprintf} e
+\funcm{vdprintf}, che prendono un file descriptor al posto dello
+\textit{stream}. Altre estensioni permettono di scrivere con caratteri
+estesi. Anche queste funzioni, il cui nome è generato dalle precedenti
+funzioni aggiungendo una \texttt{w} davanti a \texttt{print}, sono trattate in
+dettaglio nella documentazione delle \acr{glibc}.
+
+In corrispondenza alla famiglia di funzioni \func{printf} che si usano per
+l'output formattato, l'input formattato viene eseguito con le funzioni della
+famiglia \func{scanf}; fra queste le tre più importanti sono \funcd{scanf},
+\funcd{fscanf} e \funcd{sscanf}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} \funcdecl{int scanf(const char *format, ...)} Esegue una
+  scansione di \file{stdin} cercando una corrispondenza di quanto letto con il
+  formato dei dati specificato da \param{format}, ed effettua le relative
+  conversione memorizzando il risultato negli argomenti seguenti.
+  
+  \funcdecl{int fscanf(FILE *stream, const char *format, ...)}  Analoga alla
+  precedente, ma effettua la scansione su \param{stream}.
+  
+  \funcdecl{int sscanf(char *str, const char *format, ...)} Analoga alle
+  precedenti, ma effettua la scansione dalla stringa \param{str}.
+  
+  \bodydesc{Le funzioni ritornano il numero di elementi assegnati. Questi
+    possono essere in numero inferiore a quelli specificati, ed anche zero.
+    Quest'ultimo valore significa che non si è trovata corrispondenza. In caso
+    di errore o fine del file viene invece restituito \val{EOF}.}
+\end{functions}
+\noindent e come per le analoghe funzioni di scrittura esistono le relative
+\funcm{vscanf}, \funcm{vfscanf} e \funcm{vsscanf} che usano un puntatore ad
+una lista di argomenti.
+
+Tutte le funzioni della famiglia delle \func{scanf} vogliono come argomenti i
+puntatori alle variabili che dovranno contenere le conversioni; questo è un
+primo elemento di disagio in quanto è molto facile dimenticarsi di questa
+caratteristica.
+
+Le funzioni leggono i caratteri dallo \textit{stream} (o dalla stringa) di
+input ed eseguono un confronto con quanto indicato in \param{format}, la
+sintassi di questo argomento è simile a quella usata per l'analogo di
+\func{printf}, ma ci sono varie differenze.  Le funzioni di input infatti sono
+più orientate verso la lettura di testo libero che verso un input formattato
+in campi fissi. Uno spazio in \param{format} corrisponde con un numero
+qualunque di caratteri di separazione (che possono essere spazi, tabulatori,
+virgole ecc.), mentre caratteri diversi richiedono una corrispondenza
+esatta. Le direttive di conversione sono analoghe a quelle di \func{printf} e
+si trovano descritte in dettaglio nelle pagine di manuale e nel manuale delle
+\acr{glibc}.
+
+Le funzioni eseguono la lettura dall'input, scartano i separatori (e gli
+eventuali caratteri diversi indicati dalla stringa di formato) effettuando le
+conversioni richieste; in caso la corrispondenza fallisca (o la funzione non
+sia in grado di effettuare una delle conversioni richieste) la scansione viene
+interrotta immediatamente e la funzione ritorna lasciando posizionato lo
+\textit{stream} al primo carattere che non corrisponde.
+
+Data la notevole complessità di uso di queste funzioni, che richiedono molta
+cura nella definizione delle corrette stringhe di formato e sono facilmente
+soggette ad errori, e considerato anche il fatto che è estremamente macchinoso
+recuperare in caso di fallimento nelle corrispondenze, l'input formattato non
+è molto usato. In genere infatti quando si ha a che fare con un input
+relativamente semplice si preferisce usare l'input di linea ed effettuare
+scansione e conversione di quanto serve direttamente con una delle funzioni di
+conversione delle stringhe; se invece il formato è più complesso diventa più
+facile utilizzare uno strumento come \cmd{flex}\footnote{il programma
+  \cmd{flex}, è una implementazione libera di \cmd{lex} un generatore di
+  analizzatori lessicali. Per i dettagli si può fare riferimento al manuale
+  \cite{flex}.} per generare un analizzatore lessicale o il
+\cmd{bison}\footnote{il programma \cmd{bison} è un clone del generatore di
+  parser \cmd{yacc}, maggiori dettagli possono essere trovati nel relativo
+  manuale \cite{bison}.} per generare un parser.
+
+
+\subsection{Posizionamento su uno \textit{stream}}
+\label{sec:file_fseek}
+
+Come per i file descriptor anche per gli \textit{stream} è possibile spostarsi
+all'interno di un file per effettuare operazioni di lettura o scrittura in un
+punto prestabilito; sempre che l'operazione di riposizionamento sia supportata
+dal file sottostante lo \textit{stream}, quando cioè si ha a che fare con
+quello che viene detto un file ad \textsl{accesso casuale}.\footnote{dato che
+  in un sistema Unix esistono vari tipi di file, come le fifo ed i
+  \index{file!di~dispositivo} file di dispositivo, non è scontato che questo
+  sia sempre vero.}
+
+In GNU/Linux ed in generale in ogni sistema unix-like la posizione nel file è
+espressa da un intero positivo, rappresentato dal tipo \type{off\_t}, il
+problema è che alcune delle funzioni usate per il riposizionamento sugli
+\textit{stream} originano dalle prime versioni di Unix, in cui questo tipo non
+era ancora stato definito, e che in altri sistemi non è detto che la posizione
+su un file venga sempre rappresentata con il numero di caratteri dall'inizio
+(ad esempio in VMS può essere rappresentata come numero di record, più
+l'offset rispetto al record corrente).
+
+Tutto questo comporta la presenza di diverse funzioni che eseguono
+sostanzialmente le stesse operazioni, ma usano argomenti di tipo diverso. Le
+funzioni tradizionali usate per il riposizionamento della posizione in uno
+\textit{stream} sono \funcd{fseek} e \funcd{rewind} i cui prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int fseek(FILE *stream, long offset, int whence)} Sposta la
+  posizione nello \textit{stream} secondo quanto specificato
+  tramite \param{offset} e \param{whence}.
+
+  \funcdecl{void rewind(FILE *stream)} Riporta la posizione nello
+  \textit{stream} all'inizio del file.
+\end{functions}
+
+L'uso di \func{fseek} è del tutto analogo a quello di \func{lseek} per i file
+descriptor, e gli argomenti, a parte il tipo, hanno lo stesso significato; in
+particolare \param{whence} assume gli stessi valori già visti in
+sez.~\ref{sec:file_lseek}.  La funzione restituisce 0 in caso di successo e -1
+in caso di errore.  La funzione \func{rewind} riporta semplicemente la
+posizione corrente all'inizio dello \textit{stream}, ma non esattamente
+equivalente ad una \code{fseek(stream, 0L, SEEK\_SET)} in quanto vengono
+cancellati anche i flag di errore e fine del file.
+
+Per ottenere la posizione corrente si usa invece la funzione \funcd{ftell}, il
+cui prototipo è:
+\begin{prototype}{stdio.h}{long ftell(FILE *stream)} 
+  Legge la posizione attuale nello \textit{stream} \param{stream}.
+  
+  \bodydesc{La funzione restituisce la posizione corrente, o -1 in caso
+    di fallimento, che può esser dovuto sia al fatto che il file non
+    supporta il riposizionamento che al fatto che la posizione non può
+    essere espressa con un \ctyp{long int}}
+\end{prototype}
+\noindent la funzione restituisce la posizione come numero di byte
+dall'inizio dello \textit{stream}. 
+
+Queste funzioni esprimono tutte la posizione nel file come un \ctyp{long int}.
+Dato che (ad esempio quando si usa un filesystem indicizzato a 64 bit) questo
+può non essere possibile lo standard POSIX ha introdotto le nuove funzioni
+\funcd{fgetpos} e \funcd{fsetpos}, che invece usano il nuovo tipo
+\type{fpos\_t}, ed i cui prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{int fsetpos(FILE *stream, fpos\_t *pos)} Imposta la posizione
+  corrente nello \textit{stream} \param{stream} al valore specificato
+  da \param{pos}.
+  
+  \funcdecl{int fgetpos(FILE *stream, fpos\_t *pos)} Legge la posizione
+  corrente nello \textit{stream} \param{stream} e la scrive in \param{pos}.
+  
+  \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
+    errore.}
+\end{functions}
+
+In Linux, a partire dalle glibc 2.1, sono presenti anche le due funzioni
+\func{fseeko} e \func{ftello}, che sono assolutamente identiche alle
+precedenti \func{fseek} e \func{ftell} ma hanno argomenti di tipo
+\type{off\_t} anziché di tipo \ctyp{long int}. Dato che \ctyp{long} è nella
+gran parte dei casi un intero a 32 bit, questo diventa un problema quando la
+posizione sul file viene espressa con un valore a 64 bit come accade nei
+sistemi più moderni.
+
+% TODO: mettere prototipi espliciti fseeko e ftello o menzione?
+
+
+\section{Funzioni avanzate}
+\label{sec:file_stream_adv_func}
+
+In questa sezione esamineremo alcune funzioni avanzate che permettono di
+eseguire operazioni particolari sugli \textit{stream}, come leggerne gli
+attributi, controllarne le modalità di bufferizzazione, gestire direttamente i
+lock impliciti per la programmazione \itindex{thread} \textit{multi-thread}.
+
+
+\subsection{Le funzioni di controllo}
+\label{sec:file_stream_cntrl}
+
+Al contrario di quanto avviene con i file descriptor, le librerie standard del
+C non prevedono nessuna funzione come la \func{fcntl} per il controllo degli
+attributi dei file. Però, dato che ogni \textit{stream} si appoggia ad un file
+descriptor, si può usare la funzione \funcd{fileno} per ottenere quest'ultimo,
+il prototipo della funzione è:
+\begin{prototype}{stdio.h}{int fileno(FILE *stream)}
+  Legge il file descriptor sottostante lo \textit{stream} \param{stream}.
+  
+  \bodydesc{Restituisce il numero del file descriptor in caso di successo, e
+    -1 qualora \param{stream} non sia valido, nel qual caso imposta
+    \var{errno} a \errval{EBADF}.}
+\end{prototype}
+\noindent ed in questo modo diventa possibile usare direttamente \func{fcntl}.
+
+Questo permette di accedere agli attributi del file descriptor sottostante lo
+\textit{stream}, ma non ci dà nessuna informazione riguardo alle proprietà
+dello \textit{stream} medesimo.  Le \acr{glibc} però supportano alcune
+estensioni derivate da Solaris, che permettono di ottenere informazioni utili.
+
+Ad esempio in certi casi può essere necessario sapere se un certo
+\textit{stream} è accessibile in lettura o scrittura. In genere questa
+informazione non è disponibile, e si deve ricordare come il file è stato
+aperto. La cosa può essere complessa se le operazioni vengono effettuate in
+una subroutine, che a questo punto necessiterà di informazioni aggiuntive
+rispetto al semplice puntatore allo \textit{stream}; questo può essere evitato
+con le due funzioni \funcd{\_\_freadable} e \funcd{\_\_fwritable} i cui
+prototipi sono:
+\begin{functions}
+  \headdecl{stdio\_ext.h}
+  \funcdecl{int \_\_freadable(FILE *stream)}
+  Restituisce un valore diverso da zero se \param{stream} consente la lettura.
+
+  \funcdecl{int \_\_fwritable(FILE *stream)}  
+  Restituisce un valore diverso da zero se \param{stream} consente la
+  scrittura.
+\end{functions}
+\noindent che permettono di ottenere questa informazione.
+
+La conoscenza dell'ultima operazione effettuata su uno \textit{stream} aperto
+è utile in quanto permette di trarre conclusioni sullo stato del buffer e del
+suo contenuto. Altre due funzioni, \funcd{\_\_freading} e \funcd{\_\_fwriting}
+servono a tale scopo, il loro prototipo è:
+\begin{functions}
+  \headdecl{stdio\_ext.h}
+  \funcdecl{int \_\_freading(FILE *stream)}
+  Restituisce un valore diverso da zero se \param{stream} è aperto in sola
+  lettura o se l'ultima operazione è stata di lettura.
+
+  \funcdecl{int \_\_fwriting(FILE *stream)}  
+  Restituisce un valore diverso da zero se \param{stream} è aperto in sola
+  scrittura o se l'ultima operazione è stata di scrittura.
+\end{functions}
+
+Le due funzioni permettono di determinare di che tipo è stata l'ultima
+operazione eseguita su uno \textit{stream} aperto in lettura/scrittura;
+ovviamente se uno \textit{stream} è aperto in sola lettura (o sola scrittura)
+la modalità dell'ultima operazione è sempre determinata; l'unica ambiguità è
+quando non sono state ancora eseguite operazioni, in questo caso le funzioni
+rispondono come se una operazione ci fosse comunque stata.
+
+
+\subsection{Il controllo della bufferizzazione}
+\label{sec:file_buffering_ctrl}
+
+Come accennato in sez.~\ref{sec:file_buffering} le librerie definiscono una
+serie di funzioni che permettono di controllare il comportamento degli
+\textit{stream}; se non si è specificato nulla, la modalità di buffering viene
+decisa autonomamente sulla base del tipo di file sottostante, ed i buffer
+vengono allocati automaticamente.
+
+Però una volta che si sia aperto lo \textit{stream} (ma prima di aver compiuto
+operazioni su di esso) è possibile intervenire sulle modalità di buffering; la
+funzione che permette di controllare la bufferizzazione è \funcd{setvbuf}, il
+suo prototipo è:
+\begin{prototype}{stdio.h}{int setvbuf(FILE *stream, char *buf, int mode, 
+    size\_t size)}
+  
+  Imposta la bufferizzazione dello \textit{stream} \param{stream} nella
+  modalità indicata da \param{mode}, usando \param{buf} come buffer di
+  lunghezza
+  \param{size}.
+  
+  \bodydesc{Restituisce zero in caso di successo, ed un valore qualunque in
+    caso di errore, nel qual caso \var{errno} viene impostata opportunamente.}
+\end{prototype}
+
+La funzione permette di controllare tutti gli aspetti della bufferizzazione;
+l'utente può specificare un buffer da usare al posto di quello allocato dal
+sistema passandone alla funzione l'indirizzo in \param{buf} e la dimensione in
+\param{size}. 
+
+Ovviamente se si usa un buffer specificato dall'utente questo deve essere
+stato allocato e rimanere disponibile per tutto il tempo in cui si opera sullo
+\textit{stream}. In genere conviene allocarlo con \func{malloc} e disallocarlo
+dopo la chiusura del file; ma fintanto che il file è usato all'interno di una
+funzione, può anche essere usata una \index{variabili!automatiche} variabile
+automatica. In \headfile{stdio.h} è definita la macro \const{BUFSIZ}, che
+indica le dimensioni generiche del buffer di uno \textit{stream}; queste
+vengono usate dalla funzione \func{setbuf}.  Non è detto però che tale
+dimensione corrisponda sempre al valore ottimale (che può variare a seconda
+del dispositivo).
+
+Dato che la procedura di allocazione manuale è macchinosa, comporta dei rischi
+(come delle scritture accidentali sul buffer) e non assicura la scelta delle
+dimensioni ottimali, è sempre meglio lasciare allocare il buffer alle funzioni
+di libreria, che sono in grado di farlo in maniera ottimale e trasparente
+all'utente (in quanto la deallocazione avviene automaticamente). Inoltre
+siccome alcune implementazioni usano parte del buffer per mantenere delle
+informazioni di controllo, non è detto che le dimensioni dello stesso
+coincidano con quelle su cui viene effettuato l'I/O.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+    \begin{tabular}[c]{|l|l|}
+      \hline
+      \textbf{Valore} & \textbf{Modalità} \\
+      \hline
+      \hline
+      \const{\_IONBF} & \textit{unbuffered}\\
+      \const{\_IOLBF} & \textit{line buffered}\\
+      \const{\_IOFBF} & \textit{fully buffered}\\
+      \hline
+    \end{tabular}
+    \caption{Valori dell'argomento \param{mode} di \func{setvbuf} 
+      per l'impostazione delle modalità di bufferizzazione.}
+  \label{tab:file_stream_buf_mode}
+\end{table}
+
+Per evitare che \func{setvbuf} imposti il buffer basta passare un valore
+\val{NULL} per \param{buf} e la funzione ignorerà l'argomento \param{size}
+usando il buffer allocato automaticamente dal sistema.  Si potrà comunque
+modificare la modalità di bufferizzazione, passando in \param{mode} uno degli
+opportuni valori elencati in tab.~\ref{tab:file_stream_buf_mode}. Qualora si
+specifichi la modalità non bufferizzata i valori di \param{buf} e \param{size}
+vengono sempre ignorati.
+
+Oltre a \func{setvbuf} le \acr{glibc} definiscono altre tre funzioni per la
+gestione della bufferizzazione di uno \textit{stream}: \funcd{setbuf},
+\funcd{setbuffer} e \funcd{setlinebuf}; i loro prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h} 
+  
+  \funcdecl{void setbuf(FILE *stream, char *buf)} Disabilita la
+  bufferizzazione se \param{buf} è \val{NULL}, altrimenti usa \param{buf}
+  come buffer di dimensione \const{BUFSIZ} in modalità \textit{fully buffered}.
+  
+  \funcdecl{void setbuffer(FILE *stream, char *buf, size\_t size)} Disabilita
+  la bufferizzazione se \param{buf} è \val{NULL}, altrimenti usa \param{buf}
+  come buffer di dimensione \param{size} in modalità \textit{fully buffered}.
+  
+  \funcdecl{void setlinebuf(FILE *stream)} Pone lo \textit{stream} in modalità
+  \textit{line buffered}.
+\end{functions}
+\noindent tutte queste funzioni sono realizzate con opportune chiamate a
+\func{setvbuf} e sono definite solo per compatibilità con le vecchie librerie
+BSD. Infine le \acr{glibc} provvedono le funzioni non standard\footnote{anche
+  queste funzioni sono originarie di Solaris.} \funcd{\_\_flbf} e
+\funcd{\_\_fbufsize} che permettono di leggere le proprietà di bufferizzazione
+di uno \textit{stream}; i cui prototipi sono:
+\begin{functions}
+  \headdecl{stdio\_ext.h} 
+  
+  \funcdecl{int \_\_flbf(FILE *stream)} Restituisce un valore diverso da zero
+  se \param{stream} è in modalità \textit{line buffered}.
+  
+  \funcdecl{size\_t \_\_fbufsize(FILE *stream)} Restituisce le dimensioni del
+  buffer di \param{stream}.
+\end{functions}
+
+Come già accennato, indipendentemente dalla modalità di bufferizzazione
+scelta, si può forzare lo scarico dei dati sul file con la funzione
+\funcd{fflush}, il suo prototipo è:
+\begin{prototype}{stdio.h}{int fflush(FILE *stream)}
+  
+  Forza la scrittura di tutti i dati bufferizzati dello
+  \textit{stream} \param{stream}.
+  
+  \bodydesc{Restituisce zero in caso di successo, ed \val{EOF} in caso di
+    errore, impostando \var{errno} a \errval{EBADF} se \param{stream} non è
+    aperto o non è aperto in scrittura, o ad uno degli errori di
+    \func{write}.}
+\end{prototype}
+\noindent anche di questa funzione esiste una analoga
+\func{fflush\_unlocked}\footnote{accessibile definendo \macro{\_BSD\_SOURCE} o
+  \macro{\_SVID\_SOURCE} o \macro{\_GNU\_SOURCE}.} che non effettua il blocco
+dello stream.
+
+% TODO aggiungere prototipo \func{fflush\_unlocked}?
+
+Se \param{stream} è \val{NULL} lo scarico dei dati è forzato per tutti gli
+\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 questo motivo le \acr{glibc} supportano una estensione di
+Solaris, la funzione \funcd{\_flushlbf}, il cui prototipo è:
+\begin{prototype}{stdio-ext.h}{void \_flushlbf(void)}
+  Forza la scrittura di tutti i dati bufferizzati degli \textit{stream} in
+  modalità line buffered.
+\end{prototype}
+
+Si ricordi comunque che lo scarico dei dati dai buffer effettuato da queste
+funzioni non comporta la scrittura di questi su disco; se si vuole che il
+kernel dia effettivamente avvio alle operazioni di scrittura su disco occorre
+usare \func{sync} o \func{fsync} (si veda~sez.~\ref{sec:file_sync}).
+
+Infine esistono anche circostanze in cui si vuole scartare tutto l'output
+pendente; per questo si può usare \funcd{fpurge}, il cui prototipo è:
+\begin{prototype}{stdio.h}{int fpurge(FILE *stream)}
+  Cancella i buffer di input e di output dello \textit{stream} \param{stream}.
+  
+  \bodydesc{Restituisce zero in caso di successo, ed \val{EOF} in caso di
+    errore.}
+\end{prototype}
+
+La funzione scarta tutti i dati non ancora scritti (se il file è aperto in
+scrittura), e tutto l'input non ancora letto (se è aperto in lettura),
+compresi gli eventuali caratteri rimandati indietro con \func{ungetc}.
+
+
+\subsection{Gli \textit{stream} e i \textit{thread}}
+\label{sec:file_stream_thread}
+
+\itindbeg{thread}
+
+Gli \textit{stream} possono essere usati in applicazioni \textit{multi-thread}
+allo stesso modo in cui sono usati nelle applicazioni normali, ma si deve
+essere consapevoli delle possibili complicazioni anche quando non si usano i
+\textit{thread}, dato che l'implementazione delle librerie è influenzata
+pesantemente dalle richieste necessarie per garantirne l'uso con i
+\textit{thread}.
+
+Lo standard POSIX richiede che le operazioni sui file siano atomiche rispetto
+ai \textit{thread}, per questo le operazioni sui buffer effettuate dalle
+funzioni di libreria durante la lettura e la scrittura di uno \textit{stream}
+devono essere opportunamente protette (in quanto il sistema assicura
+l'atomicità solo per le system call). Questo viene fatto associando ad ogni
+\textit{stream} un opportuno blocco che deve essere implicitamente acquisito
+prima dell'esecuzione di qualunque operazione.
+
+Ci sono comunque situazioni in cui questo non basta, come quando un
+\textit{thread} necessita di compiere più di una operazione sullo
+\textit{stream} atomicamente, per questo motivo le librerie provvedono anche
+delle funzioni \funcd{flockfile}, \funcd{ftrylockfile} e \funcd{funlockfile},
+che permettono la gestione esplicita dei blocchi sugli \textit{stream}; esse
+sono disponibili definendo \macro{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro
+prototipi sono:
+\begin{functions}
+  \headdecl{stdio.h}
+  
+  \funcdecl{void flockfile(FILE *stream)} Esegue l'acquisizione del lock dello
+  \textit{stream} \param{stream}, bloccandosi se il lock non è disponibile.
+  
+  \funcdecl{int ftrylockfile(FILE *stream)} Tenta l'acquisizione del lock
+  dello \textit{stream} \param{stream}, senza bloccarsi se il lock non è
+  disponibile.  Ritorna zero in caso di acquisizione del lock, diverso da zero
+  altrimenti.
+  
+  \funcdecl{void funlockfile(FILE *stream)} Rilascia il lock dello
+  \textit{stream} \param{stream}.
+\end{functions}
+\noindent con queste funzioni diventa possibile acquisire un blocco ed
+eseguire tutte le operazioni volute, per poi rilasciarlo. 
+
+Ma, vista la complessità delle strutture di dati coinvolte, le operazioni di
+blocco non sono del tutto indolori, e quando il locking dello \textit{stream}
+non è necessario (come in tutti i programmi che non usano i \textit{thread}),
+tutta la procedura può comportare dei costi pesanti in termini di
+prestazioni. Per questo motivo abbiamo visto come alle usuali funzioni di I/O
+non formattato siano associate delle versioni \code{\_unlocked} (alcune
+previste dallo stesso standard POSIX, altre aggiunte come estensioni dalle
+\acr{glibc}) che possono essere usate quando il locking non serve\footnote{in
+  certi casi dette funzioni possono essere usate, visto che sono molto più
+  efficienti, anche in caso di necessità di locking, una volta che questo sia
+  stato acquisito manualmente.}  con prestazioni molto più elevate, dato che
+spesso queste versioni (come accade per \func{getc} e \func{putc}) sono
+realizzate come macro.
+
+La sostituzione di tutte le funzioni di I/O con le relative versioni
+\code{\_unlocked} in un programma che non usa i \textit{thread} è però un
+lavoro abbastanza noioso; per questo motivo le \acr{glibc} forniscono al
+programmatore pigro un'altra via\footnote{anche questa mutuata da estensioni
+  introdotte in Solaris.} da poter utilizzare per disabilitare in blocco il
+locking degli \textit{stream}: l'uso della funzione \funcd{\_\_fsetlocking},
+il cui prototipo è:
+\begin{prototype}{stdio\_ext.h}{int \_\_fsetlocking (FILE *stream, int type)}
+  Specifica o richiede a seconda del valore di \param{type} la modalità in cui
+  le operazioni di I/O su \param{stream} vengono effettuate rispetto
+  all'acquisizione implicita del blocco sullo \textit{stream}.
+
+  \bodydesc{Restituisce lo stato di locking interno dello \textit{stream} con
+    uno dei valori \const{FSETLOCKING\_INTERNAL} o
+    \const{FSETLOCKING\_BYCALLER}.}
+\end{prototype}
+
+La funzione imposta o legge lo stato della modalità di operazione di uno
+\textit{stream} nei confronti del locking a seconda del valore specificato
+con \param{type}, che può essere uno dei seguenti:
+\begin{basedescript}{\desclabelwidth{4.0cm}}
+\item[\const{FSETLOCKING\_INTERNAL}] Lo \textit{stream} userà da ora in poi il
+  blocco implicito predefinito.
+\item[\const{FSETLOCKING\_BYCALLER}] Al ritorno della funzione sarà l'utente a
+  dover gestire da solo il locking dello \textit{stream}.
+\item[\const{FSETLOCKING\_QUERY}] Restituisce lo stato corrente della modalità
+  di blocco dello \textit{stream}.
+\end{basedescript}
+
+% TODO trattare \func{clearerr\_unlocked} 
+
+
+\itindend{thread}
+
+
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: 
+
+% LocalWords:  stream cap system call kernel Ritchie glibc descriptor Stevens
+% LocalWords:  buf read write filesystem st blksize stat sez l'header stdio BSD
+% LocalWords:  nell'header stdin shell stdout stderr error freopen flush line
+% LocalWords:  unbuffered buffered newline fully SVr fopen fdopen POSIX const
+% LocalWords:  char path int fildes NULL errno malloc fcntl fclose fflush tab
+% LocalWords:  dup fifo socket append EXCL ccs STRING IRUSR IWUSR IRGRP IWGRP
+% LocalWords:  IROTH IWOTH umask fseek fsetpos rewind SEEK CUR EOF EBADF close
+% LocalWords:  sync fcloseall SOURCE void stdlib of feof ferror clearerr l'I ws
+% LocalWords:  unlocked fread fwrite size ptr nmemb nelem gcc padding point str
+% LocalWords:  lock thread fgetc getc getchar dell'overhead altresì unsigned ap
+% LocalWords:  getwc fgetwc getwchar wint wchar WEOF putc fputc putchar dell'I
+% LocalWords:  SVID getw putw parsing peeking ahead ungetc gets fgets string Di
+% LocalWords:  overflow Aleph stack fputs puts fgetws fputws getline ssize leak
+% LocalWords:  realloc value result argument memory getdelim delim printf short
+% LocalWords:  fprintf sprintf format snprintf variadic long double intmax list
+% LocalWords:  uintmax ptrdiff vprintf vfprintf vsprintf vsnprintf asprintf lex
+% LocalWords:  vasprintf strptr dprintf vdprintf print scanf fscanf sscanf flex
+% LocalWords:  vscanf vfscanf vsscanf bison parser yacc like off VMS whence pos
+% LocalWords:  lseek ftell fgetpos fpos fseeko ftello fileno Solaris freadable
+% LocalWords:  fwritable ext freading fwriting buffering setvbuf BUFSIZ setbuf
+% LocalWords:  IONBF IOLBF IOFBF setbuffer setlinebuf flbf fbufsize flushlbf hh
+% LocalWords:  fsync fpurge flockfile ftrylockfile funlockfile SAFE FUNCTIONS
+% LocalWords:  locking fsetlocking type BYCALLER QUERY ll
+
+
+
+% LocalWords:  descriptor system call cap like kernel sez l'inode inode VFS tab
+% LocalWords:  process table struct files flags pos all'inode dentry fig shell
+% LocalWords:  error POSIX STDIN FILENO STDOUT STDERR unistd read write lseek
+% LocalWords:  close pathname sys fcntl int const char errno EEXIST CREAT EXCL
+% LocalWords:  EISDIR ENOTDIR ENXIO NOBLOCK WRONLY fifo ENODEV ETXTBSY ELOOP of
+% LocalWords:  NOFOLLOW EACCES ENAMETOOLONG ENOENT EROFS EFAULT ENOSPC ENOMEM
+% LocalWords:  EMFILE ENFILE NFS lock race condition Denial Service DoS RDONLY
+% LocalWords:  glibc RDWR NONBLOCK NOCTTY SHLOCK shared BSD EXLOCK TRUNC device
+% LocalWords:  opendir LARGEFILE APPEND append NDELAY ASYNC l'I SIGIO SYNC SVr
+% LocalWords:  DSYNC RSYNC filesystem DIRECT caching SGI IRIX dell'I FreeBSD fd
+% LocalWords:  fork exec umask SOURCE creat filedes EBADF EINTR EIO locking off
+% LocalWords:  behind sync flush shutdown whence ESPIPE socket EINVAL INCR XTND
+% LocalWords:  SEEK CUR EPIPE ssize void buf size count EAGAIN EWOULDBLOCK log
+% LocalWords:  Specification pwrite pread EFBIG SIGPIPE nell'inode dall'inode
+% LocalWords:  CLOEXEC stat fsync cache update l'update bdflush Documentation
+% LocalWords:  fdatasync fstat ext dup oldfd newfd DUPFD cmd long arg flock pid
+% LocalWords:  SETFD GETFD GETFL SETFL GETLK SETLK SETLKW GETOWN group SIGURG
+% LocalWords:  SETOWN GETSIG SETSIG sigaction SIGINFO siginfo SETLEASE lease is
+% LocalWords:  truncate GETLEASE NOTIFY AND ACCMODE ioctl everything argp all'I
+% LocalWords:  framebuffer request ENOTTY CDROM nell'header magic number openat
+% LocalWords:  FIOCLEX FIONCLEX FIOASYNC FIONBIO NOATIME redirezione FIOSETOWN
+% LocalWords:  FIOGETOWN FIONREAD mkdirat thread Solaris mkdir at Urlich proc
+% LocalWords:  Drepper path dirfd faccessat unlinkat access fchmodat chmod Di
+% LocalWords:  fchownat chown fstatat futimesat utimes linkat mknodat mknod uid
+% LocalWords:  readlinkat readlink renameat rename symlinkat symlink unlink gid
+% LocalWords:  mkfifoat mkfifo FDCWD dereferenziazione rmdir REMOVEDIR
+% LocalWords:  epoll lsattr chattr FIOQSIZE ATFILE lutimes utimensat lchown
+% LocalWords:  lstat owner FOLLOW
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: 
index a7a25a9ccf225d4184b3cb4968bc91f51ade7f83..d8c6ee6b455bec3cf1e1ae84fbd26b72b0730bd4 100644 (file)
--- a/gapil.tex
+++ b/gapil.tex
@@ -169,8 +169,9 @@ hyperfootnotes=false]{hyperref}
 \include{process}
 \include{prochand}
 \include{filedir}
 \include{process}
 \include{prochand}
 \include{filedir}
-\include{fileunix}
-\include{filestd}
+\include{fileio}
+%\include{fileunix}
+%\include{filestd}
 \include{system}
 \include{signal}
 \include{session}
 \include{system}
 \include{signal}
 \include{session}
index d4a21ca23f402b9e8eed897171b58dcb3ad6cf73..ff72ab44a879b1cb76ab5e929cf61aef06e6b126 100644 (file)
Binary files a/img/procfile.dia and b/img/procfile.dia differ
index d01793984e25c0433139bef367693ddbf156683f..b5f1986792a67f687077f8d9c71b51208a32cb92 100644 (file)
--- a/intro.tex
+++ b/intro.tex
@@ -738,7 +738,7 @@ dispositivi. L'accesso viene gestito attraverso i \textit{file descriptor} che
 sono rappresentati da numeri interi (cioè semplici variabili di tipo
 \ctyp{int}).  L'interfaccia è definita nell'\textit{header file}
 \headfile{unistd.h} e la tratteremo in dettaglio in
 sono rappresentati da numeri interi (cioè semplici variabili di tipo
 \ctyp{int}).  L'interfaccia è definita nell'\textit{header file}
 \headfile{unistd.h} e la tratteremo in dettaglio in
-cap.~\ref{cha:file_unix_interface}.
+sez.~\ref{sec:file_unix_interface}.
 
 \itindbeg{file~stream}
 
 
 \itindbeg{file~stream}
 
@@ -756,7 +756,7 @@ Unix. Gli \textit{stream} sono oggetti complessi e sono rappresentati da
 puntatori ad un opportuna struttura definita dalle librerie del C, ad essi si
 accede sempre in maniera indiretta utilizzando il tipo \code{FILE *}.
 L'interfaccia è definita nell'\textit{header file} \headfile{stdio.h} e la
 puntatori ad un opportuna struttura definita dalle librerie del C, ad essi si
 accede sempre in maniera indiretta utilizzando il tipo \code{FILE *}.
 L'interfaccia è definita nell'\textit{header file} \headfile{stdio.h} e la
-tratteremo in dettaglio nel cap.~\ref{cha:files_std_interface}.
+tratteremo in dettaglio in sez.~\ref{sec:files_std_interface}.
 
 Entrambe le interfacce possono essere usate per l'accesso ai file come agli
 altri oggetti del VFS, ma per poter accedere alle operazioni di controllo
 
 Entrambe le interfacce possono essere usate per l'accesso ai file come agli
 altri oggetti del VFS, ma per poter accedere alle operazioni di controllo
diff --git a/ipc.tex b/ipc.tex
index 44b1ca2da855f829f417b91882b1cf5fb49cd4d5..3d567b5879b2c033be8b2527332e2006fc9889eb 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -184,7 +184,7 @@ Il programma ci servirà anche come esempio dell'uso delle funzioni di
 duplicazione dei file descriptor che abbiamo trattato in
 sez.~\ref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
 funzioni infatti che è possibile dirottare gli stream standard dei processi
 duplicazione dei file descriptor che abbiamo trattato in
 sez.~\ref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
 funzioni infatti che è possibile dirottare gli stream standard dei processi
-(che abbiamo visto in sez.~\ref{sec:file_std_descr} e
+(che abbiamo visto in tab.~\ref{tab:file_std_files} e
 sez.~\ref{sec:file_std_stream}) sulla pipe. In
 fig.~\ref{fig:ipc_barcodepage_code} abbiamo riportato il corpo del programma,
 il cui codice completo è disponibile nel file \file{BarCodePage.c} che si
 sez.~\ref{sec:file_std_stream}) sulla pipe. In
 fig.~\ref{fig:ipc_barcodepage_code} abbiamo riportato il corpo del programma,
 il cui codice completo è disponibile nel file \file{BarCodePage.c} che si
@@ -302,9 +302,9 @@ che sarà aperto in sola lettura (e quindi associato allo standard output del
 programma indicato) in caso si sia indicato \code{"r"}, o in sola scrittura (e
 quindi associato allo standard input) in caso di \code{"w"}.
 
 programma indicato) in caso si sia indicato \code{"r"}, o in sola scrittura (e
 quindi associato allo standard input) in caso di \code{"w"}.
 
-Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
-stream visti in cap.~\ref{cha:files_std_interface}, anche se è collegato ad
-una pipe e non ad un file, e viene sempre aperto in modalità
+Lo \textit{stream} restituito da \func{popen} è identico a tutti gli effetti
+ai \textit{file stream} visti in sez.~\ref{sec:files_std_interface}, anche se
+è collegato ad una pipe e non ad un file, e viene sempre aperto in modalità
 \textit{fully-buffered} (vedi sez.~\ref{sec:file_buffering}); l'unica
 differenza con gli usuali stream è che dovrà essere chiuso dalla seconda delle
 due nuove funzioni, \funcd{pclose}, il cui prototipo è:
 \textit{fully-buffered} (vedi sez.~\ref{sec:file_buffering}); l'unica
 differenza con gli usuali stream è che dovrà essere chiuso dalla seconda delle
 due nuove funzioni, \funcd{pclose}, il cui prototipo è:
@@ -3419,7 +3419,7 @@ diversi.
 La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
 possono essere specificati per \param{oflag}, che deve essere specificato come
 maschera binaria; i valori possibili per i vari bit sono quelli visti in
 La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
 possono essere specificati per \param{oflag}, che deve essere specificato come
 maschera binaria; i valori possibili per i vari bit sono quelli visti in
-tab.~\ref{tab:file_open_flags} dei quali però \func{mq\_open} riconosce solo i
+sez.~\ref{sec:file_open} dei quali però \func{mq\_open} riconosce solo i
 seguenti:
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{O\_RDONLY}] Apre la coda solo per la ricezione di messaggi. Il
 seguenti:
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{O\_RDONLY}] Apre la coda solo per la ricezione di messaggi. Il
@@ -3849,7 +3849,7 @@ La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
 possono essere specificati per \param{oflag}, che deve essere specificato come
 maschera binaria comprendente almeno uno dei due valori \const{O\_RDONLY} e
 \const{O\_RDWR}; i valori possibili per i vari bit sono quelli visti in
 possono essere specificati per \param{oflag}, che deve essere specificato come
 maschera binaria comprendente almeno uno dei due valori \const{O\_RDONLY} e
 \const{O\_RDWR}; i valori possibili per i vari bit sono quelli visti in
-tab.~\ref{tab:file_open_flags} dei quali però \func{shm\_open} riconosce solo
+sez.~\ref{sec:file_open} dei quali però \func{shm\_open} riconosce solo
 i seguenti:
 \begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{O\_RDONLY}] Apre il file descriptor associato al segmento di
 i seguenti:
 \begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{O\_RDONLY}] Apre il file descriptor associato al segmento di
index 4d83ba034f8c3bedc865cfe20a560ca25b06e195..e99d198b5d722e9cbaab8cc67b03dfd9ca49ef55 100644 (file)
@@ -448,10 +448,10 @@ registrate con \func{atexit} e \func{on\_exit} non vengono eseguite. La
 funzione chiude tutti i file descriptor appartenenti al processo, cosa che
 però non comporta il salvataggio dei dati eventualmente presenti nei buffer
 degli \textit{stream}, (torneremo sulle due interfacce dei file in
 funzione chiude tutti i file descriptor appartenenti al processo, cosa che
 però non comporta il salvataggio dei dati eventualmente presenti nei buffer
 degli \textit{stream}, (torneremo sulle due interfacce dei file in
-cap.~\ref{cha:files_std_interface} e
-cap.~\ref{cha:file_unix_interface})). Infine fa sì che ogni figlio del
-processo sia adottato da \cmd{init} (vedi sez.~\ref{sec:proc_termination}),
-manda un segnale \signal{SIGCHLD} al processo padre (vedi
+sez.~\ref{sec:file_unix_interface} e
+sez.~\ref{sec:files_std_interface}). Infine fa sì che ogni figlio del processo
+sia adottato da \cmd{init} (vedi sez.~\ref{sec:proc_termination}), manda un
+segnale \signal{SIGCHLD} al processo padre (vedi
 sez.~\ref{sec:sig_job_control}) e ritorna lo stato di uscita specificato
 in \param{status} che può essere raccolto usando la funzione \func{wait} (vedi
 sez.~\ref{sec:proc_wait}).
 sez.~\ref{sec:sig_job_control}) e ritorna lo stato di uscita specificato
 in \param{status} che può essere raccolto usando la funzione \func{wait} (vedi
 sez.~\ref{sec:proc_wait}).
index ad9f0b013f037c0834e8e9708b303b89015249d1..182ad5f29263bbc507b3a6c5aa88855cb8a22245 100644 (file)
@@ -490,7 +490,7 @@ codice.
 Un secondo aspetto molto importante nella creazione dei processi figli è
 quello dell'interazione dei vari processi con i file. Ne parleremo qui anche
 se buona parte dei concetti relativi ai file verranno trattati più avanti
 Un secondo aspetto molto importante nella creazione dei processi figli è
 quello dell'interazione dei vari processi con i file. Ne parleremo qui anche
 se buona parte dei concetti relativi ai file verranno trattati più avanti
-(principalmente nel cap.~\ref{cha:file_unix_interface}). Per illustrare meglio
+(principalmente in sez.~\ref{sec:file_unix_interface}). Per illustrare meglio
 quello che avviene si può redirigere su un file l'output del programma di
 test, quello che otterremo è:
 \begin{Command}
 quello che avviene si può redirigere su un file l'output del programma di
 test, quello che otterremo è:
 \begin{Command}
@@ -524,8 +524,8 @@ Go to next child
 che come si vede è completamente diverso da quanto ottenevamo sul terminale.
 
 Il comportamento delle varie funzioni di interfaccia con i file è analizzato
 che come si vede è completamente diverso da quanto ottenevamo sul terminale.
 
 Il comportamento delle varie funzioni di interfaccia con i file è analizzato
-in gran dettaglio in cap.~\ref{cha:file_unix_interface} per l'interfaccia
-nativa Unix ed in cap.~\ref{cha:files_std_interface} per la standardizzazione
+in gran dettaglio in sez.~\ref{sec:file_unix_interface} per l'interfaccia
+nativa Unix ed in sez.~\ref{sec:files_std_interface} per la standardizzazione
 adottata nelle librerie del linguaggio C e valida per qualunque sistema
 operativo. Qui basta accennare che si sono usate le funzioni standard della
 libreria del C che prevedono l'output bufferizzato. Il punto è che questa
 adottata nelle librerie del linguaggio C e valida per qualunque sistema
 operativo. Qui basta accennare che si sono usate le funzioni standard della
 libreria del C che prevedono l'output bufferizzato. Il punto è che questa
@@ -556,7 +556,7 @@ padre e tutti i processi figli.
 
 Quello che succede è che quando lo \textit{standard output}\footnote{si chiama
   così il file su cui un programma scrive i suoi dati in uscita, tratteremo
 
 Quello che succede è che quando lo \textit{standard output}\footnote{si chiama
   così il file su cui un programma scrive i suoi dati in uscita, tratteremo
-  l'argomento in dettaglio in sez.~\ref{sec:file_std_descr}.} del padre viene
+  l'argomento in dettaglio in sez.~\ref{sec:file_fd}.} del padre viene
 rediretto come si è fatto nell'esempio, lo stesso avviene anche per tutti i
 figli. La funzione \func{fork} infatti ha la caratteristica di duplicare nei
 processi figli tutti i \textit{file descriptor} (vedi sez.~\ref{sec:file_fd})
 rediretto come si è fatto nell'esempio, lo stesso avviene anche per tutti i
 figli. La funzione \func{fork} infatti ha la caratteristica di duplicare nei
 processi figli tutti i \textit{file descriptor} (vedi sez.~\ref{sec:file_fd})
index a4dad38f30623bb9a69677cd711474c9080376b3..12e2beb75609fbb9efef29d26349c946f8215545 100644 (file)
@@ -507,7 +507,7 @@ connessione di rete. Dato che i concetti base sono gli stessi, e dato che alla
 fine le differenze sono\footnote{in generale nel caso di login via rete o di
   terminali lanciati dall'interfaccia grafica cambia anche il processo da cui
   ha origine l'esecuzione della shell.} nel dispositivo cui il kernel associa
 fine le differenze sono\footnote{in generale nel caso di login via rete o di
   terminali lanciati dall'interfaccia grafica cambia anche il processo da cui
   ha origine l'esecuzione della shell.} nel dispositivo cui il kernel associa
-i file standard (vedi sez.~\ref{sec:file_std_descr}) per l'I/O, tratteremo
+i file standard (vedi tab.~\ref{tab:file_std_files}) per l'I/O, tratteremo
 solo il caso classico del terminale.
 
 Abbiamo già brevemente illustrato in sez.~\ref{sec:intro_kern_and_sys} le
 solo il caso classico del terminale.
 
 Abbiamo già brevemente illustrato in sez.~\ref{sec:intro_kern_and_sys} le
@@ -608,10 +608,10 @@ funzioni con i privilegi di amministratore, tutti gli \ids{UID} ed i \ids{GID}
 A questo punto \cmd{login} provvederà (fatte salve eventuali altre azioni
 iniziali, come la stampa di messaggi di benvenuto o il controllo della posta)
 ad eseguire con un'altra \func{exec} la shell, che si troverà con un ambiente
 A questo punto \cmd{login} provvederà (fatte salve eventuali altre azioni
 iniziali, come la stampa di messaggi di benvenuto o il controllo della posta)
 ad eseguire con un'altra \func{exec} la shell, che si troverà con un ambiente
-già pronto con i file standard di sez.~\ref{sec:file_std_descr} impostati sul
+già pronto con i file standard di tab.~\ref{tab:file_std_files} impostati sul
 terminale, e pronta, nel ruolo di leader di sessione e di processo di
 controllo per il terminale, a gestire l'esecuzione dei comandi come illustrato
 terminale, e pronta, nel ruolo di leader di sessione e di processo di
 controllo per il terminale, a gestire l'esecuzione dei comandi come illustrato
-in sez.~\ref{sec:sess_job_control_overview}. 
+in sez.~\ref{sec:sess_job_control_overview}.
 
 Dato che il processo padre resta sempre \cmd{init} quest'ultimo potrà
 provvedere, ricevendo un \signal{SIGCHLD} all'uscita della shell quando la
 
 Dato che il processo padre resta sempre \cmd{init} quest'ultimo potrà
 provvedere, ricevendo un \signal{SIGCHLD} all'uscita della shell quando la
index eaf88dd274b755e92c0e3e0c3a95bf977ca4731a..98590624cfab2c7afdc562447d22c8b8525c49eb 100644 (file)
@@ -2325,8 +2325,7 @@ buffer, specificata dall'argomento
 altrimenti la stringa viene troncata.
 
 Una seconda funzione usata per riportare i codici di errore in maniera
 altrimenti la stringa viene troncata.
 
 Una seconda funzione usata per riportare i codici di errore in maniera
-automatizzata sullo standard error (vedi sez.~\ref{sec:file_std_descr}) è
-\funcd{perror}, il cui prototipo è:
+automatizzata sullo standard error è \funcd{perror}, il cui prototipo è:
 \begin{prototype}{stdio.h}{void perror(const char *message)} 
   Stampa il messaggio di errore relativo al valore corrente di \var{errno}
   sullo standard error; preceduto dalla stringa \param{message}.
 \begin{prototype}{stdio.h}{void perror(const char *message)} 
   Stampa il messaggio di errore relativo al valore corrente di \var{errno}
   sullo standard error; preceduto dalla stringa \param{message}.