From 89048a8614cd82de7976ac1859a905b2ff182b50 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 23 Aug 2019 21:41:11 +0200 Subject: [PATCH] Inizio revisione file stream --- fileadv.tex | 16 ++ fileio.tex | 417 +++++++++++++++++++++++++++++++--------------------- tcpsock.tex | 6 +- 3 files changed, 269 insertions(+), 170 deletions(-) diff --git a/fileadv.tex b/fileadv.tex index 34dcbf9..15b32e4 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -804,6 +804,17 @@ comportamento sui file duplicati e nel passaggio attraverso \func{fork} ed \func{exec}. Per questo stesso motivo la funzione non è equivalente a \func{flock} e può essere usata senza interferenze insieme a quest'ultima. + +\subsection{Gli \textit{open file descriptor locks}} +\label{sec:open_file_descriptor_locks} + +Come illustrato in dettaglio nella precedente sez.~\ref{sec:file_posix_lock}, +la chiusura di un file su cui sono presenti dei \textit{file lock} comporta +l'immediato rilascio degli stessi, anche se questi sono stati acquisiti da un +processo diverso. + +da finire. + % TODO trattare i POSIX file-private lock introdotti con il 3.15, % vedi http://lwn.net/Articles/586904/ correlato: % http://www.samba.org/samba/news/articles/low_point/tale_two_stds_os2.html @@ -5817,6 +5828,7 @@ file uno \textit{sparse file} a posteriori. % vedi http://lwn.net/Articles/226710/ e http://lwn.net/Articles/240571/ % http://kernelnewbies.org/Linux_2_6_23 + % TODO aggiungere FALLOC_FL_ZERO_RANGE e FALLOC_FL_COLLAPSE_RANGE, inseriti % nel kernel 3.15 (sul secondo vedi http://lwn.net/Articles/589260/), vedi % anche http://lwn.net/Articles/629965/ @@ -5824,6 +5836,10 @@ file uno \textit{sparse file} a posteriori. % TODO aggiungere FALLOC_FL_INSERT vedi http://lwn.net/Articles/629965/ +% TODO aggiungere i file hints di fcntl (F_GET_RW_HINT e compagnia) +% con RWH_WRITE_LIFE_EXTREME e RWH_WRITE_LIFE_SHORT aggiunte con +% il kernel 4.13 (vedi https://lwn.net/Articles/727385/) + % TODO non so dove trattarli, ma dal 2.6.39 ci sono i file handle, vedi % http://lwn.net/Articles/432757/ (probabilmente da associare alle % at-functions) diff --git a/fileio.tex b/fileio.tex index 40dcd9f..59efa44 100644 --- a/fileio.tex +++ b/fileio.tex @@ -2433,7 +2433,7 @@ un file di dispositivo con \textit{major minor} e \textit{minor number} nulli, in maniera atomica quando si rinomina un file. Dato che l'uso di \const{RENAME\_WHITEOUT} comporta in sostanza la creazione di un file di dispositivo, l'operazione è privilegiata (occorre la \textit{capability} -\texttt{CAP\_MKNOD}), inoltre occorre anche il supporto nel filesystem usato +\const{CAP\_MKNOD}), inoltre occorre anche il supporto nel filesystem usato come supporto per la scrittura. Infine l'operazione non è compatibile con \const{RENAME\_EXCHANGE}. @@ -2844,7 +2844,7 @@ accennati in precedenza. \itindend{at-functions} -\subsection{Le operazioni di controllo} +\subsection{Le operazioni di controllo sui file descriptor} \label{sec:file_fcntl_ioctl} Oltre alle operazioni base esaminate in sez.~\ref{sec:file_unix_interface} @@ -2853,8 +2853,6 @@ un file descriptor, che non riguardano la normale lettura e scrittura di dati, ma la gestione sia delle loro proprietà, che di tutta una serie di ulteriori funzionalità che il kernel può mettere a disposizione. -% TODO: trattare qui i file seal - Per le operazioni di manipolazione e di controllo delle varie proprietà e caratteristiche di un file descriptor, viene usata la funzione di sistema \funcd{fcntl},\footnote{ad esempio si gestiscono con questa funzione varie @@ -2866,9 +2864,8 @@ prototipo è: \fhead{unistd.h} \fhead{fcntl.h} \fdecl{int fcntl(int fd, int cmd)} -\fdecl{int fcntl(int fd, int cmd, long arg)} -\fdecl{int fcntl(int fd, int cmd, struct flock * lock)} -\fdecl{int fcntl(int fd, int cmd, struct f\_owner\_ex * owner)} +\fdecl{int fcntl(int fd, int cmd, int arg)} +\fdecl{int fcntl(int fd, int cmd, ...)} \fdesc{Esegue una operazione di controllo sul file.} } @@ -2887,11 +2884,13 @@ prototipo è: Il primo argomento della funzione è sempre il numero di file descriptor \var{fd} su cui si vuole operare. Il comportamento di questa funzione, il numero e il tipo degli argomenti, il valore di ritorno e gli eventuali errori -aggiuntivi, sono determinati dal valore dell'argomento \param{cmd} che in -sostanza corrisponde all'esecuzione di un determinato \textsl{comando}. A -seconda del comando specificato il terzo argomento può essere assente (ma se -specificato verrà ignorato), può assumere un valore intero di tipo -\ctyp{long}, o essere un puntatore ad una struttura \struct{flock}. +aggiuntivi, sono determinati dal valore del secondo argomento \param{cmd}, che +serve a specificare il ``\textsl{comando}'' della funzione, in sostanza quale +operazione si intende eseguire. A seconda del comando richiesto il terzo +argomento può essere assente (ma se specificato lo stesso verrà semplicemente +ignorato) ed in generale dipende dal comando \param{cmd}; il caso più comune è +quello di un intero, ma ci sono comandi in cui si devono usare dei tipi +specifici, che descriveremo esplicitamente nei singoli casi. In sez.~\ref{sec:file_dup} abbiamo incontrato un esempio dell'uso di \func{fcntl} per la duplicazione dei file descriptor, una lista di tutti i @@ -2900,9 +2899,9 @@ 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[\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 + maggiore o uguale all'argomento \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 \errcode{EINVAL} se \param{arg} è negativo o maggiore del massimo consentito o \errcode{EMFILE} se il processo ha già raggiunto il massimo numero di descrittori consentito. @@ -2925,7 +2924,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: nullo significa pertanto che il flag non è impostato. \item[\constd{F\_SETFD}] imposta il valore dei \textit{file descriptor flags} - (vedi sez.~\ref{sec:file_shared_access}) al valore specificato con + (vedi sez.~\ref{sec:file_shared_access}) 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 \textit{close-on-exec}, identificato @@ -2941,36 +2940,42 @@ il nome indicato nel precedente prototipo), è riportata di seguito: dell'argomento \param{flags} di \func{open} che vengono memorizzati nella relativa voce della \textit{file table} all'apertura del file, vale a dire quelli riportati in tab.~\ref{tab:open_access_mode_flag} e - tab.~\ref{tab:open_operation_flag}). Si ricordi che quando si usa la - funzione per determinare le modalità di accesso con cui è stato aperto il - file è necessario estrarre i bit corrispondenti nel \textit{file status - flag} con la maschera \const{O\_ACCMODE} come già accennato in - sez.~\ref{sec:file_open_close}. + tab.~\ref{tab:open_operation_flag}). + + Si ricordi che quando si usa la funzione per determinare le modalità di + accesso con cui è stato aperto il file è necessario estrarre i bit + corrispondenti nel \textit{file status flag} con la maschera + \const{O\_ACCMODE} come già accennato in sez.~\ref{sec:file_open_close}. \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 modificare soltanto \const{O\_APPEND}, \const{O\_ASYNC}, \const{O\_DIRECT}, - \const{O\_NOATIME} e \const{O\_NONBLOCK}. Oltre a \errval{EBADF} si otterrà - \errcode{EPERM} se si cerca di rimuovere \const{O\_APPEND} da un file - marcato come \textit{append-only} o se di cerca di impostare - \const{O\_NOATIME} su un file di cui non si è proprietari (e non si hanno i - 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[\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}. + \const{O\_NOATIME} e \const{O\_NONBLOCK}. + + Oltre a \errval{EBADF} si otterrà \errcode{EPERM} se si cerca di rimuovere + \const{O\_APPEND} da un file marcato come \textit{append-only} o se di cerca + di impostare \const{O\_NOATIME} su un file di cui non si è proprietari (e + non si hanno i 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[\constd{F\_GETLK}] richiede un controllo sul \textit{file lock} + specificato nella struttura \struct{flock} puntata dal terzo argomento (che + pertanto dovrà essere di tipo \ctyp{struct flock *}) sovrascrivendone il + contenuto 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 il terzo argomento non è un puntatore valido restituisce + l'errore generico \errcode{EFAULT}. Questa funzionalità è trattata in + dettaglio in sez.~\ref{sec:file_posix_lock}. -\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[\constd{F\_SETLK}] richiede o rilascia un \textit{file lock} a seconda + di quanto specificato nella struttura puntata dal terzo argomento (sempre di + tipo \ctyp{struct flock *}); ritorna un valore nullo in caso di successo e + $-1$ se il \textit{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[\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 @@ -2978,15 +2983,42 @@ il nome indicato nel precedente prototipo), è riportata di seguito: imposta \var{errno} a \errcode{EINTR}. Questa funzionalità è trattata in dettaglio in sez.~\ref{sec:file_posix_lock}. +\item[\constd{F\_OFD\_GETLK}] analoga di \constd{F\_GETLK} ma per i nuovi + \textit{open file descriptor locks} introdotti con il kernel 3.15, richiede + un controllo sul \textit{file lock} specificato nella struttura + \struct{flock} puntata dal terzo argomento (che pertanto dovrà essere di + tipo \ctyp{struct flock *}) sovrascrivendone il contenuto 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 il terzo argomento + non è un puntatore valido restituisce l'errore generico + \errcode{EFAULT}. Questa funzionalità è trattata in dettaglio in + sez.~\ref{sec:open_file_descriptor_locks}. + +\item[\constd{F\_OFD\_SETLK}] analoga di \constd{F\_SETLK} ma per i nuovi + \textit{open file descriptor locks} introdotti con il kernel 3.15, richiede + o rilascia un \textit{file lock} a seconda di quanto specificato nella + struttura puntata dal terzo argomento (sempre di tipo \ctyp{struct flock + *}); ritorna un valore nullo in caso di successo e $-1$ se il \textit{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:open_file_descriptor_locks}. + +\item[\constd{F\_OFD\_SETLKW}] identica a \const{F\_OFD\_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:open_file_descriptor_locks}. + \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 - asincroni associati al file descriptor \param{fd} e del segnale - \signal{SIGURG} per la notifica dei dati urgenti di un socket (vedi - sez.~\ref{sec:TCP_urgent_data}). Restituisce $-1$ in caso di errore ed il - terzo argomento viene ignorato. Non sono previsti errori diversi da - \errval{EBADF}. + che è preposto alla ricezione dei segnali \signal{SIGIO} o \signal{SIGURG}; + il primo (o l'eventuale segnale alternativo impostato con \const{F\_SETSIG}) + per gli eventi asincroni associati al file descriptor \param{fd} (vedi + sez.~\ref{sec:file_asyncronous_operation}), il secondo per la notifica dei + dati urgenti di un socket (vedi sez.~\ref{sec:TCP_urgent_data}). Restituisce + $-1$ in caso di errore ed il terzo argomento viene ignorato. Non sono + previsti errori diversi da \errval{EBADF}. Per distinguerlo dal caso in cui il segnale viene inviato a un singolo processo, nel caso di un \textit{process group} viene restituito un valore @@ -3014,13 +3046,13 @@ 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[\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 - caso di errore. Oltre a \errval{EBADF} gli errori possibili sono - \errcode{ESRCH} se \param{arg} indica un processo o un \textit{process - group} inesistente. +\item[\constd{F\_SETOWN}] imposta, con il valore del terzo argomento + \param{arg}, l'identificatore del processo o del \textit{process group} che + riceverà i segnali \signal{SIGIO} e \signal{SIGURG} per gli eventi asincroni + associati al file descriptor \param{fd}. Ritorna un valore nullo in caso di + successo o $-1$ in caso di errore. Oltre a \errval{EBADF} gli errori + possibili sono \errcode{ESRCH} se \param{arg} indica un processo o un + \textit{process group} inesistente. L'impostazione è soggetta alle stesse restrizioni presenti sulla funzione \func{kill} (vedi sez.~\ref{sec:sig_kill_raise}), per cui un utente non @@ -3030,27 +3062,28 @@ il nome indicato nel precedente prototipo), è riportata di seguito: valore negativo, il cui valore assoluto corrisponda all'identificatore del \textit{process group}. - A partire dal kernel 2.6.12 se si sta operando con i \textit{thread} della + A partire dal kernel 2.6.12, se si sta operando con i \textit{thread} della implementazione nativa di Linux (quella della NTPL, vedi sez.~\ref{sec:linux_ntpl}) e se si è impostato un segnale specifico con \const{F\_SETSIG}, un valore positivo di \param{arg} viene interpretato come indicante un \textit{Thread ID} e non un \textit{Process ID}. Questo consente di inviare il segnale impostato con \const{F\_SETSIG} ad uno - specifico \textit{thread}. In genere questo non comporta differenze - significative per il processi ordinari, in cui non esistono altri - \textit{thread}, dato che su Linux il \textit{thread} principale, che in tal - caso è anche l'unico, mantiene un valore del \textit{Thread ID} uguale al - \ids{PID} del processo. Il problema è però che questo comportamento non si - applica a \signal{SIGURG}, per il quale \param{arg} viene sempre - interpretato come l'identificatore di un processo o di un \textit{process - group}. - -\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 - eventi associati al file descriptor \param{fd}. Ritorna un valore nullo in - caso di successo o $-1$ in caso di errore. Oltre a \errval{EBADF} e da + specifico \textit{thread}. + + In genere questo non comporta differenze significative per il processi + ordinari, in cui non esistono altri \textit{thread}, dato che su Linux il + \textit{thread} principale, che in tal caso è anche l'unico, mantiene un + valore del \textit{Thread ID} uguale al \ids{PID} del processo. Il problema + è però che questo comportamento non si applica a \signal{SIGURG}, per il + quale \param{arg} viene sempre interpretato come l'identificatore di un + processo o di un \textit{process group}. + +\item[\constd{F\_GETOWN\_EX}] legge nella struttura puntata dal terzo + argomento (che deve essere di tipo \ctyp{struct f\_owner\_ex *}) + l'identificatore del processo, \textit{thread} o \textit{process group} che + è preposto alla ricezione dei 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 caso di errore. Oltre a \errval{EBADF} e da \errval{EFAULT} se \param{owner} non è un puntatore valido. Il comando, che è disponibile solo a partire dal kernel 2.6.32, effettua lo @@ -3058,19 +3091,10 @@ il nome indicato nel precedente prototipo), è riportata di seguito: consente di superare i limiti e le ambiguità relative ai valori restituiti come identificativo. A partire dalla versione 2.11 della \acr{glibc} esso viene usato dalla libreria per realizzare una versione di \func{fcntl} che - non presenti i problemi illustrati in precedenza per la versione precedente - di \const{F\_GETOWN}. Il comando è specifico di Linux ed utilizzabile solo - se si è definita la macro \macro{\_GNU\_SOURCE}. - -\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 - descriptor \param{fd}. Ritorna un valore nullo in caso di successo o $-1$ in - caso di errore, con gli stessi errori di \const{F\_SETOWN} più - \errcode{EINVAL} se il campo \var{type} di \struct{f\_owner\_ex} non indica - un tipo di identificatore valido. - + non presenti i problemi illustrati in precedenza per \const{F\_GETOWN}. Il + comando è specifico di Linux ed utilizzabile solo se si è definita la macro + \macro{\_GNU\_SOURCE}. + \begin{figure}[!htb] \footnotesize \centering \begin{varwidth}[c]{0.5\textwidth} @@ -3081,12 +3105,23 @@ il nome indicato nel precedente prototipo), è riportata di seguito: \label{fig:f_owner_ex} \end{figure} +\item[\constd{F\_SETOWN\_EX}] imposta con il valore della struttura puntata + dal terzo argomento (che deve essere di tipo \ctyp{struct f\_owner\_ex *}) + 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 + caso di errore, con gli stessi errori di \const{F\_SETOWN} più + \errcode{EINVAL} se il campo \var{type} di \struct{f\_owner\_ex} non indica + un tipo di identificatore valido. + Come \const{F\_GETOWN\_EX} il comando richiede come terzo argomento il puntatore ad una struttura \struct{f\_owner\_ex} la cui definizione è - 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 \constd{F\_OWNER\_TID}, + riportata in fig.~\ref{fig:f_owner_ex}, in cui il campo \var{type} indica il + tipo di identificatore che si intende usare, mentre il relativo valore è + specificato nel campo \var{pid}, che assume lo stesso significato del terzo + argomenti di \const{F\_SETOWN}. + + Per \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 @@ -3119,7 +3154,7 @@ il nome indicato nel precedente prototipo), è riportata di seguito: L'impostazione di un valore diverso da zero permette inoltre, se si è installato il gestore del segnale come \var{sa\_sigaction} usando - \const{SA\_SIGINFO}, (vedi sez.~\ref{sec:sig_sigaction}), di rendere + \const{SA\_SIGINFO} (vedi sez.~\ref{sec:sig_sigaction}), di rendere disponibili al gestore informazioni ulteriori riguardo il file che ha generato il segnale attraverso i valori restituiti in \struct{siginfo\_t}. Se inoltre si imposta un segnale \textit{real-time} si @@ -3134,16 +3169,15 @@ il nome indicato nel precedente prototipo), è riportata di seguito: solo se si è definita la macro \macro{\_GNU\_SOURCE}. Questa funzionalità è trattata in dettaglio in sez.~\ref{sec:file_asyncronous_lease}. -\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à - \errcode{EINVAL} se si è specificato un valore non valido per \param{arg} - (deve essere usato uno dei valori di tab.~\ref{tab:file_lease_fctnl}), - \errcode{ENOMEM} se non c'è memoria sufficiente per creare il \textit{file - lease}, \errcode{EACCES} se non si è il proprietario del file e non si - hanno i privilegi di amministratore.\footnote{per la precisione occorre la - capacità \const{CAP\_LEASE}.} +\item[\constd{F\_SETLEASE}] imposta o rimuove a seconda del valore del terzo + argomento \param{arg} un \textit{file lease} sul file descriptor + \var{fd}. Ritorna un valore nullo in caso di successo o $-1$ in caso di + errore. Oltre a \errval{EBADF} si otterrà \errcode{EINVAL} se si è + specificato un valore non valido per \param{arg} (deve essere usato uno dei + valori di tab.~\ref{tab:file_lease_fctnl}), \errcode{ENOMEM} se non c'è + memoria sufficiente per creare il \textit{file lease}, \errcode{EACCES} se + non si è il proprietario del file e non si hanno i privilegi di + amministratore (per la precisione occorre la capacità \const{CAP\_LEASE}). Il supporto il supporto per i \textit{file lease}, che consente ad un processo che detiene un \textit{lease} su un file di riceve una notifica @@ -3178,20 +3212,72 @@ il nome indicato nel precedente prototipo), è riportata di seguito: gli errori possibili sono \errcode{EBUSY} se si cerca di ridurre la dimensione del buffer al di sotto della quantità di dati effettivamente presenti su di esso ed \errcode{EPERM} se un processo non privilegiato cerca - di impostare un valore troppo alto. La dimensione minima del buffer è pari - ad una pagina di memoria, a cui verrà comunque arrotondata ogni dimensione - inferiore, il valore specificato viene in genere arrotondato per eccesso al - valore ritenuto più opportuno dal sistema, pertanto una volta eseguita la - 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 superiore a quello indicato da + di impostare un valore troppo alto. + + La dimensione minima del buffer è pari ad una pagina di memoria, a cui verrà + comunque arrotondata ogni dimensione inferiore, il valore specificato viene + in genere arrotondato per eccesso al valore ritenuto più opportuno dal + sistema, pertanto una volta eseguita la modifica è opportuno rileggere la + nuova dimensione con \const{F\_GETPIPE\_SZ}. + + I processi non privilegiati (occorre la capacità \const{CAP\_SYS\_RESOURCE}) + non possono 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}. +\item[\constd{F\_GET\_SEALS}] restituisce in caso di successo l'insieme dei + \textit{file seal} presenti su \param{fd}, 0 se non ve ne sono o $-1$ in + caso di errore, il terzo argomento viene ignorato. Oltre a \errval{EBADF} + se il file non supporta i \textit{file seal} viene restituito un errore di + \errval{EINVAL}. Il comando è specifico di Linux, è disponibile solo a + partire dal kernel 3.17. Questa funzionalità è trattata in dettaglio in + sez.~\ref{sec:file_seal}. + +\item[\constd{F\_ADD\_SEALS}] aggiunge i \textit{file seal} espressi come + maschera binaria nell'argomento \param{arg} a quelli presenti su \param{fd}, + ritorna un valore nullo in caso di successo o $-1$ in caso di errore. Il + comando è specifico di Linux, è disponibile solo a partire dal kernel + 3.17. Questa funzionalità è trattata in dettaglio in + sez.~\ref{sec:file_seal}. + + % TODO: trovare dove trattare i file seal + +\item[\constd{F\_GET\_RW\_HINT}] legge il valore dei \textit{read/write hints} + associati all'\textit{inode} a cui fa riferimento \param{fd} nella variabile + puntata dal terzo argomento che deve essere di tipo \ctyp{uint64\_t + *}. Ritorna un valore nullo in caso di successo o $-1$ in caso di + errore. Il comando è specifico di Linux, è disponibile solo a partire dal + kernel 4.13. Questa funzionalità è trattata in dettaglio in + sez.~\ref{sec:file_fadvise}. + +\item[\constd{F\_SET\_RW\_HINT}] imposta il valore dei \textit{read/write + hints} associati all'\textit{inode} a cui fa riferimento \param{fd}; il + valore deve essere fornito nella variabile puntata dal terzo argomento, che + deve essere di tipo \ctyp{uint64\_t *}. Ritorna un valore nullo in caso di + successo o $-1$ in caso di errore. Il comando è specifico di Linux, è + disponibile solo a partire dal kernel 4.13. Questa funzionalità è trattata + in dettaglio in sez.~\ref{sec:file_fadvise}. + +\item[\constd{F\_GET\_FILE\_RW\_HINT}] legge il valore dei \textit{read/write + hints} associati al file descriptor \param{fd} nella variabile puntata dal + terzo argomento che deve essere di tipo \ctyp{uint64\_t *}. Ritorna un + valore nullo in caso di successo o $-1$ in caso di errore. Il comando è + specifico di Linux, è disponibile solo a partire dal kernel 4.13. Questa + funzionalità è trattata in dettaglio in sez.~\ref{sec:file_fadvise}. + +\item[\constd{F\_SET\_FILE\_RW\_HINT}] legge il valore dei \textit{read/write + hints} associati al file descriptor \param{fd}; il valore deve essere + fornito nella variabile puntata dal terzo argomento, che deve essere di tipo + \ctyp{uint64\_t *}. Ritorna un valore nullo in caso di successo o $-1$ in + caso di errore. Il comando è specifico di Linux, è disponibile solo a + partire dal kernel 4.13. Questa funzionalità è trattata in dettaglio in + sez.~\ref{sec:file_fadvise}. + + \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/) @@ -3200,10 +3286,11 @@ sono avanzate e richiedono degli approfondimenti ulteriori, saranno pertanto riprese più avanti quando affronteremo le problematiche ad esse relative. In particolare le tematiche relative all'I/O asincrono e ai vari meccanismi di notifica saranno trattate in maniera esaustiva in -sez.~\ref{sec:file_asyncronous_operation} mentre quelle relative al -\textit{file locking} saranno esaminate in sez.~\ref{sec:file_locking}). L'uso -di questa funzione con i socket verrà trattato in -sez.~\ref{sec:sock_ctrl_func}. +sez.~\ref{sec:file_asyncronous_operation}, quelle relative al \textit{file + locking} saranno esaminate in sez.~\ref{sec:file_locking}, quelle relative +ai \textit{file seal} in sez.~\ref{sec:file_seal} e quelle relative ai +\textit{read/write hints} in sez.~\ref{sec:file_fadvise}. L'uso di questa +funzione con i socket verrà trattato in sez.~\ref{sec:sock_ctrl_func}. La gran parte dei comandi di \func{fcntl} (come \const{F\_DUPFD}, \const{F\_GETFD}, \const{F\_SETFD}, \const{F\_GETFL}, \const{F\_SETFL}, @@ -3214,10 +3301,6 @@ esplicitamente soltanto le ulteriori richieste in termini delle macro di funzionalità di sez.~\ref{sec:intro_gcc_glibc_std} soltanto per le funzionalità inserite in standard successivi o specifiche di Linux. - -% \subsection{La funzione \func{ioctl}} -% \label{sec:file_ioctl} - Benché l'interfaccia di gestione dell'I/O sui file di cui abbiamo parlato finora si sia dimostrata valida anche per l'interazione diretta con le periferiche attraverso i loro file di dispositivo, consentendo di usare le @@ -3229,7 +3312,7 @@ porta seriale, o le dimensioni di un framebuffer. Per questo motivo nell'architettura del sistema è stata prevista l'esistenza di una apposita funzione di sistema, \funcd{ioctl}, come meccanismo generico -per compiere operazioni specializzate; il suo prototipo è: +per compiere operazioni specialistiche; il suo prototipo è: \begin{funcproto}{ \fhead{sys/ioctl.h} @@ -3313,7 +3396,7 @@ qualunque file, caratterizzate dal prefisso \texttt{FIO}. Queste operazioni 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}} +\begin{basedescript}{\desclabelwidth{1.8cm}} \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. @@ -3511,7 +3594,7 @@ input/output sul terminale. Per rispondere ad esigenze diverse lo standard definisce tre distinte modalità in cui può essere eseguita la bufferizzazione, delle quali occorre essere ben consapevoli, specie in caso di lettura e scrittura da dispositivi interattivi: -\begin{itemize} +\begin{itemize*} \item \textit{unbuffered}: in questo caso non c'è bufferizzazione ed i caratteri vengono trasmessi direttamente al file non appena possibile (effettuando immediatamente una \func{write}); @@ -3521,7 +3604,7 @@ consapevoli, specie in caso di lettura e scrittura da dispositivi interattivi: quando si preme invio); \item \textit{fully buffered}: in questo caso i caratteri vengono trasmessi da e verso il file in blocchi di dimensione opportuna. -\end{itemize} +\end{itemize*} Lo standard ANSI C specifica inoltre che lo \textit{standard output} e lo \textit{standard input} siano aperti in modalità \textit{fully buffered} @@ -3662,11 +3745,11 @@ evitare di sovrascrivere un file già esistente (è analoga all'uso dell'opzione \const{O\_EXCL} in \func{open}): se il file specificato già esiste e si aggiunge questo carattere a \param{mode} la \func{fopen} fallisce. -Un'altra estensione serve a supportare la localizzazione, quando si -aggiunge a \param{mode} una stringa della forma \verb|",ccs=STRING"| il -valore \verb|STRING| è considerato il nome di una codifica dei caratteri -e \func{fopen} marca il file per l'uso dei caratteri estesi e abilita le -opportune funzioni di conversione in lettura e scrittura. +% Un'altra estensione serve a supportare la localizzazione, quando si +% aggiunge a \param{mode} una stringa della forma \verb|",ccs=STRING"| il +% valore \verb|STRING| è considerato il nome di una codifica dei caratteri +% e \func{fopen} marca il file per l'uso dei caratteri estesi e abilita le +% opportune funzioni di conversione in lettura e scrittura. Nel caso si usi \func{fdopen} i valori specificati da \param{mode} devono essere compatibili con quelli con cui il file descriptor è stato aperto. @@ -3754,45 +3837,52 @@ 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à di -input/output non formattato: -\begin{itemize} -\item\textsl{binario} in cui si leggono e scrivono blocchi di dati di - dimensione arbitraria, (analogo della modalità ordinaria dell'I/O sui file - descriptor), trattato in sez.~\ref{sec:file_binary_io}. -\item\textsl{a caratteri} in cui si legge e scrive un carattere alla volta, - con la bufferizzazione che viene gestita automaticamente dalla libreria, - trattato in sez.~\ref{sec:file_char_io}. -\item\textsl{di linea} in cui si legge e scrive una linea alla volta, - (terminata dal carattere di newline \verb|'\n'|), trattato in - sez.~\ref{sec:file_line_io}. -\end{itemize} -a cui si aggiunge la modalità di input/output formattato, trattato in -sez.~\ref{sec:file_formatted_io}. - -Ognuna di queste modalità utilizza per l'I/O delle funzioni specifiche che -vedremo nelle sezioni citate, affronteremo qui tutte gli argomenti e le -funzioni che si applicano in generale a tutte le modalità di I/O. - -A differenza di quanto avviene con l'interfaccia dei file descriptor, con gli -\textit{stream} il raggiungimento della fine del file viene considerato un -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 +input/output non formattato, che tratteremo in +sez.~\ref{sec:file_unformatted_io}: +\begin{itemize*} +\item\textsl{Input/Output binario}, una modalità in cui si leggono e scrivono + blocchi di dati di dimensione arbitraria; è l'analogo della modalità + ordinaria dell'input/output sui file descriptor vista in + sez.~\ref{sec:file_read} e \ref{sec:file_write}. +\item\textsl{Input/Output a caratteri}, una modalità in cui si legge e scrive + un singolo carattere alla volta, anche in questo caso la bufferizzazione + viene gestita automaticamente dalla libreria; +\item\textsl{input/output di linea}, una modalità in cui si legge e scrive una + linea di testo alla volta, in questa modalità si intende per linea una + sequenza di caratteri terminata dal carattere di \textit{newline} + (\verb|'\n'|); +\end{itemize*} + +A queste tre modalità si aggiunge poi la modalità di input/output formattato, +che tratteremo in sez.~\ref{sec:file_unformatted_io}. Ognuna di queste +modalità utilizza per l'I/O delle funzioni specifiche che vedremo più avanti, +affronteremo qui invece gli argomenti e le funzioni che si applicano in +generale a tutte tutte queste diverse modalità di I/O. + +Una prima caratteristica specifica è che differenza di quanto avviene con +l'interfaccia dei file descriptor, con gli \textit{stream} il raggiungimento +della fine del file viene considerato un errore, che viene notificato come +tale dai valori di uscita delle varie funzioni. + +In vari casi questo avviene con la restituzione di uno specifico +valore intero (di tipo \ctyp{int}) definito come \val{EOF} nell'header \headfile{stdlib.h}. La costante deve essere negativa perché in molte funzioni -un valore positivo indica la quantità di dati scritti, la \acr{glibc} usa il -valore $-1$, ma altre implementazioni possono avere valori diversi. +un valore positivo indica la quantità di dati scritti e ci potrebbe essere +sovrapposizione, 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 -libreria che si appoggiano a delle \textit{system call}, esse non impostano -direttamente la variabile \var{errno}, che mantiene sempre il valore impostato -dalla \textit{system call} invocata internamente che ha riportato l'errore. +libreria realizzate usando delle \textit{system call}, esse non modificano mai +direttamente la variabile \var{errno}, che in caso di errore mantiene sempre +il valore impostato dalla \textit{system call} sottostante che lo ha +riportato. Siccome la condizione di \textit{end-of-file} è anch'essa segnalata come -errore, nasce il problema di come distinguerla da un errore effettivo; basarsi -solo sul valore di ritorno della funzione e controllare il valore di -\var{errno} infatti non basta, dato che quest'ultimo potrebbe essere stato -impostato in una altra occasione, (si veda sez.~\ref{sec:sys_errno} per i -dettagli del funzionamento di \var{errno}). +errore, nasce il problema di come distinguerla; basarsi solo sul valore di +ritorno della funzione e controllare il valore di \var{errno} infatti non +basta, dato che quest'ultimo potrebbe essere stato impostato in una altra +occasione, (si veda sez.~\ref{sec:sys_errno} per i dettagli del funzionamento +di \var{errno}). Per questo motivo tutte le implementazioni delle librerie standard mantengono per ogni \textit{stream} almeno due flag all'interno dell'oggetto \type{FILE}, @@ -3936,8 +4026,8 @@ sistemi più moderni. % TODO: mettere prototipi espliciti fseeko e ftello o menzione? -\subsection{Input/output binario} -\label{sec:file_binary_io} +\subsection{Input/output non formattato} +\label{sec:file_unformatted_io} La prima modalità di input/output non formattato ricalca quella della interfaccia dei file descriptor, e provvede semplicemente la scrittura e la @@ -4037,11 +4127,8 @@ per i dettagli), i loro prototipi sono: % TODO: trattare in generale le varie *_unlocked -\subsection{Input/output a caratteri} -\label{sec:file_char_io} - -La seconda modalità di input/output è quella a caratteri, in cui si -trasferisce un carattere alla volta. Le funzioni per la lettura a +La seconda modalità di input/output non formattato è quella a caratteri, in +cui si trasferisce un carattere alla volta. Le funzioni per la lettura a caratteri sono tre, \funcd{fgetc}, \funcd{getc} e \funcd{getchar}, ed i rispettivi prototipi sono: @@ -4206,10 +4293,6 @@ ma opera esclusivamente sul buffer interno. Se si esegue una qualunque delle operazioni di riposizionamento (vedi sez.~\ref{sec:file_io}) i caratteri rimandati indietro vengono scartati. - -\subsection{Input/output di linea} -\label{sec:file_line_io} - La terza ed ultima modalità di input/output non formattato è quella di linea, in cui si legge o si scrive una riga alla volta. Questa è la modalità usata normalmente per l'I/O da terminale, ed è anche quella che presenta le diff --git a/tcpsock.tex b/tcpsock.tex index 488dbc5..5951a91 100644 --- a/tcpsock.tex +++ b/tcpsock.tex @@ -1849,7 +1849,7 @@ scriverli su \file{stdout}. Quando si concluderà l'invio di dati mandando un \textit{end-of-file} sullo \textit{standard input} si avrà il ritorno di \func{fgets} con un puntatore -nullo (si riveda quanto spiegato in sez.~\ref{sec:file_line_io}) e la +nullo (si riveda quanto spiegato in sez.~\ref{sec:file_unformatted_io}) e la conseguente uscita dal ciclo; al che la subroutine ritorna ed il nostro programma client termina. @@ -2088,8 +2088,8 @@ tab.~\ref{tab:proc_proc_states}). Se a questo punto si inizia a scrivere qualcosa sul client non sarà trasmesso niente fintanto che non si preme il tasto di a capo (si ricordi quanto detto -in sez.~\ref{sec:file_line_io} a proposito dell'I/O su terminale). Solo -allora \func{fgets} ritornerà ed il client scriverà quanto immesso dal +in sez.~\ref{sec:file_unformatted_io} a proposito dell'I/O su terminale). +Solo allora \func{fgets} ritornerà ed il client scriverà quanto immesso dal terminale sul socket, per poi passare a rileggere quanto gli viene inviato all'indietro dal server, che a sua volta sarà inviato sullo \textit{standard output}, che nel caso ne provoca l'immediata stampa a video. -- 2.30.2