From 42a9a2d31d3d0276160e6a0aa385b53c21f6a036 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 3 Oct 2014 22:12:34 +0000 Subject: [PATCH] Piccole correzioni, e riduzioni delle note. --- fileadv.tex | 524 +++++++++++++++++++----------------- listati/epoll_pwait_means.c | 1 - 2 files changed, 270 insertions(+), 255 deletions(-) diff --git a/fileadv.tex b/fileadv.tex index 2b303c9..88f6307 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1263,14 +1263,14 @@ contestualmente all'esecuzione della funzione,\footnote{in Linux però, fino al \texttt{man select\_tut}) per cui la possibilità di \itindex{race~condition} \textit{race condition} permaneva; in tale situazione si può ricorrere ad una soluzione alternativa, chiamata \itindex{self-pipe trick} - \textit{self-pipe trick}, che consiste nell'aprire una pipe (vedi + \textit{self-pipe trick}, che consiste nell'aprire una \textit{pipe} (vedi sez.~\ref{sec:ipc_pipes}) ed usare \func{select} sul capo in lettura della stessa; si può indicare l'arrivo di un segnale scrivendo sul capo in scrittura all'interno del gestore dello stesso; in questo modo anche se il segnale va perso prima della chiamata di \func{select} questa lo riconoscerà - comunque dalla presenza di dati sulla pipe.} ribloccandolo non appena essa -ritorna, così che il precedente codice potrebbe essere riscritto nel seguente -modo: + comunque dalla presenza di dati sulla \textit{pipe}.} ribloccandolo non +appena essa ritorna, così che il precedente codice potrebbe essere riscritto +nel seguente modo: \includecodesnip{listati/pselect_norace.c} in questo caso utilizzando \var{oldmask} durante l'esecuzione di \func{pselect} la ricezione del segnale sarà abilitata, ed in caso di @@ -1974,7 +1974,8 @@ variante della funzione di attesa che consenta di reimpostare all'uscita una \begin{funcproto}{ \fhead{sys/epoll.h} \fdecl{int epoll\_pwait(int epfd, struct epoll\_event * events, int maxevents, - int timeout, const sigset\_t *sigmask)} + int timeout, \\ +\phantom{int epoll\_pwait(}const sigset\_t *sigmask)} \fdesc{Attende che uno dei file descriptor osservati sia pronto, mascherando i segnali.} } @@ -1982,7 +1983,7 @@ variante della funzione di attesa che consenta di reimpostare all'uscita una {La funzione ritorna il numero di file descriptor pronti in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori già visti con \funcd{epoll\_wait}. - + } \end{funcproto} @@ -2168,7 +2169,7 @@ Si tenga presente inoltre che la lettura di una struttura \struct{signalfd\_siginfo} relativa ad un segnale pendente è equivalente alla esecuzione di un gestore, vale a dire che una volta letta il segnale non sarà più pendente e non potrà essere ricevuto, qualora si ripristino le normali -condizioni di gestione, né da un gestore né dalla funzione \func{sigwaitinfo}. +condizioni di gestione, né da un gestore, né dalla funzione \func{sigwaitinfo}. Come anticipato, essendo questo lo scopo principale della nuova interfaccia, il file descriptor può essere tenuto sotto osservazione tramite le funzioni @@ -2276,7 +2277,7 @@ l'uso di \itindex{epoll} \textit{epoll} e \func{signalfd}, a partire (\texttt{\small 12-16}) dalla definizione delle varie variabili e strutture necessarie. Al solito si è tralasciata la parte dedicata alla decodifica delle opzioni che consentono ad esempio di cambiare il nome del file associato alla -fifo. +\textit{fifo}. Il primo passo (\texttt{\small 19-20}) è la creazione di un file descriptor \texttt{epfd} di \itindex{epoll} \textit{epoll} con \func{epoll\_create} che è @@ -2316,11 +2317,12 @@ ciclo prevede che si attenda (\texttt{\small 2-3}) la presenza di un file descriptor pronto in lettura con \func{epoll\_wait} (si ricordi che entrambi i file descriptor \var{fifofd} e \var{sigfd} sono stati posti in osservazioni per eventi di tipo \const{EPOLLIN}) che si bloccherà fintanto che non siano -stati scritti dati sulla fifo o che non sia arrivato un segnale.\footnote{per - semplificare il codice non si è trattato il caso in cui \func{epoll\_wait} - viene interrotta da un segnale, assumendo che tutti quelli che possano - interessare siano stati predisposti per la notifica tramite file descriptor, - per gli altri si otterrà semplicemente l'uscita dal programma.} +stati scritti dati sulla \textit{fifo} o che non sia arrivato un +segnale.\footnote{per semplificare il codice non si è trattato il caso in cui + \func{epoll\_wait} viene interrotta da un segnale, assumendo che tutti + quelli che possano interessare siano stati predisposti per la notifica + tramite file descriptor, per gli altri si otterrà semplicemente l'uscita dal + programma.} Anche se in questo caso i file descriptor pronti possono essere al più due, si è comunque adottato un approccio generico in cui questi verranno letti @@ -2344,7 +2346,7 @@ ritorno della funzione \func{read} è negativo, uscendo dal programma (\texttt{\small 11}) in caso di errore reale, o terminando il ciclo (\texttt{\small 13}) con un \texttt{break} qualora si ottenga un errore di \errcode{EAGAIN} per via dell'esaurimento dei dati. Si ricordi infatti come -sia la fifo che il file descriptor per i segnali siano stati aperti in +sia la \textit{fifo} che il file descriptor per i segnali siano stati aperti in modalità non-bloccante, come previsto per l’\textit{I/O multiplexing}, pertanto ci si aspetta di ricevere un errore di \errcode{EAGAIN} quando non vi saranno più dati da leggere. @@ -2362,21 +2364,21 @@ del programma, che verrà eseguita dopo aver rimosso il file della \textit{name fifo}. Il secondo condizionale (\texttt{\small 26-39}) è invece relativo al caso in -cui ci siano dati pronti in lettura sulla fifo e che il file descriptor pronto -corrisponda (\texttt{\small 26}) a \var{fifofd}. Di nuovo si effettueranno le -letture in un ciclo (\texttt{\small 28-39}) ripetendole fin tanto che la -funzione \func{read} non restituisce un errore di \errcode{EAGAIN} -(\texttt{\small 29-35}). Il procedimento è lo stesso adottato per il file -descriptor associato al segnale, in cui si esce dal programma in caso di -errore reale, in questo caso però alla fine dei dati prima di uscire si stampa -anche (\texttt{\small 32}) un messaggio di chiusura. - -Se invece vi sono dati validi letti dalla fifo si inserirà (\texttt{\small - 36}) una terminazione di stringa sul buffer e si stamperà il tutto -(\texttt{\small 37-38}) sullo \textit{standard output}. L'ultimo condizionale -(\texttt{\small 40-44}) è semplicemente una condizione di cattura per una -eventualità che comunque non dovrebbe mai verificarsi, e che porta alla uscita -dal programma con una opportuna segnalazione di errore. +cui ci siano dati pronti in lettura sulla \textit{fifo} e che il file +descriptor pronto corrisponda (\texttt{\small 26}) a \var{fifofd}. Di nuovo si +effettueranno le letture in un ciclo (\texttt{\small 28-39}) ripetendole fin +tanto che la funzione \func{read} non restituisce un errore di +\errcode{EAGAIN} (\texttt{\small 29-35}). Il procedimento è lo stesso adottato +per il file descriptor associato al segnale, in cui si esce dal programma in +caso di errore reale, in questo caso però alla fine dei dati prima di uscire +si stampa anche (\texttt{\small 32}) un messaggio di chiusura. + +Se invece vi sono dati validi letti dalla \textit{fifo} si inserirà +(\texttt{\small 36}) una terminazione di stringa sul buffer e si stamperà il +tutto (\texttt{\small 37-38}) sullo \textit{standard output}. L'ultimo +condizionale (\texttt{\small 40-44}) è semplicemente una condizione di cattura +per una eventualità che comunque non dovrebbe mai verificarsi, e che porta +alla uscita dal programma con una opportuna segnalazione di errore. A questo punto si potrà eseguire il comando lanciandolo su un terminale, ed osservarne le reazioni agli eventi generati da un altro terminale; lanciando @@ -2619,7 +2621,7 @@ impostato la stessa con \func{fcntl}, nel qual caso fallisce con l'errore di \errval{EAGAIN}. -% TODO trattare qui eventfd introdotte con il 2.6.22 +% TODO trattare qui eventfd introdotto con il 2.6.22 \section{L'accesso \textsl{asincrono} ai file} @@ -2657,18 +2659,17 @@ 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. -Quello che succede è che per tutti i file posti in questa modalità\footnote{si - tenga presente però che essa non è utilizzabile con i file ordinari ma solo - con socket, file di terminale o pseudo terminale, ed anche, a partire dal - 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_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 -necessità di restare bloccati in attesa della disponibilità di accesso ai -file. +Quello che succede è che per tutti i file posti in questa modalità il sistema +genera un apposito segnale, \signal{SIGIO}, tutte le volte che diventa +possibile leggere o scrivere dal file descriptor; si tenga presente però che +essa non è utilizzabile con i file ordinari ma solo con socket, file di +terminale o pseudo terminale, ed anche, a partire dal kernel 2.6, per +\textit{fifo} e \textit{pipe}. Inoltre è possibile, come 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 necessità di restare +bloccati in attesa della disponibilità di accesso ai file. % TODO: per i thread l'uso di F_SETOWN ha un significato diverso @@ -2692,43 +2693,44 @@ illustrato in sez.~\ref{sec:sig_notification}), in presenza di più file descriptor attivi contemporaneamente, più segnali emessi nello stesso momento verrebbero notificati una volta sola. -Linux però supporta le estensioni POSIX.1b dei segnali real-time, che vengono -accodati e che permettono di riconoscere il file descriptor che li ha emessi. -In questo caso infatti si può fare ricorso alle informazioni aggiuntive -restituite attraverso la struttura \struct{siginfo\_t}, utilizzando la forma -estesa \var{sa\_sigaction} del gestore installata con il flag +Linux però supporta le estensioni POSIX.1b dei segnali \textit{real-time}, che +vengono accodati e che permettono di riconoscere il file descriptor che li ha +emessi. In questo caso infatti si può fare ricorso alle informazioni +aggiuntive restituite attraverso la struttura \struct{siginfo\_t}, utilizzando +la forma estesa \var{sa\_sigaction} del gestore installata con il flag \const{SA\_SIGINFO} (si riveda quanto illustrato in sez.~\ref{sec:sig_sigaction}). -Per far questo però occorre utilizzare le funzionalità dei segnali real-time -(vedi sez.~\ref{sec:sig_real_time}) impostando esplicitamente con il comando -\const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di -I/O asincrono (il segnale predefinito è \signal{SIGIO}). In questo caso il -gestore, tutte le volte che riceverà \const{SI\_SIGIO} come valore del campo -\var{si\_code}\footnote{il valore resta \const{SI\_SIGIO} qualunque sia il - segnale che si è associato all'I/O, ed indica appunto che il segnale è stato - generato a causa di attività di I/O.} di \struct{siginfo\_t}, troverà nel -campo \var{si\_fd} il valore del file descriptor che ha generato il segnale. - -Un secondo vantaggio dell'uso dei segnali real-time è che essendo questi -ultimi dotati di una coda di consegna ogni segnale sarà associato ad uno solo -file descriptor; inoltre sarà possibile stabilire delle priorità nella -risposta a seconda del segnale usato, dato che i segnali real-time supportano -anche questa funzionalità. In questo modo si può identificare immediatamente -un file su cui l'accesso è diventato possibile evitando completamente l'uso di -funzioni come \func{poll} e \func{select}, almeno fintanto che non si satura -la coda. +Per far questo però occorre utilizzare le funzionalità dei segnali +\textit{real-time} (vedi sez.~\ref{sec:sig_real_time}) impostando +esplicitamente con il comando \const{F\_SETSIG} di \func{fcntl} un segnale +\textit{real-time} da inviare in caso di I/O asincrono (il segnale predefinito +è \signal{SIGIO}). In questo caso il gestore, tutte le volte che riceverà +\const{SI\_SIGIO} come valore del campo \var{si\_code} di \struct{siginfo\_t}, +troverà nel campo \var{si\_fd} il valore del file descriptor che ha generato +il segnale. Si noti che il valore di\var{si\_code} resta \const{SI\_SIGIO} +qualunque sia il segnale che si è associato all'I/O, in quanto indica che il +segnale è stato generato a causa di attività di I/O. + +Un secondo vantaggio dell'uso dei segnali \textit{real-time} è che essendo +questi ultimi dotati di una coda di consegna ogni segnale sarà associato ad +uno solo file descriptor; inoltre sarà possibile stabilire delle priorità +nella risposta a seconda del segnale usato, dato che i segnali +\textit{real-time} supportano anche questa funzionalità. In questo modo si può +identificare immediatamente un file su cui l'accesso è diventato possibile +evitando completamente l'uso di funzioni come \func{poll} e \func{select}, +almeno fintanto che non si satura la coda. Se infatti si eccedono le dimensioni di quest'ultima, il kernel, non potendo -più assicurare il comportamento corretto per un segnale real-time, invierà al -suo posto un solo \signal{SIGIO}, su cui si saranno accumulati tutti i segnali -in eccesso, e si dovrà allora determinare con un ciclo quali sono i file -diventati attivi. L'unico modo per essere sicuri che questo non avvenga è di -impostare la lunghezza della coda dei segnali real-time ad una dimensione -identica al valore massimo del numero di file descriptor -utilizzabili.\footnote{vale a dire impostare il contenuto di - \sysctlfile{kernel/rtsig-max} allo stesso valore del contenuto di - \sysctlfile{fs/file-max}.} +più assicurare il comportamento corretto per un segnale \textit{real-time}, +invierà al suo posto un solo \signal{SIGIO}, su cui si saranno accumulati +tutti i segnali in eccesso, e si dovrà allora determinare con un ciclo quali +sono i file diventati attivi. L'unico modo per essere sicuri che questo non +avvenga è di impostare la lunghezza della coda dei segnali \textit{real-time} +ad una dimensione identica al valore massimo del numero di file descriptor +utilizzabili, vale a dire impostare il contenuto di +\sysctlfile{kernel/rtsig-max} allo stesso valore del contenuto di +\sysctlfile{fs/file-max}. % TODO fare esempio che usa O_ASYNC @@ -2740,19 +2742,19 @@ utilizzabili.\footnote{vale a dire impostare il contenuto di \label{sec:file_asyncronous_lease} Una delle domande più frequenti nella programmazione in ambiente unix-like è -quella di come fare a sapere quando un file viene modificato. La -risposta\footnote{o meglio la non risposta, tanto che questa nelle Unix FAQ - \cite{UnixFAQ} viene anche chiamata una \textit{Frequently Unanswered - Question}.} è che nell'architettura classica di Unix questo non è -possibile. Al contrario di altri sistemi operativi infatti un kernel unix-like -classico non prevedeva alcun meccanismo per cui un processo possa essere -\textsl{notificato} di eventuali modifiche avvenute su un file. Questo è il -motivo per cui i demoni devono essere \textsl{avvisati} in qualche -modo\footnote{in genere questo vien fatto inviandogli un segnale di - \signal{SIGHUP} che, per una convenzione adottata dalla gran parte di detti - programmi, causa la rilettura della configurazione.} se il loro file di -configurazione è stato modificato, perché possano rileggerlo e riconoscere le -modifiche. +quella di come fare a sapere quando un file viene modificato. La risposta, o +meglio la non risposta, tanto che questa nelle Unix FAQ \cite{UnixFAQ} viene +anche chiamata una \textit{Frequently Unanswered Question}, è che +nell'architettura classica di Unix questo non è possibile. Al contrario di +altri sistemi operativi infatti un kernel unix-like classico non prevedeva +alcun meccanismo per cui un processo possa essere \textsl{notificato} di +eventuali modifiche avvenute su un file. + +Questo è il motivo per cui i demoni devono essere \textsl{avvisati} in qualche +modo se il loro file di configurazione è stato modificato, perché possano +rileggerlo e riconoscere le modifiche; in genere questo vien fatto inviandogli +un segnale di \signal{SIGHUP} che, per una convenzione adottata dalla gran +parte di detti programmi, causa la rilettura della configurazione. Questa scelta è stata fatta perché provvedere un simile meccanismo a livello generico per qualunque file comporterebbe un notevole aumento di complessità @@ -2766,7 +2768,7 @@ nessuna funzionalità di notifica. Visto però il crescente interesse nei confronti di una funzionalità di questo tipo, che è molto richiesta specialmente nello sviluppo dei programmi ad -interfaccia grafica, quando si deve presentare all'utente lo stato del +interfaccia grafica quando si deve presentare all'utente lo stato del filesystem, sono state successivamente introdotte delle estensioni che permettessero la creazione di meccanismi di notifica più efficienti dell'unica soluzione disponibile con l'interfaccia tradizionale, che è quella del @@ -2787,17 +2789,18 @@ questo è un meccanismo che consente ad un processo, detto \textit{lease holder}, di essere notificato quando un altro processo, chiamato a sua volta \textit{lease breaker}, cerca di eseguire una \func{open} o una \func{truncate} sul file del quale l'\textit{holder} detiene il -\textit{lease}. -La notifica avviene in maniera analoga a come illustrato in precedenza per -l'uso di \const{O\_ASYNC}: di default viene inviato al \textit{lease holder} -il segnale \signal{SIGIO}, ma questo segnale può essere modificato usando il -comando \const{F\_SETSIG} di \func{fcntl}.\footnote{anche in questo caso si - può rispecificare lo stesso \signal{SIGIO}.} Se si è fatto questo\footnote{è - in genere è opportuno farlo, come in precedenza, per utilizzare segnali - real-time.} e si è installato il gestore del segnale con \const{SA\_SIGINFO} -si riceverà nel campo \var{si\_fd} della struttura \struct{siginfo\_t} il -valore del file descriptor del file sul quale è stato compiuto l'accesso; in -questo modo un processo può mantenere anche più di un \textit{file lease}. +\textit{lease}. La notifica avviene in maniera analoga a come illustrato in +precedenza per l'uso di \const{O\_ASYNC}: di default viene inviato al +\textit{lease holder} il segnale \signal{SIGIO}, ma questo segnale può essere +modificato usando il comando \const{F\_SETSIG} di \func{fcntl} (anche in +questo caso si può rispecificare lo stesso \signal{SIGIO}). + +Se si è fatto questo (ed in genere è opportuno farlo, come in precedenza, per +utilizzare segnali \textit{real-time}) e se inoltre si è installato il gestore +del segnale con \const{SA\_SIGINFO} si riceverà nel campo \var{si\_fd} della +struttura \struct{siginfo\_t} il valore del file descriptor del file sul quale +è stato compiuto l'accesso; in questo modo un processo può mantenere anche più +di un \textit{file lease}. Esistono due tipi di \textit{file lease}: di lettura (\textit{read lease}) e di scrittura (\textit{write lease}). Nel primo caso la notifica avviene quando @@ -2843,9 +2846,9 @@ presenza del rispettivo tipo di \textit{lease}, o, nel caso di Si tenga presente che un processo può mantenere solo un tipo di \textit{lease} su un file, e che un \textit{lease} può essere ottenuto solo su file di dati -(pipe e dispositivi sono quindi esclusi). Inoltre un processo non privilegiato -può ottenere un \textit{lease} soltanto per un file appartenente ad un -\ids{UID} corrispondente a quello del processo. Soltanto un processo con +(\textit{pipe} e dispositivi sono quindi esclusi). Inoltre un processo non +privilegiato può ottenere un \textit{lease} soltanto per un file appartenente +ad un \ids{UID} corrispondente a quello del processo. Soltanto un processo con privilegi di amministratore (cioè con la \itindex{capabilities} capability \const{CAP\_LEASE}, vedi sez.~\ref{sec:proc_capabilities}) può acquisire \textit{lease} su qualunque file. @@ -2854,16 +2857,16 @@ Se su un file è presente un \textit{lease} quando il \textit{lease breaker} esegue una \func{truncate} o una \func{open} che confligge con esso,\footnote{in realtà \func{truncate} confligge sempre, mentre \func{open}, se eseguita in sola lettura, non confligge se si tratta di un \textit{read - lease}.} la funzione si blocca\footnote{a meno di non avere aperto il file - con \const{O\_NONBLOCK}, nel qual caso \func{open} fallirebbe con un errore - di \errcode{EWOULDBLOCK}.} e viene eseguita la notifica al \textit{lease - holder}, così che questo possa completare le sue operazioni sul file e -rilasciare il \textit{lease}. In sostanza con un \textit{read lease} si -rilevano i tentativi di accedere al file per modificarne i dati da parte di un -altro processo, mentre con un \textit{write lease} si rilevano anche i -tentativi di accesso in lettura. Si noti comunque che le operazioni di -notifica avvengono solo in fase di apertura del file e non sulle singole -operazioni di lettura e scrittura. + lease}.} la funzione si blocca (a meno di non avere aperto il file con +\const{O\_NONBLOCK}, nel qual caso \func{open} fallirebbe con un errore di +\errcode{EWOULDBLOCK}) e viene eseguita la notifica al \textit{lease holder}, +così che questo possa completare le sue operazioni sul file e rilasciare il +\textit{lease}. In sostanza con un \textit{read lease} si rilevano i +tentativi di accedere al file per modificarne i dati da parte di un altro +processo, mentre con un \textit{write lease} si rilevano anche i tentativi di +accesso in lettura. Si noti comunque che le operazioni di notifica avvengono +solo in fase di apertura del file e non sulle singole operazioni di lettura e +scrittura. L'utilizzo dei \textit{file lease} consente al \textit{lease holder} di assicurare la consistenza di un file, a seconda dei due casi, prima che un @@ -2879,13 +2882,13 @@ operazione di lettura, declassando il \textit{lease} a lettura con Se il \textit{lease holder} non provvede a rilasciare il \textit{lease} entro il numero di secondi specificato dal parametro di sistema mantenuto in -\sysctlfile{fs/lease-break-time} sarà il kernel stesso a rimuoverlo (o -declassarlo) automaticamente.\footnote{questa è una misura di sicurezza per - evitare che un processo blocchi indefinitamente l'accesso ad un file - acquisendo un \textit{lease}.} Una volta che un \textit{lease} è stato -rilasciato o declassato (che questo sia fatto dal \textit{lease holder} o dal -kernel è lo stesso) le chiamate a \func{open} o \func{truncate} eseguite dal -\textit{lease breaker} rimaste bloccate proseguono automaticamente. +\sysctlfile{fs/lease-break-time} sarà il kernel stesso a rimuoverlo o +declassarlo automaticamente (questa è una misura di sicurezza per evitare che +un processo blocchi indefinitamente l'accesso ad un file acquisendo un +\textit{lease}). Una volta che un \textit{lease} è stato rilasciato o +declassato (che questo sia fatto dal \textit{lease holder} o dal kernel è lo +stesso) le chiamate a \func{open} o \func{truncate} eseguite dal \textit{lease + breaker} rimaste bloccate proseguono automaticamente. Benché possa risultare utile per sincronizzare l'accesso ad uno stesso file da parte di più processi, l'uso dei \textit{file lease} non consente comunque di @@ -2907,10 +2910,10 @@ un'altra interfaccia,\footnote{si ricordi che anche questa è una interfaccia che consente di richiedere una notifica quando una directory, o uno qualunque dei file in essa contenuti, viene modificato. Come per i \textit{file lease} la notifica avviene di default attraverso il segnale \signal{SIGIO}, ma se ne -può utilizzare un altro.\footnote{e di nuovo, per le ragioni già esposte in - precedenza, è opportuno che si utilizzino dei segnali real-time.} Inoltre, -come in precedenza, si potrà ottenere nel gestore del segnale il file -descriptor che è stato modificato tramite il contenuto della struttura +può utilizzare un altro, e di nuovo, per le ragioni già esposte in precedenza, +è opportuno che si utilizzino dei segnali \textit{real-time}. Inoltre, come +in precedenza, si potrà ottenere nel gestore del segnale il file descriptor +che è stato modificato tramite il contenuto della struttura \struct{siginfo\_t}. \itindend{file~lease} @@ -2999,15 +3002,17 @@ questa è una interfaccia specifica di Linux (pertanto non deve essere usata se si devono scrivere programmi portabili), ed è basata sull'uso di una coda di notifica degli eventi associata ad un singolo file descriptor, il che permette di risolvere il principale problema di \itindex{dnotify} \textit{dnotify}. La -coda viene creata attraverso la funzione \funcd{inotify\_init}, il cui -prototipo è: -\begin{prototype}{sys/inotify.h} - {int inotify\_init(void)} - - Inizializza una istanza di \textit{inotify}. - - \bodydesc{La funzione restituisce un file descriptor in caso di successo, o - $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: +coda viene creata attraverso la funzione di sistema \funcd{inotify\_init}, il +cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/inotify.h} +\fdecl{int inotify\_init(void)} +\fdesc{Inizializza una istanza di \textit{inotify}.} +} + +{La funzione ritornaun file descriptor in caso di successo, o $-1$ in caso di + errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EMFILE}] si è raggiunto il numero massimo di istanze di \textit{inotify} consentite all'utente. @@ -3017,52 +3022,56 @@ prototipo è: l'istanza. \end{errlist} } -\end{prototype} +\end{funcproto} La funzione non prende alcun argomento; inizializza una istanza di \textit{inotify} e restituisce un file descriptor attraverso il quale verranno -effettuate le operazioni di notifica;\footnote{per evitare abusi delle risorse - di sistema è previsto che un utente possa utilizzare un numero limitato di - istanze di \textit{inotify}; il valore di default del limite è di 128, ma - questo valore può essere cambiato con \func{sysctl} o usando il file - \sysctlfile{fs/inotify/max\_user\_instances}.} si tratta di un file -descriptor speciale che non è associato a nessun file su disco, e che viene -utilizzato solo per notificare gli eventi che sono stati posti in -osservazione. Dato che questo file descriptor non è associato a nessun file o -directory reale, l'inconveniente di non poter smontare un filesystem i cui -file sono tenuti sotto osservazione viene completamente -eliminato.\footnote{anzi, una delle capacità dell'interfaccia di - \textit{inotify} è proprio quella di notificare il fatto che il filesystem - su cui si trova il file o la directory osservata è stato smontato.} +effettuate le operazioni di notifica; si tratta di un file descriptor speciale +che non è associato a nessun file su disco, e che viene utilizzato solo per +notificare gli eventi che sono stati posti in osservazione. Per evitare abusi +delle risorse di sistema è previsto che un utente possa utilizzare un numero +limitato di istanze di \textit{inotify}; il valore di default del limite è di +128, ma questo valore può essere cambiato con \func{sysctl} o usando il file +\sysctlfile{fs/inotify/max\_user\_instances}. + +Dato che questo file descriptor non è associato a nessun file o directory +reale, l'inconveniente di non poter smontare un filesystem i cui file sono +tenuti sotto osservazione viene completamente eliminato; anzi, una delle +capacità dell'interfaccia di \textit{inotify} è proprio quella di notificare +il fatto che il filesystem su cui si trova il file o la directory osservata è +stato smontato. Inoltre trattandosi di un file descriptor a tutti gli effetti, esso potrà 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: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} +con l'interfaccia di \textit{epoll}, 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}. 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, 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 -la coda di notifica si devono definire gli eventi da tenere sotto -osservazione; questo viene fatto attraverso una \textsl{lista di osservazione} -(o \textit{watch list}) che è associata alla coda. Per gestire la lista di -osservazione l'interfaccia fornisce due funzioni, la prima di queste è -\funcd{inotify\_add\_watch}, il cui prototipo è: -\begin{prototype}{sys/inotify.h} - {int inotify\_add\_watch(int fd, const char *pathname, uint32\_t mask)} - - Aggiunge un evento di osservazione alla lista di osservazione di \param{fd}. - - \bodydesc{La funzione restituisce un valore positivo in caso di successo, o - $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: +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 la coda di notifica si devono definire gli eventi da tenere +sotto osservazione; questo viene fatto attraverso una \textsl{lista di + osservazione} (o \textit{watch list}) che è associata alla coda. Per gestire +la lista di osservazione l'interfaccia fornisce due funzioni di sistema, la +prima di queste è \funcd{inotify\_add\_watch}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/inotify.h} +\fdecl{int inotify\_add\_watch(int fd, const char *pathname, uint32\_t mask)} +\fdesc{Aggiunge un evento di osservazione a una lista di osservazione.} +} + +{La funzione ritorna un valore positivo in caso di successo, o $-1$ per un + errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EACCES}] non si ha accesso in lettura al file indicato. \item[\errcode{EINVAL}] \param{mask} non contiene eventi legali o \param{fd} @@ -3070,23 +3079,24 @@ osservazione l'interfaccia fornisce due funzioni, la prima di queste è \item[\errcode{ENOSPC}] si è raggiunto il numero massimo di voci di osservazione o il kernel non ha potuto allocare una risorsa necessaria. \end{errlist} - ed inoltre \errval{EFAULT}, \errval{ENOMEM} e \errval{EBADF}.} -\end{prototype} + ed inoltre \errval{EFAULT}, \errval{ENOMEM} e \errval{EBADF} nel loro + significato generico.} +\end{funcproto} La funzione consente di creare un ``\textsl{osservatore}'' (il cosiddetto ``\textit{watch}'') nella lista di osservazione di una coda di notifica, che deve essere indicata specificando il file descriptor ad essa associato -nell'argomento \param{fd}.\footnote{questo ovviamente dovrà essere un file - descriptor creato con \func{inotify\_init}.} Il file o la directory da -porre sotto osservazione vengono invece indicati per nome, da passare +nell'argomento \param{fd}, che ovviamente dovrà essere un file descriptor +creato con \func{inotify\_init}. Il file o la directory da porre sotto +osservazione vengono invece indicati per nome, da passare nell'argomento \param{pathname}. Infine il terzo argomento, \param{mask}, indica che tipo di eventi devono essere tenuti sotto osservazione e le modalità della stessa. L'operazione può essere ripetuta per tutti i file e le directory che si vogliono tenere sotto osservazione,\footnote{anche in questo caso c'è un limite massimo che di default è pari a 8192, ed anche questo valore può essere cambiato con \func{sysctl} o usando il file - \sysctlfile{fs/inotify/max\_user\_watches}.} e si utilizzerà sempre -un solo file descriptor. + \sysctlfile{fs/inotify/max\_user\_watches}.} e si utilizzerà sempre un solo +file descriptor. Il tipo di evento che si vuole osservare deve essere specificato nell'argomento \param{mask} come maschera binaria, combinando i valori delle @@ -3100,7 +3110,7 @@ flag della prima parte. \begin{table}[htb] \centering \footnotesize - \begin{tabular}[c]{|l|c|p{10cm}|} + \begin{tabular}[c]{|l|c|p{8cm}|} \hline \textbf{Valore} & & \textbf{Significato} \\ \hline @@ -3161,7 +3171,7 @@ contrario dei precedenti non vengono mai impostati nei risultati in uscita. \begin{table}[htb] \centering \footnotesize - \begin{tabular}[c]{|l|p{10cm}|} + \begin{tabular}[c]{|l|p{8cm}|} \hline \textbf{Valore} & \textbf{Significato} \\ \hline @@ -3214,16 +3224,18 @@ detto \textit{watch descriptor}, che identifica univocamente un riferimento sia riguardo i risultati restituiti da \textit{inotify}, che per la eventuale rimozione dello stesso. -La seconda funzione per la gestione delle code di notifica, che permette di -rimuovere un \textsl{osservatore}, è \funcd{inotify\_rm\_watch}, ed il suo -prototipo è: -\begin{prototype}{sys/inotify.h} - {int inotify\_rm\_watch(int fd, uint32\_t wd)} +La seconda funzione di sistema per la gestione delle code di notifica, che +permette di rimuovere un \textsl{osservatore}, è \funcd{inotify\_rm\_watch}, +ed il suo prototipo è: - Rimuove un \textsl{osservatore} da una coda di notifica. - - \bodydesc{La funzione restituisce 0 in caso di successo, o $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: +\begin{funcproto}{ +\fhead{sys/inotify.h} +\fdecl{int inotify\_rm\_watch(int fd, uint32\_t wd)} +\fdesc{Rimuove un \textsl{osservatore} da una coda di notifica.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EBADF}] non si è specificato in \param{fd} un file descriptor valido. @@ -3231,14 +3243,14 @@ prototipo è: non è associato ad una coda di notifica. \end{errlist} } -\end{prototype} +\end{funcproto} La funzione rimuove dalla coda di notifica identificata dall'argomento \param{fd} l'osservatore identificato dal \textit{watch descriptor} -\param{wd};\footnote{ovviamente deve essere usato per questo argomento un - valore ritornato da \func{inotify\_add\_watch}, altrimenti si avrà un errore - di \errval{EINVAL}.} in caso di successo della rimozione, contemporaneamente -alla cancellazione dell'osservatore, sulla coda di notifica verrà generato un +\param{wd}; ovviamente deve essere usato per questo argomento un valore +ritornato da \func{inotify\_add\_watch}, altrimenti si avrà un errore di +\errval{EINVAL}. In caso di successo della rimozione, contemporaneamente alla +cancellazione dell'osservatore, sulla coda di notifica verrà generato un evento di tipo \const{IN\_IGNORED} (vedi tab.~\ref{tab:inotify_read_event_flag}). Si tenga presente che se un file viene cancellato o un filesystem viene smontato i relativi osservatori vengono @@ -3256,7 +3268,7 @@ modalità non bloccante) fino all'arrivo di almeno un evento. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.90\textwidth} \includestruct{listati/inotify_event.h} \end{minipage} \normalsize @@ -3267,8 +3279,8 @@ modalità non bloccante) fino all'arrivo di almeno un evento. Una ulteriore caratteristica dell'interfaccia di \textit{inotify} è che essa permette di ottenere con \func{ioctl}, come per i file descriptor associati ai -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 +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_fcntl_ioctl}), che è disponibile solo per i socket e per i file descriptor creati con \func{inotify\_init}.} Si può così @@ -3283,10 +3295,10 @@ restituito nel campo \var{wd} il \textit{watch descriptor} con cui il relativo osservatore è stato registrato. Il campo \var{mask} contiene invece una maschera di bit che identifica il tipo di evento verificatosi; in essa compariranno sia i bit elencati nella prima parte di -tab.~\ref{tab:inotify_event_watch}, che gli eventuali valori -aggiuntivi\footnote{questi compaiono solo nel campo \var{mask} di - \struct{inotify\_event}, e non utilizzabili in fase di registrazione - dell'osservatore.} di tab.~\ref{tab:inotify_read_event_flag}. +tab.~\ref{tab:inotify_event_watch}, che gli eventuali valori aggiuntivi di +tab.~\ref{tab:inotify_read_event_flag} (questi compaiono solo nel campo +\var{mask} di \struct{inotify\_event}, e non sono utilizzabili in fase di +registrazione dell'osservatore). \begin{table}[htb] \centering @@ -3318,12 +3330,12 @@ aggiuntivi\footnote{questi compaiono solo nel campo \var{mask} di \label{tab:inotify_read_event_flag} \end{table} -\footnotetext{la coda di notifica ha una dimensione massima specificata dal - parametro di sistema \sysctlfile{fs/inotify/max\_queued\_events} che - indica il numero massimo di eventi che possono essere mantenuti sulla - stessa; quando detto valore viene ecceduto gli ulteriori eventi vengono - scartati, ma viene comunque generato un evento di tipo - \const{IN\_Q\_OVERFLOW}.} +\footnotetext{la coda di notifica ha una dimensione massima che viene + controllata dal parametro di sistema + \sysctlfile{fs/inotify/max\_queued\_events}, che indica il numero massimo di + eventi che possono essere mantenuti sulla stessa; quando detto valore viene + ecceduto gli ulteriori eventi vengono scartati, ma viene comunque generato + un evento di tipo \const{IN\_Q\_OVERFLOW}.} Il campo \var{cookie} contiene invece un intero univoco che permette di identificare eventi correlati (per i quali avrà lo stesso valore), al momento @@ -3361,13 +3373,13 @@ funzioni di ausilio è riportato in fig.~\ref{fig:inotify_monitor_example}. \label{fig:inotify_monitor_example} \end{figure} -Una volta completata la scansione delle opzioni il corpo principale del -programma inizia controllando (\texttt{\small 11-15}) che sia rimasto almeno -un argomento che indichi quale file o directory mettere sotto osservazione (e -qualora questo non avvenga esce stampando la pagina di aiuto); dopo di che -passa (\texttt{\small 16-20}) all'inizializzazione di \textit{inotify} -ottenendo con \func{inotify\_init} il relativo file descriptor (oppure usce in -caso di errore). +Una volta completata la scansione delle opzioni il corpo del programma inizia +controllando (\texttt{\small 11-15}) che sia rimasto almeno un argomento che +indichi quale file o directory mettere sotto osservazione (e qualora questo +non avvenga esce stampando la pagina di aiuto); dopo di che passa +(\texttt{\small 16-20}) all'inizializzazione di \textit{inotify} ottenendo con +\func{inotify\_init} il relativo file descriptor (o si esce in caso di +errore). Il passo successivo è aggiungere (\texttt{\small 21-30}) alla coda di notifica gli opportuni osservatori per ciascuno dei file o directory indicati @@ -3384,26 +3396,25 @@ Completa l'inizializzazione di \textit{inotify} inizia il ciclo principale (\texttt{\small 32-56}) del programma, nel quale si resta in attesa degli eventi che si intendono osservare. Questo viene fatto eseguendo all'inizio del ciclo (\texttt{\small 33}) una \func{read} che si bloccherà fintanto che non -si saranno verificati eventi. +si saranno verificati eventi. Dato che l'interfaccia di \textit{inotify} può riportare anche più eventi in una sola lettura, si è avuto cura di passare alla \func{read} un buffer di dimensioni adeguate, inizializzato in (\texttt{\small 7}) ad un valore di -approssimativamente 512 eventi.\footnote{si ricordi che la quantità di dati - restituita da \textit{inotify} è variabile a causa della diversa lunghezza - del nome del file restituito insieme a \struct{inotify\_event}.} In caso di -errore di lettura (\texttt{\small 35-40}) il programma esce con un messaggio -di errore (\texttt{\small 37-39}), a meno che non si tratti di una -interruzione della \textit{system call}, nel qual caso (\texttt{\small 36}) si -ripete la lettura. +approssimativamente 512 eventi (si ricordi che la quantità di dati restituita +da \textit{inotify} è variabile a causa della diversa lunghezza del nome del +file restituito insieme a \struct{inotify\_event}). In caso di errore di +lettura (\texttt{\small 35-40}) il programma esce con un messaggio di errore +(\texttt{\small 37-39}), a meno che non si tratti di una interruzione della +\textit{system call}, nel qual caso (\texttt{\small 36}) si ripete la lettura. Se la lettura è andata a buon fine invece si esegue un ciclo (\texttt{\small 43-52}) per leggere tutti gli eventi restituiti, al solito si inizializza l'indice \var{i} a zero (\texttt{\small 42}) e si ripetono le operazioni (\texttt{\small 43}) fintanto che esso non supera il numero di byte restituiti -in lettura. Per ciascun evento all'interno del ciclo si assegna\footnote{si - noti come si sia eseguito un opportuno \textit{casting} del puntatore.} alla -variabile \var{event} l'indirizzo nel buffer della corrispondente struttura +in lettura. Per ciascun evento all'interno del ciclo si assegna alla variabile +\var{event} (si noti come si sia eseguito un opportuno \textit{casting} del +puntatore) l'indirizzo nel buffer della corrispondente struttura \struct{inotify\_event} (\texttt{\small 44}), e poi si stampano il numero di \textit{watch descriptor} (\texttt{\small 45}) ed il file a cui questo fa riferimento (\texttt{\small 46}), ricavato dagli argomenti passati a riga di @@ -3412,18 +3423,20 @@ in ordine progressivo crescente a partire da 1. Qualora sia presente il riferimento ad un nome di file associato all'evento lo si stampa (\texttt{\small 47-49}); si noti come in questo caso si sia -utilizzato il valore del campo \var{event->len} e non al fatto che -\var{event->name} riporti o meno un puntatore nullo.\footnote{l'interfaccia - infatti, qualora il nome non sia presente, non avvalora il campo - \var{event->name}, che si troverà a contenere quello che era precedentemente - presente nella rispettiva locazione di memoria, nel caso più comune il - puntatore al nome di un file osservato in precedenza.} Si utilizza poi -(\texttt{\small 50}) la funzione \code{printevent}, che interpreta il valore -del campo \var{event->mask} per stampare il tipo di eventi -accaduti.\footnote{per il relativo codice, che non riportiamo in quanto non - essenziale alla comprensione dell'esempio, si possono utilizzare direttamente - i sorgenti allegati alla guida.} Infine (\texttt{\small 51}) si provvede ad -aggiornare l'indice \var{i} per farlo puntare all'evento successivo. +controllato il valore del campo \var{event->len} e non il fatto che +\var{event->name} riporti o meno un puntatore nullo. L'interfaccia infatti, +qualora il nome non sia presente, non tocca il campo \var{event->name}, che +si troverà pertanto a contenere quello che era precedentemente presente nella +rispettiva locazione di memoria, nel caso più comune il puntatore al nome di +un file osservato in precedenza. + +Si utilizza poi (\texttt{\small 50}) la funzione \code{printevent}, che +interpreta il valore del campo \var{event->mask}, per stampare il tipo di +eventi accaduti.\footnote{per il relativo codice, che non riportiamo in quanto + non essenziale alla comprensione dell'esempio, si possono utilizzare + direttamente i sorgenti allegati alla guida.} Infine (\texttt{\small 51}) si +provvede ad aggiornare l'indice \var{i} per farlo puntare all'evento +successivo. Se adesso usiamo il programma per mettere sotto osservazione una directory, e da un altro terminale eseguiamo il comando \texttt{ls} otterremo qualcosa del @@ -3532,7 +3545,7 @@ disponibilità dell'interfaccia per l'I/O asincrono. Le operazioni di I/O asincrono possono essere effettuate solo su un file già aperto; il file deve inoltre supportare la funzione \func{lseek}, pertanto -terminali e pipe sono esclusi. Non c'è limite al numero di operazioni +terminali e \textit{pipe} sono esclusi. Non c'è limite al numero di operazioni contemporanee effettuabili su un singolo file. Ogni operazione deve inizializzare opportunamente un \textit{control block}. Il file descriptor su cui operare deve essere specificato tramite il campo \var{aio\_fildes}; dato @@ -4113,12 +4126,13 @@ Non tutti i file possono venire mappati in memoria, dato che, come illustrato in fig.~\ref{fig:file_mmap_layout}, la mappatura introduce una corrispondenza biunivoca fra una sezione di un file ed una sezione di memoria. Questo comporta che ad esempio non è possibile mappare in memoria file descriptor -relativi a pipe, socket e fifo, per i quali non ha senso parlare di -\textsl{sezione}. Lo stesso vale anche per alcuni file di dispositivo, che non -dispongono della relativa operazione \func{mmap} (si ricordi quanto esposto in -sez.~\ref{sec:file_vfs_work}). Si tenga presente però che esistono anche casi -di dispositivi (un esempio è l'interfaccia al ponte PCI-VME del chip Universe) -che sono utilizzabili solo con questa interfaccia. +relativi a \textit{pipe}, socket e \textit{fifo}, per i quali non ha senso +parlare di \textsl{sezione}. Lo stesso vale anche per alcuni file di +dispositivo, che non dispongono della relativa operazione \func{mmap} (si +ricordi quanto esposto in sez.~\ref{sec:file_vfs_work}). Si tenga presente +però che esistono anche casi di dispositivi (un esempio è l'interfaccia al +ponte PCI-VME del chip Universe) che sono utilizzabili solo con questa +interfaccia. \begin{figure}[htb] \centering @@ -4715,7 +4729,8 @@ sez.~\ref{sec:file_read} e \ref{sec:file_write}); le due funzioni sono \begin{errlist} \item[\errcode{EOVERFLOW}] \param{offset} ha un valore che non può essere usato come \type{off\_t}. - \item[\errcode{ESPIPE}] \param{fd} è associato ad un socket o una pipe. + \item[\errcode{ESPIPE}] \param{fd} è associato ad un socket o una + \textit{pipe}. \end{errlist} } \end{functions} @@ -4900,7 +4915,7 @@ definito la macro \macro{\_GNU\_SOURCE},\footnote{si ricordi che questa \funcdecl{long splice(int fd\_in, off\_t *off\_in, int fd\_out, off\_t *off\_out, size\_t len, unsigned int flags)} - Trasferisce dati da un file verso una pipe o viceversa. + Trasferisce dati da un file verso una \textit{pipe} o viceversa. \bodydesc{La funzione restituisce il numero di byte trasferiti in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno @@ -4910,7 +4925,8 @@ definito la macro \macro{\_GNU\_SOURCE},\footnote{si ricordi che questa non sono file descriptor validi o, rispettivamente, non sono stati aperti in lettura o scrittura. \item[\errcode{EINVAL}] il filesystem su cui si opera non supporta - \func{splice}, oppure nessuno dei file descriptor è una pipe, oppure si + \func{splice}, oppure nessuno dei file descriptor è una \textit{pipe}, + oppure si è dato un valore a \param{off\_in} o \param{off\_out} ma il corrispondente file è un dispositivo che non supporta la funzione \func{lseek}. @@ -5011,8 +5027,8 @@ descrizioni complete di tutti i valori possibili anche quando, come per \footnotetext[120]{per una maggiore efficienza \func{splice} usa quando possibile i meccanismi della memoria virtuale per eseguire i trasferimenti di dati (in maniera analoga a \func{mmap}), qualora le pagine non possano - essere spostate dalla pipe o il buffer non corrisponda a pagine intere esse - saranno comunque copiate.} + essere spostate dalla \textit{pipe} o il buffer non corrisponda a pagine + intere esse saranno comunque copiate.} \footnotetext[121]{questa opzione consente di utilizzare delle opzioni di gestione dei socket che permettono di ottimizzare le trasmissioni via rete, @@ -5213,8 +5229,8 @@ funzione non bloccante. La funzione restituisce il numero di byte copiati da una \textit{pipe} all'altra (o $-1$ in caso di errore), un valore nullo indica che non ci sono -byte disponibili da copiare e che il capo in scrittura della pipe è stato -chiuso.\footnote{si tenga presente però che questo non avviene se si è +byte disponibili da copiare e che il capo in scrittura della \textit{pipe} è +stato chiuso.\footnote{si tenga presente però che questo non avviene se si è impostato il flag \const{SPLICE\_F\_NONBLOCK}, in tal caso infatti si avrebbe un errore di \errcode{EAGAIN}.} Un esempio di realizzazione del comando \texttt{tee} usando questa funzione, ripreso da quello fornito nella @@ -5316,7 +5332,7 @@ all'accesso al disco; il suo prototipo è: \item[\errcode{EBADF}] l'argomento \param{fd} non è un file descriptor valido o non è aperto in lettura. \item[\errcode{EINVAL}] l'argomento \param{fd} si riferisce ad un tipo di - file che non supporta l'operazione (come una pipe o un socket). + file che non supporta l'operazione (come una \textit{pipe} o un socket). \end{errlist} } \end{functions} @@ -5372,8 +5388,8 @@ valore di almeno 600, è: valido. \item[\errcode{EINVAL}] il valore di \param{advice} non è valido o \param{fd} si riferisce ad un tipo di file che non supporta l'operazione - (come una pipe o un socket). - \item[\errcode{ESPIPE}] previsto dallo standard se \param{fd} è una pipe o + (come una \textit{pipe} o un socket). + \item[\errcode{ESPIPE}] previsto dallo standard se \param{fd} è una \textit{pipe} o un socket (ma su Linux viene restituito \errcode{EINVAL}). \end{errlist} } @@ -5482,7 +5498,7 @@ almeno 600, è: file regolare. \item[\errcode{ENOSPC}] non c'è sufficiente spazio disco per eseguire l'operazione. - \item[\errcode{ESPIPE}] l'argomento \param{fd} è una pipe. + \item[\errcode{ESPIPE}] l'argomento \param{fd} è una \textit{pipe}. \end{errlist} } \end{functions} diff --git a/listati/epoll_pwait_means.c b/listati/epoll_pwait_means.c index 75645f1..7576ce0 100644 --- a/listati/epoll_pwait_means.c +++ b/listati/epoll_pwait_means.c @@ -1,5 +1,4 @@ sigset_t origmask; - sigprocmask(SIG_SETMASK, &sigmask, &origmask); ready = epoll_wait(epfd, &events, maxevents, timeout); sigprocmask(SIG_SETMASK, &origmask, NULL); -- 2.30.2