%% fileio.tex (merge fileunix.tex - filestd.tex)
%%
-%% Copyright (C) 2000-2015 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2018 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}
\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}
\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}
\textbf{File} & \textbf{Significato} \\
\hline
\hline
- \const{STDIN\_FILENO} & \textit{file descriptor} dello \textit{standard
- input}.\\
- \const{STDOUT\_FILENO} & \textit{file descriptor} dello \textit{standard
- output}.\\
- \const{STDERR\_FILENO} & \textit{file descriptor} dello \textit{standard
- error}.\\
+ \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.}
analoga di quella delle voci di una directory, con la possibilità di avere più
voci che fanno riferimento allo stesso \textit{inode}. L'analogia è in realtà
molto stretta perché quando si cancella un file, il kernel verifica anche che
-non resti nessun riferimento in una una qualunque voce della \textit{file
- table} prima di liberare le risorse ad esso associate e disallocare il
-relativo \textit{inode}.
+non resti nessun riferimento in una qualunque voce della \textit{file table}
+prima di liberare le risorse ad esso associate e disallocare il relativo
+\textit{inode}.
Nelle vecchie versioni di Unix (ed anche in Linux fino al kernel 2.0.x) il
numero di file aperti era anche soggetto ad un limite massimo dato dalle
\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
\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
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 \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
+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 \const{O\_EXEC} che permetterebbe l'apertura
+ 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.}
\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 \textit{append mode}. La
+ \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
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\_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
- 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
- \textit{race condition} che si potrebbe verificare
- con i \textit{thread} fra l'apertura del file e
- 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\_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
+ \textit{race condition} che si potrebbe verificare
+ con i \textit{thread} fra l'apertura del file e
+ l'impostazione della suddetta modalità con
+ \func{fcntl} (vedi
+ sez.~\ref{sec:file_fcntl_ioctl}).\\
+ \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
conseguente effetto sulle caratteristiche operative che controllano (torneremo
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
+Il flag \const{O\_ASYNC} (che, per compatibilità con BSD, si può indicare
+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
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
la dimensione di un file sarà più o meno corrispondente alla quantità di
spazio disco da esso occupato, ma esistono dei casi, come questo in cui ci si
sposta in una posizione oltre la fine corrente del file, o come quello
-accennato in in sez.~\ref{sec:file_file_size} in cui si estende la dimensione
-di un file con una \func{truncate}, in cui in sostanza si modifica il valore
+accennato in sez.~\ref{sec:file_file_size} in cui si estende la dimensione di
+un file con una \func{truncate}, in cui in sostanza si modifica il valore
della dimensione di \var{st\_size} senza allocare spazio su disco. Questo
consente di creare inizialmente file di dimensioni anche molto grandi, senza
dover occupare da subito dello spazio disco che in realtà sarebbe
La funzione \func{read} è una delle \textit{system call} fondamentali,
esistenti fin dagli albori di Unix, ma nella seconda versione delle
\textit{Single Unix Specification}\footnote{questa funzione, e l'analoga
- \func{pwrite} sono state aggiunte nel kernel 2.1.60, il supporto nelle
+ \func{pwrite} sono state aggiunte nel kernel 2.1.60, il supporto nella
\acr{glibc}, compresa l'emulazione per i vecchi kernel che non hanno la
\textit{system call}, è stato aggiunto con la versione 2.1, in versioni
precedenti sia del kernel che delle librerie la funzione non è disponibile.}
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
+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 \textit{file
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 è \const{FD\_CLOEXEC},
+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
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
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
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
+\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
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},
+\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
interpretato come l'identificatore di un processo o di un \textit{process
group}.
-\item[\const{F\_GETOWN\_EX}] legge nella struttura puntata
+\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
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 \textit{process group} che riceverà i segnali \signal{SIGIO} e
\signal{SIGURG} per gli eventi associati al file
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 \textit{file lease} che il
+\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[\const{F\_SETLEASE}] imposta o rimuove a seconda del valore
+\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à
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}
modifica è opportuno rileggere la nuova dimensione con
\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, è
+ impostare un valore superiore a quello indicato da
+ \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}.
\end{basedescript}
+% TODO: trattare RWH_WRITE_LIFE_EXTREME e RWH_WRITE_LIFE_SHORT aggiunte con
+% il kernel 4.13 (vedi https://lwn.net/Articles/727385/)
+
La maggior parte delle funzionalità controllate dai comandi di \func{fcntl}
sono avanzate e richiedono degli approfondimenti ulteriori, saranno pertanto
riprese più avanti quando affronteremo le problematiche ad esse relative. In
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},
-\const{F\_SETLK} e \const{F\_SETLKW}) sono previsti da SVr4 e 4.3BSD e
-standardizzati in POSIX.1-2001 che inoltre prevede gli ulteriori
+La gran parte dei comandi di \func{fcntl} (come \const{F\_DUPFD},
+\const{F\_GETFD}, \const{F\_SETFD}, \const{F\_GETFL}, \const{F\_SETFL},
+\const{F\_GETLK}, \const{F\_SETLK} e \const{F\_SETLKW}) sono previsti da SVr4
+e 4.3BSD e standardizzati in POSIX.1-2001 che inoltre prevede gli ulteriori
\const{F\_GETOWN} e \const{F\_SETOWN}. Pertanto nell'elenco si sono indicate
esplicitamente soltanto le ulteriori richieste in termini delle macro di
funzionalità di sez.~\ref{sec:intro_gcc_glibc_std} soltanto per le
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{}
Queste funzioni di libreria, insieme alle altre funzioni definite dallo
standard (che sono state implementate la prima volta da Ritchie nel 1976 e da
allora sono rimaste sostanzialmente immutate), vengono a costituire il nucleo
-delle \acr{glibc} per la gestione dei file.
+della \acr{glibc} per la gestione dei file.
Esamineremo in questa sezione le funzioni base dell'interfaccia degli
\textit{stream}, analoghe a quelle di sez.~\ref{sec:file_unix_interface} per i
accesso.
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.
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]
distinzione non esiste e il valore viene accettato solo per
compatibilità, ma non ha alcun effetto.
-Le \acr{glibc} supportano alcune estensioni, queste devono essere sempre
+La \acr{glibc} supporta alcune estensioni, queste devono essere sempre
indicate dopo aver specificato il \param{mode} con uno dei valori di
tab.~\ref{tab:file_fopen_mode}. L'uso del carattere \texttt{x} serve per
evitare di sovrascrivere un file già esistente (è analoga all'uso dell'opzione
tutti i dati presenti nei buffer di uscita e scarta tutti i dati in ingresso;
se era stato allocato un buffer per lo \textit{stream} questo verrà
rilasciato. La funzione effettua lo scarico solo per i dati presenti nei
-buffer in \textit{user space} usati dalle \acr{glibc}; se si vuole essere
+buffer in \textit{user space} usati dalla \acr{glibc}; se si vuole essere
sicuri che il kernel forzi la scrittura su disco occorrerà effettuare una
\func{sync} (vedi sez.~\ref{sec:file_sync}).
-Linux supporta anche una altra funzione, \funcd{fcloseall}, come estensione
-GNU implementata dalle \acr{glibc}, accessibile avendo definito
+Linux supporta anche un'altra funzione, \funcd{fcloseall}, come estensione
+GNU implementata dalla \acr{glibc}, accessibile avendo definito
\macro{\_GNU\_SOURCE}, il suo prototipo è:
\begin{funcproto}{
Una delle caratteristiche più utili dell'interfaccia degli \textit{stream} è
la ricchezza delle funzioni disponibili per le operazioni di lettura e
-scrittura sui file. Sono infatti previste ben tre diverse modalità modalità di
+scrittura sui file. Sono infatti previste ben tre diverse modalità di
input/output non formattato:
\begin{itemize}
\item\textsl{binario} in cui si leggono e scrivono blocchi di dati di
funzioni. Nella maggior parte dei casi questo avviene con la restituzione del
valore intero (di tipo \ctyp{int}) \val{EOF} definito anch'esso nell'header
\headfile{stdlib.h}. La costante deve essere negativa perché in molte funzioni
-un valore positivo indica la quantità di dati scritti, le \acr{glibc} usano il
+un valore positivo indica la quantità di dati scritti, la \acr{glibc} usa il
valore $-1$, ma altre implementazioni possono avere valori diversi.
Dato che le funzioni dell'interfaccia degli \textit{stream} sono funzioni di
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}
ordinamento dei bit o il formato delle variabili in floating point.
Per questo motivo quando si usa l'input/output binario occorre sempre prendere
-le opportune precauzioni (in genere usare un formato di più alto livello che
-permetta di recuperare l'informazione completa), per assicurarsi che versioni
-diverse del programma siano in grado di rileggere i dati tenendo conto delle
+le opportune precauzioni come usare un formato di più alto livello che
+permetta di recuperare l'informazione completa, per assicurarsi che versioni
+diverse del programma siano in grado di rileggere i dati, tenendo conto delle
eventuali differenze.
-Le \acr{glibc} definiscono altre due funzioni per l'I/O binario,
-\funcd{fread\_unlocked} e \funcd{fwrite\_unlocked} che evitano il lock
-implicito dello \textit{stream}, usato per dalla librerie per la gestione
-delle applicazioni \textit{multi-thread} (si veda
-sez.~\ref{sec:file_stream_thread} per i dettagli), i loro prototipi sono:
+La \acr{glibc} definisce infine due ulteriori 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 \textit{multi-thread} (si veda sez.~\ref{sec:file_stream_thread}
+per i dettagli), i loro prototipi sono:
\begin{funcproto}{
\fhead{stdio.h}
ritorno è sempre un intero; in caso di errore o fine del file il valore di
ritorno è \val{EOF}.
-Come nel caso dell'I/O binario con \func{fread} e \func{fwrite} le \acr{glibc}
-provvedono come estensione, per ciascuna delle funzioni precedenti,
+Come nel caso dell'I/O binario con \func{fread} e \func{fwrite} la \acr{glibc}
+provvede come estensione, per ciascuna delle funzioni precedenti,
un'ulteriore funzione, il cui nome è ottenuto aggiungendo un
\code{\_unlocked}, che esegue esattamente le stesse operazioni, evitando però
il lock implicito dello \textit{stream}.
``\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}
caratteri massimo, terminatore della stringa, \textit{newline}) è espresso in
termini di caratteri estesi anziché di normali caratteri ASCII.
-Come per l'I/O binario e quello a caratteri, anche per l'I/O di linea le
-\acr{glibc} supportano una serie di altre funzioni, estensioni di tutte quelle
+Come per l'I/O binario e quello a caratteri, anche per l'I/O di linea la
+\acr{glibc} supporta una serie di altre funzioni, estensioni di tutte quelle
illustrate finora (eccetto \func{gets} e \func{puts}), che eseguono
esattamente le stesse operazioni delle loro equivalenti, evitando però il lock
implicito dello \textit{stream} (vedi sez.~\ref{sec:file_stream_thread}). Come
complicazione ulteriore della logica del programma. Lo stesso dicasi quando si
deve gestire il caso di stringa che eccede le dimensioni del buffer.
-Per questo motivo le \acr{glibc} prevedono, come estensione GNU, due nuove
+Per questo motivo la \acr{glibc} prevede, come estensione GNU, due nuove
funzioni per la gestione dell'input/output di linea, il cui uso permette di
risolvere questi problemi. L'uso di queste funzioni deve essere attivato
definendo la macro \macro{\_GNU\_SOURCE} prima di includere
Dettagli ulteriori sulle varie opzioni di stampa e su tutte le casistiche
dettagliate dei vari formati possono essere trovati nella pagina di manuale di
-\func{printf} e nella documentazione delle \acr{glibc}.
+\func{printf} e nella documentazione della \acr{glibc}.
\begin{table}[htb]
\centering
\textit{stream}. Altre estensioni permettono di scrivere con caratteri
estesi. Anche queste funzioni, il cui nome è generato dalle precedenti
funzioni aggiungendo una \texttt{w} davanti a \texttt{print}, sono trattate in
-dettaglio nella documentazione delle \acr{glibc}.
+dettaglio nella documentazione della \acr{glibc}.
In corrispondenza alla famiglia di funzioni \func{printf} che si usano per
l'output formattato, l'input formattato viene eseguito con le funzioni della
qualunque di caratteri di separazione (che possono essere spazi, tabulatori,
virgole ecc.), mentre caratteri diversi richiedono una corrispondenza
esatta. Le direttive di conversione sono analoghe a quelle di \func{printf} e
-si trovano descritte in dettaglio nelle pagine di manuale e nel manuale delle
+si trovano descritte in dettaglio nelle pagine di manuale e nel manuale della
\acr{glibc}.
Le funzioni eseguono la lettura dall'input, scartano i separatori (e gli
In questo modo diventa possibile usare direttamente \func{fcntl} sul file
descriptor sottostante, ma anche se questo permette di accedere agli attributi
del file descriptor sottostante lo \textit{stream}, non ci dà nessuna
-informazione riguardo alle proprietà dello \textit{stream} medesimo. Le
-\acr{glibc} però supportano alcune estensioni derivate da Solaris, che
+informazione riguardo alle proprietà dello \textit{stream} medesimo. La
+\acr{glibc} però supporta alcune estensioni derivate da Solaris, che
permettono di ottenere informazioni utili relative allo \textit{stream}.
Ad esempio in certi casi può essere necessario sapere se un certo
\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
specifichi la modalità non bufferizzata i valori di \param{buf} e \param{size}
vengono sempre ignorati.
-Oltre a \func{setvbuf} le \acr{glibc} definiscono altre tre funzioni per la
+Oltre a \func{setvbuf} la \acr{glibc} definisce altre tre funzioni per la
gestione della bufferizzazione di uno \textit{stream}: \funcd{setbuf},
\funcd{setbuffer} e \funcd{setlinebuf}, i rispettivi prototipi sono:
vecchie librerie BSD, pertanto non è il caso di usarle se non per la
portabilità su vecchi sistemi.
-Infine le \acr{glibc} provvedono le funzioni non standard, anche queste
+Infine la \acr{glibc} provvede le funzioni non standard, anche queste
originarie di Solaris, \funcd{\_\_flbf} e \funcd{\_\_fbufsize} che permettono
di leggere le proprietà di bufferizzazione di uno \textit{stream}; i cui
prototipi sono:
\end{funcproto}
\noindent anche di questa funzione esiste una analoga \func{fflush\_unlocked}
-(accessibile definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE} o
+(accessibile definendo una fra \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE} o
\macro{\_GNU\_SOURCE}) che non effettua il blocco dello \textit{stream}.
% TODO aggiungere prototipo \func{fflush\_unlocked}?
\textit{stream} aperti. Esistono però circostanze, ad esempio quando si vuole
essere sicuri che sia stato eseguito tutto l'output su terminale, in cui serve
poter effettuare lo scarico dei dati solo per gli \textit{stream} in modalità
-\textit{line buffered}. Per fare questo le \acr{glibc} supportano una
+\textit{line buffered}. Per fare questo la \acr{glibc} supporta una
estensione di Solaris, la funzione \funcd{\_flushlbf}, il cui prototipo è:
\begin{funcproto}{
\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
Per questo motivo abbiamo visto come alle usuali funzioni di I/O non
formattato siano associate delle versioni \code{\_unlocked} (alcune previste
-dallo stesso standard POSIX, altre aggiunte come estensioni dalle \acr{glibc})
+dallo stesso standard POSIX, altre aggiunte come estensioni dalla \acr{glibc})
che possono essere usate quando il locking non serve\footnote{in certi casi
dette funzioni possono essere usate, visto che sono molto più efficienti,
anche in caso di necessità di locking, una volta che questo sia stato
La sostituzione di tutte le funzioni di I/O con le relative versioni
\code{\_unlocked} in un programma che non usa i \textit{thread} è però un
-lavoro abbastanza noioso. Per questo motivo le \acr{glibc} forniscono al
+lavoro abbastanza noioso. Per questo motivo la \acr{glibc} fornisce al
programmatore pigro un'altra via, anche questa mutuata da estensioni
introdotte in Solaris, da poter utilizzare per disabilitare in blocco il
locking degli \textit{stream}: l'uso della funzione \funcd{\_\_fsetlocking},
\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: