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}.
\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}
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
\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.}
}
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
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.
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
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
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
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
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
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}
\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
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
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
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/)
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},
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
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}
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.
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});
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}
\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.
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},
% 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
% 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:
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