\func{fchown}, \func{fchmod}, \func{ioctl}, ecc.) fallirà con un errore di
\errval{EBADF}, come se questo non fosse un file descriptor valido. Per questo
motivo usando questo flag non è necessario avere nessun permesso per aprire un
-file, neanche quello di lettura (occorre ovviamente avere il permesso di
+file, neanche quello di lettura (ma occorre ovviamente avere il permesso di
esecuzione per le directory sovrastanti).
Questo consente di usare il file descriptor con funzioni che non richiedono
supportano l'uso come come primo argomento (torneremo su questo in
sez.~\ref{sec:file_openat}).
-
Nelle prime versioni di Unix i valori di \param{flag} specificabili per
\func{open} erano solo quelli relativi alle modalità di accesso del file. Per
questo motivo per creare un nuovo file c'era una \textit{system call}
Infine si tenga presente che, come accennato in sez.~\ref{sec:file_file_size},
con \func{lseek} è possibile impostare una posizione anche oltre la corrente
fine del file. In tal caso alla successiva scrittura il file sarà esteso a
-partire da detta posizione, con la creazione di quello che viene chiamato
+partire da detta posizione, con la creazione di quello che viene chiamato un
``\textsl{buco}'' (in gergo \textit{hole}) nel file. Il nome deriva dal fatto
che nonostante la dimensione del file sia cresciuta in seguito alla scrittura
-effettuata, lo spazio vuoto fra la precedente fine del file ed la nuova parte
-scritta dopo lo spostamento non corrisponde ad una allocazione effettiva di
+effettuata, lo spazio vuoto fra la precedente fine del file e la nuova parte,
+scritta dopo lo spostamento, non corrisponde ad una allocazione effettiva di
spazio su disco, che sarebbe inutile dato che quella zona è effettivamente
vuota.
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
-nell'\textit{inode} del file viene segnata l'allocazione di un blocco di dati
-a partire dalla nuova posizione, ma non viene allocato nulla per le posizioni
-intermedie; in caso di lettura sequenziale del contenuto del file il kernel si
-accorgerà della presenza del buco, e restituirà degli zeri come contenuto di
-quella parte del file.
+sistema unix-like e quando si ha questa situazione si dice che il file in
+questione è uno \textit{sparse file}. In sostanza, se si ricorda la struttura
+di un filesystem illustrata in fig.~\ref{fig:file_filesys_detail}, quello che
+accade è che nell'\textit{inode} del file viene segnata l'allocazione di un
+blocco di dati a partire dalla nuova posizione, ma non viene allocato nulla
+per le posizioni intermedie. In caso di lettura sequenziale del contenuto del
+file il kernel si accorgerà della presenza del buco, e restituirà degli zeri
+come contenuto di quella parte del file.
Questa funzionalità comporta una delle caratteristiche della gestione dei file
su Unix che spesso genera più confusione in chi non la conosce, per cui
\cmd{du}, che calcola lo spazio disco occupato in base al numero dei blocchi
effettivamente allocati per il file.
-Questo avviene proprio perché in un sistema unix-like la dimensione di un file
-è una caratteristica del tutto indipendente dalla quantità di spazio disco
-effettivamente allocato, e viene registrata sull'\textit{inode} come le altre
-proprietà del file. La dimensione viene aggiornata automaticamente quando si
-estende un file scrivendoci, e viene riportata dal campo \var{st\_size} di una
-struttura \struct{stat} quando si effettua 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
-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 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
-inutilizzato.
+Tutto ciò avviene proprio perché in un sistema unix-like la dimensione di un
+file è una caratteristica del tutto indipendente dalla quantità di spazio
+disco effettivamente allocato, e viene registrata sull'\textit{inode} come le
+altre proprietà del file. La dimensione viene aggiornata automaticamente
+quando si estende un file scrivendoci, e viene riportata dal campo
+\var{st\_size} di una struttura \struct{stat} quando si effettua la chiamata
+ad una delle funzioni \texttt{*stat} viste in sez.~\ref{sec:file_stat}.
+
+Questo comporta che la dimensione di un file, fintanto che lo si è scritto
+sequenzialmente, sarà corrispondente alla quantità di spazio disco da esso
+occupato, ma possono esistere dei casi, come questo in cui ci si sposta in una
+posizione oltre la fine corrente del file, o come quello accennato in
+sez.~\ref{sec:file_file_size} in cui si estende la dimensione di un file con
+una \func{truncate}, in cui si modifica soltanto il valore della dimensione di
+\var{st\_size} senza allocare spazio su disco. Così è possibile creare
+inizialmente file di dimensioni anche molto grandi, senza dover occupare da
+subito dello spazio disco che in realtà sarebbe inutilizzato.
\itindend{sparse~file}
La funzione tenta di leggere \param{count} byte dal file \param{fd} a partire
dalla posizione corrente, scrivendoli nel buffer \param{buf}.\footnote{fino ad
- un massimo di \const{0x7ffff000} bytes, indipendentemente che l'architettura
+ un massimo di \const{0x7ffff000} byte, indipendentemente che l'architettura
sia a 32 o 64 bit.} Dopo la lettura la posizione sul file è spostata
automaticamente in avanti del numero di byte letti. Se \param{count} è zero la
funzione restituisce zero senza nessun altro risultato. Inoltre che non è
La funzione prende esattamente gli stessi argomenti di \func{read} con lo
stesso significato, a cui si aggiunge l'argomento \param{offset} che indica
-una posizione sul file a partire dalla quale verranno i \param{count}
-bytes. Identico è il comportamento ed il valore di ritorno, ma la posizione
+una posizione sul file a partire dalla quale verranno letti i \param{count}
+byte. Identico è il comportamento ed il valore di ritorno, ma la posizione
corrente sul file resterà invariata. Il valore di \param{offset} fa sempre
riferimento all'inizio del file.
\textit{Single Unix Specification} con un valore della macro
\macro{\_XOPEN\_SOURCE} maggiore o uguale a 500 o a partire dalla \acr{glibc}
2.12 con un valore dalla macro \macro{\_POSIX\_C\_SOURCE} maggiore o uguale al
-varore \val{200809L}. Si ricordi di definire queste macro prima
+valore \val{200809L}. Si ricordi di definire queste macro prima
dell'inclusione del file di dichiarazione \headfile{unistd.h}.
potuto scrivere qualsiasi dato.
\item[\errcode{EINVAL}] \param{fd} è connesso ad un oggetto che non consente
la scrittura o si è usato \const{O\_DIRECT} ed il buffer non è allineato.
-% \item[\errcode{EPERM}] la scrittura è proibita da un \textit{file seal}.
+ \item[\errcode{EPERM}] la scrittura è proibita da un \textit{file seal}
+ (vedi sez.~\ref{sec:file_fcntl_ioctl}).
\item[\errcode{EPIPE}] \param{fd} è connesso ad una \textit{pipe} il cui
altro capo è chiuso in lettura; in questo caso viene anche generato il
segnale \signal{SIGPIPE}, se questo viene gestito (o bloccato o ignorato)
della gestione file in un sistema unix-like, esaminando in dettaglio il
comportamento delle funzioni base, inoltre tratteremo le funzioni che
permettono di eseguire alcune operazioni avanzate con i file (il grosso
-dell'argomento sarà comunque affrontato in cap.~\ref{cha:file_advanced}).
+dell'argomento sarà comunque affrontato nel cap.~\ref{cha:file_advanced}).
\subsection{La gestione dell'accesso concorrente ai files}
\label{fig:file_mult_acc}
\end{figure}
-Il primo caso è quello in cui due processi diversi aprono lo stesso file su
-disco; sulla base di quanto visto in sez.~\ref{sec:file_fd} avremo una
+Il primo caso è quello in cui due processi indipendenti aprono lo stesso file
+su disco; sulla base di quanto visto in sez.~\ref{sec:file_fd} avremo una
situazione come quella illustrata in fig.~\ref{fig:file_mult_acc}: ciascun
processo avrà una sua voce nella \textit{file table} referenziata da un
diverso file descriptor nella sua \kstruct{file\_struct}. Entrambe le voci
\end{figure}
Il secondo caso è quello in cui due file descriptor di due processi diversi
-puntino alla stessa voce nella \textit{file table}. Questo è ad esempio il
+puntano 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
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
differenza di altri sistemi operativi, dei meccanismi di blocco o di
-restrizione dell'accesso impliciti se più processi vogliono accedere allo
+restrizione dell'accesso impliciti quando più processi vogliono accedere allo
stesso file. Questo significa che le operazioni di lettura e scrittura vengono
-sempre fatte da ogni processo in maniera autonoma, utilizzando una posizione
-corrente nel file che normalmente (a meno di non trovarsi nella situazione di
-fig.~\ref{fig:file_acc_child}) è locale a ciascuno di essi.
+sempre fatte da ogni processo in maniera indipendente, utilizzando una
+posizione corrente nel file che normalmente, a meno di non trovarsi nella
+situazione di fig.~\ref{fig:file_acc_child}, è locale a ciascuno di essi.
Dal punto di vista della lettura dei dati questo comporta la possibilità di
poter leggere dati non coerenti in caso di scrittura contemporanea da parte di
Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
vari processi devono scrivere alla fine di un file (ad esempio un file di
log). Come accennato in sez.~\ref{sec:file_lseek} impostare la posizione alla
-fine del file e poi scrivere può condurre ad una \textit{race condition};
-infatti può succedere che un secondo processo scriva alla fine del file fra la
-\func{lseek} e la \func{write}. In questo caso, come abbiamo appena visto, il
-file sarà esteso, ma il primo processo, avrà una posizione corrente che aveva
-impostato con la \func{lseek} che non corrisponde più alla fine del file, e la
-sua successiva \func{write} sovrascriverà i dati del secondo processo.
+fine del file con \func{lseek} e poi scrivere con \func{write} può condurre ad
+una \textit{race condition}; infatti può succedere che un secondo processo
+scriva alla fine del file fra la \func{lseek} e la \func{write}. In questo
+caso, come abbiamo appena visto, il file sarà esteso, ma il primo processo,
+avrà una posizione corrente che aveva impostato con \func{lseek} che non
+corrisponde più alla fine del file, e la sua successiva \func{write}
+sovrascriverà i dati del secondo processo.
Il problema deriva dal fatto che usare due \textit{system call} in successione
non è mai un'operazione atomica dato che il kernel può interrompere
Abbiamo già visto in sez.~\ref{sec:file_shared_access} come un processo figlio
condivida gli stessi file descriptor del padre; è possibile però ottenere un
-comportamento analogo all'interno di uno stesso processo \textit{duplicando}
-un file descriptor. Per far questo si usa la funzione di sistema \funcd{dup},
-il cui prototipo è:
+comportamento analogo all'interno di uno stesso processo con la cosiddetta
+\textit{duplicazione} di un file descriptor. Per far questo si usa la funzione
+di sistema \funcd{dup}, il cui prototipo è:
\begin{funcproto}{
\fhead{unistd.h}
\begin{errlist}
\item[\errcode{EBADF}] \param{oldfd} non è un file aperto.
\item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
- descriptor aperti.
+ descriptor aperti (vedi sez.~\ref{sec:sys_resource_limit}).
\end{errlist}
}
\end{funcproto}
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 \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
+una \textit{fifo} o un socket, oppure potrebbe essere un file associato ad un
+file descriptor che si è ereditato già aperto (ad esempio attraverso una
\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
ignorare le origini del file descriptor che si duplica e funziona in maniera
Come accennato in sez.~\ref{sec:file_open_close} tutte le operazioni di
scrittura sono in genere bufferizzate dal kernel, che provvede ad effettuarle
-in maniera asincrona, ad esempio accorpando gli accessi alla stessa zona del
-disco, in un secondo tempo rispetto al momento della esecuzione della
-\func{write}.
+in maniera asincrona per ottimizzarle, ad esempio accorpando gli accessi alla
+stessa zona del disco in un secondo tempo rispetto al momento della esecuzione
+della \func{write}.
-Per questo motivo quando è necessaria una sincronizzazione dei dati il sistema
-mette a disposizione delle funzioni che provvedono a forzare lo scarico dei
-dati dai buffer del kernel. La prima di queste funzioni di sistema è
-\funcd{sync}, il cui prototipo è:\footnote{questo è il prototipo usato a
- partire dalla \acr{glibc} 2.2.2 seguendo gli standard, in precedenza la
- funzione era definita come \code{int sync(void)} e ritornava sempre $0$.}
+Per questo motivo quando è necessaria una sincronizzazione immediata dei dati
+il sistema mette a disposizione delle funzioni che provvedono a forzare lo
+scarico dei dati dai buffer del kernel. La prima di queste funzioni di
+sistema è \funcd{sync}, il cui prototipo è:\footnote{questo è il prototipo
+ usato a partire dalla \acr{glibc} 2.2.2 seguendo gli standard, in precedenza
+ la funzione era definita come \code{int sync(void)} e ritornava sempre $0$.}
\begin{funcproto}{
\fhead{unistd.h}
\end{funcproto}
I vari standard prevedono che la funzione si limiti a far partire le
-operazioni, ritornando immediatamente, con Linux fin dal kernel 1.3.20 invece
+operazioni ritornando immediatamente, con Linux invece, fin dal kernel 1.3.20,
la funzione aspetta la conclusione delle operazioni di sincronizzazione. Si
tenga presente comunque che questo non dà la garanzia assoluta che i dati
siano integri dopo la chiamata, l'hardware dei dischi è in genere dotato di un
-suo meccanismo interno di bufferizzazione che può ritardare ulteriormente la
-scrittura effettiva.
+suo meccanismo interno di bufferizzazione che a sua volta può ritardare
+ulteriormente la scrittura effettiva.
La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
esplicitamente lo scarico dei dati su disco, un tempo era invocata da un
apposito demone di sistema (in genere chiamato \cmd{update}) che eseguiva lo
scarico dei dati ad intervalli di tempo fissi. Con le nuove versioni del
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
-\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
-presente che la funzione di sistema \funcm{bdflush}, che un tempo veniva usata
-per queste impostazioni, è deprecata e causa semplicemente la stampa di un
-messaggio nei log del kernel, pertanto non la prenderemo in esame.
+memoria virtuale, attraverso opportuni \textit{task} interni al kernel. Nei
+kernel recenti questo comportamento può essere controllato con l'uso dei vari
+file \texttt{dirty\_*} in \sysctlfiled{vm/}.\footnote{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 presente che la funzione di sistema \funcm{bdflush}, che un tempo
+veniva usata per controllare lo scaricamento dei dati, è deprecata a partire
+dal kernel 2.6 e causa semplicemente la stampa di un messaggio nei log del
+kernel, e non è più presente dalle \acr{glibc} 2.23, pertanto non la
+prenderemo in esame.
Quando si vogliano scaricare i dati di un singolo file, ad esempio essere
sicuri che i dati di un database siano stati registrati su disco, si possono
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
caso \var{errno} assumerà uno dei valori:
\begin{errlist}
+ \item[\errcode{EDQUOT}] si è superata un quota disco durante la
+ sincronizzazione.
\item[\errcode{EINVAL}] \param{fd} è un file speciale che non supporta la
+ sincronizzazione (talvolta anche \errval{EROFS}).
+ \item[\errcode{EIO}] c'è stato un errore di I/O durante la sincronizzazione,
+ che in questo caso può derivare anche da scritture sullo stesso file
+ eseguite su altri file descriptor.
+ \item[\errcode{ENOSPC}] si è esaurito lo spazio disco durante la
sincronizzazione.
\end{errlist}
- ed inoltre \errval{EBADF}, \errval{EIO} e \errval{EROFS} nel loro
- significato generico.}
+ ed inoltre \errval{EBADF} nel suo significato generico.}
\end{funcproto}
Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
con l'opzione \cmd{sync}, il kernel provvede anche alla sincronizzazione
automatica delle voci delle directory.}
+La funzione può restituire anche \errval{ENOSPC} e \errval{EDQUOT} per quei
+casi in cui l'allocazione dello spazio disco non viene effettuata
+all'esecuzione di una \func{write} (come NFS o altri filesystem di rete) per
+cui l'errore viene rilevato quando la scrittura viene effettivamente
+eseguita.
+
L'uso di \func{sync} presenta in certi casi, quando ci sono più filesystem
montati, problemi di prestazioni dovute al fatto che la funzione provoca la
sincronizzazione dei dati su tutti quanti i filesystem, anche quando
interesserebbe che questo avvenga soltanto su quello dei file su cui si sta
-lavorando, se i dati in attesa sono molti questo può causare seri problemi di
+lavorando. se i dati in attesa sono molti questo può causare seri problemi di
prestazioni.
Per questo motivo è stata introdotta una nuova funzione di sistema,
\itindbeg{at-functions}
-Un problema generale che si pone con l'uso della funzione \func{open}, così
-come per le altre funzioni che prendono come argomenti dei \textit{pathname}
-relativi, è la possibilità, quando un \textit{pathname} relativo non fa
-riferimento ad un file posto direttamente nella directory di lavoro corrente,
-che alcuni dei componenti del \textit{pathname} vengano modificati in
-parallelo alla chiamata a \func{open}, cosa che lascia aperta la possibilità
-di una \textit{race condition} in cui c'è spazio per un \textit{symlink
- attack} (si ricordi quanto visto per \func{access} in
-sez.~\ref{sec:file_perm_management}).
+Un problema generico che si pone con l'uso della funzione \func{open}, così
+come con le altre funzioni che prendono come argomenti dei \textit{pathname},
+è la possibilità, quando si usa un \textit{pathname} che non fa riferimento
+diretto ad un file posto nella directory di lavoro corrente, che alcuni dei
+componenti dello stesso vengano modificati in parallelo alla chiamata a
+\func{open}, cosa che lascia aperta la possibilità di una \textit{race
+ condition} in cui c'è spazio per un \textit{symlink attack} (si ricordi
+quanto visto per \func{access} in sez.~\ref{sec:file_perm_management}).
Inoltre come già accennato, la directory di lavoro corrente è una proprietà
-del singolo processo; questo significa che quando si lavora con i
-\textit{thread} essa sarà la stessa per tutti, ma esistono molti casi in cui
-sarebbe invece utile che ogni singolo \textit{thread} avesse la sua directory
-di lavoro.
+associata al singolo processo; questo significa che quando si lavora con i
+\textit{thread} questa sarà sempre la stessa per tutti \textit{thread}, per
+cui un cabiamento di directory di lavoro effettuato all'interno di un
+\textit{thread} verrà applicato anche a tutti gli altri; non esiste quindi con
+le funzioni classiche un modo semplice per far si che i singoli
+\textit{thread} possano aprire file usando una propria directory per risolvere
+i \textit{pathname} relativi.
Per risolvere questi problemi, riprendendo una interfaccia già presente in
Solaris, a fianco delle normali funzioni che operano sui file (come
\func{open}, \func{mkdir}, ecc.) sono state introdotte delle ulteriori
-funzioni, dette anche ``\textit{at-functions}'' in quanto contraddistinte dal
-suffisso \texttt{at}, che permettono l'apertura di un file (o le rispettive
-altre operazioni) usando un \textit{pathname} relativo ad una directory
+funzioni di sistema, chiamate genericamente ``\textit{at-functions}'' in
+quanto usualmente contraddistinte dal suffisso \texttt{at}, che permettono
+l'apertura di un file (o le rispettive altre operazioni) usando un
+\textit{pathname} relativo ad una directory
specificata.\footnote{l'introduzione è avvenuta su proposta dello sviluppatore
principale della \acr{glibc} Urlich Drepper e le corrispondenti
\textit{system call} sono state inserite nel kernel a partire dalla versione
prestazioni inferiori, funzionava facendo ricorso all'uso del filesystem
\textit{proc} con l'apertura del file attraverso il riferimento a
\textit{pathname} del tipo di \texttt{/proc/self/fd/dirfd/relative\_path}.}
+
Benché queste funzioni non siano presenti negli standard tradizionali esse
sono state adottate da altri sistemi unix-like come Solaris, i vari BSD, fino
ad essere incluse in una recente revisione (la POSIX.1-2008) dello standard
POSIX.1. Con la \acr{glibc} per l'accesso a queste funzioni è necessario
-definire la macro \macro{\_ATFILE\_SOURCE}.
-
-L'uso di queste funzioni prevede una apertura iniziale della directory che
-sarà la base della risoluzione dei \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 \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
-devono eseguire molte operazioni su sezioni dell'albero dei file che prevedono
-delle gerarchie di sottodirectory molto profonde. Infatti in questo caso basta
-eseguire la risoluzione del \textit{pathname} della directory di partenza una
-sola volta (nell'apertura iniziale) e non tutte le volte che si deve accedere
-a ciascun file che essa contiene.
-
-La sintassi generale di queste nuove funzioni è che esse prevedono come primo
-argomento il file descriptor della directory da usare come base per la
+definire la macro \macro{\_ATFILE\_SOURCE} (attiva di default).
+
+L'uso di queste funzioni prevede una apertura iniziale della directory che si
+intende usare come base per la risoluzione dei \textit{pathname} relativi,
+dopo di che si dovrà passare il suddetto file descriptor alle stesse, che
+useranno quella directory come punto di partenza per 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} dovuti
+al possibile cambiamento di uno dei componenti del \textit{pathname}, consente
+anche di ottenere aumenti di prestazioni significativi quando si devono
+eseguire molte operazioni su sezioni dell'albero dei file che prevedono delle
+gerarchie di sottodirectory molto profonde. Infatti in questo caso basta
+eseguire la risoluzione del \textit{pathname} di una qualunque directory di
+partenza una sola volta (nell'apertura iniziale) e non tutte le volte che si
+deve accedere a ciascun file che essa contiene.
+
+La sintassi generale di queste nuove funzioni è l'utilizzo come primo
+argomento del file descriptor della directory da usare come base per la
risoluzione dei nomi, mentre gli argomenti successivi restano identici a
-quelli della corrispondente funzione ordinaria. Se ad esempio prendiamo in
-esame la nuova funzione di sistema \funcd{openat}, avremo il prototipo:
+quelli della corrispondente funzione ordinaria. Come esempio prendiamo in
+esame la nuova funzione di sistema \funcd{openat}, il cui prototipo è:
\begin{funcproto}{
\fhead{fcntl.h}
}
\end{funcproto}
-Il comportamento delle nuove funzioni è del tutto analogo a quello delle
-corrispettive classiche, con la sola eccezione del fatto che se fra i loro
-argomenti si utilizza un \textit{pathname} relativo questo sarà risolto
-rispetto alla directory indicata da \param{dirfd}. Qualora invece si usi un
+Il comportamento di \func{openat} è del tutto analogo a quello di \func{open},
+con la sola eccezione del fatto che se per l'argomento \param{pathname} 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 \constd{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
-usare occorrerà includere comunque questo file, anche per le funzioni che non
-sono definite in esso.
+processo. Questa, come le altre costanti \texttt{AT\_*}, è definita in
+\headfile{fcntl.h}, per cui per usarla occorrerà includere comunque questo
+file, anche per le funzioni che non sono definite in esso.
+
+Si tenga presente che l'uso di \func{openat} non risolve in generale tutte le
+possibili \textit{race condition} legate all'apertura di un file dopo un
+eventuale controllo di accesso o esistenza, ma consente comunque di difendersi
+da tutti gli attacchi eseguiti modificando le componenti superiori del suo
+\textit{pathname}. Inoltre una ...
Così come il comportamento, anche i valori di ritorno e le condizioni di
errore delle nuove funzioni sono gli stessi delle funzioni classiche, agli
\textbf{Funzione} &\textbf{Flags} &\textbf{Corrispondente} \\
\hline
\hline
+ \func{execveat} &$\bullet$&\func{execve} \\
\func{faccessat} &$\bullet$&\func{access} \\
\funcm{fchmodat} &$\bullet$&\func{chmod} \\
\func{fchownat} &$\bullet$&\func{chown},\func{lchown}\\
\funcm{fstatat} &$\bullet$&\func{stat},\func{lstat} \\
- \func{utimensat} &$\bullet$&\func{utimes},\func{lutimes}\\
\func{linkat} &$\bullet$\footnotemark&\func{link} \\
\funcm{mkdirat} & -- &\func{mkdir} \\
+ \funcm{mkfifoat} & -- &\func{mkfifo} \\
\funcm{mknodat} & -- &\func{mknod} \\
\func{openat} & -- &\func{open} \\
\funcm{readlinkat}& -- &\func{readlink}\\
\funcm{renameat} & -- &\func{rename} \\
+ \funcm{statx} &$\bullet$&\func{stat} \\
\funcm{symlinkat}& -- &\func{symlink} \\
\func{unlinkat} &$\bullet$&\func{unlink},\func{rmdir} \\
- \funcm{mkfifoat} & -- &\func{mkfifo} \\
+ \func{utimensat} &$\bullet$&\func{utimes},\func{lutimes}\\
\hline
\end{tabular}
\caption{Corrispondenze fra le nuove funzioni ``\textit{at}'' e le
anche l'aggiunta di un ulteriore argomento finale, \param{flags}.
-
-
% TODO trattare fstatat e con essa
% TODO trattare anche statx, aggiunta con il kernel 4.11 (vedi
% https://lwn.net/Articles/707602/ e
% TODO manca prototipo di execveat, introdotta nel 3.19, vedi
% https://lwn.net/Articles/626150/ cerca anche fexecve
+% TODO: trattare i nuovi AT_flags quando e se arriveranno, vedi
+% https://lwn.net/Articles/767547/
+
Per tutte le funzioni che lo prevedono, a parte \func{unlinkat} e
\funcd{faccessat}, l'ulteriore argomento è stato introdotto solo per fornire
ma la gestione sia delle loro proprietà, che di tutta una serie di ulteriori
funzionalità che il kernel può mettere a disposizione.
+% TODO: trattare qui i file seal
+
Per le operazioni di manipolazione e di controllo delle varie proprietà e
caratteristiche di un file descriptor, viene usata la funzione di sistema
\funcd{fcntl},\footnote{ad esempio si gestiscono con questa funzione varie
%%% TeX-master: "gapil"
%%% End:
-% LocalWords: nell' du vm Documentation Urlich Drepper futimesat times
+% LocalWords: nell' du vm Documentation Urlich Drepper futimesat times l'I
% LocalWords: futimens fs Tread all'I ll TMPFILE EDQUOT extN Minix UDF XFS
% LocalWords: shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF
-% LocalWords: fstatfs sull'
+% LocalWords: fstatfs sull' SIGTTIN EDESTADDRREQ datagram connect