%% 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 "Prefazione",
%% 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 "Prefazione",
dalle system call, che non prevede funzionalità evolute come la
bufferizzazione o funzioni di lettura o scrittura formattata, e sulla quale è
costruita anche l'interfaccia definita dallo standard ANSI C che affronteremo
dalle system call, che non prevede funzionalità evolute come la
bufferizzazione o funzioni di lettura o scrittura formattata, e sulla quale è
costruita anche l'interfaccia definita dallo standard ANSI C che affronteremo
\index{file!descriptor|(} Per poter accedere al contenuto di un file occorre
creare un canale di comunicazione con il kernel che renda possibile operare su
\index{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 (si ricordi quanto visto in \secref{sec:file_vfs_work}). Questo si fa
-aprendo il file con la funzione \func{open} che provvederà a localizzare
+di esso (si ricordi quanto visto in sez.~\ref{sec:file_vfs_work}). Questo si
+fa aprendo il file con la funzione \func{open} che provvederà a localizzare
l'inode\index{inode} del file e inizializzare i puntatori che rendono
disponibili le funzioni che il VFS mette a disposizione (riportate in
l'inode\index{inode} del file e inizializzare i puntatori che rendono
disponibili le funzioni che il VFS mette a disposizione (riportate in
-\tabref{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.
+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 intero non
negativo, chiamato appunto \textit{file descriptor}.
All'interno di ogni processo i file aperti sono identificati da un intero non
negativo, chiamato appunto \textit{file descriptor}.
sua volta all'inode\index{inode} passando per la nuova struttura del VFS.}
del file.
%\item un puntatore alla tabella delle funzioni \footnote{la struttura
sua volta all'inode\index{inode} passando per la nuova struttura del VFS.}
del file.
%\item un puntatore alla tabella delle funzioni \footnote{la struttura
questa architettura, ed in cui si sono evidenziate le interrelazioni fra le
varie strutture di dati sulla quale essa è basata.
\begin{figure}[htb]
questa architettura, ed in cui si sono evidenziate le interrelazioni fra le
varie strutture di dati sulla quale essa è basata.
\begin{figure}[htb]
-In \figref{tab:file_std_files} si è utilizzata questa situazione come esempio,
-facendo riferimento ad un programma in cui lo \textit{standard input} è
-associato ad un file mentre lo \textit{standard output} e lo \textit{standard
- error} sono entrambi associati ad un altro file (e quindi utilizzano lo
-stesso inode\index{inode}).
+In tab.~\ref{tab:file_std_files} si è utilizzata questa situazione come
+esempio, facendo riferimento ad un programma in cui lo \textit{standard input}
+è associato ad un file mentre lo \textit{standard output} e lo
+\textit{standard error} sono entrambi associati ad un altro file (e quindi
+utilizzano lo stesso inode\index{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
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
descriptor dentro \struct{file\_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
descriptor dentro \struct{file\_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
\hline % modalità di apertura del file
\hline
\const{O\_CREAT} & se il file non esiste verrà creato, con le regole di
\hline % modalità di apertura del file
\hline
\const{O\_CREAT} & se il file non esiste verrà creato, con le regole di
\param{mode} deve essere specificato. \\
\const{O\_EXCL} & usato in congiunzione con \const{O\_CREAT} fa sì che
l'esistenza del file diventi un errore\protect\footnotemark\ che fa fallire
\param{mode} deve essere specificato. \\
\const{O\_EXCL} & usato in congiunzione con \const{O\_CREAT} fa sì che
l'esistenza del file diventi un errore\protect\footnotemark\ che fa fallire
\const{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo
valore specifica anche una modalità di operazione (vedi sotto), e
comporta che \func{open} ritorni immediatamente (l'opzione ha senso
\const{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo
valore specifica anche una modalità di operazione (vedi sotto), e
comporta che \func{open} ritorni immediatamente (l'opzione ha senso
\const{O\_NOCTTY} & se \param{pathname} si riferisce ad un dispositivo di
terminale, questo non diventerà il terminale di controllo, anche se il
\const{O\_NOCTTY} & se \param{pathname} si riferisce ad un dispositivo di
terminale, questo non diventerà il terminale di controllo, anche se il
\const{O\_TRUNC} & se il file esiste ed è un file di dati e la modalità di
apertura consente la scrittura, allora la sua lunghezza verrà troncata a
zero. Se il file è un terminale o una fifo il flag verrà ignorato, negli
\const{O\_TRUNC} & se il file esiste ed è un file di dati e la modalità di
apertura consente la scrittura, allora la sua lunghezza verrà troncata a
zero. Se il file è un terminale o una fifo il flag verrà ignorato, negli
file. Può causare corruzione del file con NFS se più di un processo scrive
allo stesso tempo.\footnotemark\\
\const{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per
file. Può causare corruzione del file con NFS se più di un processo scrive
allo stesso tempo.\footnotemark\\
\const{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per
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
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
\const{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di
\const{O\_NONBLOCK}.\\
\const{O\_ASYNC} & apre il file per l'I/O in modalità
\const{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di
\const{O\_NONBLOCK}.\\
\const{O\_ASYNC} & apre il file per l'I/O in modalità
- asincrona (vedi \secref{sec:file_asyncronous_io}). Quando è impostato viene
- generato il segnale \const{SIGIO} tutte le volte che sono disponibili
+ asincrona (vedi sez.~\ref{sec:file_asyncronous_io}). Quando è impostato
+ viene generato il segnale \const{SIGIO} tutte le volte che sono disponibili
- \const{O\_SYNC} & apre il file per l'input/output sincrono, ogni
- \func{write} bloccherà fino al completamento della scrittura di tutti dati
- sul sull'hardware sottostante.\\
+ \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.\\
\const{O\_FSYNC} & sinonimo di \const{O\_SYNC}. \\
\const{O\_NOATIME} & blocca l'aggiornamento dei tempi di accesso dei
\const{O\_FSYNC} & sinonimo di \const{O\_SYNC}. \\
\const{O\_NOATIME} & blocca l'aggiornamento dei tempi di accesso dei
- file (vedi \secref{sec:file_file_times}). In Linux questa opzione non è
- disponibile per il singolo file ma come opzione per il filesystem in fase
+ file (vedi sez.~\ref{sec:file_file_times}). Per molti filesystem questa
+ funzionalità non è disponibile per il singolo file ma come opzione in fase
\textsl{file di lock}\index{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
\textsl{file di lock}\index{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
\footnotetext[3]{\textit{Denial of Service}\index{DoS}, si chiamano così
attacchi miranti ad impedire un servizio causando una qualche forma di
\footnotetext[3]{\textit{Denial of Service}\index{DoS}, si chiamano così
attacchi miranti ad impedire un servizio causando una qualche forma di
\footnotetext[4]{il problema è che NFS non supporta la scrittura in append, ed
il kernel deve simularla, ma questo comporta la possibilità di una race
\footnotetext[4]{il problema è che NFS non supporta la scrittura in append, ed
il kernel deve simularla, ma questo comporta la possibilità di una race
\footnotetext[5]{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
\footnotetext[5]{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
zero da parte di \func{read} ha il significato di una end-of-file.}
Questa caratteristica permette di prevedere 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
zero da parte di \func{read} ha il significato di una end-of-file.}
Questa caratteristica permette di prevedere 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
input e si apre subito dopo un nuovo file questo diventerà il nuovo standard
input (avrà cioè il file descriptor 0). Il nuovo file descriptor non è
condiviso con nessun altro processo (torneremo sulla condivisione dei file, in
input e si apre subito dopo un nuovo file questo diventerà il nuovo standard
input (avrà cioè il file descriptor 0). Il nuovo file descriptor non è
condiviso con nessun altro processo (torneremo sulla condivisione dei file, in
-\tabref{tab:file_bit_perm}. Questi permessi sono filtrati dal valore di
-\var{umask} (vedi \secref{sec:file_umask}) per il processo.
+tab.~\ref{tab:file_bit_perm}. Questi permessi sono filtrati dal valore di
+\var{umask} (vedi sez.~\ref{sec:file_umask}) 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 flag di stato del file (o \textit{file status flag}), che è mantenuto nel
campo \var{f\_flags} della struttura \struct{file} (al solito si veda lo schema
La funzione prevede diverse opzioni, che vengono specificate usando vari bit
dell'argomento \param{flags}. Alcuni di questi bit vanno anche a costituire
il flag di stato del file (o \textit{file status flag}), che è mantenuto nel
campo \var{f\_flags} della struttura \struct{file} (al solito si veda lo schema
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)
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)
- locking}\index{file!locking} è trattato in \secref{sec:file_locking}) che il
-processo poteva avere acquisito su di esso; se \param{fd} è l'ultimo
+ locking}\index{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
file table vengono rilasciate. Infine se il file descriptor era l'ultimo
riferimento ad un file su disco quest'ultimo viene cancellato.
riferimento (di eventuali copie) ad un file aperto, tutte le risorse nella
file table vengono rilasciate. Infine se il file descriptor era l'ultimo
riferimento ad un file su disco quest'ultimo viene cancellato.
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
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
\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
\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
una \textsl{posizione corrente nel file} (il cosiddetto \textit{file offset},
mantenuto nel campo \var{f\_pos} di \struct{file}) espressa da un numero intero
positivo come numero di byte dall'inizio del file. Tutte le operazioni di
una \textsl{posizione corrente nel file} (il cosiddetto \textit{file offset},
mantenuto nel campo \var{f\_pos} di \struct{file}) espressa da un numero intero
positivo come numero di byte dall'inizio del file. Tutte le operazioni di
impostare la posizione corrente anche oltre la fine del file, e alla
successiva scrittura il file sarà esteso. La chiamata non causa nessun accesso
al file, si limita a modificare la posizione corrente (cioè il valore
impostare la posizione corrente anche oltre la fine del file, e alla
successiva scrittura il file sarà esteso. La chiamata non causa nessun accesso
al file, si limita a modificare la posizione corrente (cioè il valore
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)}.
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)}.
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
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}).
+(questa è una potenziale sorgente di \textit{race condition}
+\index{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{EPIPE}. Questo, oltre che per
Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
questo caso la funzione ritorna l'errore \errcode{EPIPE}. Questo, oltre che per
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
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
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
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
lettura da certi file di dispositivo, come le unità a nastro, che
restituiscono sempre i dati ad un singolo blocco alla volta.
lettura da certi file di dispositivo, come le unità a nastro, che
restituiscono sempre i dati ad un singolo blocco alla volta.
\errcode{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 intraprendere è quella di rieseguire la funzione.
\errcode{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 intraprendere è quella di rieseguire la funzione.
allora ritorna immediatamente con un errore \errcode{EAGAIN}\footnote{BSD usa
per questo errore la costante \errcode{EWOULDBLOCK}, in Linux, con le
\acr{glibc}, questa è sinonima di \errcode{EAGAIN}.} che indica soltanto che
allora ritorna immediatamente con un errore \errcode{EAGAIN}\footnote{BSD usa
per questo errore la costante \errcode{EWOULDBLOCK}, in Linux, con le
\acr{glibc}, questa è sinonima di \errcode{EAGAIN}.} che indica soltanto che
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
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
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)}
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)}
\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
\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
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
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
esamineremo ora in dettaglio le conseguenze che questa architettura ha nei
confronti dell'accesso allo stesso file da parte di processi diversi.
esamineremo ora in dettaglio le conseguenze che questa architettura ha nei
confronti dell'accesso allo stesso file da parte di processi diversi.
-su disco; sulla base di quanto visto in \secref{sec:file_fd} avremo una
-situazione come quella illustrata in \figref{fig:file_mult_acc}: ciascun
+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 \struct{file\_struct}. Entrambe le voci
nella \textit{file table} faranno però riferimento allo stesso
processo avrà una sua voce nella \textit{file table} referenziata da un
diverso file descriptor nella sua \struct{file\_struct}. Entrambe le voci
nella \textit{file table} faranno però riferimento allo stesso
Il secondo caso è quello in cui due file descriptor di due processi diversi
puntino alla stessa voce nella \textit{file table}; questo è ad esempio il
caso dei file aperti che vengono ereditati dal processo figlio all'esecuzione
Il secondo caso è quello in cui due file descriptor di due processi diversi
puntino alla stessa voce nella \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 \secref{sec:proc_fork}). La
-situazione è illustrata in \figref{fig:file_acc_child}; dato che il processo
+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 \struct{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
figlio riceve una copia dello spazio di indirizzi del padre, riceverà anche
una copia di \struct{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
corrente nel file varierà per entrambi i processi (in quanto verrà modificato
\var{f\_pos} che è lo stesso per entrambi).
corrente nel file varierà per entrambi i processi (in quanto verrà modificato
\var{f\_pos} che è lo stesso per entrambi).
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 \textit{file
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 \textit{file
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
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
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
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
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
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
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}.
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}.
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
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
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
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
semplicemente quello di copiare il valore nella struttura
\struct{file\_struct}, cosicché anche il nuovo file descriptor fa riferimento
alla stessa voce nella \textit{file table}; per questo si dice che il nuovo
semplicemente quello di copiare il valore nella struttura
\struct{file\_struct}, cosicché anche il nuovo file descriptor fa riferimento
alla stessa voce nella \textit{file table}; per questo si dice che il nuovo
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
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
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}\index{close-on-exec} (vedi
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}\index{close-on-exec} (vedi
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
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
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
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
La duplicazione dei file descriptor può essere effettuata anche usando la
funzione di controllo dei file \func{fnctl} (che esamineremo in
La duplicazione dei file descriptor può essere effettuata anche usando la
funzione di controllo dei file \func{fnctl} (che esamineremo in
la sintassi \code{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per
\param{newfd} diventa equivalente a \func{dup}.
la sintassi \code{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per
\param{newfd} diventa equivalente a \func{dup}.
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
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
- \secref{sec:file_asyncronous_operation}) e il file
- locking\index{file!locking} (vedi \secref{sec:file_locking}).}
+ sez.~\ref{sec:file_asyncronous_operation}) e il file
+ locking\index{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},
Per queste operazioni di manipolazione e di controllo delle varie proprietà e
caratteristiche di un file descriptor, viene usata la funzione \funcd{fcntl},
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
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
per la duplicazione dei file descriptor, una lista di tutti i possibili valori
per \var{cmd} è riportata di seguito:
\begin{basedescript}{\desclabelwidth{2.0cm}}
per la duplicazione dei file descriptor, una lista di tutti i possibili valori
per \var{cmd} è riportata di seguito:
\begin{basedescript}{\desclabelwidth{2.0cm}}
valore specificato con \param{arg}. Al momento l'unico bit usato è quello di
\textit{close-on-exec}\index{close-on-exec}, identificato dalla costante
\const{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella
valore specificato con \param{arg}. Al momento l'unico bit usato è quello di
\textit{close-on-exec}\index{close-on-exec}, identificato dalla costante
\const{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella
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
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
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
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
\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
\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
riporta come impostabili solo \const{O\_APPEND}, \const{O\_NONBLOCK} e
\const{O\_ASYNC}.}
\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
riporta come impostabili solo \const{O\_APPEND}, \const{O\_NONBLOCK} e
\const{O\_ASYNC}.}
\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
\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
\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
\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.
\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.
\item[\const{F\_GETOWN}] restituisce il \acr{pid} del processo o
l'identificatore del process group\footnote{i \texttt{process group} sono
\item[\const{F\_GETOWN}] restituisce il \acr{pid} del processo o
l'identificatore del process group\footnote{i \texttt{process group} sono
controllo di sessione; a ciascuno di essi è associato un identificatore
(un numero positivo analogo al \acr{pid}).} che è preposto alla ricezione
dei segnali \const{SIGIO} e \const{SIGURG} per gli eventi associati al file
controllo di sessione; a ciascuno di essi è associato un identificatore
(un numero positivo analogo al \acr{pid}).} che è preposto alla ricezione
dei segnali \const{SIGIO} e \const{SIGURG} per gli eventi associati al file
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
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
indica il valore predefinito (che è \const{SIGIO}), un valore diverso da
zero indica il segnale richiesto, (che può essere anche lo stesso
\const{SIGIO}). In caso di errore ritorna -1.
indica il valore predefinito (che è \const{SIGIO}), un valore diverso da
zero indica il segnale richiesto, (che può essere anche lo stesso
\const{SIGIO}). In caso di errore ritorna -1.
valore diverso da zero (compreso lo stesso \const{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
valore diverso da zero (compreso lo stesso \const{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
disponibili al gestore informazioni ulteriori riguardo il file che ha
generato il segnale attraverso i valori restituiti in \struct{siginfo\_t}
disponibili al gestore informazioni ulteriori riguardo il file che ha
generato il segnale attraverso i valori restituiti in \struct{siginfo\_t}
\const{F\_SETSIG} e \const{F\_GETSIG} sono una estensione specifica di
Linux.}
\item[\const{F\_SETLEASE}] imposta o rimuove un \textit{file
\const{F\_SETSIG} e \const{F\_GETSIG} sono una estensione specifica di
Linux.}
\item[\const{F\_SETLEASE}] imposta o rimuove un \textit{file
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 è
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 è
\item[\const{F\_GETLEASE}] restituisce il tipo di \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
\item[\const{F\_GETLEASE}] restituisce il tipo di \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
\item[\const{F\_NOTIFY}] attiva un meccanismo di notifica per cui viene
riportata al processo chiamante, tramite il segnale \const{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
\item[\const{F\_NOTIFY}] attiva un meccanismo di notifica per cui viene
riportata al processo chiamante, tramite il segnale \const{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
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
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
-\secref{sec:file_asyncronous_operation} mentre quelle relative al \textit{file
- locking}\index{file!locking} saranno esaminate in
-\secref{sec:file_locking}).
+sez.~\ref{sec:file_asyncronous_operation} mentre quelle relative al
+\textit{file locking}\index{file!locking} saranno esaminate in
+sez.~\ref{sec:file_locking}).