X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileio.tex;h=7b326993c04038bb18fab5dea3c210530d45183e;hp=a044eec8facbf96bed7ac9f2c90fa14ef4efd209;hb=5a15091e17c25f37a6f53751ccde91f504006773;hpb=99fa5a06cd27160cf673e3483ad552d32efa2c05 diff --git a/fileio.tex b/fileio.tex index a044eec..7b32699 100644 --- a/fileio.tex +++ b/fileio.tex @@ -1,6 +1,6 @@ %% 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", @@ -59,10 +59,10 @@ file dovrà essere chiuso, e questo chiuderà il canale di comunicazione 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} @@ -109,7 +109,7 @@ particolare: \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} @@ -133,18 +133,18 @@ essenziali come: \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} @@ -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 @@ -178,12 +178,9 @@ tab.~\ref{tab:file_std_files}. \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.} @@ -209,9 +206,9 @@ Si ritrova quindi anche con le voci della \textit{file table} una situazione 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 @@ -251,23 +248,35 @@ 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 - \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 @@ -275,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} @@ -284,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 @@ -308,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 @@ -340,9 +351,9 @@ costanti di tab.~\ref{tab:open_access_mode_flag}. \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 @@ -368,16 +379,16 @@ La modalità di accesso deve sempre essere specificata quando si apre un file, 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.} -\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 @@ -399,51 +410,56 @@ sez.~\ref{sec:file_fcntl_ioctl}). \textbf{Flag} & \textbf{Significato} \\ \hline \hline - \const{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 - 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 - 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 - \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 - 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.\\ - \const{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\_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}.\\ - \const{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 - 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 @@ -451,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 @@ -464,34 +474,91 @@ 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 \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 - 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 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 @@ -500,42 +567,42 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il \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 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.\\ - \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 - 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}.\\ - \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}).\\ + \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}).\\ \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 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 @@ -543,32 +610,38 @@ 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}.\\ - \const{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 - 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\_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 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 + \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 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 @@ -583,20 +656,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}). - -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 +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à @@ -604,7 +677,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 @@ -632,7 +705,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 @@ -666,6 +739,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} @@ -721,24 +847,32 @@ Si ricordi che quando un processo termina tutti i suoi file descriptor vengono 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} @@ -780,8 +914,8 @@ da \param{offset}, che viene sommato al riferimento dato 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 @@ -796,23 +930,23 @@ posizione corrente nel file con \code{lseek(fd, 0, SEEK\_CUR)}. \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 @@ -889,8 +1023,8 @@ 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 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 @@ -912,11 +1046,11 @@ riporti sempre la fine del file e \const{SEEK\_DATA} il valore 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}). @@ -1010,7 +1144,7 @@ torneremo sull'argomento in sez.~\ref{sec:file_noblocking}. 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.} @@ -1039,8 +1173,8 @@ L'uso di \func{pread} è equivalente all'esecuzione di una \func{read} seguita 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 @@ -1071,6 +1205,10 @@ prototipo è: \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. @@ -1078,13 +1216,14 @@ prototipo è: 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} @@ -1197,7 +1336,7 @@ situazione è illustrata in fig.~\ref{fig:file_acc_child}; dato che il processo figlio riceve una copia dello spazio di indirizzi del padre, riceverà anche una copia di \kstruct{file\_struct} e della relativa tabella dei file aperti. -Questo significa che il figlio avrà gli stessi file aperti del padre, in +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 @@ -1215,7 +1354,7 @@ mantenuti nella struttura \kstruct{file} della \textit{file table}, vengono condivisi, per cui una modifica degli stessi con \func{fcntl} (vedi sez.~\ref{sec:file_fcntl_ioctl}) si applicherebbe a tutti processi che condividono la voce nella \textit{file table}. Ai file però sono associati -anche altri flag, dei quali l'unico usato al momento è \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 @@ -1330,7 +1469,7 @@ standard che si vuole redirigere e poi aprire direttamente con \func{open} il file vi si vuole far corrispondere, invece di duplicare un file descriptor che si è già aperto. La risposta sta nel fatto che il file che si vuole redirigere non è detto sia un file regolare, ma potrebbe essere, come accennato, anche -una fifo o un socket, oppure potrebbe essere un file associato ad un file +una \textit{fifo} o un socket, oppure potrebbe essere un file associato ad un file descriptor che si è ereditato già aperto (ad esempio attraverso un'altra \func{exec}) da un processo antenato del padre, del quale non si conosce il nome. Operando direttamente con i file descriptor \func{dup} consente di @@ -1471,7 +1610,7 @@ 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 -\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 @@ -1638,7 +1777,7 @@ 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 \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 @@ -1697,9 +1836,21 @@ tab.~\ref{tab:file_atfunc_corr}, oltre al nuovo argomento iniziale, è prevista 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 +% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) + % 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/ @@ -1837,18 +1988,20 @@ costanti utilizzabili per i valori di \param{flags}. \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 @@ -1857,15 +2010,88 @@ costanti utilizzabili per i valori di \param{flags}. \end{table} +\texttt{ATTENZIONE PARTE DA RIVEDERE} + + 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 -precisione fino al nanosecondo. +precisione fino al nanosecondo; la funzione è stata introdotta con il kernel +2.6.22,\footnote{in precedenza, a partire dal kernel 2.6.16, era stata + introdotta una \textit{system call} \funcm{futimesat} seguendo una bozza + della revisione dello standard poi modificata; questa funzione, sostituita + da \func{utimensat}, è stata dichiarata obsoleta, non è supportata da + nessuno standard e non deve essere più utilizzata: pertanto non ne + parleremo.} ed il suo prototipo è: + +\begin{funcproto}{ +\fhead{sys/time.h} +\fdecl{int utimensat(int dirfd, const char *pathname, const struct + timespec times[2], int flags)} +\fdesc{Cambia i tempi di un file.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EACCES}] si è richiesta l'impostazione del tempo corrente ma + non si ha il permesso di scrittura sul file, o non si è proprietari del + file o non si hanno i privilegi di amministratore; oppure il file è + immutabile (vedi sez.~\ref{sec:file_perm_overview}). + \item[\errcode{EBADF}] \param{dirfd} non è \const{AT\_FDCWD} o un file + descriptor valido. + \item[\errcode{EFAULT}] \param{times} non è un puntatore valido oppure + \param{dirfd} è \const{AT\_FDCWD} ma \param{pathname} è \var{NULL} o non è + un puntatore valido. + \item[\errcode{EINVAL}] si sono usati dei valori non corretti per i tempi di + \param{times}, oppure è si usato un valore non valido per \param{flags}, + oppure \param{pathname} è \var{NULL}, \param{dirfd} non è + \const{AT\_FDCWD} e \param{flags} contiene \const{AT\_SYMLINK\_NOFOLLOW}. + \item[\errcode{EPERM}] si è richiesto un cambiamento nei tempi non al tempo + corrente, ma non si è proprietari del file o non si hanno i privilegi di + amministratore; oppure il file è immutabile o \textit{append-only} (vedi + sez.~\ref{sec:file_perm_overview}). + \item[\errcode{ESRCH}] non c'è il permesso di attraversamento per una delle + componenti di \param{pathname}. + \end{errlist} + ed inoltre per entrambe \errval{EROFS} e per \func{utimensat} + \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel + loro significato generico.} +\end{funcproto} + +La funzione imposta i tempi dei file utilizzando i valori passati nel vettore +di strutture \struct{timespec} esattamente come \func{futimes} (si veda quanto +illustrato in sez.~\ref{sec:file_file_times}). + +La funzione supporta invece, rispetto ad \func{utimes} che abbiamo visto in +sez.~\ref{sec:file_file_times}, una sintassi più complessa che consente una +indicazione sicura del file su cui operare specificando la directory su cui si +trova tramite il file descriptor \param{dirfd} ed il suo nome come +\textit{pathname relativo} in \param{pathname}.\footnote{su Linux solo + \func{utimensat} è una \textit{system call} e \func{futimens} è una funzione + di libreria, infatti se \param{pathname} è \var{NULL} \param{dirfd} viene + considerato un file descriptor ordinario e il cambiamento del tempo + applicato al file sottostante, qualunque esso sia, per cui + \code{futimens(fd, times}) è del tutto equivalente a \code{utimensat(fd, + NULL, times, 0)} ma nella \acr{glibc} questo comportamento è disabilitato + seguendo lo standard POSIX, e la funzione ritorna un errore di + \errval{EINVAL} se invocata in questo modo.} + +Torneremo su questa sintassi e sulla sua motivazione in +sez.~\ref{sec:file_openat}, quando tratteremo tutte le altre funzioni (le +cosiddette \textit{at-functions}) che la utilizzano; essa prevede comunque +anche la presenza dell'argomento \param{flags} con cui attivare flag di +controllo che modificano il comportamento della funzione, nel caso specifico +l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che indica alla +funzione di non dereferenziare i collegamenti simbolici, cosa che le permette +di riprodurre le funzionalità di \func{lutimes}. + + +\texttt{ATTENZIONE PARTE DA RIVEDERE} -% NOTA: manca prototipo di utimensat, per ora si lascia una menzione \itindend{at-functions} @@ -1927,7 +2153,7 @@ possibili valori per \var{cmd}, e del relativo significato, dei codici di 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 @@ -1937,7 +2163,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: \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 @@ -1945,7 +2171,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: \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 @@ -1954,7 +2180,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: \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 @@ -1965,7 +2191,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: \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 @@ -1978,7 +2204,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -1990,26 +2216,26 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2045,7 +2271,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2076,7 +2302,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2093,7 +2319,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2117,17 +2343,17 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2137,8 +2363,8 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2158,14 +2384,14 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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à @@ -2184,7 +2410,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2194,7 +2420,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2202,7 +2428,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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} @@ -2216,13 +2442,16 @@ il nome indicato nel precedente prototipo), è riportata di seguito: 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 @@ -2233,10 +2462,10 @@ sez.~\ref{sec:file_asyncronous_operation} mentre quelle relative al 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 @@ -2342,36 +2571,36 @@ sono definite nel kernel a livello generale, e vengono sempre interpretate per 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. @@ -2395,6 +2624,7 @@ due funzioni sono rimaste. % 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{} @@ -2412,7 +2642,7 @@ ANSI C, che invece sono realizzate attraverso opportune funzioni di libreria. 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 @@ -2460,7 +2690,7 @@ concorrente ed in sez.~\ref{sec:file_access_control} per il controllo di 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. @@ -2630,7 +2860,7 @@ esso viene preventivamente chiuso e tutti i dati pendenti vengono scaricati. 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] @@ -2682,7 +2912,7 @@ distinguere i file binari dai file di testo; in un sistema POSIX questa 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 @@ -2749,12 +2979,12 @@ La funzione chiude lo \textit{stream} \param{stream} ed effettua lo scarico di 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}{ @@ -2780,7 +3010,7 @@ sez.~\ref{sec:proc_conclusion}). 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 @@ -2806,7 +3036,7 @@ errore, e viene notificato come tale dai valori di uscita delle varie 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 @@ -2871,9 +3101,9 @@ all'interno di un file per effettuare operazioni di lettura o scrittura in un 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 @@ -2938,7 +3168,7 @@ intero di tipo \ctyp{long}. Dato che in certi casi, ad esempio quando si usa 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} @@ -3037,16 +3267,16 @@ di architettura hardware, come la dimensione del bus o la modalità di 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} @@ -3162,8 +3392,8 @@ essere ottenuto con un cast da un \ctyp{unsigned char}). Anche il valore di 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}. @@ -3270,14 +3500,16 @@ che vedremo in sez.~\ref{sec:file_formatted_io} come ``\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 @@ -3288,6 +3520,8 @@ l'esecuzione nel codice inviato nella stringa stessa, che in genere contiene 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} @@ -3351,8 +3585,8 @@ quello di \func{fgets} e \func{fputs}, a parte il fatto che tutto (numero di 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 @@ -3370,7 +3604,7 @@ conclusione della stringa presente nel buffer), ma a costo di una 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 @@ -3603,7 +3837,7 @@ specificati in questo ordine: 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 @@ -3717,7 +3951,7 @@ Infine una ulteriore estensione GNU definisce le due funzioni \funcm{dprintf} e \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 @@ -3763,7 +3997,7 @@ in campi fissi. Uno spazio in \param{format} corrisponde con un numero 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 @@ -3824,8 +4058,8 @@ quest'ultimo; il suo prototipo è: 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 @@ -3922,9 +4156,9 @@ in \param{buf} e la dimensione in \param{size}. \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} @@ -3937,7 +4171,7 @@ stato allocato e rimanere disponibile per tutto il tempo in cui si opera sullo \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 @@ -3960,7 +4194,7 @@ opportuni valori elencati in tab.~\ref{tab:file_stream_buf_mode}. Qualora si 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: @@ -3987,7 +4221,7 @@ chiamate a \func{setvbuf} e sono definite solo per compatibilità con le 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: @@ -4022,7 +4256,7 @@ scelta, si può forzare lo scarico dei dati sul file con la funzione \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}? @@ -4031,7 +4265,7 @@ Se \param{stream} è \val{NULL} lo scarico dei dati è forzato per tutti gli \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}{ @@ -4069,7 +4303,6 @@ compresi gli eventuali caratteri rimandati indietro con \func{ungetc}. \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 @@ -4130,7 +4363,7 @@ comportare dei costi pesanti in termini di prestazioni. 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 @@ -4140,7 +4373,7 @@ come macro. 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}, @@ -4169,14 +4402,14 @@ assumere uno dei valori indicati in tab.~\ref{tab:file_fsetlocking_type}. \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} @@ -4191,8 +4424,6 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o % TODO trattare \func{clearerr\_unlocked} -\itindend{thread} - %%% Local Variables: @@ -4245,9 +4476,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'