\footnotetext[2]{la pagina di manuale di \func{open} segnala che questa
opzione è difettosa su NFS, e che i programmi che la usano per stabilire un
- file di lock possono incorrere in una race condition\index{race condition}.
- Si consiglia come alternativa di usare un file con un nome univoco e la
- funzione \func{link} per verificarne l'esistenza.}
+ file di lock (vedi \secref{sec:ipc_file_lock}) possono incorrere in una race
+ condition\index{race condition}. Si consiglia come alternativa di usare un
+ file con un nome univoco e la funzione \func{link} per verificarne
+ l'esistenza.}
\footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti
ad impedire un servizio causando una qualche forma di carico eccessivo per
input e si apre subito dopo un nuovo file questo diventerà il nuovo standard
input (avrà cioè il file descriptor 0).
-Il nuovo file descriptor non è condiviso con nessun altro processo, (torneremo
+Il nuovo file descriptor non è condiviso con nessun altro processo (torneremo
sulla condivisione dei file, in genere accessibile dopo una \func{fork}, in
\secref{sec:file_sharing}). Il nuovo file descriptor è impostato per restare
aperto attraverso una \func{exec} (come accennato in \secref{sec:proc_exec}) e
con un OR aritmetico per costruire il valore (in forma di maschera binaria)
dell'argomento \param{flags} da passare alla \func{open} per specificarne il
comportamento. I due flag \macro{O\_NOFOLLOW} e \macro{O\_DIRECTORY} sono
-estensioni specifiche di Linux, e deve essere usata definita la macro
+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{creat}, il cui prototipo è:
\begin{prototype}{fcntl.h}
{int creat(const char *pathname, mode\_t mode)}
- Crea un nuovo file vuoto, con i permessi specificati da \var{mode}. É del
+ Crea un nuovo file vuoto, con i permessi specificati da \var{mode}. È del
tutto equivalente a \code{open(filedes, O\_CREAT|O\_WRONLY|O\_TRUNC, mode)}.
\end{prototype}
\noindent adesso questa funzione resta solo per compatibilità con i vecchi
automaticamente spostata in avanti del numero di byte letti o scritti.
In genere (a meno di non avere richiesto la modalità \macro{O\_APPEND}) questa
-posizione viene impostata a zero all'apertura del file. È possibile impostarla ad
-un valore qualsiasi con la funzione \func{lseek}, il cui prototipo è:
+posizione viene impostata a zero all'apertura del file. È possibile impostarla
+ad un valore qualsiasi con la funzione \func{lseek}, il cui prototipo è:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{unistd.h}
questi valori possono essere rimpiazzati rispettivamente con 0, 1 e 2 o con
\macro{L\_SET}, \macro{L\_INCR} e \macro{L\_XTND}.}:
\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\macro{SEEK\_SET}] si fa riferimento all'inizio del file: il valore di
- \var{offset} è la nuova posizione.
+\item[\macro{SEEK\_SET}] si fa riferimento all'inizio del file: il valore
+ (sempre positivo) di \param{offset} indica direttamente la nuova posizione
+ corrente.
\item[\macro{SEEK\_CUR}] si fa riferimento alla posizione corrente del file:
- \var{offset} può essere negativo e positivo.
-\item[\macro{SEEK\_END}] si fa riferimento alla fine del file: il valore di
- \var{offset} può essere negativo e positivo.
+ ad essa viene sommato \param{offset} (che può essere negativo e positivo)
+ per ottenere la nuova posizione corrente.
+\item[\macro{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}
Come accennato in \secref{sec:file_file_size} con \func{lseek} è possibile
-impostare la posizione corrente anche al di la della fine del file, e alla
+impostare la posizione corrente anche oltre la fine del file, e alla
successiva scrittura il file sarà esteso. La chiamata non causa nessuna
attività di input/output, si limita a modificare la posizione corrente nel
kernel (cioè \var{f\_pos} in \var{file}, vedi \figref{fig:file_proc_file}).
funzione con \code{lseek(fd, 0, SEEK\_CUR)}.
Si tenga presente inoltre che usare \macro{SEEK\_END} non assicura affatto che
-successiva scrittura avvenga alla fine del file, infatti se questo è stato
+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
-\textit{race condition}\index{race condition}, vedi \secref{sec:file_atomic}).
+essersi spostata, ma noi scriveremo alla posizione impostata in precedenza
+(questa è una potenziale sorgente di \textit{race condition}\index{race
+ condition}, vedi \secref{sec:file_atomic}).
Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per
i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che non
-supportano questa funzione, come ad esempio per le \acr{tty}.\footnote{altri
- sistemi, usando \macro{SEEK\_SET}, in questo caso ritornano il numero di
- caratteri che vi sono stati scritti.} Lo standard POSIX però non specifica
-niente al proposito. Infine alcuni device, ad esempio \file{/dev/null}, non
-causano un errore ma restituiscono un valore indefinito.
+supportano questa funzione, come ad esempio per i file di
+terminale.\footnote{altri sistemi, usando \macro{SEEK\_SET}, in questo caso
+ ritornano il numero di caratteri che vi sono stati scritti.} Lo standard
+POSIX però non specifica niente in proposito. Infine alcuni file speciali, ad
+esempio \file{/dev/null}, non causano un errore ma restituiscono un valore
+indefinito.
\subsection{La funzione \func{read}}
\label{sec:file_read}
-Una volta che un file è stato aperto su possono leggere i dati che contiene
-utilizzando la funzione \func{read}, il cui prototipo è:
+Una volta che un file è stato aperto (con il permesso in lettura) su possono
+leggere i dati che contiene utilizzando la funzione \func{read}, il cui
+prototipo è:
\begin{prototype}{unistd.h}{ssize\_t read(int fd, void * buf, size\_t count)}
Cerca di leggere \var{count} byte dal file \var{fd} al buffer \var{buf}.
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
+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
In realtà anche le due condizioni segnalate dagli errori \macro{EINTR} e
\macro{EAGAIN} non sono 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 prendere è quella di rieseguire la funzione. Torneremo in
-dettaglio sull'argomento in \secref{sec:sig_gen_beha}.
+tal caso l'azione da intraprendere è quella di rieseguire la funzione.
+Torneremo in dettaglio sull'argomento in \secref{sec:sig_gen_beha}.
La seconda si verifica quando il file è in modalità non bloccante (vedi
\secref{sec:file_noblocking}) e non ci sono dati in ingresso: la funzione
allora ritorna immediatamente con un errore \macro{EAGAIN}\footnote{sotto BSD
- questo per questo errore viene usata la costante \macro{EWOULDBLOCK}, in
- Linux, con le glibc, questa è sinonima di \macro{EAGAIN}.} che nel caso
-indica soltanto che occorrerà provare a ripetere la lettura.
+ per questo errore viene usata la costante \macro{EWOULDBLOCK}, in Linux, con
+ le glibc, questa è sinonima di \macro{EAGAIN}.} che indica soltanto che
+occorrerà provare a ripetere la lettura.
La funzione \func{read} è una delle system call fondamentali, esistenti fin
dagli albori di Unix, ma nella seconda versione delle \textit{Single Unix
\end{verbatim}
Questa funzione serve quando si vogliono leggere dati dal file senza
-modificarne la posizione corrente. È equivalente alla esecuzione di una
+modificare la posizione corrente. È 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
\subsection{La funzione \func{write}}
\label{sec:file_write}
-Una volta che un file è stato aperto su può scrivere su di esso utilizzando la
-funzione \func{write}, il cui prototipo è:
+Una volta che un file è stato aperto (con il permesso in scrittura) su può
+scrivere su di esso utilizzando la funzione \func{write}, il cui prototipo è:
\begin{prototype}{unistd.h}{ssize\_t write(int fd, void * buf, size\_t count)}
Scrive \var{count} byte dal buffer \var{buf} sul file \var{fd}.
\label{sec:file_sharing}
In \secref{sec:file_fd} abbiamo descritto brevemente l'architettura
-dell'interfaccia coi file da parte di un processo, mostrando in
+dell'interfaccia con i file da parte di un processo, mostrando in
\figref{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.
posizione corrente sul file. Questo ha le conseguenze descritte a suo tempo in
\secref{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 è la stesso per entrambi).
+\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
-\subsection{Operazioni atomiche coi file}
+\subsection{Operazioni atomiche con i file}
\label{sec:file_atomic}
-Come si è visto in un sistema unix è sempre possibile per più processi
+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.
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 \secref{sec:file_lseek} impostare la posizione alla fine
-del file e poi scrivere può condurre ad una
-\textit{race condition}\index{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.
+log). Come accennato in \secref{sec:file_lseek} impostare la posizione alla
+fine del file e poi scrivere può condurre ad una \textit{race
+ condition}\index{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à
possibilità di una race condition\index{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 pe \func{open} i due flag
+Per questo motivo sono stati introdotti per \func{open} i due flag
\macro{O\_CREAT} e \macro{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
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 da la garanzia assoluta che i dati siano integri dopo la chiamata,
- l'hardware dei dischi è in genere dotato di un suo meccanismo interno che
- può ritardare ulteriormente la scrittura effettiva.} La prima di queste
-funzioni è \func{sync} il cui prototipo è:
+ 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 è \func{sync} il cui
+prototipo è:
\begin{prototype}{unistd.h}{int sync(void)}
Sincronizza il buffer della cache dei file col disco.
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 per l'update dei dati è ogni 30 secondi, ma in Linux era
-di 5 secondi; con le nuove versioni poi, è il kernel che si occupa
-direttamente di tutto quanto.
+valore tradizionale, usato da BSD, per l'update dei dati è ogni 30 secondi, ma
+in Linux ilvalore utilizzato è di 5 secondi; con le nuove versioni poi, è il
+kernel che si occupa direttamente di tutto quanto.
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
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 i codici restituiti in \var{errno} sono:
+ nel qual caso \var{errno} assume i valori:
\begin{errlist}
\item[\macro{EINVAL}] \param{fd} è un file speciale che non supporta la
sincronizzazione.
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 metadata dell'inode (i dati
-di \var{fstat} come i tempi del file).
+\func{fsync} forza anche la sincronizzazione dei metadati del file (che
+riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli
+altri dati contenuti nell'inode che si leggono con \var{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
nella terza sezione di \tabref{tab:file_open_flags}.\footnote{la pagina di
manuale riporta come impostabili solo \macro{O\_APPEND},
\macro{O\_NONBLOCK} e \macro{O\_ASYNC}.}
-\item[\macro{F\_GETLK}] se un file lock è attivo restituisce nella struttura
- \param{lock} la struttura \type{flock} che impedisce l'acquisizione del
- blocco, altrimenti imposta il campo \var{l\_type} a \macro{F\_UNLCK} (per i
- dettagli sul \textit{file locking} vedi \secref{sec:file_locking}).
-\item[\macro{F\_SETLK}] richiede il file lock specificato da \param{lock} se
- \var{l\_type} è \macro{F\_RDLCK} o \macro{F\_WRLLCK} o lo rilascia se
- \var{l\_type} è \macro{F\_UNLCK}. Se il lock è tenuto da qualcun'altro
- ritorna immediatamente restituendo -1 e imposta \var{errno} a \macro{EACCES}
- o \macro{EAGAIN} (per i dettagli sul \textit{file locking} vedi
- \secref{sec:file_locking}).
+\item[\macro{F\_GETLK}] richiede un controllo sul file lock specificato da
+ \param{lock}, sovrascrivendo la struttura da esso puntata con il risultato
+ (questa funzionalità è trattata in dettaglio in
+ \secref{sec:file_posix_lock}).
+\item[\macro{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
+ \macro{EACCES} o \macro{EAGAIN} (questa funzionalità è trattata in dettaglio
+ in \secref{sec:file_posix_lock}).
\item[\macro{F\_SETLKW}] identica a \macro{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 \macro{EINTR} (per i dettagli sul \textit{file locking} vedi
- \secref{sec:file_locking}).
+ \var{errno} a \macro{EINTR} (questa funzionalità è trattata in dettaglio in
+ \secref{sec:file_posix_lock}).
\item[\macro{F\_GETOWN}] restituisce il \acr{pid} del processo o il process
group che è preposto alla ricezione dei segnali \macro{SIGIO} e
\macro{SIGURG} per gli eventi associati al file descriptor \var{fd}. Il