La seconda interfaccia per l'\textit{advisory locking} disponibile in Linux è
quella standardizzata da POSIX, basata sulla funzione \func{fcntl}. Abbiamo
già trattato questa funzione nelle sue molteplici possibilità di utilizzo in
-sez.~\ref{sec:file_fcntl}. Quando la si impiega per il \textit{file locking}
-essa viene usata solo secondo il seguente prototipo:
+sez.~\ref{sec:file_fcntl_ioctl}. Quando la si impiega per il \textit{file
+ locking} essa viene usata solo secondo il seguente prototipo:
\begin{prototype}{fcntl.h}{int fcntl(int fd, int cmd, struct flock *lock)}
Applica o rimuove un \textit{file lock} sul file \param{fd}.
Oltre a quanto richiesto tramite i campi di \struct{flock}, l'operazione
effettivamente svolta dalla funzione è stabilita dal valore dall'argomento
-\param{cmd} che, come già riportato in sez.~\ref{sec:file_fcntl}, specifica
-l'azione da compiere; i valori relativi al \textit{file locking} sono tre:
+\param{cmd} che, come già riportato in sez.~\ref{sec:file_fcntl_ioctl},
+specifica l'azione da compiere; i valori relativi al \textit{file locking}
+sono tre:
\begin{basedescript}{\desclabelwidth{2.0cm}}
\item[\const{F\_GETLK}] verifica se il \textit{file lock} specificato dalla
struttura puntata da \param{lock} può essere acquisito: in caso negativo
\section{L'accesso \textsl{asincrono} ai file}
-\label{sec:file_asyncronous_access}
+\label{sec:file_asyncronous_operation}
Benché l'\textit{I/O multiplexing} sia stata la prima, e sia tutt'ora una fra
le più diffuse modalità di gestire l'I/O in situazioni complesse in cui si
\subsection{Il \textit{Signal driven I/O}}
-\label{sec:file_asyncronous_operation}
+\label{sec:file_signal_driven_io}
\itindbeg{signal~driven~I/O}
\const{O\_ASYNC}, che consentirebbe di aprire un file in modalità asincrona,
anche se in realtà è opportuno attivare in un secondo tempo questa modalità
impostando questo flag attraverso l'uso di \func{fcntl} con il comando
-\const{F\_SETFL} (vedi sez.~\ref{sec:file_fcntl}).\footnote{l'uso del flag di
- \const{O\_ASYNC} e dei comandi \const{F\_SETOWN} e \const{F\_GETOWN} per
- \func{fcntl} è specifico di Linux e BSD.} In realtà parlare di apertura in
-modalità asincrona non significa che le operazioni di lettura o scrittura del
-file vengono eseguite in modo asincrono (tratteremo questo, che è ciò che più
-propriamente viene chiamato \textsl{I/O asincrono}, in
+\const{F\_SETFL} (vedi sez.~\ref{sec:file_fcntl_ioctl}).\footnote{l'uso del
+ flag di \const{O\_ASYNC} e dei comandi \const{F\_SETOWN} e \const{F\_GETOWN}
+ per \func{fcntl} è specifico di Linux e BSD.} In realtà parlare di apertura
+in modalità asincrona non significa che le operazioni di lettura o scrittura
+del file vengono eseguite in modo asincrono (tratteremo questo, che è ciò che
+più propriamente viene chiamato \textsl{I/O asincrono}, in
sez.~\ref{sec:file_asyncronous_io}), quanto dell'attivazione un meccanismo di
notifica asincrona delle variazione dello stato del file descriptor aperto in
questo modo.
kernel 2.6, anche per fifo e pipe.} il sistema genera un apposito segnale,
\signal{SIGIO}, tutte le volte che diventa possibile leggere o scrivere dal
file descriptor che si è posto in questa modalità. Inoltre è possibile, come
-illustrato in sez.~\ref{sec:file_fcntl}, selezionare con il comando
+illustrato in sez.~\ref{sec:file_fcntl_ioctl}, selezionare con il comando
\const{F\_SETOWN} di \func{fcntl} quale processo o quale gruppo di processi
dovrà ricevere il segnale. In questo modo diventa possibile effettuare le
operazioni di I/O in risposta alla ricezione del segnale, e non ci sarà più la
supportano meccanismi simili). Alcune di esse sono realizzate, e solo a
partire dalla versione 2.4 del kernel, attraverso l'uso di alcuni
\textsl{comandi} aggiuntivi per la funzione \func{fcntl} (vedi
-sez.~\ref{sec:file_fcntl}), che divengono disponibili soltanto se si è
+sez.~\ref{sec:file_fcntl_ioctl}), che divengono disponibili soltanto se si è
definita la macro \macro{\_GNU\_SOURCE} prima di includere \headfile{fcntl.h}.
\itindbeg{file~lease}
il file viene aperto in lettura; in quest'ultimo caso però il \textit{lease}
può essere ottenuto solo se nessun altro processo ha aperto lo stesso file.
-Come accennato in sez.~\ref{sec:file_fcntl} il comando di \func{fcntl} che
-consente di acquisire un \textit{file lease} è \const{F\_SETLEASE}, che viene
-utilizzato anche per rilasciarlo. In tal caso il file descriptor \param{fd}
-passato a \func{fcntl} servirà come riferimento per il file su cui si vuole
-operare, mentre per indicare il tipo di operazione (acquisizione o rilascio)
-occorrerà specificare come valore dell'argomento \param{arg} di \func{fcntl}
-uno dei tre valori di tab.~\ref{tab:file_lease_fctnl}.
+Come accennato in sez.~\ref{sec:file_fcntl_ioctl} il comando di \func{fcntl}
+che consente di acquisire un \textit{file lease} è \const{F\_SETLEASE}, che
+viene utilizzato anche per rilasciarlo. In tal caso il file
+descriptor \param{fd} passato a \func{fcntl} servirà come riferimento per il
+file su cui si vuole operare, mentre per indicare il tipo di operazione
+(acquisizione o rilascio) occorrerà specificare come valore
+dell'argomento \param{arg} di \func{fcntl} uno dei tre valori di
+tab.~\ref{tab:file_lease_fctnl}.
\begin{table}[htb]
\centering
essere utilizzato come argomento per le funzioni \func{select} e \func{poll} e
con l'interfaccia di \textit{epoll};\footnote{ed a partire dal kernel 2.6.25 è
stato introdotto anche il supporto per il \itindex{signal~driven~I/O}
- \texttt{signal-driven I/O} trattato in
- sez.~\ref{sec:file_asyncronous_operation}.} siccome gli eventi vengono
-notificati come dati disponibili in lettura, dette funzioni ritorneranno tutte
-le volte che si avrà un evento di notifica. Così, invece di dover utilizzare i
-segnali,\footnote{considerati una pessima scelta dal punto di vista
- dell'interfaccia utente.} si potrà gestire l'osservazione degli eventi con
-una qualunque delle modalità di \textit{I/O multiplexing} illustrate in
-sez.~\ref{sec:file_multiplexing}. Qualora si voglia cessare l'osservazione,
-sarà sufficiente chiudere il file descriptor e tutte le risorse allocate
-saranno automaticamente rilasciate.
+ \texttt{signal-driven I/O} trattato in sez.~\ref{sec:signal_driven_io}.}
+siccome gli eventi vengono notificati come dati disponibili in lettura, dette
+funzioni ritorneranno tutte le volte che si avrà un evento di notifica. Così,
+invece di dover utilizzare i segnali,\footnote{considerati una pessima scelta
+ dal punto di vista dell'interfaccia utente.} si potrà gestire l'osservazione
+degli eventi con una qualunque delle modalità di \textit{I/O multiplexing}
+illustrate in sez.~\ref{sec:file_multiplexing}. Qualora si voglia cessare
+l'osservazione, sarà sufficiente chiudere il file descriptor e tutte le
+risorse allocate saranno automaticamente rilasciate.
Infine l'interfaccia di \textit{inotify} consente di mettere sotto
osservazione, oltre che una directory, anche singoli file. Una volta creata
socket (si veda sez.~\ref{sec:sock_ioctl_IP}) il numero di byte disponibili in
lettura sul file descriptor, utilizzando su di esso l'operazione
\const{FIONREAD}.\footnote{questa è una delle operazioni speciali per i file
- (vedi sez.~\ref{sec:file_ioctl}), che è disponibile solo per i socket e per
- i file descriptor creati con \func{inotify\_init}.} Si può così utilizzare
-questa operazione, oltre che per predisporre una operazione di lettura con un
-buffer di dimensioni adeguate, anche per ottenere rapidamente il numero di
-file che sono cambiati.
+ (vedi sez.~\ref{sec:file_fcntl_ioctl}), che è disponibile solo per i socket
+ e per i file descriptor creati con \func{inotify\_init}.} Si può così
+utilizzare questa operazione, oltre che per predisporre una operazione di
+lettura con un buffer di dimensioni adeguate, anche per ottenere rapidamente
+il numero di file che sono cambiati.
Una volta effettuata la lettura con \func{read} a ciascun evento sarà
associata una struttura \struct{inotify\_event} contenente i rispettivi dati.
driver, in cui si richiede la verifica della capacità di accesso in lettura
e scrittura ma viene restituito un file descriptor che non può essere letto
o scritto, ma solo usato con una \func{ioctl} (vedi
- sez.~\ref{sec:file_ioctl}).}
+ sez.~\ref{sec:file_fcntl_ioctl}).}
La modalità di accesso deve sempre essere specificata quando si apre un file,
il valore indicato in \param{flags} viene salvato nei
\itindex{file~status~flag} \textit{file status flags}, e può essere riletto
-con \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}), il relativo valore può
-essere poi ottenuto un AND aritmetico della maschera binaria
+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 \const{O\_WRONLY}.\footnote{si tratta di
\func{open} nel momento in viene eseguita per aprire un file. Questi flag
hanno effetto solo nella chiamata della funzione, non sono memorizzati fra i
\itindex{file~status~flag} \textit{file status flags} e non possono essere
-riletti da \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}).
+riletti da \func{fcntl} (vedi sez.~\ref{sec:file_fcntl_ioctl}).
\begin{table}[htb]
\centering
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
- sez.~\ref{sec:file_asyncronous_io}). Quando è
+ 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
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}).\\
+ 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
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_ioctl}).\\
+ sez.~\ref{sec:file_fcntl_ioctl}).\\
\const{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
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}).
+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
l'uso di \func{fcntl}. Per questo motivo, non essendovi nessuna necessità
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}).
+sez.~\ref{sec:file_fcntl_ioctl}).
Il flag \const{O\_DIRECT} non è previsto da nessuno standard, anche se è
presente in alcuni kernel unix-like.\footnote{il flag è stato introdotto dalla
quelle classiche appena esposte. 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_ioctl}).
+(vedi sez.~\ref{sec:file_fcntl_ioctl}).
Si noti inoltre che in questo caso anche i \itindex{file~status~flag} flag di
stato del file, essendo 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}) si applicherebbe a tutti
+\func{fcntl} (vedi sez.~\ref{sec:file_fcntl_ioctl}) si applicherebbe a tutti
processi che condividono la voce nella \itindex{file~table} \textit{file
table}. Ai file però sono associati anche altri flag, dei quali l'unico
usato al momento è \const{FD\_CLOEXEC}, detti \itindex{file~descriptor~flags}
tenuto presente che nel caso in cui si usi \func{dup} per duplicare un file
descriptor, se questo ha il flag di \textit{close-on-exec}
\itindex{close-on-exec} attivo (vedi sez.~\ref{sec:proc_exec} e
-sez.~\ref{sec:file_fcntl}), questo verrà cancellato nel file descriptor
+sez.~\ref{sec:file_fcntl_ioctl}), questo verrà cancellato nel file descriptor
restituito come copia.
L'uso principale di questa funzione è nella shell per la redirezione dei file
La duplicazione dei file descriptor può essere effettuata anche usando la
funzione di controllo dei file \func{fcntl} (che esamineremo in
-sez.~\ref{sec:file_fcntl}) con il parametro \const{F\_DUPFD}. L'operazione ha
+sez.~\ref{sec:file_fcntl_ioctl}) con il parametro \const{F\_DUPFD}. L'operazione ha
la sintassi \code{fcntl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per
\param{newfd} diventa equivalente a \func{dup}. La sola differenza fra le due
funzioni (a parte la sintassi ed i diversi codici di errore) è che \func{dup2}
% http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
-\subsection{La funzione \func{fcntl}}
-\label{sec:file_fcntl}
+\subsection{Le operazioni di controllo}
+\label{sec:file_fcntl_ioctl}
Oltre alle operazioni base esaminate in sez.~\ref{sec:file_unix_interface}
esistono tutta una serie di operazioni ausiliarie che è possibile eseguire su
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.\footnote{ad esempio si
- gestiscono con questa funzione varie modalità di I/O asincrono (vedi
- sez.~\ref{sec:file_asyncronous_operation}) e il \itindex{file~locking}
- \textit{file locking} (vedi sez.~\ref{sec:file_locking}).}
+funzionalità che il kernel può mettere a disposizione.
-Per queste operazioni di manipolazione e di controllo delle varie proprietà e
+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}, il cui prototipo è:
+\funcd{fcntl},\footnote{ad esempio si gestiscono con questa funzione varie
+ modalità di I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_operation}) e
+ il \itindex{file~locking} \textit{file locking} (vedi
+ sez.~\ref{sec:file_locking}).} il cui prototipo è:
\begin{funcproto}{
\fhead{unistd.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)}
\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
-sono determinati dal valore dell'argomento \param{cmd} che in sostanza
-corrisponde all'esecuzione di un determinato \textsl{comando}; 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 possibili valori
-per \var{cmd} è riportata di seguito:
+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}.
+
+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
+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{2.0cm}}
\item[\const{F\_DUPFD}] trova il primo file descriptor disponibile di valore
- maggiore o uguale ad \param{arg} e ne fa una copia di \param{fd}. Ritorna il
- nuovo file descriptor in caso di successo e $-1$ in caso di errore. 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.
+ 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
+ \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.
+
\item[\const{F\_DUPFD\_CLOEXEC}] ha lo stesso effetto di \const{F\_DUPFD}, ma
in più attiva il flag di \itindex{close-on-exec} \textit{close-on-exec} sul
- nuovo file descriptor duplicato, in modo da evitare una successiva chiamata
- con \const{F\_SETFD}. Introdotta con il kernel 2.6.24.
+ 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
+ è prevista nello standard POSIX.1-2008 (si deve perciò definire
+ \macro{\_POSIX\_C\_SOURCE} ad un valore adeguato secondo quanto visto in
+ sez.~\ref{sec:intro_gcc_glibc_std}).
+
\item[\const{F\_GETFD}] ritorna il valore dei \textit{file descriptor flags} di
- \param{fd} o $-1$ in caso di errore, \param{arg} viene ignorato. Se
- \const{FD\_CLOEXEC} è impostato i file descriptor aperti vengono chiusi
- attraverso una \func{exec} altrimenti (il comportamento predefinito) restano
- aperti.
-\item[\const{F\_SETFD}] imposta il valore dei \textit{file descriptor flags} al
- valore specificato con \param{arg}. Al momento l'unico bit usato è quello 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 \itindex{close-on-exec}
+ \textit{close-on-exec}, identificato dalla costante \const{FD\_CLOEXEC}, che
+ serve a richiedere che il file venga chiuso nella esecuzione di una
+ \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}
+ 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
\itindex{close-on-exec} \textit{close-on-exec}, identificato dalla costante
- \const{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella
- esecuzione di una \func{exec} (vedi sez.~\ref{sec:proc_exec}). Ritorna un
- valore nullo in caso di successo e $-1$ in caso di errore.
-\item[\const{F\_GETFL}] ritorna il valore dei \textit{file status flags} in
- caso di successo o $-1$ in caso di errore; permette cioè di rileggere quei
- valori dell'argomento \param{flags} di \func{open} che vengono memorizzati,
- più precisamente quelli riportati in tab.~\ref{tab:open_access_mode_flag} e
+ \const{FD\_CLOEXEC}, tutti gli altri bit di \param{arg}, anche se impostati,
+ vengono ignorati.\footnote{questo almeno è quanto avviene fino al kernel
+ 3.2, come si può evincere dal codice della funzione \texttt{do\_fcntl} nel
+ file \texttt{fs/fcntl.c} dei sorgenti del kernel.}
+
+\item[\const{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
+ 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}).
-\item[\const{F\_SETFL}] imposta il \textit{file status flag} al valore
- specificato da \param{arg}, ritorna un valore nullo in caso di successo o
- $-1$ in caso di errore. Possono essere impostati solo flag fra quelli
- riportati in tab.~\ref{tab:open_operation_flag}. su Linux si possono
+
+\item[\const{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}.
+ \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 amministatore) 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
- \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. Questa
+ \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
- specificato nella struttura puntata da \param{lock}. Se il lock è tenuto da
- qualcun altro ritorna immediatamente restituendo $-1$ e imposta \var{errno} a
- \errcode{EACCES} o \errcode{EAGAIN}, in caso di successo ritorna un valore
- nullo. Questa funzionalità è trattata in dettaglio in
- sez.~\ref{sec:file_posix_lock}.
+ 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
- la funzione non ritorna subito ma attende che il blocco sia rilasciato. Se
+ 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}, in caso di successo ritorna un valore
- nullo. Questa funzionalità è trattata in dettaglio in
- sez.~\ref{sec:file_posix_lock}.
-\item[\const{F\_GETOWN}] restituisce il \ids{PID} del processo o
- l'identificatore del \itindex{process~group} \textit{process
- group}\footnote{i \itindex{process~group} \textit{process group} sono
- (vedi sez.~\ref{sec:sess_proc_group}) raggruppamenti di processi usati nel
- controllo di sessione; a ciascuno di essi è associato un identificatore
- (un numero positivo analogo al \ids{PID}).} che è preposto alla ricezione
- dei segnali \signal{SIGIO} (o qualunque altro segnale alternativo impostato
- con \const{F\_SETSIG}) per gli eventi associati al file
- descriptor \param{fd}\footnote{il segnale viene usato sia per il
- \textit{Signal Drive I/O}, che tratteremo in
- sez.~\ref{sec:file_asyncronous_operation}, che dai vari meccanismi di
- notifica asincrona, che tratteremo in
- sez.~\ref{sec:file_asyncronous_lease}.} e \signal{SIGURG} per la notifica
- dei dati urgenti di un socket (vedi sez.~\ref{sec:TCP_urgent_data}). Nel
- caso di un \textit{process group} viene restituito un valore negativo il cui
- valore assoluto corrisponde all'identificatore del \itindex{process~group}
- \textit{process group}.\footnote{si tenga presente però che se questo valore
- è compreso nell'intervallo fra $-1$ e $-4095$ questo viene interpretato
- dalla \acr{glibc} come un errore per cui in tal caso \func{fcntl}
- ritornerà comunque $-1$ mentre il valore restituito dalla \textit{system
- call} verrà assegnato ad \var{errno}, cambiato di segno.} In caso di
- errore viene restituito $-1$.
+ 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
+ processo o del \itindex{process~group} \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}.
+
+ 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
+ negativo il cui valore assoluto corrisponde all'identificatore del
+ \itindex{process~group} \textit{process group}. Con Linux questo comporta un
+ problema perché se il valore restitituito dalla \textit{system call} è
+ compreso nell'intervallo fra $-1$ e $-4095$ in alcune architetture questo
+ viene trattato dalla \acr{glibc} come un errore,\footnote{il problema deriva
+ dalle limitazioni presenti in architetture come quella dei normali PC
+ (i386) per via delle modalità in cui viene effettuata l'invocazione delle
+ \textit{system call} che non consentono di restituire un adeguato codice
+ di ritorno.} per cui in tal caso \func{fcntl} ritornerà comunque $-1$
+ mentre il valore restituito dalla \textit{system call} verrà assegnato ad
+ \var{errno}, cambiato di segno.
+
+ Per questo motivo con il kernel 2.6.32 è stato introdotto il comando
+ alternativo \const{F\_GETOWN\_EX}, che vedremo a breve, che consente di
+ evitare il problema. A partire dalla versione 2.11 la \acr{glibc}, se
+ disponibile, usa questa versione alternativa per mascherare il problema
+ precedente e restituire un valore corretto in tutti i casi.\footnote{in cui
+ cioè viene restituito un valore negativo corretto qualunque sia
+ l'identificatore del \itindex{process~group} \textit{process group}, che
+ non potendo avere valore unitario (non esiste infatti un
+ \itindex{process~group} \textit{process group} per \cmd{init}) non può
+ generare ambiguità con il codice di errore.} Questo però comporta che 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},
l'identificatore del processo o del \itindex{process~group} \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. Come per \const{F\_GETOWN}, per
- indicare un \itindex{process~group} \textit{process group} si deve usare
- per \param{arg} un valore negativo, il cui valore assoluto corrisponde
- all'identificatore del \itindex{process~group} \textit{process
- group}. L'impostazione è soggetta alle stesse restrizioni presenti sulla
- funzione \func{kill} (vedi sez.~\ref{sec:sig_kill_raise}), per cui in
- sostanza un utente non privilegiato potrà cioè inviare i segnali solo ad un
- processo che gli appartiene. Nel caso di \textit{thread},\footnote{in questo
- caso si fa riferimento alla implementazione nativa di Linux delle NTPL,
- vedi sez.~\ref{sec:linux_ntpl}. } quando si è impostato un segnale con
- \const{F\_SETSIG}, un valore positivo di \param{arg} verrà interpretato come
- indicante il \textit{Thread ID} che indica uno specifico \textit{thread} e
- non come \textit{Process ID}, dato che in tal caso il \textit{thread}
- principale mantiene un valore del \textit{Thread ID} uguale al \ids{PID}.
-\item[\const{F\_GETSIG}] restituisce il valore del segnale inviato quando un
- file descriptor aperto ed impostato per l'I/O asincrono (si veda
- sez.~\ref{sec:file_asyncronous_io}) è pronto per le operazioni di lettura o
- scrittura. Il valore 0 indica il valore predefinito, che è \signal{SIGIO},
- un valore diverso da zero indica il segnale richiesto, che può essere anche
- lo stesso \signal{SIGIO}. In caso di errore ritorna $-1$.
-\item[\const{F\_SETSIG}] imposta il segnale da inviare quando diventa
- possibile effettuare I/O sul file descriptor in caso di I/O asincrono,
- ritorna un valore nullo in caso di successo o $-1$ in caso di errore. Il
- valore zero indica di usare il segnale predefinito, \signal{SIGIO}. Un altro
- valore diverso da zero, compreso lo stesso \signal{SIGIO}, specifica il
- segnale voluto; l'uso di un valore diverso da zero permette inoltre, se si è
+ 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
+ \itindex{process~group} \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
+ privilegiato può inviare i segnali solo ad un processo che gli appartiene,
+ in genere comunque si usa il processo corrente. Come per \const{F\_GETOWN},
+ per indicare un \itindex{process~group} \textit{process group} si deve usare
+ per \param{arg} un valore negativo, il cui valore assoluto corrisponda
+ all'identificatore del \itindex{process~group} \textit{process group}.
+
+ 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
+ \itindex{process~group} \textit{process group}.
+
+\item[\const{F\_GETOWN\_EX}] legge nella struttura puntata
+ dal'argomento \param{owner} l'identificatore del processo, \textit{thread} o
+ \itindex{process~group} \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
+ \errval{EFAULT} se \param{owner} non è un puntatore valido.
+
+ Il comando, che è disponibile solo a partire dal kernel 2.6.32, effettua lo
+ stesso compito di \const{F\_GETOWN} di cui costituisce una evoluzione che
+ 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[\const{F\_SETOWN\_EX}] imposta con il valore della struttura
+ \struct{f\_owner\_ex} puntata \param{owner}, l'identificatore del processo o
+ del \itindex{process~group} \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.
+
+ \begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{varwidth}[c]{0.5\textwidth}
+ \includestruct{listati/f_owner_ex.h}
+ \end{varwidth}
+ \normalsize
+ \caption{La struttura \structd{f\_owner\_ex}.}
+ \label{fig:f_owner_ex}
+ \end{figure}
+
+ 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 indentificatore 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 intedende 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
+ 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
+ errori diversi da \errval{EBADF}. Un valore nullo indica che si sta usando
+ il segnale predefinito, che è \signal{SIGIO}. Un valore diverso da zero
+ indica il segnale che è stato impostato con \const{F\_SETSIG}, che può
+ 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
+ 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
+ \errcode{EINVAL} se \param{arg} indica un numero di segnale non valido. Un
+ valore nullo di \param{arg} indica di usare il segnale predefinito, cioè
+ \signal{SIGIO}. Un valore diverso da zero, compreso lo stesso
+ \signal{SIGIO}, specifica il segnale voluto. Il comando è specifico di
+ Linux ed utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
+
+ 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
disponibili al gestore informazioni ulteriori riguardo il file che ha
- generato il segnale attraverso i valori restituiti in \struct{siginfo\_t}
- (come vedremo in sez.~\ref{sec:file_asyncronous_io}).\footnote{i due comandi
- \const{F\_SETSIG} e \const{F\_GETSIG} sono una estensione specifica di
- Linux e sono utilizzabili solo se si è definita la macro
- \macro{\_GNU\_SOURCE}.}
-\item[\const{F\_SETLEASE}] imposta o rimuove un \itindex{file~lease}
- \textit{file lease} sul file descriptor \var{fd} a seconda del valore del
- terzo argomento, che in questo caso è un \ctyp{int}, ritorna un valore nullo
- in caso di successo o $-1$ in caso di errore. Questa è una funzionalità
- specifica di Linux (vedi sez.~\ref{sec:file_asyncronous_lease}) presente a
- partire dai kernel della serie 2.4.x, in cui il processo che detiene un
- \textit{lease} su un file riceve una notifica qualora un altro processo
- cerchi di eseguire una \func{open} o una \func{truncate} su di esso.
+ generato il segnale attraverso i valori restituiti in
+ \struct{siginfo\_t}. Se inoltre si imposta un segnale \textit{real-time} si
+ potranno sfruttare le caratteristiche di avanzate di questi ultimi (vedi
+ 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 \itindex{file~lease}
\textit{file lease} che il processo detiene nei confronti del file
- descriptor \var{fd} o $-1$ in caso di errore. Con questo comando il terzo
- argomento può essere omesso. Questa funzionalità avanzata è trattata in
- dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
-\item[\const{F\_NOTIFY}] attiva un meccanismo di notifica per cui viene
- riportata al processo chiamante, tramite il segnale \signal{SIGIO} (o altro
- segnale specificato con \const{F\_SETSIG}) ogni modifica eseguita o
+ 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
+ di \param{arg} un \itindex{file~lease} \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{EACCESS} se non si è
+ il proprietario del file e non si hanno i privilegi di
+ amministratore.\footnote{per la precisione occorre la capacità
+ \itindex{capabilities} \const{CAP\_LEASE}.}
+
+ Il comando è specifico di Linux ed utilizzabile solo se si è definita la
+ macro \macro{\_GNU\_SOURCE}. Il comando è presente a partire dai kernel
+ della serie 2.4.x, quando è stato introdotto il supporto \textit{file
+ lease}, per cui un processo che detiene un \textit{lease} su un file
+ riceve una notifica qualora un altro processo cerchi di eseguire una
+ \func{open} o una \func{truncate} su di esso. Questa funzionalità è trattata
+ in dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
+
+\item[\const{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
- in essa contenuti; ritorna un valore nullo in caso di successo o $-1$ in caso
- di errore. Questa funzionalità avanzata, disponibile dai kernel della serie
- 2.4.x, è trattata in dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
+ in essa contenuti; ritorna un valore nullo in caso di successo o $-1$ in
+ caso di errore. Il comando è specifico di Linux ed utilizzabile solo se si è
+ definita la macro \macro{\_GNU\_SOURCE}. Questa funzionalità, disponibile
+ dai kernel della serie 2.4.x, è trattata in dettaglio in
+ sez.~\ref{sec:file_asyncronous_lease}.
+
+\item[\const{F\_GETPIPE\_SZ}]
+
+\item[\const{F\_SETPIPE\_SZ}]
+
\end{basedescript}
-La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per
-poter essere affrontate in tutti i loro aspetti a questo punto; 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_access} mentre quelle relative al
-\itindex{file~locking} \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}.
+La maggior parte delle funzionalità controllate dai comandi di \func{fcntl}
+sono molto avanzate e richiedono degli approfondimenti ulteriori rispetto a
+quanto illustrato adesso; 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 \itindex{file~locking} \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}.
+
+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 presenti da molto tempo, 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
+funzionalità inserite in standard successivi o specifiche di Linux.
Si tenga presente infine che quando si usa la funzione per determinare le
modalità di accesso con cui è stato aperto il file (attraverso l'uso del
-\subsection{La funzione \func{ioctl}}
-\label{sec:file_ioctl}
+% \subsection{La funzione \func{ioctl}}
+% \label{sec:file_ioctl}
Benché il concetto di \textit{everything is a file} si sia dimostrato molto
valido anche per l'interazione con i dispositivi più vari, fornendo una
usate per i normali file di dati, esisteranno sempre caratteristiche
peculiari, specifiche dell'hardware e della funzionalità che ciascun
dispositivo può provvedere, che non possono venire comprese in questa
-interfaccia astratta (un caso tipico è l'impostazione della velocità di una
-porta seriale, o le dimensioni di un framebuffer).
+interfaccia astratta come ad esempio l'impostazione della velocità di una
+porta seriale, o le dimensioni di un framebuffer.
Per questo motivo nell'architettura del sistema è stata prevista l'esistenza
di una funzione apposita, \funcd{ioctl}, con cui poter compiere le operazioni
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
- file (vedi sez.~\ref{sec:file_asyncronous_operation}); il terzo argomento
+ 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).