%% fileio.tex (merge fileunix.tex - filestd.tex)
%%
-%% Copyright (C) 2000-2015 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2017 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",
\chapter{La gestione dell'I/O su file}
\label{cha:file_IO_interface}
-Esamineremo in questo capitolo le due interfacce di programmazione che
+Esamineremo in questo capitol le due interfacce di programmazione che
consentono di gestire i dati mantenuti nei file. Cominceremo con quella nativa
del sistema, detta dei \textit{file descriptor}, che viene fornita
direttamente dalle \textit{system call} e che non prevede funzionalità evolute
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.
+intero non negativo, che viene chiamato appunto \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.
\itindbeg{process~table}
\itindbeg{file~table}
contengono le informazioni necessarie per la gestione dei file, ed in
particolare:
\begin{itemize*}
-\item i flag di stato \itindex{file~status~flag} del file nel campo
- \var{f\_flags}.
+\item i flag di 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
\centering
\includegraphics[width=12cm]{img/procfile}
\caption{Schema della architettura dell'accesso ai file attraverso
- l'interfaccia dei \textit{file descriptor}.}
+ l'interfaccia dei file descriptor.}
\label{fig:file_proc_file}
\end{figure}
interrelazioni fra la \textit{file table}, la \textit{process table} e le
varie strutture di dati che il kernel mantiene per ciascun file e ciascun
processo.
+
\itindend{process~table}
Come si può notare alla fine il collegamento che consente di porre in
\textit{file table}.
\end{itemize*}
-In questa infrastruttura un \textit{file descriptor} non è altro che l'intero
-positivo che indicizza quest'ultima tabella, e che consente di recuperare il
-puntatore alla struttura \kstruct{file} corrispondente al file aperto dal
-processo a cui era stato assegnato questo indice. Una volta ottenuta grazie al
-\textit{file descriptor} la struttura \kstruct{file} corrispondente al file
-voluto nella \textit{file table}, il kernel potrà usare le funzioni messe
-disposizione dal VFS per eseguire sul file tutte le operazioni necessarie.
+In questa infrastruttura un file descriptor non è altro che l'intero positivo
+che indicizza quest'ultima tabella, e che consente di recuperare il puntatore
+alla struttura \kstruct{file} corrispondente al file aperto dal processo a cui
+era stato assegnato questo indice. Una volta ottenuta grazie al file
+descriptor la struttura \kstruct{file} corrispondente al file voluto nella
+\textit{file table}, 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.
+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.
\itindbeg{standard~input}
\itindbeg{standard~output}
In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
processo si aspetta di avere sempre tre file aperti che, per quanto appena
-detto, avranno come \itindex{file~descriptor} \textit{file descriptor} i
-valori 0, 1 e 2. Il primo file è sempre associato al cosiddetto
-\textit{standard input}, è cioè il file da cui un processo si aspetta di dover
-leggere i dati in ingresso. Il secondo file è il cosiddetto \textit{standard
- output}, cioè quello su cui ci si aspetta di dover scrivere i dati in
-uscita. Il terzo è lo \textit{standard error}, su cui
-vengono scritti i dati relativi agli errori.
+detto, avranno come \textit{file descriptor} i valori 0, 1 e 2. Il primo file
+è sempre associato al cosiddetto \textit{standard input}, è cioè il file da
+cui un processo si aspetta di dover leggere i dati in ingresso. Il secondo
+file è il cosiddetto \textit{standard output}, cioè quello su cui ci si
+aspetta di dover scrivere i dati in uscita. Il terzo è lo \textit{standard
+ error}, su cui vengono scritti i dati relativi agli errori.
+
+\itindend{file~descriptor}
+
Benché questa sia soltanto una convenzione, essa è seguita dalla gran parte
delle applicazioni, e non aderirvi potrebbe portare a problemi di
\textbf{File} & \textbf{Significato} \\
\hline
\hline
- \const{STDIN\_FILENO} & \textit{file descriptor} dello
- \itindex{standard~input} \textit{standard
- input}.\\
- \const{STDOUT\_FILENO} & \textit{file descriptor} dello
- \itindex{standard~output} \textit{standard
- output}.\\
- \const{STDERR\_FILENO} & \textit{file descriptor} dello \textit{standard
- error}.\\
+ \constd{STDIN\_FILENO} & file descriptor dello \textit{standard input}.\\
+ \constd{STDOUT\_FILENO} & file descriptor dello \textit{standard output}.\\
+ \constd{STDERR\_FILENO} & file descriptor dello \textit{standard error}.\\
\hline
\end{tabular}
\caption{Costanti definite in \headfile{unistd.h} per i file standard.}
di gestione dei file, quella che dato un \textit{pathname} consente di
ottenere un file descriptor ``\textsl{aprendo}'' il file
corrispondente,\footnote{è \func{open} che alloca \kstruct{file}, la inserisce
- nella \itindex{file~table} \textit{file table} e crea il riferimento nella
+ nella \textit{file table} e crea il riferimento nella
\kstruct{files\_struct} del processo.} il suo prototipo è:
\begin{funcproto}{
\item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e
\param{pathname} non è una directory.
\item[\errcode{ENXIO}] si sono impostati \const{O\_NONBLOCK} 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.
+ \const{O\_WRONLY} ed il file è una \textit{fifo} che non viene letta da
+ nessun processo o \param{pathname} è un file di dispositivo ma il
+ dispositivo è assente.
\item[\errcode{EPERM}] si è specificato \const{O\_NOATIME} e non si è né
amministratori né proprietari del file.
\item[\errcode{ETXTBSY}] si è cercato di accedere in scrittura all'immagine
essergli assegnati. 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
-comunque filtrati dal valore della \itindex{umask} \textit{umask} (vedi
+comunque filtrati dal valore della \textit{umask} (vedi
sez.~\ref{sec:file_perm_management}) del processo.
La funzione restituisce sempre il primo file descriptor libero, una
caratteristica che permette di prevedere qual è il valore del file descriptor
che si otterrà al ritorno di \func{open}, e che viene spesso usata dalle
applicazioni per sostituire i file corrispondenti ai file standard visti in
-tab.~\ref{tab:file_std_files}. Se ad esempio si chiude lo
-\itindex{standard~input} \textit{standard input} e si apre subito dopo un
-nuovo file questo diventerà il nuovo \itindex{standard~input} \textit{standard
- input} dato che avrà il file descriptor 0.
+tab.~\ref{tab:file_std_files}. Se ad esempio si chiude lo \textit{standard
+ input} e si apre subito dopo un nuovo file questo diventerà il nuovo
+\textit{standard input} dato che avrà il file descriptor 0.
Al momento dell'apertura il nuovo file descriptor non è condiviso con nessun
altro processo (torneremo sul significato della condivisione dei file
esso direttamente tramite il file descriptor, e quanto avviene al
\textit{pathname} con cui lo si è aperto sarà del tutto ininfluente.
+\itindbeg{file~status~flag}
+
Il comportamento della funzione, e le diverse modalità con cui può essere
aperto il file, vengono controllati dall'argomento \param{flags} il cui valore
deve essere indicato come maschera binaria in cui ciascun bit ha un
significato specifico. Alcuni di questi bit vanno anche a costituire i
-cosiddetti \textsl{flag di stato} del file (i cosiddetti
-\itindex{file~status~flag} \textit{file status flags}), che vengono mantenuti
-nel campo \var{f\_flags} della struttura \kstruct{file} che abbiamo riportato
-anche in fig.~\ref{fig:file_proc_file}).
+cosiddetti \textsl{flag di stato} del file (i cosiddetti \textit{file status
+ flags}), che vengono mantenuti nel campo \var{f\_flags} della struttura
+\kstruct{file} che abbiamo riportato anche in fig.~\ref{fig:file_proc_file}).
Ciascun flag viene identificato da una apposita costante, ed il valore
di \param{flags} deve essere specificato come OR aritmetico di queste
\textbf{Flag} & \textbf{Significato} \\
\hline
\hline
- \const{O\_RDONLY} & Apre il file in sola lettura.\\
- \const{O\_WRONLY} & Apre il file in sola scrittura.\\
- \const{O\_RDWR} & Apre il file sia in lettura che in scrittura.\\
+ \constd{O\_RDONLY} & Apre il file in sola lettura.\\
+ \constd{O\_WRONLY} & Apre il file in sola scrittura.\\
+ \constd{O\_RDWR} & Apre il file sia in lettura che in scrittura.\\
\hline
\end{tabular}
\caption{Le tre costanti che identificano le modalità di accesso
sez.~\ref{sec:file_fcntl_ioctl}).}
La modalità di accesso deve sempre essere specificata quando si apre un file,
-il valore indicato in \param{flags} viene salvato nei
-\itindex{file~status~flag} \textit{file status flags}, e può essere riletto
-con \func{fcntl} (vedi sez.~\ref{sec:file_fcntl_ioctl}), il relativo valore
-può essere poi ottenuto un AND aritmetico della maschera binaria
-\const{O\_ACCMODE}, ma non può essere modificato. Nella \acr{glibc} sono
-definite inoltre \const{O\_READ} come sinonimo di \const{O\_RDONLY} e
-\const{O\_WRITE} come sinonimo di \const{O\_WRONLY}.\footnote{si tratta di
- definizioni completamente fuori standard, attinenti, insieme a
- \const{O\_EXEC} che permetterebbe l'apertura di un file per l'esecuzione, ad
- un non meglio precisato ``\textit{GNU system}''; pur essendo equivalenti
- alle definizioni classiche non è comunque il caso di utilizzarle.}
+il valore indicato in \param{flags} viene salvato nei \textit{file status
+ flags}, e può essere riletto con \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl_ioctl}), il relativo valore può essere poi ottenuto
+un AND aritmetico della maschera binaria \constd{O\_ACCMODE}, ma non può essere
+modificato. Nella \acr{glibc} sono definite inoltre \constd{O\_READ} come
+sinonimo di \const{O\_RDONLY} e \constd{O\_WRITE} come sinonimo di
+\const{O\_WRONLY}.\footnote{si tratta di definizioni completamente fuori
+ standard, attinenti, insieme a \constd{O\_EXEC} che permetterebbe l'apertura
+ di un file per l'esecuzione, ad un non meglio precisato ``\textit{GNU
+ system}''; pur essendo equivalenti alle definizioni classiche non è
+ comunque il caso di utilizzarle.}
+
+\itindend{file~status~flag}
Il secondo gruppo di flag è quello delle \textsl{modalità di
apertura},\footnote{la pagina di manuale di \func{open} parla di
permettono di specificare alcune delle caratteristiche del comportamento di
\func{open} nel momento in viene eseguita per aprire un file. Questi flag
hanno effetto solo nella chiamata della funzione, non sono memorizzati fra i
-\itindex{file~status~flag} \textit{file status flags} e non possono essere
-riletti da \func{fcntl} (vedi sez.~\ref{sec:file_fcntl_ioctl}).
+\textit{file status flags} e non possono essere riletti da \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl_ioctl}).
\begin{table}[htb]
\centering
\textbf{Flag} & \textbf{Significato} \\
\hline
\hline
- \const{O\_CREAT} & Se il file non esiste verrà creato, con le regole
+ \constd{O\_CREAT} & Se il file non esiste verrà creato, con le regole
di titolarità del file viste in
sez.~\ref{sec:file_ownership_management}. Se si
imposta questo flag l'argomento \param{mode} deve
essere sempre specificato.\\
- \const{O\_DIRECTORY}& Se \param{pathname} non è una directory la
+ \constd{O\_DIRECTORY}&Se \param{pathname} non è una directory la
chiamata fallisce. Questo flag, introdotto con il
kernel 2.1.126, è specifico di Linux e
serve ad evitare dei possibili
\itindex{Denial~of~Service~(DoS)}
\textit{DoS}\footnotemark quando \func{opendir}
- viene chiamata su una fifo o su un dispositivo
+ viene chiamata su una \textit{fifo} o su un dispositivo
associato ad una unità a nastri. Non viene
usato al di fuori dell'implementazione di
\func{opendir}, ed è utilizzabile soltanto se si è
definita la macro \macro{\_GNU\_SOURCE}.\\
- \const{O\_EXCL} & Deve essere usato in congiunzione con
+ \constd{O\_EXCL} & Deve essere usato in congiunzione con
\const{O\_CREAT} ed in tal caso impone che il file
indicato da \param{pathname} non sia già esistente
(altrimenti causa il fallimento della chiamata con
un errore di \errcode{EEXIST}).\\
- \const{O\_LARGEFILE}& Viene usato sui sistemi a 32 bit per richiedere
+ \constd{O\_LARGEFILE}&Viene usato sui sistemi a 32 bit per richiedere
l'apertura di file molto grandi, la cui
dimensione non è rappresentabile con la versione a
32 bit del tipo \type{off\_t}, utilizzando
delle funzioni che si attiva assegnando a $64$ la
macro \macro{\_FILE\_OFFSET\_BITS}, e non usare mai
questo flag.\\
- \const{O\_NOCTTY} & Se \param{pathname} si riferisce ad un dispositivo
+ \constd{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}).\\
- \const{O\_NOFOLLOW} & Se \param{pathname} è un collegamento simbolico
+ \constd{O\_NOFOLLOW}& Se \param{pathname} è un collegamento simbolico
la chiamata fallisce. Questa è un'estensione BSD
aggiunta in Linux a partire dal kernel
2.1.126, ed utilizzabile soltanto se si è definita
la macro \macro{\_GNU\_SOURCE}.\\
- \const{O\_TRUNC} & Se usato su un file di dati aperto in scrittura,
+ \constd{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
+ una \textit{fifo} viene ignorato, negli altri casi il
comportamento non è specificato.\\
\hline
\end{tabular}
Si è riportato in tab.~\ref{tab:open_time_flag} l'elenco dei flag delle
\textsl{modalità di apertura}.\footnote{la \acr{glibc} definisce anche i due
- flag \const{O\_SHLOCK}, che aprirebbe il file con uno \textit{shared lock} e
- \const{O\_EXLOCK} che lo aprirebbe con un \textit{exclusive lock} (vedi
+ flag \constd{O\_SHLOCK}, che aprirebbe il file con uno \textit{shared lock} e
+ \constd{O\_EXLOCK} che lo aprirebbe con un \textit{exclusive lock} (vedi
sez.~\ref{sec:file_locking}, si tratta di opzioni specifiche di BSD, che non
esistono con Linux.} Uno di questi, \const{O\_EXCL}, ha senso solo se usato
in combinazione a \const{O\_CREAT} quando si vuole creare un nuovo file per
\textbf{Flag} & \textbf{Significato} \\
\hline
\hline
- \const{O\_APPEND} & Il file viene aperto in \itindex{append~mode}
- \textit{append mode}. La posizione sul file (vedi
- sez.~\ref{sec:file_lseek}) viene sempre mantenuta
- sulla sua coda, per cui quanto si scrive
- viene sempre aggiunto al contenuto precedente. Con
- NFS questa funzionalità non è supportata
- e viene emulata, per questo possono verificarsi
- \textit{race condition} con una sovrapposizione dei
- dati se più di un processo scrive allo stesso
- tempo.\\
- \const{O\_ASYNC} & Apre il file per l'I/O in modalità asincrona (vedi
+ \constd{O\_APPEND} & Il file viene aperto in \textit{append mode}. La
+ posizione sul file (vedi sez.~\ref{sec:file_lseek})
+ viene sempre mantenuta sulla sua coda, per cui
+ quanto si scrive viene sempre aggiunto al contenuto
+ precedente. Con NFS questa funzionalità non è
+ supportata e viene emulata, per questo possono
+ verificarsi \textit{race condition} con una
+ sovrapposizione dei dati se più di un processo
+ scrive allo stesso tempo.\\
+ \constd{O\_ASYNC} & Apre il file per l'I/O in modalità asincrona (vedi
sez.~\ref{sec:signal_driven_io}). Quando è
impostato viene generato il segnale \signal{SIGIO}
tutte le volte che il file è pronto per le
operazioni di lettura o scrittura. Questo flag si
può usare solo terminali, pseudo-terminali e socket
- e, a partire dal kernel 2.6, anche sulle fifo. Per
+ e, a partire dal kernel 2.6, anche sulle \textit{fifo}. Per
un bug dell'implementazione non è opportuno usarlo
in fase di apertura del file, deve
invece essere attivato successivamente con
\func{fcntl}.\\
- \const{O\_CLOEXEC}& Attiva la modalità di \textit{close-on-exec} (vedi
+ \constd{O\_CLOEXEC}& Attiva la modalità di \textit{close-on-exec} (vedi
sez.~\ref{sec:proc_exec}) sul file. Il flag è
previsto dallo standard POSIX.1-2008, ed è stato
introdotto con il kernel 2.6.23 per evitare una
l'impostazione della suddetta modalità con
\func{fcntl} (vedi
sez.~\ref{sec:file_fcntl_ioctl}).\\
- \const{O\_DIRECT} & Esegue l'I/O direttamente dalla memoria in
+ \constd{O\_DIRECT} & Esegue l'I/O direttamente dalla memoria in
\textit{user space} in maniera sincrona, in modo da
scavalcare i meccanismi di bufferizzazione del
kernel. Introdotto con il kernel 2.4.10 ed
utilizzabile soltanto se si è definita la
macro \macro{\_GNU\_SOURCE}.\\
- \const{O\_NOATIME} & Blocca l'aggiornamento dei tempi di accesso dei
+ \constd{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
montaggio. Introdotto con il kernel 2.6.8 ed
utilizzabile soltanto se si è definita la
macro \macro{\_GNU\_SOURCE}.\\
- \const{O\_NONBLOCK}& Apre il file in \textsl{modalità non bloccante} per
+ \constd{O\_NONBLOCK}&Apre il file in \textsl{modalità non bloccante} per
le operazioni di I/O (vedi
sez.~\ref{sec:file_noblocking}). Questo significa
il fallimento delle successive operazioni di
blocco delle stesse in attesa di una successiva
possibilità di esecuzione come avviene
normalmente. Questa modalità ha senso solo per le
- fifo, vedi sez.~\ref{sec:ipc_named_pipe}), o quando
+ \textit{fifo}, vedi sez.~\ref{sec:ipc_named_pipe}), o quando
si vuole aprire un file di dispositivo per eseguire
una \func{ioctl} (vedi
sez.~\ref{sec:file_fcntl_ioctl}).\\
- \const{O\_NDELAY} & In Linux è un sinonimo di \const{O\_NONBLOCK}, ma
+ \constd{O\_NDELAY} & In Linux è un sinonimo di \const{O\_NONBLOCK}, ma
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 un valore nullo da parte di \func{read} ha
il significato di una \textit{end-of-file}.\\
- \const{O\_SYNC} & Apre il file per l'input/output sincrono. Ogni
+ \constd{O\_SYNC} & Apre il file per l'input/output sincrono. Ogni
scrittura si bloccherà fino alla conferma
dell'arrivo di tutti i dati e di tutti i metadati
sull'hardware sottostante (in questo significato
solo dal kernel 2.6.33).\\
- \const{O\_DSYNC} & Apre il file per l'input/output sincrono. Ogni
+ \constd{O\_DSYNC} & Apre il file per l'input/output sincrono. Ogni
scrittura di dati si bloccherà fino alla conferma
dell'arrivo degli stessi e della parte di metadati
ad essi relativa sull'hardware sottostante (in
sull'argomento in sez.~\ref{sec:file_fcntl_ioctl}).
Il flag \const{O\_ASYNC} (che, per per compatibilità con BSD, si può indicare
-anche con la costante \const{FASYNC}) è definito come possibile valore per
+anche con la costante \constd{FASYNC}) è definito come possibile valore per
\func{open}, ma per un bug dell'implementazione,\footnote{segnalato come
ancora presente nella pagina di manuale almeno fino al Settembre 2011.} non
solo non attiva il comportamento citato, ma se usato richiede di essere
\end{funcproto}
La funzione chiude il file descriptor \param{fd}. La chiusura rilascia ogni
-eventuale blocco (il \textit{file locking} \itindex{file~locking} è trattato
-in sez.~\ref{sec:file_locking}) che il processo poteva avere acquisito su di
+eventuale blocco (il \textit{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, vedi
sez.~\ref{sec:file_shared_access} e \ref{sec:file_dup}) 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.
+tutte le risorse nella \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 tutti i suoi file descriptor vengono
automaticamente chiusi, molti programmi sfruttano questa caratteristica e non
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à di \textit{append} con
-\const{O\_APPEND}, questa posizione viene impostata a zero all'apertura del
-file. È possibile impostarla ad un valore qualsiasi con la funzione di sistema
-\funcd{lseek}, il cui prototipo è:
+In genere, a meno di non avere richiesto la modalità di scrittura in
+\textit{append} (vedi sez.~\ref{sec:file_write}) con \const{O\_APPEND}, questa
+posizione viene impostata a zero all'apertura del file. È possibile impostarla
+ad un valore qualsiasi con la funzione di sistema \funcd{lseek}, il cui
+prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
dall'argomento \param{whence}, che deve essere indicato con una delle costanti
riportate in tab.~\ref{tab:lseek_whence_values}.\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}.} Si tenga presente che la chiamata a \func{lseek} non causa
+ rispettivamente con 0, 1 e 2 o con \constd{L\_SET}, \constd{L\_INCR} e
+ \constd{L\_XTND}.} Si tenga presente che la chiamata a \func{lseek} non causa
nessun accesso al file, si limita a modificare la posizione corrente (cioè il
campo \var{f\_pos} della struttura \kstruct{file}, vedi
fig.~\ref{fig:file_proc_file}). Dato che la funzione ritorna la nuova
\textbf{Costante} & \textbf{Significato} \\
\hline
\hline
- \const{SEEK\_SET} & Si fa riferimento all'inizio del file: il valore, che
+ \constd{SEEK\_SET}& Si fa riferimento all'inizio del file: il valore, che
deve essere positivo, di \param{offset} indica
direttamente la nuova posizione corrente.\\
- \const{SEEK\_CUR} & Si fa riferimento alla posizione corrente del file:
+ \constd{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.\\
- \const{SEEK\_END} & Si fa riferimento alla fine del file: alle dimensioni
+ \constd{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.\\
\hline
- \const{SEEK\_DATA}& Sposta la posizione nel file sull'inizio del primo
+ \constd{SEEK\_DATA}&Sposta la posizione nel file sull'inizio del primo
blocco di dati dopo un \textit{hole} che segue (o
coincide) con la posizione indicata da \param{offset}
(dal kernel 3.1).\\
- \const{SEEK\_HOLE}& Sposta la posizione sul file all'inizio del primo
+ \constd{SEEK\_HOLE}&Sposta la posizione sul file all'inizio del primo
\textit{hole} nel file che segue o inizia
con \param{offset}, oppure si porta su \param{offset}
se questo è all'interno di un \textit{hole}, oppure si
Questa è una delle caratteristiche specifiche della gestione dei file di un
sistema unix-like 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 \itindex{inode}
+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
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 \itindex{inode}
-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 la chiamata ad una delle funzioni \texttt{*stat} viste in
-sez.~\ref{sec:file_stat}.
+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 la 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
\end{funcproto}
+\itindbeg{append~mode}
+
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
\func{write} che li ha scritti è ritornata; ma dati i meccanismi di caching
non è detto che tutti i filesystem supportino questa capacità.
+\itindend{append~mode}
+
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
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} \textit{inode} su disco.
+nella \textit{file table} faranno però riferimento allo stesso \textit{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:
+vengono mantenute nella sua voce della \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
scrivente. Se la scrittura eccede la dimensione corrente del file questo
verrà esteso automaticamente con l'aggiornamento del campo \var{i\_size}
della struttura \kstruct{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 dalla struttura
- \kstruct{inode}. Dopo la scrittura il file viene automaticamente esteso.
+\item se un file è in modalità \const{O\_APPEND} tutte le volte che viene
+ effettuata una scrittura la posizione corrente viene prima impostata alla
+ dimensione corrente del file letta dalla struttura \kstruct{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 dalla struttura \kstruct{inode}.
+ \var{f\_pos} nella struttura \kstruct{file} della \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
+ dalla struttura \kstruct{inode}.
\end{itemize}
\begin{figure}[!htb]
\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 della relativa tabella dei file aperti.
+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 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 della relativa tabella dei file aperti.
Questo significa che il figlio avrà gli stessi file aperti del padre, in
quanto la sua \kstruct{file\_struct}, pur essendo allocata in maniera
indipendente, contiene gli stessi valori di quella del padre e quindi i suoi
-file descriptor faranno riferimento alla stessa voce nella
-\itindex{file~table} \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 o lettura da parte di uno dei
-due processi, la posizione corrente nel file varierà per entrambi, in quanto
-verrà modificato il campo \var{f\_pos} della struttura \kstruct{file}, che è
-la stessa per entrambi. Questo consente una sorta di
-``\textsl{sincronizzazione}'' automatica della posizione sul file fra padre e
-figlio che occorre tenere presente.
-
-Si noti inoltre che in questo caso anche i \itindex{file~status~flag} flag di
-stato del file, essendo mantenuti nella struttura \kstruct{file} della
-\textit{file table}, vengono condivisi, per cui una modifica degli stessi con
-\func{fcntl} (vedi sez.~\ref{sec:file_fcntl_ioctl}) si applicherebbe a tutti
-processi che condividono la voce nella \itindex{file~table} \textit{file
- table}. Ai file però sono associati anche altri flag, dei quali l'unico
-usato al momento è \const{FD\_CLOEXEC}, detti \itindex{file~descriptor~flags}
-\textit{file descriptor flags}; questi invece sono mantenuti in
-\kstruct{file\_struct}, e perciò sono locali per ciascun processo e non
-vengono modificati dalle azioni degli altri anche in caso di condivisione
-della stessa voce della \itindex{file~table} \textit{file table}.
+file descriptor 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 o lettura da parte di uno dei due processi, la posizione corrente
+nel file varierà per entrambi, in quanto verrà modificato il campo
+\var{f\_pos} della struttura \kstruct{file}, che è la stessa per
+entrambi. Questo consente una sorta di ``\textsl{sincronizzazione}''
+automatica della posizione sul file fra padre e figlio che occorre tenere
+presente.
+
+Si noti inoltre che in questo caso anche i flag di stato del file, essendo
+mantenuti nella struttura \kstruct{file} della \textit{file table}, vengono
+condivisi, per cui una modifica degli stessi con \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl_ioctl}) si applicherebbe a tutti processi che
+condividono la voce nella \textit{file table}. Ai file però sono associati
+anche altri flag, dei quali l'unico usato al momento è \constd{FD\_CLOEXEC},
+detti \itindex{file~descriptor~flags} \textit{file descriptor flags}; questi
+invece sono mantenuti in \kstruct{file\_struct}, e perciò sono locali per
+ciascun processo e non vengono modificati dalle azioni degli altri anche in
+caso di condivisione della stessa voce della \textit{file table}.
Si tenga presente dunque che in un sistema unix-like è sempre possibile per
più processi accedere in contemporanea allo stesso file e che non esistono, a
sezione di file, dato che ciascuno lo farà in maniera indipendente. Il
sistema però fornisce in alcuni casi la possibilità di eseguire alcune
operazioni di scrittura in maniera coordinata anche senza utilizzare dei
-meccanismi di sincronizzazione espliciti come il \itindex{file~locking}
-\textit{file locking}, che esamineremo in sez.~\ref{sec:file_locking}.
+meccanismi di sincronizzazione espliciti come il \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
Il problema deriva dal fatto che usare due \textit{system call} in successione
non è mai un'operazione atomica dato che il kernel può interrompere
l'esecuzione del processo fra le due. Nel caso specifico il problema è stato
-risolto introducendo la modalità di scrittura \itindex{append~mode} in
-\textit{append}, attivabile con il flag \const{O\_APPEND}. In questo caso
-infatti, come abbiamo illustrato in sez.~\ref{sec:file_open_close}, è 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 \textit{system call}, la \func{write}, che non
-essendo interrompibile da un altro processo realizza un'operazione atomica.
+risolto introducendo la modalità di scrittura in \textit{append}, attivabile
+con il flag \const{O\_APPEND}. In questo caso infatti, come abbiamo illustrato
+in sez.~\ref{sec:file_open_close}, è 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 \textit{system
+ call}, la \func{write}, che non essendo interrompibile da un altro processo
+realizza un'operazione atomica.
\subsection{La duplicazione dei file descriptor}
\end{figure}
Si noti che per quanto illustrato in fig.~\ref{fig:file_dup} i file descriptor
-duplicati condivideranno eventuali lock (vedi sez.~\ref{sec:file_locking}),
-\itindex{file~status~flag} i flag di stato, e la posizione corrente sul
-file. 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.
+duplicati condivideranno eventuali lock (vedi sez.~\ref{sec:file_locking}), i
+flag di stato, e la posizione corrente sul file. 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à un
suo \textit{file descriptor flag} indipendente. A questo proposito deve essere
L'uso principale di questa funzione è nella shell per la redirezione dei file
standard di tab.~\ref{tab:file_std_files} fra l'esecuzione di una \func{fork}
e la successiva \func{exec}. Diventa così possibile associare un file (o una
-\textit{pipe}) allo \itindex{standard~input} \textit{standard input} o allo
-\itindex{standard~output} \textit{standard output} (vedremo un esempio in
-sez.~\ref{sec:ipc_pipe_use}, quando tratteremo le \textit{pipe}).
+\textit{pipe}) allo \textit{standard input} o allo \textit{standard output}
+(vedremo un esempio in sez.~\ref{sec:ipc_pipe_use}, quando tratteremo le
+\textit{pipe}).
Ci si può chiedere perché non sia in questo caso sufficiente chiudere il file
standard che si vuole redirigere e poi aprire direttamente con \func{open} il
file vi si vuole far corrispondere, invece di duplicare un file descriptor che
si è già aperto. La risposta sta nel fatto che il file che si vuole redirigere
non è detto sia un file regolare, ma potrebbe essere, come accennato, anche
-una fifo o un socket, oppure potrebbe essere un file associato ad un file
+una \textit{fifo} o un socket, oppure potrebbe essere un file associato ad un file
descriptor che si è ereditato già aperto (ad esempio attraverso un'altra
\func{exec}) da un processo antenato del padre, del quale non si conosce il
nome. Operando direttamente con i file descriptor \func{dup} consente di
kernel queste operazioni vengono gestite direttamente dal sistema della
memoria virtuale, attraverso opportuni \textit{task} interni al kernel il cui
comportamento può essere controllato attraverso il file
-\sysctlfile{vm/bdflush}.\footnote{per il significato dei valori che si possono
+\sysctlfiled{vm/bdflush}.\footnote{per il significato dei valori che si possono
scrivere in questo file si consulti la documentazione allegata ai sorgenti
del kernel nel file \file{Documentation/sysctl/vm.txt}, trattandosi di
argomenti di natura sistemistica non li prenderemo in esame.} Si tenga
file specificato, ed attendono fino alla conclusione delle operazioni. La
prima, \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'\textit{inode} che si leggono
-con \func{fstat}, come i tempi del file. Se lo scopo dell'operazione, come
-avviene spesso per i database, è assicurarsi che i dati raggiungano il disco e
-siano rileggibili immediatamente in maniera corretta, è sufficiente l'uso di
-\func{fdatasync} che non comporta anche l'esecuzione di operazioni non
-necessarie all'integrità dei dati, come l'aggiornamento dei tempi di ultima
-modifica ed ultimo accesso.
+gli altri dati contenuti nell'\textit{inode} che si leggono con \func{fstat},
+come i tempi del file. Se lo scopo dell'operazione, come avviene spesso per i
+database, è assicurarsi che i dati raggiungano il disco e siano rileggibili
+immediatamente in maniera corretta, è sufficiente l'uso di \func{fdatasync}
+che non comporta anche l'esecuzione di operazioni non necessarie all'integrità
+dei dati, come l'aggiornamento dei tempi di ultima modifica ed ultimo accesso.
Si tenga presente che l'uso di queste funzioni non comporta la
sincronizzazione della directory che contiene il file e la scrittura della
sarà la base della risoluzione dei \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. In questo modo, anche quando si lavora con i \itindex{thread}
-\textit{thread}, si può mantenere una directory di lavoro diversa per ciascuno
-di essi.
+la risoluzione. In questo modo, anche quando si lavora con i \textit{thread},
+si può mantenere una directory di lavoro diversa per ciascuno di essi.
Questo metodo, oltre a risolvere i problemi di \textit{race condition},
consente anche di ottenere aumenti di prestazioni significativi quando si
argomenti si utilizza un \textit{pathname} relativo questo sarà risolto
rispetto alla directory indicata da \param{dirfd}. Qualora invece si usi un
\textit{pathname} assoluto \param{dirfd} verrà semplicemente ignorato. Infine
-se per \param{dirfd} si usa il valore speciale \const{AT\_FDCWD}, la
+se per \param{dirfd} si usa il valore speciale \constd{AT\_FDCWD}, la
risoluzione sarà effettuata rispetto alla directory di lavoro corrente del
processo. Si tenga presente però che questa, come le altre costanti
\texttt{AT\_*}, è definita in \headfile{fcntl.h}, pertanto se la si vuole
\textbf{Costante} & \textbf{Significato} \\
\hline
\hline
- \const{AT\_SYMLINK\_NOFOLLOW}& Se impostato la funzione non esegue la
- dereferenziazione dei collegamenti simbolici.\\
- \const{AT\_SYMLINK\_FOLLOW}& Se impostato la funzione esegue la
- dereferenziazione dei collegamenti simbolici
- (usato esplicitamente solo da \func{linkat}).\\
- \const{AT\_EACCES} & Usato solo da \func{faccessat}, richiede che
- il controllo dei permessi sia fatto usando
- l'\ids{UID} effettivo invece di quello
- reale.\\
- \const{AT\_REMOVEDIR} & Usato solo da \func{unlinkat}, richiede che
- la funzione si comporti come \func{rmdir}
- invece che come \func{unlink}.\\
+ \constd{AT\_SYMLINK\_NOFOLLOW}& Se impostato la funzione non esegue la
+ dereferenziazione dei collegamenti
+ simbolici.\\
+ \constd{AT\_SYMLINK\_FOLLOW}& Se impostato la funzione esegue la
+ dereferenziazione dei collegamenti simbolici
+ (usato esplicitamente solo da
+ \func{linkat}).\\
+ \constd{AT\_EACCES} & Usato solo da \func{faccessat}, richiede che
+ il controllo dei permessi sia fatto usando
+ l'\ids{UID} effettivo invece di quello
+ reale.\\
+ \constd{AT\_REMOVEDIR} & Usato solo da \func{unlinkat}, richiede che
+ la funzione si comporti come \func{rmdir}
+ invece che come \func{unlink}.\\
\hline
\end{tabular}
\caption{Le costanti utilizzate per i bit dell'argomento
Un'ultima differenza fra le \textit{at-functions} e le funzioni tradizionali
di cui sono estensione è, come accennato in sez.~\ref{sec:file_temp_file},
-quella relativa a \funcm{utimensat} che non è propriamente una corrispondente
+quella relativa a \func{utimensat} che non è propriamente una corrispondente
esatta di \func{utimes} e \func{lutimes}, dato che questa funzione ha una
maggiore precisione nella indicazione dei tempi dei file, per i quali come per
\func{futimes}, si devono usare strutture \struct{timespec} che consentono una
caratteristiche di un file descriptor, viene usata la funzione di sistema
\funcd{fcntl},\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}).} il cui prototipo è:
+ il \textit{file locking} (vedi sez.~\ref{sec:file_locking}).} il cui
+prototipo è:
\begin{funcproto}{
\fhead{unistd.h}
errore restituiti e del tipo del terzo argomento (cui faremo riferimento con
il nome indicato nel precedente prototipo), è riportata di seguito:
\begin{basedescript}{\desclabelwidth{1.8cm}}
-\item[\const{F\_DUPFD}] trova il primo file descriptor disponibile di valore
+\item[\constd{F\_DUPFD}] trova il primo file descriptor disponibile di valore
maggiore o uguale ad \param{arg}, e ne fa un duplicato
di \param{fd}, ritorna il nuovo file descriptor in caso di successo e $-1$
in caso di errore. Oltre a \errval{EBADF} gli errori possibili sono
\itindbeg{close-on-exec}
-\item[\const{F\_DUPFD\_CLOEXEC}] ha lo stesso effetto di \const{F\_DUPFD}, ma
+\item[\constd{F\_DUPFD\_CLOEXEC}] ha lo stesso effetto di \const{F\_DUPFD}, ma
in più attiva il flag di \textit{close-on-exec} sul file descriptor
duplicato, in modo da evitare una successiva chiamata con
\const{F\_SETFD}. La funzionalità è stata introdotta con il kernel 2.6.24 ed
\macro{\_POSIX\_C\_SOURCE} ad un valore adeguato secondo quanto visto in
sez.~\ref{sec:intro_gcc_glibc_std}).
-\item[\const{F\_GETFD}] restituisce il valore dei \textit{file descriptor
+\item[\constd{F\_GETFD}] restituisce il valore dei \textit{file descriptor
flags} di \param{fd} in caso di successo o $-1$ in caso di errore, il
terzo argomento viene ignorato. Non sono previsti errori diversi da
\errval{EBADF}. Al momento l'unico flag usato è quello di
\func{exec} (vedi sez.~\ref{sec:proc_exec}). Un valore nullo significa
pertanto che il flag non è impostato.
-\item[\const{F\_SETFD}] imposta il valore dei \textit{file descriptor flags}
+\item[\constd{F\_SETFD}] imposta il valore dei \textit{file descriptor flags}
al valore specificato con \param{arg}, ritorna un valore nullo in caso di
successo e $-1$ in caso di errore. Non sono previsti errori diversi da
\errval{EBADF}. Dato che l'unico flag attualmente usato è quello di
\texttt{fs/fcntl.c} dei sorgenti del kernel.}
\itindend{close-on-exec}
-\item[\const{F\_GETFL}] ritorna il valore dei \textit{file status flags} di
+\item[\constd{F\_GETFL}] ritorna il valore dei \textit{file status flags} di
\param{fd} in caso di successo o $-1$ in caso di errore, il terzo argomento
viene ignorato. Non sono previsti errori diversi da \errval{EBADF}. Il
comando permette di rileggere il valore di quei bit
flag} con la maschera \const{O\_ACCMODE} come già accennato in
sez.~\ref{sec:file_open_close}.
-\item[\const{F\_SETFL}] imposta il valore dei \textit{file status flags} al
+\item[\constd{F\_SETFL}] imposta il valore dei \textit{file status flags} al
valore specificato da \param{arg}, ritorna un valore nullo in caso di
successo o $-1$ in caso di errore. In generale possono essere impostati solo
i flag riportati in tab.~\ref{tab:open_operation_flag}, su Linux si possono
permessi di amministratore) ed \errcode{EINVAL} se si cerca di impostare
\const{O\_DIRECT} su un file che non supporta questo tipo di operazioni.
-\item[\const{F\_GETLK}] richiede un controllo sul file lock specificato da
+\item[\constd{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. Come
per i due successivi comandi oltre a \errval{EBADF} se \param{lock} non è un
puntatore valido restituisce l'errore generico \errcode{EFAULT}. 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
+\item[\constd{F\_SETLK}] richiede o rilascia un file lock a seconda di quanto
specificato nella struttura puntata da \param{lock}, ritorna un valore nullo
in caso di successo e $-1$ se il file lock è tenuto da qualcun altro, nel
qual caso si ha un errore di \errcode{EACCES} o \errcode{EAGAIN}. 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
+\item[\constd{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}. Questa funzionalità è trattata in
dettaglio in sez.~\ref{sec:file_posix_lock}.
-\item[\const{F\_GETOWN}] restituisce in caso di successo l'identificatore del
- processo o del \itindex{process~group} \textit{process group} (vedi
- sez.~\ref{sec:sess_proc_group}) che è preposto alla ricezione del segnale
- \signal{SIGIO} (o l'eventuale segnale alternativo impostato con
- \const{F\_SETSIG}) per gli eventi asincroni associati al file
- descriptor \param{fd} e del segnale \signal{SIGURG} per la notifica dei dati
- urgenti di un socket (vedi sez.~\ref{sec:TCP_urgent_data}). Restituisce $-1$
- in caso di errore ed il terzo argomento viene ignorato. Non sono previsti
- errori diversi da \errval{EBADF}.
+\item[\constd{F\_GETOWN}] restituisce in caso di successo l'identificatore del
+ processo o del \textit{process group} (vedi sez.~\ref{sec:sess_proc_group})
+ che è preposto alla ricezione del segnale \signal{SIGIO} (o l'eventuale
+ segnale alternativo impostato con \const{F\_SETSIG}) per gli eventi
+ asincroni associati al file descriptor \param{fd} e del segnale
+ \signal{SIGURG} per la notifica dei dati urgenti di un socket (vedi
+ sez.~\ref{sec:TCP_urgent_data}). Restituisce $-1$ in caso di errore ed il
+ terzo argomento viene ignorato. Non sono previsti errori diversi da
+ \errval{EBADF}.
Per distinguerlo dal caso in cui il segnale viene inviato a un singolo
processo, 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}. Con Linux questo comporta un
- problema perché se il valore restituito dalla \textit{system call} è
- compreso nell'intervallo fra $-1$ e $-4095$ in alcune architetture questo
- viene trattato dalla \acr{glibc} come un errore,\footnote{il problema deriva
- dalle limitazioni presenti in architetture come quella dei normali PC
- (i386) per via delle modalità in cui viene effettuata l'invocazione delle
- \textit{system call} che non consentono di restituire un adeguato codice
- di ritorno.} per cui in tal caso \func{fcntl} ritornerà comunque $-1$
- mentre il valore restituito dalla \textit{system call} verrà assegnato ad
- \var{errno}, cambiato di segno.
+ \textit{process group}. Con Linux questo comporta un problema perché se il
+ valore restituito dalla \textit{system call} è compreso nell'intervallo fra
+ $-1$ e $-4095$ in alcune architetture questo viene trattato dalla
+ \acr{glibc} come un errore,\footnote{il problema deriva dalle limitazioni
+ presenti in architetture come quella dei normali PC (i386) per via delle
+ modalità in cui viene effettuata l'invocazione delle \textit{system call}
+ che non consentono di restituire un adeguato codice di ritorno.} per cui
+ in tal caso \func{fcntl} ritornerà comunque $-1$ mentre il valore restituito
+ dalla \textit{system call} verrà assegnato ad \var{errno}, cambiato di
+ segno.
Per questo motivo con il kernel 2.6.32 è stato introdotto il comando
alternativo \const{F\_GETOWN\_EX}, che vedremo a breve, che consente di
disponibile, usa questa versione alternativa per mascherare il problema
precedente e restituire un valore corretto in tutti i casi.\footnote{in cui
cioè viene restituito un valore negativo corretto qualunque sia
- l'identificatore del \itindex{process~group} \textit{process group}, che
- non potendo avere valore unitario (non esiste infatti un
- \itindex{process~group} \textit{process group} per \cmd{init}) non può
- generare ambiguità con il codice di errore.} Questo però comporta che il
- comportamento del comando può risultare diverso a seconda delle versioni
+ l'identificatore del \textit{process group}, che non potendo avere valore
+ unitario (non esiste infatti un \textit{process group} per \cmd{init}) non
+ può generare ambiguità con il codice di errore.} Questo però comporta che
+ il comportamento del comando può risultare diverso a seconda delle versioni
della \acr{glibc} e del kernel.
-\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. Oltre a \errval{EBADF} gli errori
- possibili sono \errcode{ESRCH} se \param{arg} indica un processo o un
- \itindex{process~group} \textit{process group} inesistente.
+\item[\constd{F\_SETOWN}] imposta, con il valore dell'argomento \param{arg},
+ l'identificatore del processo o del \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. Oltre a \errval{EBADF} gli errori possibili sono
+ \errcode{ESRCH} se \param{arg} indica un processo o un \textit{process
+ group} inesistente.
L'impostazione è soggetta alle stesse restrizioni presenti sulla funzione
\func{kill} (vedi sez.~\ref{sec:sig_kill_raise}), per cui un utente non
privilegiato può inviare i segnali solo ad un processo che gli appartiene,
in genere comunque si usa il processo corrente. Come per \const{F\_GETOWN},
- per indicare un \itindex{process~group} \textit{process group} si deve usare
- per \param{arg} un valore negativo, il cui valore assoluto corrisponda
- all'identificatore del \itindex{process~group} \textit{process group}.
+ per indicare un \textit{process group} si deve usare per \param{arg} un
+ valore negativo, il cui valore assoluto corrisponda all'identificatore del
+ \textit{process group}.
A partire dal kernel 2.6.12 se si sta operando con i \textit{thread} della
implementazione nativa di Linux (quella della NTPL, vedi
caso è anche l'unico, mantiene un valore del \textit{Thread ID} uguale al
\ids{PID} del processo. Il problema è però che questo comportamento non si
applica a \signal{SIGURG}, per il quale \param{arg} viene sempre
- interpretato come l'identificatore di un processo o di un
- \itindex{process~group} \textit{process group}.
-
-\item[\const{F\_GETOWN\_EX}] legge nella struttura puntata
- dall'argomento \param{owner} l'identificatore del processo, \textit{thread} o
- \itindex{process~group} \textit{process group} (vedi
- sez.~\ref{sec:sess_proc_group}) che è preposto alla ricezione dei 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. Oltre a \errval{EBADF} e da
- \errval{EFAULT} se \param{owner} non è un puntatore valido.
+ interpretato come l'identificatore di un processo o di un \textit{process
+ group}.
+
+\item[\constd{F\_GETOWN\_EX}] legge nella struttura puntata
+ dall'argomento \param{owner} l'identificatore del processo, \textit{thread}
+ o \textit{process group} (vedi sez.~\ref{sec:sess_proc_group}) che è
+ preposto alla ricezione dei 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. Oltre a \errval{EBADF} e da
+ \errval{EFAULT} se \param{owner} non è un puntatore valido.
Il comando, che è disponibile solo a partire dal kernel 2.6.32, effettua lo
stesso compito di \const{F\_GETOWN} di cui costituisce una evoluzione che
di \const{F\_GETOWN}. Il comando è specifico di Linux ed utilizzabile solo
se si è definita la macro \macro{\_GNU\_SOURCE}.
-\item[\const{F\_SETOWN\_EX}] imposta con il valore della struttura
+\item[\constd{F\_SETOWN\_EX}] imposta con il valore della struttura
\struct{f\_owner\_ex} puntata \param{owner}, 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
+ del \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, con gli stessi errori di \const{F\_SETOWN} più
\errcode{EINVAL} se il campo \var{type} di \struct{f\_owner\_ex} non indica
riportata in fig.~\ref{fig:f_owner_ex}, in cui il primo campo indica il tipo
di identificatore il cui valore è specificato nel secondo campo, che assume
lo stesso significato di \param{arg} per \const{F\_SETOWN}. Per il campo
- \var{type} i soli valori validi sono \const{F\_OWNER\_TID},
- \const{F\_OWNER\_PID} e \const{F\_OWNER\_PGRP}, che indicano rispettivamente
- che si intende specificare con \var{pid} un \textit{Tread ID}, un
- \textit{Process ID} o un \textit{Process Group ID}. A differenza di
- \const{F\_SETOWN} se si specifica un \textit{Tread ID} questo riceverà sia
- \signal{SIGIO} (o il segnale impostato con \const{F\_SETSIG}) che
+ \var{type} i soli valori validi sono \constd{F\_OWNER\_TID},
+ \constd{F\_OWNER\_PID} e \constd{F\_OWNER\_PGRP}, che indicano
+ rispettivamente che si intende specificare con \var{pid} un \textit{Tread
+ ID}, un \textit{Process ID} o un \textit{Process Group ID}. A differenza
+ di \const{F\_SETOWN} se si specifica un \textit{Tread ID} questo riceverà
+ sia \signal{SIGIO} (o il segnale impostato con \const{F\_SETSIG}) che
\signal{SIGURG}. Il comando è specifico di Linux, è disponibile solo a
partire dal kernel 2.6.32, ed è utilizzabile solo se si è definita la macro
\macro{\_GNU\_SOURCE}.
-\item[\const{F\_GETSIG}] restituisce il valore del segnale inviato dai vari
+\item[\constd{F\_GETSIG}] restituisce il valore del segnale inviato dai vari
meccanismi di I/O asincrono associati al file descriptor \param{fd} (quelli
trattati in sez.~\ref{sec:file_asyncronous_operation}) in caso di successo o
$-1$ in caso di errore, il terzo argomento viene ignorato. Non sono previsti
essere anche lo stesso \signal{SIGIO}. Il comando è specifico di Linux ed
utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
-\item[\const{F\_SETSIG}] imposta il segnale inviato dai vari meccanismi di I/O
- asincrono associati al file descriptor \param{fd} (quelli trattati in
+\item[\constd{F\_SETSIG}] imposta il segnale inviato dai vari meccanismi di
+ I/O asincrono associati al file descriptor \param{fd} (quelli trattati in
sez.~\ref{sec:file_asyncronous_operation}) al valore indicato
da \param{arg}, ritorna un valore nullo in caso di successo o $-1$ in caso
di errore. Oltre a \errval{EBADF} gli errori possibili sono
sez.~\ref{sec:sig_real_time}), ed in particolare la capacità di essere
accumulati in una coda prima della notifica.
-\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, il terzo argomento viene
- ignorato. Non sono previsti errori diversi da \errval{EBADF}. Il comando è
- specifico di Linux ed utilizzabile solo se si è definita la macro
- \macro{\_GNU\_SOURCE}. Questa funzionalità è trattata in dettaglio in
- sez.~\ref{sec:file_asyncronous_lease}.
-
-\item[\const{F\_SETLEASE}] imposta o rimuove a seconda del valore
- di \param{arg} un \itindex{file~lease} \textit{file lease} sul file
- descriptor \var{fd} a seconda del valore indicato da \param{arg}. Ritorna un
- valore nullo in caso di successo o $-1$ in caso di errore. Oltre a
- \errval{EBADF} si otterrà \errcode{EINVAL} se si è specificato un valore non
- valido per \param{arg} (deve essere usato uno dei valori di
- tab.~\ref{tab:file_lease_fctnl}), \errcode{ENOMEM} se non c'è memoria
- sufficiente per creare il \textit{file lease}, \errcode{EACCES} se non si è
- il proprietario del file e non si hanno i privilegi di
- amministratore.\footnote{per la precisione occorre la capacità
- \const{CAP\_LEASE}.}
+\item[\constd{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, il terzo argomento viene ignorato. Non sono previsti errori
+ diversi da \errval{EBADF}. Il comando è specifico di Linux ed utilizzabile
+ solo se si è definita la macro \macro{\_GNU\_SOURCE}. Questa funzionalità è
+ trattata in dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
+
+\item[\constd{F\_SETLEASE}] imposta o rimuove a seconda del valore
+ di \param{arg} un \textit{file lease} sul file descriptor \var{fd} a seconda
+ del valore indicato da \param{arg}. Ritorna un valore nullo in caso di
+ successo o $-1$ in caso di errore. Oltre a \errval{EBADF} si otterrà
+ \errcode{EINVAL} se si è specificato un valore non valido per \param{arg}
+ (deve essere usato uno dei valori di tab.~\ref{tab:file_lease_fctnl}),
+ \errcode{ENOMEM} se non c'è memoria sufficiente per creare il \textit{file
+ lease}, \errcode{EACCES} se non si è il proprietario del file e non si
+ hanno i privilegi di amministratore.\footnote{per la precisione occorre la
+ capacità \const{CAP\_LEASE}.}
Il supporto il supporto per i \textit{file lease}, che consente ad un
processo che detiene un \textit{lease} su un file di riceve una notifica
definita la macro \macro{\_GNU\_SOURCE}. Questa funzionalità è trattata in
dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
-\item[\const{F\_NOTIFY}] attiva il meccanismo di notifica asincrona per cui
+\item[\constd{F\_NOTIFY}] attiva il meccanismo di notifica asincrona per cui
viene riportato 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
dai kernel della serie 2.4.x, è trattata in dettaglio in
sez.~\ref{sec:file_asyncronous_lease}.
-\item[\const{F\_GETPIPE\_SZ}] restituisce in caso di successo la dimensione
+\item[\constd{F\_GETPIPE\_SZ}] restituisce in caso di successo la dimensione
del buffer associato alla \textit{pipe} \param{fd} (vedi
sez.~\ref{sec:ipc_pipes}) o $-1$ in caso di errore, il terzo argomento viene
ignorato. Non sono previsti errori diversi da \errval{EBADF}, che viene
specifico di Linux, è disponibile solo a partire dal kernel 2.6.35, ed è
utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
-\item[\const{F\_SETPIPE\_SZ}] imposta la dimensione del buffer associato alla
+\item[\constd{F\_SETPIPE\_SZ}] imposta la dimensione del buffer associato alla
\textit{pipe} \param{fd} (vedi sez.~\ref{sec:ipc_unix}) ad un valore uguale
o superiore a quello indicato dall'argomento \param{arg}. Ritorna un valore
nullo in caso di successo o $-1$ in caso di errore. Oltre a \errval{EBADF}
\const{F\_GETPIPE\_SZ}. I processi non privilegiati\footnote{per la
precisione occorre la capacità \const{CAP\_SYS\_RESOURCE}.} non possono
impostare un valore valore superiore a quello indicato da
- \sysctlfile{fs/pipe-size-max}. Il comando è specifico di Linux, è
+ \sysctlfiled{fs/pipe-size-max}. Il comando è specifico di Linux, è
disponibile solo a partire dal kernel 2.6.35, ed è utilizzabile solo se si è
definita la macro \macro{\_GNU\_SOURCE}.
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_operation} 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}.
+\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}.
La gran parte dei comandi di \func{fcntl} (\const{F\_DUPFD}, \const{F\_GETFD},
\const{F\_SETFD}, \const{F\_GETFL}, \const{F\_SETFL}, \const{F\_GETLK},
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
+file \headfiled{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
prime, per cui, come illustrato in \cite{LinDevDri}, eventuali operazioni
specifiche che usino lo stesso valore verrebbero ignorate:
\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\const{FIOCLEX}] imposta il flag di \textit{close-on-exec} sul file, in
+\item[\constd{FIOCLEX}] imposta il flag di \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 \textit{close-on-exec} sul file,
+\item[\constd{FIONCLEX}] cancella il flag di \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
+\item[\constd{FIOASYNC}] abilita o disabilita la modalità di I/O asincrono sul
file (vedi sez.~\ref{sec:signal_driven_io}); 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
+\item[\constd{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
+\item[\constd{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
+\item[\constd{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
+\item[\constd{FIONREAD}] legge il numero di byte disponibili in lettura sul
file descriptor; 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
+\item[\constd{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.
% TODO trovare qualche posto per la eventuale documentazione delle seguenti
% (bassa/bassissima priorità)
% EXT4_IOC_MOVE_EXT (dal 2.6.31)
+% EXT4_IOC_SHUTDOWN (dal 4.10), XFS_IOC_GOINGDOWN e futura FS_IOC_SHUTDOWN
% ioctl di btrfs, vedi http://lwn.net/Articles/580732/
% \chapter{}
concorrente ed in sez.~\ref{sec:file_access_control} per il controllo di
accesso.
-\itindend{file~stream}
-
Per ragioni storiche la struttura di dati che rappresenta uno \textit{stream}
-è stata chiamata \type{FILE}, questi oggetti sono creati dalle funzioni di
+è stata chiamata \typed{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}.
+queste strutture (che sono dei \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}.
+
+\itindend{file~stream}
Ai tre file descriptor standard (vedi tab.~\ref{tab:file_std_files}) aperti
per ogni processo, corrispondono altrettanti \textit{stream}, che
nell'header \headfile{stdio.h} che sono:
\begin{basedescript}{\desclabelwidth{3.0cm}}
-\item[\var{FILE *stdin}] Lo \itindex{standard~input} \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
+\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 \itindex{standard~output} \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} \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.
+\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
trasmessi da e verso il file in blocchi di dimensione opportuna.
\end{itemize}
-Lo standard ANSI C specifica inoltre che lo \itindex{standard~output}
-\textit{standard output} e lo \itindex{standard~input} \textit{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}.
+Lo standard ANSI C specifica inoltre che lo \textit{standard output} e lo
+\textit{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 \itindex{standard~input} \textit{standard input}
-e \itindex{standard~output} \textit{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.
+rapidamente possibile, e che \textit{standard input} \textit{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 \itindex{standard~input} \textit{standard
- input} e \itindex{standard~output} \textit{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.
+Il comportamento specificato per \textit{standard input} e \textit{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à
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
+usare gli \textit{stream} con file come le \textit{fifo} o i socket, che non possono
essere aperti con le funzioni delle librerie standard del C.
\begin{table}[htb]
% \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
+ scrittura, lo \textit{stream} è 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
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.\\
+ \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.\\
+ \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à. \\
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 della \itindex{umask} \textit{umask}
-per il processo (si veda sez.~\ref{sec:file_perm_management}). 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.
+\val{0666}) modificato secondo il valore della \textit{umask} per il processo
+(si veda sez.~\ref{sec:file_perm_management}). 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.
In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
di mezzo una bufferizzazione; per questo motivo lo standard ANSI C
punto prestabilito, sempre che l'operazione di riposizionamento sia supportata
dal file sottostante lo \textit{stream}, nel caso cioè in cui si ha a che fare
con quello che viene detto un file ad \textsl{accesso casuale}. Dato che in un
-sistema Unix esistono vari tipi di file, come le fifo ed i file di dispositivo
-(ad esempio i terminali), non è scontato che questo sia vero in generale, pur
-essendolo sempre nel caso di file di dati.
+sistema Unix esistono vari tipi di file, come le \textit{fifo} ed i file di
+dispositivo (ad esempio i terminali), non è scontato che questo sia vero in
+generale, pur essendolo sempre nel caso di file di dati.
Con Linux ed in generale in ogni sistema unix-like la posizione nel file, come
abbiamo già visto in sez.~\ref{sec:file_lseek}, è espressa da un intero
un filesystem indicizzato a 64 bit su una macchina con architettura a 32 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:
+\typed{fpos\_t}, ed i cui prototipi sono:
\begin{funcproto}{
\fhead{stdio.h}
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
+implicito dello \textit{stream}, usato per dalla librerie per la gestione
+delle applicazioni \textit{multi-thread} (si veda
sez.~\ref{sec:file_stream_thread} per i dettagli), i loro prototipi sono:
\begin{funcproto}{
\fdecl{int fgetc(FILE *stream)}
\fdesc{Leggono un singolo byte da uno \textit{stream}.}
\fdecl{int getchar(void)}
-\fdesc{Legge un byte dallo \itindex{standard~input} \textit{standard input}.}
+\fdesc{Legge un byte dallo \textit{standard input}.}
}
{Le funzioni ritornano il byte letto in caso di successo e \val{EOF} per un
\fdecl{wint\_t fgetwc(FILE *stream)}
\fdesc{Leggono un carattere da uno \textit{stream}.}
\fdecl{wint\_t getwchar(void)}
-\fdesc{Legge un carattere dallo \itindex{standard~input} \textit{standard
- input}.}
+\fdesc{Legge un carattere dallo \textit{standard input}.}
}
{Le funzioni ritornano il carattere letto in caso di successo e \val{WEOF} per
\fdecl{int fputc(int c, FILE *stream)}
\fdesc{Scrive un byte su uno \textit{stream}.}
\fdecl{int putchar(int c)}
-\fdesc{Scrive un byte sullo \itindex{standard~output} \textit{standard
- output}.}
+\fdesc{Scrive un byte sullo \textit{standard output}.}
}
{Le funzioni ritornano il valore del byte scritto in caso di successo e
\begin{funcproto}{
\fhead{stdio.h}
\fdecl{char *gets(char *string)}
-\fdesc{Legge una linea di testo dallo \itindex{standard~input}
- \textit{standard input}.}
+\fdesc{Legge una linea di testo dallo \textit{standard input}.}
\fdecl{char *fgets(char *string, int size, FILE *stream)}
\fdesc{Legge una linea di testo da uno \textit{stream}.}
}
\end{funcproto}
Entrambe le funzioni effettuano la lettura, dal file specificato \func{fgets},
-dallo \itindex{standard~input} \textit{standard input} \func{gets}, di una
-linea di caratteri terminata dal carattere ASCII di \textit{newline}, che come
-detto corrisponde a quello generato dalla pressione del tasto di invio sulla
-tastiera. Si tratta del carattere che indica la terminazione di una riga (in
-sostanza del carattere di ``\textsl{a capo}'') che viene rappresentato nelle
-stringhe di formattazione che vedremo in sez.~\ref{sec:file_formatted_io} come
+dallo \textit{standard input} \func{gets}, di una linea di caratteri terminata
+dal carattere ASCII di \textit{newline}, che come detto corrisponde a quello
+generato dalla pressione del tasto di invio sulla tastiera. Si tratta del
+carattere che indica la terminazione di una riga (in sostanza del carattere di
+``\textsl{a capo}'') che viene rappresentato nelle stringhe di formattazione
+che vedremo in sez.~\ref{sec:file_formatted_io} come
``\verb|\n|''. Nell'esecuzione delle funzioni \func{gets} sostituisce
``\verb|\n|'' con uno zero, mentre \func{fgets} aggiunge uno zero dopo il
\textit{newline}, che resta dentro la stringa.
+\itindbeg{buffer~overflow}
+
Se la lettura incontra la fine del file (o c'è un errore) viene restituito un
puntatore \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}.}
+letta superi le dimensioni del buffer, si avrà un \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
uno \textit{shell code}, cioè una sezione di programma che lancia una shell da
cui si potranno poi eseguire altri programmi.
+\itindend{buffer~overflow}
+
La funzione \func{fgets} non ha i precedenti problemi di \func{gets} in quanto
prende in ingresso la dimensione del buffer \param{size}, che non verrà mai
ecceduta in lettura. La funzione legge fino ad un massimo di \param{size}
\begin{funcproto}{
\fhead{stdio.h}
\fdecl{int puts(char *string)}
-\fdesc{Scrive una linea di testo sullo \itindex{standard~output}
- \textit{standard output}.}
+\fdesc{Scrive una linea di testo sullo \textit{standard output}.}
\fdecl{int fputs(char *string, int size, FILE *stream)}
\fdesc{Scrive una linea di testo su uno \textit{stream}.}
}
\end{funcproto}
La funzione \func{puts} scrive una linea di testo mantenuta
-all'indirizzo \param{string} sullo \itindex{standard~output} \textit{standard
- output} mentre \func{puts} la scrive sul file indicato da \param{stream}.
-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 \itindex{standard~output} \textit{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 \textit{newline}, che deve essere previsto esplicitamente.
+all'indirizzo \param{string} sullo \textit{standard output} mentre \func{puts}
+la scrive sul file indicato da \param{stream}. 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 \textit{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 \textit{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
\begin{funcproto}{
\fhead{stdio.h}
\fdecl{int printf(const char *format, ...)}
-\fdesc{Scrive una stringa formattata sullo \itindex{standard~output}
- \textit{standard output}.}
+\fdesc{Scrive una stringa formattata sullo \textit{standard output}.}
\fdecl{int fprintf(FILE *stream, const char *format, ...)}
\fdesc{Scrive una stringa formattata su uno \textit{stream}.}
\fdecl{int sprintf(char *str, const char *format, ...)}
cui dovrà essere scritto il contenuto degli argomenti, il cui numero è
variabile e dipende dal formato stesso.
-Le prime due servono per scrivere su file (lo \itindex{standard~output}
-\textit{standard output} o quello specificato) la terza permette di scrivere
-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 \textit{buffer overflow}. Per
-questo motivo si consiglia l'uso dell'alternativa \funcd{snprintf}, il cui
-prototipo è:
+Le prime due servono per scrivere su file (lo \textit{standard output} o
+quello specificato) la terza permette di scrivere 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 \textit{buffer overflow}. Per questo motivo si consiglia l'uso
+dell'alternativa \funcd{snprintf}, il cui prototipo è:
\begin{funcproto}{
\fhead{stdio.h}
\begin{funcproto}{
\fhead{stdio.h}
\fdecl{int vprintf(const char *format, va\_list ap)}
-\fdesc{Scrive una stringa formattata sullo \itindex{standard~output}
- \textit{standard output}.}
+\fdesc{Scrive una stringa formattata sullo \textit{standard output}.}
\fdecl{int vfprintf(FILE *stream, const char *format, va\_list ap)}
\fdesc{Scrive una stringa formattata su uno \textit{stream}.}
\fdecl{int vsprintf(char *str, const char *format, va\_list ap)}
\begin{funcproto}{
\fhead{stdio.h}
\fdecl{int scanf(const char *format, ...)}
-\fdesc{Esegue la scansione di dati dallo \itindex{standard~input}
- \textit{standard input}.}
+\fdesc{Esegue la scansione di dati dallo \textit{standard input}.}
\fdecl{int fscanf(FILE *stream, const char *format, ...)}
\fdesc{Esegue la scansione di dati da uno \textit{stream}. }
\fdecl{int sscanf(char *str, const char *format, ...)}
eseguire operazioni di basso livello nella gestione degli \textit{stream},
come leggerne gli attributi, controllarne le modalità di bufferizzazione,
gestire in maniera esplicita i lock impliciti presenti ad uso della
-programmazione \itindex{thread} \textit{multi-thread}.
+programmazione \textit{multi-thread}.
\subsection{Le funzioni di controllo}
\textbf{Valore} & \textbf{Modalità} \\
\hline
\hline
- \const{\_IONBF} & \textit{unbuffered}\\
- \const{\_IOLBF} & \textit{line buffered}\\
- \const{\_IOFBF} & \textit{fully buffered}\\
+ \constd{\_IONBF} & \textit{unbuffered}\\
+ \constd{\_IOLBF} & \textit{line buffered}\\
+ \constd{\_IOFBF} & \textit{fully buffered}\\
\hline
\end{tabular}
\caption{Valori dell'argomento \param{mode} di \func{setvbuf}
\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 variabile automatica. In
-\headfile{stdio.h} è definita la macro \const{BUFSIZ}, che indica le
+\headfile{stdio.h} è definita la costante \constd{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
\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
\textit{stream} atomicamente. Per questo motivo le librerie provvedono anche
le funzioni \funcd{flockfile} 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:
+\macrod{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro prototipi sono:
\begin{funcproto}{
\fhead{stdio.h}
\textbf{Valore} & \textbf{Significato} \\
\hline
\hline
- \const{FSETLOCKING\_INTERNAL}& Lo \textit{stream} userà da ora in poi il
- blocco implicito predefinito.\\
- \const{FSETLOCKING\_BYCALLER}& Al ritorno della funzione sarà l'utente a
- dover gestire da solo il locking dello
- \textit{stream}.\\
- \const{FSETLOCKING\_QUERY} & Restituisce lo stato corrente della
- modalità di blocco dello
- \textit{stream}.\\
+ \constd{FSETLOCKING\_INTERNAL}& Lo \textit{stream} userà da ora in poi il
+ blocco implicito predefinito.\\
+ \constd{FSETLOCKING\_BYCALLER}& Al ritorno della funzione sarà l'utente a
+ dover gestire da solo il locking dello
+ \textit{stream}.\\
+ \constd{FSETLOCKING\_QUERY} & Restituisce lo stato corrente della
+ modalità di blocco dello
+ \textit{stream}.\\
\hline
\end{tabular}
\caption{Valori dell'argomento \param{type} di \func{\_\_fsetlocking}
% TODO trattare \func{clearerr\_unlocked}
-\itindend{thread}
-
%%% Local Variables: