X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileio.tex;h=dc5bdfa2d45b291a0e6ff3304af097350b9a5f30;hp=0a66a9ba195298aba135f7e42a920ffe85d70c6c;hb=2f4922efce6bcac7c6ff10a4c5af7bebccb1f151;hpb=4ee752aa050a142f6a8c35d44a98e704f7fdf6bf diff --git a/fileio.tex b/fileio.tex index 0a66a9b..dc5bdfa 100644 --- a/fileio.tex +++ b/fileio.tex @@ -12,7 +12,7 @@ \chapter{La gestione dell'I/O su file} \label{cha:file_IO_interface} -Esamineremo in questo capitol le due interfacce di programmazione che +Esamineremo in questo capitolo 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 @@ -162,8 +162,8 @@ aspetta di dover scrivere i dati in uscita. Il terzo è lo \textit{standard \itindend{file~descriptor} -Benché questa sia soltanto una convenzione, essa è seguita dalla gran parte -delle applicazioni, e non aderirvi potrebbe portare a problemi di +Benché questa sia alla fine soltanto una convenzione, essa è seguita dalla +totalità delle applicazioni, e non aderirvi potrebbe portare a problemi di interoperabilità. Nel caso della shell tutti questi file sono associati al terminale di controllo, e corrispondono quindi alla lettura della tastiera per l'ingresso e alla scrittura sul terminale per l'uscita. Lo standard POSIX.1 @@ -248,17 +248,29 @@ corrispondente,\footnote{è \func{open} che alloca \kstruct{file}, la inserisce \const{O\_CREAT} e \const{O\_EXCL}. \item[\errcode{EINTR}] la funzione era bloccata ed è stata interrotta da un segnale (vedi sez.~\ref{sec:sig_gen_beha}). - \item[\errcode{EISDIR}] \param{pathname} indica una directory e si è tentato - l'accesso in scrittura o in lettura/scrittura. - \item[\errcode{EFBIG}] il file è troppo grande per essere aperto (lo - standard richiederebbe \errval{EOVERFLOW}). + \item[\errcode{EINVAL}] si è usato \const{O\_CREAT} indicando un pathname + con caratteri non supportati dal filesystem sottostante o si è richiesto + \const{O\_TMPFILE} senza indicare \const{O\_WRONLY} o \const{O\_RDWR} o si + è usato \const{O\_DIRECT} per un filesystem che non lo supporta. + \item[\errcode{EISDIR}] \param{pathname} indica una directory e o si è + tentato un accesso che prevede la scrittura o si è usato + \const{O\_TMPFILE} con accesso che prevede la scrittura ma il kernel non + 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 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 risolvere \param{pathname} o si è indicato \const{O\_NOFOLLOW} e - \param{pathname} è un collegamento simbolico. + \param{pathname} è un collegamento simbolico (e non si è usato + \const{O\_PATH}). \item[\errcode{ENODEV}] \param{pathname} si riferisce a un file di dispositivo che non esiste. \item[\errcode{ENOENT}] \param{pathname} non esiste e non si è richiesto - \const{O\_CREAT}, o non esiste un suo componente. + \const{O\_CREAT}, o non esiste un suo componente, o si riferisce ad una + directory inesistente, si è usato \const{O\_TMPFILE} con accesso che + prevede la scrittura ma il kernel non supporta la funzionalità. \item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e \param{pathname} non è una directory. \item[\errcode{ENXIO}] si sono impostati \const{O\_NONBLOCK} o @@ -272,7 +284,7 @@ corrispondente,\footnote{è \func{open} che alloca \kstruct{file}, la inserisce \item[\errcode{EWOULDBLOCK}] la funzione si sarebbe bloccata ma si è richiesto \const{O\_NONBLOCK}. \end{errlist} - ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EMFILE}, + ed inoltre \errval{EACCES}, \errval{EDQUOT}, \errval{EFAULT}, \errval{EMFILE}, \errval{ENAMETOOLONG}, \errval{ENFILE}, \errval{ENOMEM}, \errval{ENOSPC}, \errval{EROFS}, nel loro significato generico.} \end{funcproto} @@ -281,7 +293,9 @@ La funzione apre il file indicato da \param{pathname} nella modalità indicata da \param{flags}. Essa può essere invocata in due modi diversi, specificando opzionalmente un terzo argomento \param{mode}. Qualora il file non esista e venga creato, questo argomento consente di indicare quali permessi dovranno -essergli assegnati. I valori possibili sono gli stessi già visti in +essergli assegnati.\footnote{questo è possibile solo se si è usato in + \param{flags} uno fra \const{O\_CREATE} e \const{O\_TMPFILE}, in tutti gli + altri casi sarà ignorato.} I valori possibili sono gli stessi già visti in sez.~\ref{sec:file_perm_overview} e possono essere specificati come OR binario delle costanti descritte in tab.~\ref{tab:file_bit_perm}. Questi permessi sono comunque filtrati dal valore della \textit{umask} (vedi @@ -305,15 +319,15 @@ impostata all'inizio del file. Una volta aperto un file si potrà operare su di esso direttamente tramite il file descriptor, e quanto avviene al \textit{pathname} con cui lo si è aperto sarà del tutto ininfluente. -\itindbeg{file~status~flag} +\itindbeg{file~status~flags} Il comportamento della funzione, e le diverse modalità con cui può essere aperto il file, vengono controllati dall'argomento \param{flags} il cui valore deve essere indicato come maschera binaria in cui ciascun bit ha un significato specifico. Alcuni di questi bit vanno anche a costituire i -cosiddetti \textsl{flag di stato} del file (i cosiddetti \textit{file status - flags}), che vengono mantenuti nel campo \var{f\_flags} della struttura -\kstruct{file} che abbiamo riportato anche in fig.~\ref{fig:file_proc_file}). +cosiddetti \textit{file status flags} (i \textsl{flag di stato} del file), che +vengono mantenuti nel campo \var{f\_flags} della struttura \kstruct{file} che +abbiamo riportato anche in fig.~\ref{fig:file_proc_file}). Ciascun flag viene identificato da una apposita costante, ed il valore di \param{flags} deve essere specificato come OR aritmetico di queste @@ -374,7 +388,7 @@ sinonimo di \const{O\_RDONLY} e \constd{O\_WRITE} come sinonimo di system}''; pur essendo equivalenti alle definizioni classiche non è comunque il caso di utilizzarle.} -\itindend{file~status~flag} +\itindend{file~status~flags} Il secondo gruppo di flag è quello delle \textsl{modalità di apertura},\footnote{la pagina di manuale di \func{open} parla di @@ -396,51 +410,56 @@ sez.~\ref{sec:file_fcntl_ioctl}). \textbf{Flag} & \textbf{Significato} \\ \hline \hline - \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.\\ - \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 \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}.\\ - \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}).\\ - \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 - l'interfaccia alternativa abilitata con la - macro \macro{\_LARGEFILE64\_SOURCE}. Come - illustrato in sez.~\ref{sec:intro_gcc_glibc_std} è - sempre preferibile usare la conversione automatica - delle funzioni che si attiva assegnando a $64$ la - macro \macro{\_FILE\_OFFSET\_BITS}, e non usare mai - questo flag.\\ - \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}).\\ + \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.\\ + \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 \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}.\\ + \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}).\\ + \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 + l'interfaccia alternativa abilitata con la + macro \macro{\_LARGEFILE64\_SOURCE}. Come + illustrato in sez.~\ref{sec:intro_gcc_glibc_std} è + sempre preferibile usare la conversione automatica + delle funzioni che si attiva assegnando a $64$ la + macro \macro{\_FILE\_OFFSET\_BITS}, e non usare mai + questo flag.\\ + \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}).\\ \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}.\\ - \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 il - comportamento non è specificato.\\ + 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 + il comportamento non è specificato.\\ \hline \end{tabular} \caption{Le costanti che identificano le \textit{modalità di apertura} di @@ -448,12 +467,6 @@ sez.~\ref{sec:file_fcntl_ioctl}). \label{tab:open_time_flag} \end{table} - -% 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/ - \footnotetext{acronimo di \itindex{Denial~of~Service~(DoS)} \textit{Denial of Service}, si chiamano così attacchi miranti ad impedire un servizio causando una qualche forma di carico eccessivo per il sistema, che resta @@ -461,34 +474,92 @@ sez.~\ref{sec:file_fcntl_ioctl}). 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 \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 + 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 assicurarsi che questo non esista di già, e lo si usa spesso per creare i -cosiddetti ``\textsl{file di lock}'' (vedi sez.~\ref{sec:ipc_file_lock}). Si -tenga presente che questa opzione è supportata su NFS solo a partire da 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}.\footnote{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}).} +cosiddetti ``\textsl{file di lock}'' (vedi sez.~\ref{sec:ipc_file_lock}). + +Si tenga presente che questa opzione è supportata su NFS solo a partire da +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 +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}). Se si usa \const{O\_EXCL} senza \const{O\_CREAT} il comportamento è -indefinito. Nella creazione di un file con \const{O\_CREAT} occorre sempre -specificare l'argomento di \param{mode}, che altrimenti è ignorato. Si tenga -presente che indipendentemente dai permessi che si possono assegnare, che in -seguito potrebbero non consentire lettura o scrittura, quando il file viene -aperto l'accesso viene garantito secondo quanto richiesto con i flag di +indefinito, escluso il caso in cui viene usato con \const{O\_TMPFILE} su cui +torneremo più avanti; un'altra eccezione è quello in cui lo si usa da solo su +un file di dispositivo, in quel caso se questo è in uso (ad esempio se è +relativo ad un filesystem che si è montato) si avrà un errore di +\errval{EBUSY}, e pertanto può essere usato in questa modalità per rilevare lo +stato del dispositivo. + +Nella creazione di un file con \const{O\_CREAT} occorre sempre specificare +l'argomento di \param{mode}, che altrimenti è ignorato. Si tenga presente che +indipendentemente dai permessi che si possono assegnare, che in seguito +potrebbero non consentire lettura o scrittura, quando il file viene aperto +l'accesso viene garantito secondo quanto richiesto con i flag di tab.~\ref{tab:open_access_mode_flag}. Quando viene creato un nuovo file \const{O\_CREAT} con tutti e tre i tempi del file di tab.~\ref{tab:file_file_times} vengono impostati al tempo corrente. Se invece 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 da cui non si potrà comunque mai 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 non avrebbe senso fallire se il file non esiste, dato che +questo è sempre vero. + +L'uso di \const{O\_EXCL} attiene all'altro possibile impiego di +\const{O\_TMPFILE} oltre a quello della creazione sicura di un file temporaneo +come sostituto di \func{tmpfile}: la possibilità di creare un eventuale +contenuto iniziale ed impostare permessi, proprietario e attributi estesi con +\func{fchmod}, \func{fchown} e \func{fsetxattr} operando sul file descriptor, +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 @@ -502,7 +573,7 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il viene sempre mantenuta sulla sua coda, per cui quanto si scrive viene sempre aggiunto al contenuto precedente. Con NFS questa funzionalità non è - supportata e viene emulata, per questo possono + supportata e viene emulata, per questo possono verificarsi \textit{race condition} con una sovrapposizione dei dati se più di un processo scrive allo stesso tempo.\\ @@ -512,10 +583,10 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il 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 \textit{fifo}. Per - un bug dell'implementazione non è opportuno usarlo - in fase di apertura del file, deve - invece essere attivato successivamente con + 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}.\\ \constd{O\_CLOEXEC}& Attiva la modalità di \textit{close-on-exec} (vedi sez.~\ref{sec:proc_exec}) sul file. Il flag è @@ -526,7 +597,7 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il 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 @@ -540,19 +611,19 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il montaggio. Introdotto con il kernel 2.6.8 ed utilizzabile soltanto se si è definita la macro \macro{\_GNU\_SOURCE}.\\ - \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 - lettura o scrittura qualora il file non sia pronto - per la loro esecuzione immediata, invece del - blocco delle stesse in attesa di una successiva - possibilità di esecuzione come avviene - normalmente. Questa modalità ha senso solo per le - \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}).\\ + \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 + lettura o scrittura qualora il file non sia pronto + per la loro esecuzione immediata, invece del + blocco delle stesse in attesa di una successiva + possibilità di esecuzione come avviene + normalmente. Questa modalità ha senso solo per le + \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}).\\ \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 @@ -560,6 +631,12 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il 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\_PATH} & Ottiene un file descriptor io cui uso è limitato + all'indicare una posizione sul filesystem o + eseguire operazioni che operano solo a livello del + file descriptor (e non di accesso al contenuto del + file). Introdotto con il kernel 2.6.39, è specifico + di Linux.\\ \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 @@ -580,20 +657,20 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il Il terzo gruppo è quello dei flag delle \textsl{modalità di operazione}, riportati in tab.~\ref{tab:open_operation_flag}, che permettono di specificare varie caratteristiche del comportamento delle operazioni di I/O che verranno -eseguite sul file. Tutti questi, tranne \const{O\_CLOEXEC}, che viene -mantenuto per ogni singolo file descriptor, vengono salvati nel campo -\var{f\_flags} della struttura \kstruct{file} insieme al valore della -\textsl{modalità di accesso} andando far parte dei cosiddetti \textit{file - status flags}. Il loro valore viene impostato alla chiamata di \func{open}, -ma possono venire riletti in un secondo tempo con \func{fcntl}, inoltre alcuni -di essi possono anche essere modificati tramite questa funzione, con -conseguente effetto sulle caratteristiche operative che controllano (torneremo -sull'argomento in sez.~\ref{sec:file_fcntl_ioctl}). +eseguite sul file o le modalità in cui lo si potrà utilizzare. Tutti questi, +tranne \const{O\_CLOEXEC}, che viene mantenuto per ogni singolo file +descriptor, vengono salvati nel campo \var{f\_flags} della struttura +\kstruct{file} insieme al valore della \textsl{modalità di accesso}, andando +far parte dei \textit{file status flags}. Il loro valore viene impostato alla +chiamata di \func{open}, ma possono venire riletti in un secondo tempo con +\func{fcntl}, inoltre alcuni di essi possono anche essere modificati tramite +questa funzione, con conseguente effetto sulle caratteristiche operative che +controllano (torneremo sull'argomento in sez.~\ref{sec:file_fcntl_ioctl}). 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 + ancora presente nella pagina di manuale, almeno fino al novembre 2018.} non solo non attiva il comportamento citato, ma se usato richiede di essere esplicitamente disattivato prima di essere attivato in maniera effettiva con l'uso di \func{fcntl}. Per questo motivo, non essendovi nessuna necessità @@ -601,7 +678,7 @@ specifica di definirlo in fase di apertura del file, è sempre opportuno 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 @@ -629,7 +706,7 @@ completamente equivalente all'uso di \const{O\_SYNC} che garantisce anche 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 @@ -663,6 +740,59 @@ torni a corrispondere al valore di \const{O\_DSYNC}. % NOTE: per le differenze fra O_DSYNC, O_SYNC e O_RSYNC introdotte nella % nello sviluppo del kernel 2.6.33, vedi http://lwn.net/Articles/350219/ +Il flag \constd{O\_PATH}, introdotto con il kernel 2.6.39, viene usato per +limitare l'uso del file descriptor restituito da \func{open} o +all'identificazione di una posizione sul filesystem (ad uso delle +\textit{at-functions} che tratteremo in sez.~\ref{sec:file_openat}) o alle +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}); +\item cambiare directory di lavoro con \func{fchdir} se il file descriptor fa + riferimento a una directory (dal kernel 3.5); +\item usare le funzioni che duplicano il file descriptor (vedi + sez.~\ref{sec:file_dup}); +\item passare il file descriptor ad un altro processo usando un socket + \const{PF\_UNIX} (vedi sez.~\ref{sec:unix_socket}) +\item ottenere le informazioni relative al file con \func{fstat} (dal kernel + 3.6) o al filesystem con \func{fstatfs} (dal kernel 3.12); +\item ottenere il valore dei \textit{file descriptor flags} (fra cui comparirà + anche lo stesso \const{O\_PATH}) o impostare o leggere i \textit{file status + 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}. +\end{itemize*} + +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.) 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. 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 \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} @@ -1703,7 +1833,12 @@ anche l'aggiunta di un ulteriore argomento finale, \param{flags}. % 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/ @@ -4329,9 +4464,14 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o % LocalWords: FIONREAD epoll FIOQSIZE side effects SAFE BYCALLER QUERY EACCES % LocalWords: EBUSY OpenBSD syncfs futimes timespec only init ESRCH kill NTPL % LocalWords: ENXIO NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK PGRP SZ -% LocalWords: EFAULT capabilities GETPIPE SETPIPE RESOURCE +% LocalWords: EFAULT capabilities GETPIPE SETPIPE RESOURCE dell'I all' NFSv %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: + +% 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'