supporta la funzionalità.
\item[\errcode{EFBIG}] il file è troppo grande per essere aperto, in genere
dovuto al fatto che si è compilata una applicazione a 32 bit senza
- abilitare il supporto per le dimesioni a 64 bit; questo è il valore
+ abilitare il supporto per le dimensioni a 64 bit; questo è il valore
restituito fino al kernel 2.6.23, coi successivi viene restituito
\errcode{EOVERFLOW} come richiesto da POSIX.1.
\item[\errcode{ELOOP}] si sono incontrati troppi collegamenti simbolici nel
aggiunta in Linux a partire dal kernel
2.1.126, ed utilizzabile soltanto se si è definita
la macro \macro{\_GNU\_SOURCE}.\\
+ \const{O\_TMPFILE} & Consente di creare un file temporaneo anonimo, non
+ visibile con un pathname sul filesystem, ma
+ leggibile e scrivibile all'interno del processo.
+ Introdotto con il kernel 3.11, è specifico di
+ Linux.\\
\constd{O\_TRUNC} & Se usato su un file di dati aperto in scrittura,
ne tronca la lunghezza a zero; con un terminale o
una \textit{fifo} viene ignorato, negli altri casi
\textsl{modalità di apertura}.\footnote{la \acr{glibc} definisce anche i due
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
+ 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
assicurarsi che questo non esista di già, e lo si usa spesso per creare i
NFSv3 e con il kernel 2.6, nelle versioni precedenti la funzionalità viene
emulata controllando prima l'esistenza del file per cui usarla per creare un
file di lock potrebbe dar luogo a una \textit{race condition}, in tal caso
-infatto un file potrebbe venir creato fra il controllo la successiva apertura
+infatti un file potrebbe venir creato fra il controllo la successiva apertura
con \const{O\_CREAT}; la cosa si può risolvere comunque creando un file con un
nome univoco ed usando la funzione \func{link} per creare il file di lock,
(vedi sez.~\ref{sec:ipc_file_lock}).
si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il
\textit{modification time} e lo \textit{status change time}.
+Il flag \constd{O\_TMPFILE}, introdotto con il kernel
+3.11,\footnote{inizialmente solo su alcuni filesystem (i vari \acr{extN},
+ \acr{Minix}, \acr{UDF}, \acr{shmem}) poi progressivamente esteso ad altri
+ (\acr{XFS} con il 3.15, \acr{Btrfs} e \acr{F2FS} con il 3.16, \acr{ubifs}
+ con il 4.9).} consente di aprire un file temporaneo senza che questo venga
+associato ad un nome e compaia nel filesystem. In questo caso la funzione
+restituirà un file descriptor da poter utilizzare per leggere e scrivere dati,
+ma il contenuto dell'argomento \param{path} verrà usato solamente per
+determinare, in base alla directory su cui si verrebbe a trovare il
+\textit{pathname} indicato, il filesystem all'interno del quale deve essere
+allocato l'\textit{inode} e lo spazio disco usato dal file
+descriptor. L'\textit{inode} resterà anonimo e l'unico riferimento esistente
+sarà quello contenuto nella \textit{file table} del processo che ha chiamato
+\func{open}.
+
+Lo scopo principale del flag è quello fornire una modalità atomica, semplice e
+sicura per applicare la tecnica della creazione di un file temporaneo seguita
+dalla sua immediata cancellazione con \func{unlink} per non lasciare rimasugli
+sul filesystem, di cui è parlato in sez.~\ref{sec:link_symlink_rename}.
+Inoltre, dato che il file non compare nel filesystem, si evitano alla radice
+tutti gli eventuali problemi di \textit{race condition} o \textit{symlink
+ attack} e non ci si deve neanche preoccupare di ottenere un opportuno nome
+univoco con l'uso delle funzioni di sez.~\ref{sec:file_temp_file}.
+
+Una volta aperto il file vi si potrà leggere o scrivere a seconda che siano
+utilizzati \const{O\_RDWR} o \const{O\_WRONLY}, mentre l'uso di
+\func{O\_RDONLY} non è consentito, non avendo molto senso ottenere un file
+descriptor su un file che nasce vuoto per cui non si potrà comunque leggere
+nulla. L'unico altro flag che può essere utilizzato insieme a
+\const{O\_TMPFILE} è \const{O\_EXCL}, che in questo caso assume però un
+significato diverso da quello ordinario, dato che in questo caso il file
+associato al file descriptor non esiste comunque.
+
+L'uso di \const{O\_EXCL} attiene infatti all'altro possibile impiego di
+\const{O\_TMPFILE} oltre a quello citato della creazione sicura di un file
+temporaneo come sostituto sicuro di \func{tmpfile}: la possibilità di creare
+un contenuto iniziale per un file ed impostarne permessi, proprietario e
+attributi estesi con \func{fchmod}, \func{fchown} e \func{fsetxattr}, senza
+possibilità di \textit{race condition} ed interferenze esterne, per poi far
+apparire il tutto sul filesystem in un secondo tempo utilizzando \func{linkat}
+sul file descriptor (torneremo su questo in sez.~\ref{sec:file_openat}) per
+dargli un nome. Questa operazione però non sarà possibile se si è usato
+\const{O\_EXCL}, che in questo caso viene ad assumere il significato di
+escludere la possibilità di far esistere il file anche in un secondo tempo.
+
+% NOTE: per O_TMPFILE vedi: http://kernelnewbies.org/Linux_3.11
+% https://lwn.net/Articles/558598/ http://lwn.net/Articles/619146/
+
+
\begin{table}[!htb]
\centering
\footnotesize
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
+ \const{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
dell'arrivo degli stessi e della parte di metadati
ad essi relativa sull'hardware sottostante (in
questo significato solo dal kernel 2.6.33).\\
- \const{O\_TMPFILE} & Consente di creare un file temporaneo anonimo, non
- visibile con un pathname sul filesystem, ma
- leggibile e scrivibile all'iterno del processo.
- Introdotto con il kernel 3.11, è specifico di
- Linux.\\
\hline
\end{tabular}
\caption{Le costanti che identificano le \textit{modalità di operazione} di
attivarlo in un secondo tempo con \func{fcntl} (vedi
sez.~\ref{sec:file_fcntl_ioctl}).
-Il flag \const{O\_DIRECT} non è previsto da nessuno standard, anche se è
+Il flag \constd{O\_DIRECT} non è previsto da nessuno standard, anche se è
presente in alcuni kernel unix-like.\footnote{il flag è stato introdotto dalla
SGI in IRIX, ma è presente senza limiti di allineamento dei buffer anche in
FreeBSD.} Per i kernel della serie 2.4 si deve garantire che i buffer in
sulla scrittura sincrona dei metadati associati alla scrittura dei dati del
file.\footnote{la situazione si complica ulteriormente per NFS, in cui l'uso
del flag disabilita la bufferizzazione solo dal lato del client, e può
- causare problemi di prestazioni.} Per questo in genere è opportuno se si usa
+ causare problemi di prestazioni.} Per questo in genere se si usa
\const{O\_DIRECT} è opportuno richiedere anche \const{O\_SYNC}.
Si tenga presente infine che la implementazione di \const{O\_SYNC} di Linux
operazioni che riguardano il file descriptor in quanto tale, senza consentire
operazioni sul file; in sostanza se si apre un file con \const{O\_PATH} si
potrà soltanto:
-
\begin{itemize*}
\item usare il file descriptor come indicatore della directory di partenza con
una delle \textit{at-functions} (vedi sez.~\ref{sec:file_openat});
flags} con \func{fcntl} (rispettivamente con le operazioni
\const{F\_GETFL}, \const{F\_SETFD} e \const{F\_GETFD}, vedi
sez.~\ref{sec:file_fcntl_ioctl}).
-\item chiudere il file con \func{close};
+\item chiudere il file con \func{close}.
\end{itemize*}
-In realtà usando \const{O\_PATH} il file non viene effettivamente aperto per
+In realtà usando \const{O\_PATH} il file non viene effettivamente aperto, per
cui ogni tentativo di usare il file descriptor così ottenuto con funzioni che
operano effettivamente sul file (come ad esempio \func{read}, \func{write},
-\func{fchown}, \func{fchmod}, \func{ioctl}, ecc.) fallirano con un errore di
-\errval{EBADF}, come se questo non fosse un file descriptor valido.
+\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
+esecuzione per le directory sovrastanti).
+
+Questo consente di usare il file descriptor con funzioni che non richiedono
+permessi sul file, come \func{fstat}, laddove un'apertura con
+\const{O\_RDONLY} sarebbe fallita. I permessi verranno eventualmente
+controllati, se necessario, nelle operazioni seguenti, ad esempio per usare
+\func{fchdir} con il file descriptor (se questo fa riferimento ad una
+directory) occorrerà avere il permesso di esecuzione.
Se si usa \const{O\_PATH} tutti gli altri flag eccettuati \const{O\_CLOEXEC},
-\const{O\_DIRECTORY} e \const{O\_NOFOLLOW} verranno ignorati.
-
-% TODO: aggiungere O_TMPFILE per la creazione di file temporanei senza che
-% questi appaiano sul filesystem, introdotto con il 3.11, vedi:
-% https://lwn.net/Articles/556512/, http://kernelnewbies.org/Linux_3.11
-% https://lwn.net/Articles/558598/ http://lwn.net/Articles/619146/
-
-
+\const{O\_DIRECTORY} e \const{O\_NOFOLLOW} verranno ignorati. I primi due
+mantengono il loro significato usuale, mentre \const{O\_NOFOLLOW} fa si che se
+il file indicato è un un link simbolico venga aperto quest'ultimo (cambiando
+quindi il comportamento ordinario che prova il fallimento della chiamata),
+così da poter usare il file descriptor ottenuto per le funzioni
+\func{fchownat}, \func{fstatat}, \func{linkat} e \func{readlinkat} che ne
+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
automaticamente chiusi, molti programmi sfruttano questa caratteristica e non
usano esplicitamente \func{close}. In genere comunque chiudere un file senza
controllare lo stato di uscita di \func{close} un è errore; molti filesystem
-infatti implementano la tecnica del cosiddetto \textit{write-behind}, per cui
-una \func{write} può avere successo anche se i dati non sono stati
-effettivamente scritti su disco. In questo caso un eventuale errore di I/O
-avvenuto in un secondo tempo potrebbe sfuggire, mentre verrebbe riportato alla
-chiusura esplicita del file. Per questo motivo non effettuare il controllo può
-portare ad una perdita di dati inavvertita.\footnote{in Linux questo
- comportamento è stato osservato con NFS e le quote su disco.}
+infatti implementano la tecnica del cosiddetto \itindex{write-behind}
+\textit{write-behind}, per cui una \func{write} può avere successo anche se i
+dati non sono stati effettivamente scritti su disco. In questo caso un
+eventuale errore di I/O avvenuto in un secondo tempo potrebbe sfuggire, mentre
+verrebbe riportato alla chiusura esplicita del file. Per questo motivo non
+effettuare il controllo può portare ad una perdita di dati
+inavvertita.\footnote{in Linux questo comportamento è stato osservato con NFS
+ e le quote su disco.}
In ogni caso una \func{close} andata a buon fine non garantisce che i dati
siano stati effettivamente scritti su disco, perché il kernel può decidere di
ottimizzare l'accesso a disco ritardandone la scrittura. L'uso della funzione
-\func{sync} (vedi sez.~\ref{sec:file_sync}) effettua esplicitamente il
-\emph{flush} dei dati, ma anche in questo caso resta l'incertezza dovuta al
-comportamento dell'hardware, che a sua volta può introdurre ottimizzazioni
-dell'accesso al disco che ritardano la scrittura dei dati. Da questo deriva
-l'abitudine di alcuni sistemisti di ripetere tre volte il comando omonimo
-prima di eseguire lo shutdown di una macchina.
-
+\func{sync} (vedi sez.~\ref{sec:file_sync}) effettua esplicitamente lo scarico
+dei dati, ma anche in questo caso resta l'incertezza dovuta al comportamento
+dell'hardware, che a sua volta può introdurre ottimizzazioni dell'accesso al
+disco che ritardano la scrittura dei dati. Da questo deriva l'abitudine di
+alcuni sistemisti di ripetere tre volte il comando omonimo prima di eseguire
+lo shutdown di una macchina.
+
+Si tenga comunque presente che ripetere la chiusura in caso di fallimento non
+è opportuno, una volta chiamata \func{close} il file descriptor viene comunque
+rilasciato, indipendentemente dalla presenza di errori, e se la riesecuzione
+non comporta teoricamente problemi (se non la sua inutilità) se fatta
+all'interno di un processo singolo, nel caso si usino i \textit{thread} si
+potrebbe chiudere un file descriptor aperto nel contempo da un altro
+\textit{thread}.
\subsection{La gestione della posizione nel file}
\label{sec:file_lseek}
di \param{offset}.
Inoltre la decisione di come riportare (o di non riportare) la presenza di un
-buco in un file è lasciata all'implementazione del
-filesystem, dato che esistono vari motivi per cui una sezione di un file può
-non contenere dati ed essere riportata come tale (ad esempio può essere stata
-preallocata con \func{fallocate}, vedi sez.~\ref{sec:file_fadvise}) oltre a
-quelle classiche appena esposte. Questo significa che l'uso di questi nuovi
+buco in un file è lasciata all'implementazione del filesystem, dato che oltre
+a quelle classiche appena esposte esistono vari motivi per cui una sezione di
+un file può non contenere dati ed essere riportata come tale (ad esempio può
+essere stata preallocata con \func{fallocate}, vedi
+sez.~\ref{sec:file_fadvise}). Questo significa che l'uso di questi nuovi
valori non garantisce la mappatura della effettiva allocazione dello spazio
disco di un file, per il quale esiste una specifica operazione di controllo
(vedi sez.~\ref{sec:file_fcntl_ioctl}).
da una \func{lseek} che riporti al valore precedente la posizione corrente sul
file, ma permette di eseguire l'operazione atomicamente. Questo può essere
importante quando la posizione sul file viene condivisa da processi diversi
-(vedi sez.~\ref{sec:file_shared_access}). Il valore di
-\param{offset} fa sempre riferimento all'inizio del file.
+(vedi sez.~\ref{sec:file_shared_access}). Il valore di \param{offset} fa
+sempre riferimento all'inizio del file.
La funzione \func{pread} è disponibile anche in Linux, però diventa
accessibile solo attivando il supporto delle estensioni previste dalle
\begin{errlist}
\item[\errcode{EAGAIN}] ci si sarebbe bloccati, ma il file era aperto in
modalità \const{O\_NONBLOCK}.
+ \item[\errcode{EDESTADDRREQ}] si è eseguita una scrittura su un socket di
+ tipo \textit{datagram} (vedi sez.~\ref{sec:sock_type}) senza aver prima
+ connesso il corrispondente con \func{connect} (vedi
+ sez.~\ref{sec:UDP_sendto_recvfrom}).
\item[\errcode{EFBIG}] si è cercato di scrivere oltre la dimensione massima
consentita dal filesystem o il limite per le dimensioni dei file del
processo o su una posizione oltre il massimo consentito.
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{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)
la funzione ritorna questo errore.
\end{errlist}
- ed inoltre \errval{EBADF}, \errval{EFAULT}, \errval{EIO}, \errval{EISDIR},
- \errval{ENOSPC} nel loro significato generico.}
+ ed inoltre \errval{EBADF}, \errval{EDQUOT}, \errval{EFAULT}, \errval{EIO},
+ \errval{EISDIR}, \errval{ENOSPC} nel loro significato generico.}
\end{funcproto}
% TODO manca prototipo di linkat, verificare se metterlo o metter menzione
% altre modifiche al riguardo nel 3.11 (AT_EMPTY_PATH?) vedi
-% http://lwn.net/Articles/562488/
+% http://lwn.net/Articles/562488/
+
+% TODO: Trattare esempio di inzializzazione di file e successivo collegamento
+% con l'uso di O_TMPFILE e linkat, vedi man open
+
+
% TODO manca prototipo di utimensat, verificare se metterlo o metter menzione
% TODO manca prototipo di renameat2, introdotta nel 3.15, vedi
% http://lwn.net/Articles/569134/
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
-% LocalWords: l'I nell' du vm Documentation Urlich Drepper futimesat times
-% LocalWords: futimens fs Tread all'I ll
+
+% LocalWords: nell' du vm Documentation Urlich Drepper futimesat times
+% 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'