Altro materiale sparso, con alcune indicizzazioni (file descriptor
authorSimone Piccardi <piccardi@gnulinux.it>
Wed, 6 Sep 2006 14:23:52 +0000 (14:23 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Wed, 6 Sep 2006 14:23:52 +0000 (14:23 +0000)
set) che si erano perse per strada.

fileadv.tex
sockadv.tex
sockctrl.tex
tcpsock.tex

index 58c7ee6bed6825316e9765751e1cd1ca6512a516..b65f9228c2ab84c1783a8e20b5c32571f36b05b5 100644 (file)
@@ -127,10 +127,10 @@ degli insiemi specificati (\param{readfds}, \param{writefds} e
 Per specificare quali file descriptor si intende \textsl{selezionare}, la
 funzione usa un particolare oggetto, il \textit{file descriptor set},
 identificato dal tipo \type{fd\_set}, che serve ad identificare un insieme di
-file descriptor, in maniera analoga a come un
-\itindex{signal~set}\textit{signal set} (vedi sez.~\ref{sec:sig_sigset})
-identifica un insieme di segnali. Per la manipolazione di questi \textit{file
-  descriptor set} si possono usare delle opportune macro di preprocessore:
+file descriptor, in maniera analoga a come un \itindex{signal~set}
+\textit{signal set} (vedi sez.~\ref{sec:sig_sigset}) identifica un insieme di
+segnali. Per la manipolazione di questi \textit{file descriptor set} si
+possono usare delle opportune macro di preprocessore:
 \begin{functions}
   \headdecl{sys/time.h}
   \headdecl{sys/types.h}
@@ -185,7 +185,6 @@ ritorni; se impostato a \val{NULL} la funzione attende indefinitamente. Si pu
 specificare anche un tempo nullo (cioè una struttura \struct{timeval} con i
 campi impostati a zero), qualora si voglia semplicemente controllare lo stato
 corrente dei file descriptor.
-\itindend{file~descriptor~set}
 
 La funzione restituisce il numero di file descriptor pronti,\footnote{questo è
   il comportamento previsto dallo standard, ma la standardizzazione della
@@ -198,6 +197,8 @@ modificati.  In caso di errore la funzione restituisce -1, ed i valori dei tre
 insiemi sono indefiniti e non si può fare nessun affidamento sul loro
 contenuto.
 
+\itindend{file~descriptor~set}
+
 In Linux \func{select} modifica anche il valore di \param{timeout},
 impostandolo al tempo restante in caso di interruzione prematura; questo è
 utile quando la funzione viene interrotta da un segnale, in tal caso infatti
@@ -291,25 +292,26 @@ interrotta, e la ricezione del segnale non sar
 
 Per questo è stata introdotta \func{pselect} che attraverso l'argomento
 \param{sigmask} permette di riabilitare la ricezione il segnale
-contestualmente all'esecuzione della funzione,\footnote{in Linux però non è
-  presente la relativa system call, e la funzione è implementata nelle
-  \acr{glibc} attraverso \func{select} (vedi \texttt{man select\_tut}) per cui
-  la possibilità di \itindex{race~condition}\textit{race condition} permane;
-  esiste però una soluzione, chiamata \itindex{self-pipe trick}
-  \textit{self-pipe trick}, che consiste nell'aprire una pipe (vedi
-  sez.~\ref{sec:ipc_pipes}) ed usare \func{select} sul capo in lettura della
-  stessa, e indicare l'arrivo di un segnale scrivendo sul capo in scrittura
-  all'interno del manipolatore; 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:
+contestualmente all'esecuzione della funzione,\footnote{in Linux però, fino al
+  kernel 2.6.26, non è presente la relativa system call, e la funzione è
+  implementata nelle \acr{glibc} attraverso \func{select} (vedi \texttt{man
+    select\_tut}) per cui la possibilità di \itindex{race~condition}
+  \textit{race condition} permane; esiste però una soluzione, chiamata
+  \itindex{self-pipe trick} \textit{self-pipe trick}, che consiste nell'aprire
+  una pipe (vedi sez.~\ref{sec:ipc_pipes}) ed usare \func{select} sul capo in
+  lettura della stessa, e indicare l'arrivo di un segnale scrivendo sul capo
+  in scrittura all'interno del manipolatore; 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:
 \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
 interruzione si potranno eseguire le relative operazioni.
 
 % TODO pselect è stata introdotta nel kernel 2.6.16 (o 15 o 17?) insieme a
-% ppoll mettere e verificare
+% ppoll mettere e verificare, vedi articolo LWN http://lwn.net/Articles/176750/
 
 
 \subsection{La funzione \func{poll}}
index 25ca6995a3144eb15e5180439670aac3132ac596..f50177191246d037f9904369071bdc6cfa9f4ca1 100644 (file)
@@ -59,13 +59,23 @@ fig.~\ref{fig:sock_extended_err_struct}.
 
 
 
-\subsection{I dati \textit{out-of-band}}
+\subsection{I \textsl{dati urgenti} o \textit{out-of-band}}
 \label{sec:TCP_urgent_data}
 
 \itindbeg{out-of-band} 
-Una caratteristica speciale dei socket TCP è quella della presenza dei
-cosiddetti dati \textit{out-of-band} ...
 
+Una caratteristica particolare dei socket TCP è quella che consente di inviare
+all'altro capo della comunicazione una sorta di messaggio privilegiato, che si
+richide che sia trattato il prima possibile. Si fa riferimento a questa
+funzionalità come all'invio dei cosiddetti \textsl{dati urgenti} (o
+\textit{udernt data}); tavolta essi chiamati anche dati \textit{out-of-band}
+poiché, come vedremo più anvati, possono essere letti anche al di fuori del
+flusso di dati normale.
+
+Come già accennato in sez.~\ref{sec:file_multiplexing} la presenza di dati
+urgenti viene rilevata in maniera specifica sia di \func{select} (con il
+\itindex{file~descriptor~set} \textit{file descriptor set} \param{exceptfds})
+che da \func{poll} (con la condizione \const{POLLRDBAND}).
 
 
 Le modalità di lettura dei dati urgenti sono due, la prima e più comune
index 2946d86525124743424d14ad5b825d8deb6c01ee..8bc4d038ee9e228a5076463d2193a225a1c1b3cc 100644 (file)
@@ -2274,7 +2274,11 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
 
 \item[\const{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
   può essere utilizzata soltanto con \func{getsockopt} e prende per
-  \param{optval} un valore intero.  
+  \param{optval} un valore intero, nel quale viene restituito il codice di
+  errore, e la condizione di errore sul socket viene cancellata. Viene
+  usualmente utilizzata per ricevere il codice di errore, come accennato in
+  sez.~\ref{sec:TCP_sock_select}, quando si sta osservando il socket con una
+  \func{select} che ritorna a causa dello stesso.
 \end{basedescript}
 
 
@@ -3259,7 +3263,7 @@ sono le seguenti:
   soltanto una etichetta associata a detto \textsl{indice}, che permette di
   rendere più comprensibile l'indicazione dell'interfaccia all'interno dei
   comandi; si può ottenere un elenco delle interfacce che contiene anche il
-  valore del relativo indice usando il comando \cmd{ip link}.}
+  valore del relativo indice usando il comando \cmd{ip link}.
 
 \item[\const{SIOCGIFINDEX}] restituisce nel campo \var{ifr\_ifindex} il valore
   numerico dell'indice dell'interfaccia specificata con \var{ifr\_name}, è in
index 7535d61a9a4eb73be1556942323b942ddc6516e2..d3d1f559c4ffa3fd66f861fb83d2a993e4bb2ae0 100644 (file)
@@ -2754,14 +2754,16 @@ sez.~\ref{sec:file_multiplexing} e non staremo a ripetere quanto detto l
 sappiamo che la funzione ritorna quando uno o più dei file descriptor messi
 sotto controllo è pronto per la relativa operazione.
 
+
+
 In quell'occasione non abbiamo però definito cosa si intende per pronto,
 infatti per dei normali file, o anche per delle pipe, la condizione di essere
 pronti per la lettura o la scrittura è ovvia; invece lo è molto meno nel caso
 dei socket, visto che possono intervenire tutte una serie di possibili
 condizioni di errore dovute alla rete. Occorre allora specificare chiaramente
 quali sono le condizioni per cui un socket risulta essere ``\textsl{pronto}''
-quando viene passato come membro di uno dei tre \textit{file descriptor set}
-usati da \func{select}.
+quando viene passato come membro di uno dei tre \itindex{file~descriptor~set}
+\textit{file descriptor set} usati da \func{select}.
 
 Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
 che un socket (che sarà riportato nel primo insieme di file descriptor) è
@@ -2785,8 +2787,8 @@ pronto per la lettura sono le seguenti:
   non si bloccherà ma restituirà una condizione di errore (ad esempio
   \func{read} restituirà -1) e imposterà la variabile \var{errno} al relativo
   valore. Vedremo in sez.~\ref{sec:sock_generic_options} come sia possibile
-  estrarre e cancellare errori pendenti su un socket usando l'opzione
-  \const{SO\_ERROR}.
+  estrarre e cancellare gli errori pendenti su un socket senza usare
+  \func{read} usando l'opzione \const{SO\_ERROR}.
 \item quando si sta utilizzando un \textit{listening socket} ed ci sono delle
   connessioni completate. In questo caso la funzione \func{accept} non si
   bloccherà.\footnote{in realtà questo non è sempre vero, come accennato in
@@ -2900,26 +2902,27 @@ codice completo si trova nel file \file{TCP\_echo\_third.c} dei sorgenti
 allegati alla guida.
 
 In questo caso la funzione comincia (\texttt{\small 8--9}) con l'azzeramento
-del file descriptor set \var{fset} e l'impostazione del valore \var{maxfd}, da
-passare a \func{select} come massimo per il numero di file descriptor. Per
-determinare quest'ultimo si usa la macro \code{max} definita nel nostro file
-\file{macro.h} che raccoglie una collezione di macro di preprocessore di varia
-utilità.
+del \itindex{file~descriptor~set} \textit{file descriptor set} \var{fset} e
+l'impostazione del valore \var{maxfd}, da passare a \func{select} come massimo
+per il numero di file descriptor. Per determinare quest'ultimo si usa la macro
+\code{max} definita nel nostro file \file{macro.h} che raccoglie una
+collezione di macro di preprocessore di varia utilità.
 
 La funzione prosegue poi (\texttt{\small 10--41}) con il ciclo principale, che
 viene ripetuto indefinitamente. Per ogni ciclo si reinizializza
-(\texttt{\small 11--12}) il file descriptor set, impostando i valori per il
-file descriptor associato al socket \var{socket} e per lo standard input (il
-cui valore si recupera con la funzione \func{fileno}). Questo è necessario in
-quanto la successiva (\texttt{\small 13}) chiamata a \func{select} comporta
-una modifica dei due bit relativi, che quindi devono essere reimpostati
-all'inizio di ogni ciclo.
+(\texttt{\small 11--12}) il \itindex{file~descriptor~set} \textit{file
+  descriptor set}, impostando i valori per il file descriptor associato al
+socket \var{socket} e per lo standard input (il cui valore si recupera con la
+funzione \func{fileno}). Questo è necessario in quanto la successiva
+(\texttt{\small 13}) chiamata a \func{select} comporta una modifica dei due
+bit relativi, che quindi devono essere reimpostati all'inizio di ogni ciclo.
 
 Si noti come la chiamata a \func{select} venga eseguita usando come primo
 argomento il valore di \var{maxfd}, precedentemente calcolato, e passando poi
-il solo file descriptor set per il controllo dell'attività in lettura, negli
-altri argomenti sono passati tutti puntatori nulli, non interessando né il
-controllo delle altre attività, né l'impostazione di un valore di timeout.
+il solo \itindex{file~descriptor~set} \textit{file descriptor set} per il
+controllo dell'attività in lettura, negli altri argomenti sono passati tutti
+puntatori nulli, non interessando né il controllo delle altre attività, né
+l'impostazione di un valore di timeout.
 
 Al ritorno di \func{select} si provvede a controllare quale dei due file
 descriptor presenta attività in lettura, cominciando (\texttt{\small 14--24})
@@ -3196,7 +3199,7 @@ prima (\texttt{\small 19}) si imposta opportunamente \var{eof} ad un valore
 non nullo, dopo di che (\texttt{\small 20}) si effettua la chiusura del lato
 in scrittura del socket con \func{shutdown}. Infine (\texttt{\small 21}) si
 usa la macro \macro{FD\_CLR} per togliere lo standard input dal file
-descriptor set.
+descriptor set. \itindex{file~descriptor~set}
 
 In questo modo anche se la lettura del file in ingresso è conclusa, la
 funzione non esce dal ciclo principale (\texttt{\small 11--50}), ma continua
@@ -3278,14 +3281,15 @@ aperti viene impostato a quello del socket in ascolto,\footnote{in quanto esso
   alto.} che verrà anche (\texttt{\small 4}) inserito nella tabella.
 
 La prima sezione (\texttt{\small 7--10}) del ciclo principale esegue la
-costruzione del \textit{file descriptor set} \var{fset} in base ai socket
-connessi in un certo momento; all'inizio ci sarà soltanto il socket in
-ascolto, ma nel prosieguo delle operazioni, verranno utilizzati anche tutti i
-socket connessi registrati nella tabella \var{fd\_open}.  Dato che la chiamata
-di \func{select} modifica il valore del \textit{file descriptor set}, è
-necessario ripetere (\texttt{\small 7}) ogni volta il suo azzeramento, per poi
-procedere con il ciclo (\texttt{\small 8--10}) in cui si impostano i socket
-trovati attivi.
+costruzione del \itindex{file~descriptor~set} \textit{file descriptor set}
+\var{fset} in base ai socket connessi in un certo momento; all'inizio ci sarà
+soltanto il socket in ascolto, ma nel prosieguo delle operazioni, verranno
+utilizzati anche tutti i socket connessi registrati nella tabella
+\var{fd\_open}.  Dato che la chiamata di \func{select} modifica il valore del
+\itindex{file~descriptor~set} \textit{file descriptor set}, è necessario
+ripetere (\texttt{\small 7}) ogni volta il suo azzeramento, per poi procedere
+con il ciclo (\texttt{\small 8--10}) in cui si impostano i socket trovati
+attivi.
 
 Per far questo si usa la caratteristica dei file descriptor, descritta in
 sez.~\ref{sec:file_open}, per cui il kernel associa sempre ad ogni nuovo file
@@ -3334,14 +3338,14 @@ vi sono dati sui socket connessi, per questo si ripete un ciclo
 (\texttt{\small 29--55}) fintanto che il numero di socket attivi \var{n} resta
 diverso da zero; in questo modo se l'unico socket con attività era quello
 connesso, avendo opportunamente decrementato il contatore, il ciclo verrà
-saltato, e si ritornerà immediatamente (ripetuta l'inizializzazione del file
-descriptor set con i nuovi valori nella tabella) alla chiamata di
-\func{accept}. Se il socket attivo non è quello in ascolto, o ce ne sono
-comunque anche altri, il valore di \var{n} non sarà nullo ed il controllo sarà
-eseguito. Prima di entrare nel ciclo comunque si inizializza (\texttt{\small
-  28}) il valore della variabile \var{i} che useremo come indice nella tabella
-\var{fd\_open} al valore minimo, corrispondente al file descriptor del socket
-in ascolto.
+saltato, e si ritornerà immediatamente (ripetuta l'inizializzazione del
+\itindex{file~descriptor~set} file descriptor set con i nuovi valori nella
+tabella) alla chiamata di \func{accept}. Se il socket attivo non è quello in
+ascolto, o ce ne sono comunque anche altri, il valore di \var{n} non sarà
+nullo ed il controllo sarà eseguito. Prima di entrare nel ciclo comunque si
+inizializza (\texttt{\small 28}) il valore della variabile \var{i} che useremo
+come indice nella tabella \var{fd\_open} al valore minimo, corrispondente al
+file descriptor del socket in ascolto.
 
 Il primo passo (\texttt{\small 30}) nella verifica è incrementare il valore
 dell'indice \var{i} per posizionarsi sul primo valore possibile per un file
@@ -3416,7 +3420,8 @@ maggior parte dei casi, in quanto essa 
 queste problematiche con i socket.  Abbiamo però visto in
 sez.~\ref{sec:file_multiplexing} come la funzione \func{poll} possa costituire
 una alternativa a \func{select}, con alcuni vantaggi.\footnote{non soffrendo
-  delle limitazioni dovute all'uso dei \textit{file descriptor set}.}
+  delle limitazioni dovute all'uso dei \itindex{file~descriptor~set}
+  \textit{file descriptor set}.}
 
 Ancora una volta in sez.~\ref{sec:file_poll} abbiamo trattato la funzione in
 maniera generica, parlando di file descriptor, ma come per \func{select}
@@ -3550,11 +3555,11 @@ effettuarne la riscrittura all'indietro, con il solito controllo ed eventuale
 uscita e notifica in caso si errore (\texttt{\small 49--52}).
 
 Come si può notare la logica del programma è identica a quella vista in
-fig.~\ref{fig:TCP_SelectEchod} per l'analogo server basato su \func{select}; la
-sola differenza significativa è che in questo caso non c'è bisogno di
-rigenerare i file descriptor set in quanto l'uscita è indipendente dai dati in
-ingresso. Si applicano comunque anche a questo server le considerazioni finali
-di sez.~\ref{sec:TCP_serv_select}.
+fig.~\ref{fig:TCP_SelectEchod} per l'analogo server basato su \func{select};
+la sola differenza significativa è che in questo caso non c'è bisogno di
+rigenerare i \itindex{file~descriptor~set} file descriptor set in quanto
+l'uscita è indipendente dai dati in ingresso. Si applicano comunque anche a
+questo server le considerazioni finali di sez.~\ref{sec:TCP_serv_select}.
 
 
 % LocalWords:  socket TCP client dell'I multiplexing stream three way handshake