Fatte mq_open, mq_close, mq_unlink, mq_setattr, mq_getaddr.
[gapil.git] / socket.tex
index 619c1dd15ad0f29ef7684673bbcd254af4068ca0..2e34e78d3bdeaaa3bab7428c8740310ecc3b36ec 100644 (file)
@@ -1,3 +1,13 @@
+%% socket.tex
+%%
+%% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
+%% copy, distribute and/or modify this document under the terms of the GNU Free
+%% Documentation License, Version 1.1 or any later version published by the
+%% Free Software Foundation; with the Invariant Sections being "Prefazione",
+%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
+%% license is included in the section entitled "GNU Free Documentation
+%% License".
+%%
 \chapter{Introduzione ai socket}
 \label{cha:socket_intro}
 
@@ -17,6 +27,8 @@ concluderemo il capitolo con un primo esempio di applicazione.
 Iniziamo con una descrizione essenziale di cosa sono i \textit{socket} e di
 quali sono i concetti fondamentali da tenere presente quando si ha a che fare
 con essi.
+\index{socket|(}
+
 
 \subsection{I \textit{socket}}
 \label{sec:sock_socket_def}
@@ -26,10 +38,11 @@ Il \textit{socket}\footnote{una traduzione letterale potrebbe essere
   sempre la parola inglese.} è uno dei principali meccanismi di comunicazione
 fra programmi utilizzato in ambito Unix. Il socket costituisce in sostanza un
 canale di comunicazione fra due processi su cui si possono leggere e scrivere
-dati analogo a quello di una pipe ma a differenza di questa e degli altri
-meccanismi esaminati nel capitolo \capref{cha:IPC} i socket non sono limitati
-alla comunicazione fra processi che girano sulla stessa macchina ma possono
-effettuare la comunicazione anche attraverso la rete.
+dati analogo a quello di una pipe (vedi \secref{sec:ipc_pipes}) ma a
+differenza di questa e degli altri meccanismi esaminati nel capitolo
+\capref{cha:IPC} i socket non sono limitati alla comunicazione fra processi
+che girano sulla stessa macchina ma possono effettuare la comunicazione anche
+attraverso la rete.
 
 Quella dei socket costituisce infatti la principale API (\textit{Application
   Program Interface}) usata nella programmazione di rete.  La loro origine
@@ -37,8 +50,8 @@ risale al 1983, quando furono introdotti nel BSD 4.2; l'interfaccia 
 sostanzialmente la stessa con piccole modifiche negli anni successivi. Benché
 siano state sviluppate interfacce alternative, originate dai sistemi SVr4,
 come la XTI (\textit{X/Open Transport Interface}) nessuna ha mai raggiunto la
-diffusione e la popolarità di quella dei socket (né tantomeno usabilità e
-flessibilità).
+diffusione e la popolarità di quella dei socket (né tantomeno la stessa
+usabilità e flessibilità).
 
 La flessibilità e la genericità dell'interfaccia inoltre ha consentito di
 utilizzare i socket con i più disparati meccanismi di comunicazione, e non
@@ -57,11 +70,11 @@ usato, le funzioni da usare restano le stesse.
 
 Per questo motivo una semplice descrizione dell'interfaccia è assolutamente
 inutile, in quanto il comportamento di quest'ultima e le problematiche da
-affrontare cambiano radicalmente a seconda dello ``stile'' di comunicazione
-usato.  La scelta di questo stile va infatti ad incidere sulla semantica che
-verrà utilizzata a livello utente per gestire la comunicazione (su come
-inviare e ricevere i dati) e sul comportamento effettivo delle funzioni
-utilizzate.
+affrontare cambiano radicalmente a seconda dello \textsl{stile} di
+comunicazione usato.  La scelta di questo stile va infatti ad incidere sulla
+semantica che verrà utilizzata a livello utente per gestire la comunicazione
+(su come inviare e ricevere i dati) e sul comportamento effettivo delle
+funzioni utilizzate.
 
 La scelta di uno stile dipende sia dai meccanismi disponibili, sia dal tipo di
 comunicazione che si vuole effettuare. Ad esempio alcuni stili di
@@ -77,8 +90,8 @@ avviene, in certi casi essa pu
 con un solo partner come per una telefonata; altri casi possono prevedere una
 comunicazione come per lettera, in cui si scrive l'indirizzo su ogni
 pacchetto, altri ancora una comunicazione \textit{broadcast} come per la
-radio, in cui i pacchetti vengono emessi su appositi ``canali'' dove chiunque
-si collega possa riceverli.
+radio, in cui i pacchetti vengono emessi su appositi ``\textsl{canali}'' dove
+chiunque si collega possa riceverli.
 
 É chiaro che ciascuno di questi stili comporta una modalità diversa di gestire
 la comunicazione, ad esempio se è inaffidabile occorrerà essere in grado di
@@ -97,44 +110,43 @@ il tipo di comunicazione che esso deve utilizzare.
 \label{sec:sock_socket}
 
 La creazione di un socket avviene attraverso l'uso della funzione
-\func{socket} questa restituisce un \textit{socket descriptor} (un valore
-intero non negativo) che come gli analoghi file descriptor di file e alle
-pipe serve come riferimento al socket; in sostanza è l'indice nella tabella
-dei file che contiene i puntatori alle opportune strutture usate dal kernel ed
-allocate per ogni processo, (la stessa usata per i files e le pipes [NdA
-verificare!]).
-
-La funzione prende tre parametri, il dominio del socket (che definisce la
-famiglia di protocolli, vedi \secref{sec:sock_domain}), il tipo di socket (che
-definisce lo stile di comunicazione vedi \secref{sec:sock_type}) e il
-protocollo; in genere quest'ultimo è indicato implicitamente dal tipo di
-socket, per cui viene messo a zero (con l'eccezione dei \textit{raw socket}).
-
+\funcd{socket}; questa restituisce un \textit{file descriptor}\footnote{del
+  tutto analogo a quelli che si ottengono per i file di dati e le pipe,
+  descritti in \secref{sec:file_fd}.} che serve come riferimento al socket; il
+suo prototipo è:
 \begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)}
 
   Apre un socket.
   
-  \bodydesc{La funzione restituisce un intero positivo se riesce, e -1 se
-    fallisce, in quest'ultimo caso la variabile \var{errno} è settata con i
-    seguenti codici di errore:
-
+  \bodydesc{La funzione restituisce un intero positivo in caso di successo, e
+    -1 in caso di fallimento, nel qual caso la variabile \var{errno} assumerà
+  i valori:
   \begin{errlist}
-  \item[\macro{EPROTONOSUPPORT}] Il tipo di socket o il protocollo scelto non
+  \item[\errcode{EPROTONOSUPPORT}] Il tipo di socket o il protocollo scelto non
     sono supportati nel dominio.
-  \item[\macro{ENFILE}] Il kernel non ha memoria sufficiente a creare una
+  \item[\errcode{ENFILE}] Il kernel non ha memoria sufficiente a creare una
     nuova struttura per il socket.
-  \item[\macro{EMFILE}] Si è ecceduta la tabella dei file.
-  \item[\macro{EACCES}] Non si hanno privilegi per creare un socket nel
+  \item[\errcode{EMFILE}] Si è ecceduta la tabella dei file.
+  \item[\errcode{EACCES}] Non si hanno privilegi per creare un socket nel
     dominio o con il protocollo specificato.
-  \item[\macro{EINVAL}] Protocollo sconosciuto o dominio non disponibile.
-  \item[\macro{ENOBUFS}] Non c'è sufficiente memoria per creare il socket (può
-    essere anche \macro{ENOMEM}).
+  \item[\errcode{EINVAL}] Protocollo sconosciuto o dominio non disponibile.
+  \item[\errcode{ENOBUFS}] Non c'è sufficiente memoria per creare il socket
+    (può essere anche \errval{ENOMEM}).
   \end{errlist}}
 \end{prototype}
 
-Si noti che la creazione del socket non comporta nulla riguardo
-all'indicazione degli indirizzi remoti o locali attraverso i quali si vuole
-effettuare la comunicazione.
+La funzione ha tre argomenti, \param{domain} specifica il dominio del socket
+(definisce cioè la famiglia di protocolli, come vedremo in
+\secref{sec:sock_domain}), \param{type} specifica il tipo di socket (definisce
+cioè lo stile di comunicazione, come vedremo in \secref{sec:sock_type}) e
+\param{protocol} il protocollo; in genere quest'ultimo è indicato
+implicitamente dal tipo di socket, per cui viene messo a zero (con l'eccezione
+dei \textit{raw socket}).
+
+Si noti che la creazione del socket si limita ad allocare le opportune
+strutture nel kernel (sostanzialmente una voce nella \textit{file table}) e
+non comporta nulla riguardo all'indicazione degli indirizzi remoti o locali
+attraverso i quali si vuole effettuare la comunicazione.
 
 \subsection{Il dominio, o \textit{protocol family}}
 \label{sec:sock_domain}
@@ -148,9 +160,10 @@ altro nome con cui si indicano i domini.
 
 A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per
 \texttt{AF\_} da \textit{address family}, e che identifica il formato degli
-indirizzi usati in quel dominio; le man pages di Linux si riferiscono a questi
-anche come \textit{name space}, (nome che però il manuale della glibc riserva
-ai domini) e che identifica il formato degli indirizzi usati in quel dominio.
+indirizzi usati in quel dominio; le pagine di manuale di Linux si riferiscono
+a questi anche come \textit{name space}, (nome che però il manuale delle
+\acr{glibc} riserva ai domini) e che identifica il formato degli indirizzi
+usati in quel dominio.
 
 L'idea alla base della distinzione era che una famiglia di protocolli potesse
 supportare vari tipi di indirizzi, per cui il prefisso \texttt{PF\_} si
@@ -162,7 +175,7 @@ nomi sono equivalenti e corrispondono agli stessi valori.
 
 I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di
 indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di
-protocolli disponibili sono riportate in \ntab.
+protocolli disponibili sono riportate in \tabref{tab:net_pf_names}.
 
 \begin{table}[htb]
   \footnotesize
@@ -172,17 +185,17 @@ protocolli disponibili sono riportate in \ntab.
        \textbf{Nome}      & \textbf{Utilizzo}           &\textbf{Man page} \\
        \hline
        \hline
-       \macro{PF\_UNIX},
-       \macro{PF\_LOCAL}  & Local communication            & unix(7)    \\
-       \macro{PF\_INET}   & IPv4 Internet protocols        & ip(7)      \\
-       \macro{PF\_INET6}  & IPv6 Internet protocols        &            \\
-       \macro{PF\_IPX}    & IPX - Novell protocols         &            \\
-       \macro{PF\_NETLINK}& Kernel user interface device   & netlink(7) \\
-       \macro{PF\_X25}    & ITU-T X.25 / ISO-8208 protocol & x25(7)     \\
-       \macro{PF\_AX25}   & Amateur radio AX.25 protocol   &            \\
-       \macro{PF\_ATMPVC} & Access to raw ATM PVCs         &            \\
-       \macro{PF\_APPLETALK}& Appletalk                    & ddp(7)     \\
-       \macro{PF\_PACKET} & Low level packet interface     & packet(7)  \\    
+       \const{PF\_UNIX},
+       \const{PF\_LOCAL}  & Local communication            & unix(7)    \\
+       \const{PF\_INET}   & IPv4 Internet protocols        & ip(7)      \\
+       \const{PF\_INET6}  & IPv6 Internet protocols        & ipv6(7)    \\
+       \const{PF\_IPX}    & IPX - Novell protocols         &            \\
+       \const{PF\_NETLINK}& Kernel user interface device   & netlink(7) \\
+       \const{PF\_X25}    & ITU-T X.25 / ISO-8208 protocol & x25(7)     \\
+       \const{PF\_AX25}   & Amateur radio AX.25 protocol   &            \\
+       \const{PF\_ATMPVC} & Access to raw ATM PVCs         &            \\
+       \const{PF\_APPLETALK}& Appletalk                    & ddp(7)     \\
+       \const{PF\_PACKET} & Low level packet interface     & packet(7)  \\    
        \hline
   \end{tabular}
   \caption{Famiglie di protocolli definiti in Linux}
@@ -190,9 +203,9 @@ protocolli disponibili sono riportate in \ntab.
 \end{table}
 
 Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad
-esempio in generale tutti i socket di tipo \macro{SOCK\_RAW} possono essere
-creati solo da processi che hanno i privilegi di root (cioè effective uid
-uguale a zero) o la capability \macro{CAP\_NET\_RAW}.
+esempio in generale tutti i socket di tipo \const{SOCK\_RAW} possono essere
+creati solo da processi che hanno i privilegi di root (cioè con user-ID
+effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_RAW}.
 
 
 \subsection{Il tipo, o stile}
@@ -202,63 +215,64 @@ La scelta di un dominio non comporta per
 comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad
 utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di
 scegliere lo stile di comunicazione indicando il tipo di socket; Linux e le
-glibc mettono a disposizione i seguenti tipi di socket (che il manuale della
-glibc chiama \textit{styles}) definiti come \type{int} in \file{socket.h}:
+\acr{glibc} mettono a disposizione i seguenti tipi di socket (che il manuale
+della \acr{glibc} chiama \textit{styles}) definiti come \ctyp{int} in
+\file{socket.h}:
 
 \begin{list}{}{}
-\item \macro{SOCK\_STREAM} Provvede un canale di trasmissione dati
+\item \const{SOCK\_STREAM} Provvede un canale di trasmissione dati
   bidirezionale, sequenziale e affidabile. Opera su una connessione con un
   altro socket. I dati vengono ricevuti e trasmessi come un flusso continuo di
   byte (da cui il nome \textit{stream}). 
-\item \macro{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza
+\item \const{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza
   massima fissata (\textit{datagram}) indirizzati singolarmente, senza
   connessione e in maniera non affidabile. È l'opposto del precedente. 
-\item \macro{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati
+\item \const{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati
   bidirezionale, sequenziale e affidabile. Opera su una connessione con un
   altro socket. I dati possono solo essere trasmessi e letti per pacchetti (di
   dimensione massima fissata).
-\item \macro{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di
+\item \const{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di
   rete e alle varie interfacce. I normali programmi di comunicazione non
   devono usarlo.
-\item \macro{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
+\item \const{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
   affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti.
-\item \macro{SOCK\_PACKET} Obsoleto, non deve essere usato.
+\item \const{SOCK\_PACKET} Obsoleto, non deve essere usato.
 \end{list}
 
-Si tenga presente che non tutte le combinazioni di famiglia di protocolli e
-tipo di socket sono valide, in quanto non è detto che nella famiglia esista un
-protocollo per tutti gli stili di comunicazione indicati qui sopra. Una
-tabella che mostra le combinazioni valide è la seguente:
+Si tenga presente che non tutte le combinazioni fra una famiglia di protocolli
+e un tipo di socket sono valide, in quanto non è detto che in una famiglia
+esista un protocollo per ciascuno dei diversi stili di comunicazione appena
+elencati.
 
 \begin{table}[htb]
   \footnotesize
   \centering
   \begin{tabular}{l|c|c|c|c|c|}
-   \multicolumn{1}{c}{} &\multicolumn{1}{c}{\macro{SOCK\_STREAM}}& 
-     \multicolumn{1}{c}{\macro{SOCK\_DGRAM}} & 
-     \multicolumn{1}{c}{\macro{SOCK\_RAW}} & 
-     \multicolumn{1}{c}{\macro{SOCK\_PACKET}}& 
-     \multicolumn{1}{c}{\macro{SOCK\_SEQPACKET}} \\
+   \multicolumn{1}{c}{} &\multicolumn{1}{c}{\const{SOCK\_STREAM}}& 
+     \multicolumn{1}{c}{\const{SOCK\_DGRAM}} & 
+     \multicolumn{1}{c}{\const{SOCK\_RAW}} & 
+     \multicolumn{1}{c}{\const{SOCK\_PACKET}}& 
+     \multicolumn{1}{c}{\const{SOCK\_SEQPACKET}} \\
      \cline{2-6}
-    \macro{PF\_UNIX}      &  si & si  &      &     &     \\
+    \const{PF\_UNIX}      &  si & si  &      &     &     \\
      \cline{2-6}
-    \macro{PF\_INET}      & TCP & UDP & IPv4 &     &     \\
+    \const{PF\_INET}      & TCP & UDP & IPv4 &     &     \\
      \cline{2-6}
-    \macro{PF\_INET6}     & TCP & UDP & IPv6 &     &     \\
+    \const{PF\_INET6}     & TCP & UDP & IPv6 &     &     \\
      \cline{2-6}
-    \macro{PF\_IPX}       &     &     &      &     &     \\
+    \const{PF\_IPX}       &     &     &      &     &     \\
      \cline{2-6}
-    \macro{PF\_NETLINK}   &     &  si &  si  &     &     \\
+    \const{PF\_NETLINK}   &     &  si &  si  &     &     \\
      \cline{2-6}
-    \macro{PF\_X25}       &     &     &      &     &  si \\
+    \const{PF\_X25}       &     &     &      &     &  si \\
      \cline{2-6}
-    \macro{PF\_AX25}      &     &     &      &     &     \\
+    \const{PF\_AX25}      &     &     &      &     &     \\
      \cline{2-6}
-    \macro{PF\_ATMPVC}    &     &     &      &     &     \\
+    \const{PF\_ATMPVC}    &     &     &      &     &     \\
      \cline{2-6}
-    \macro{PF\_APPLETALK} &     & si  &  si  &     &     \\
+    \const{PF\_APPLETALK} &     & si  &  si  &     &     \\
      \cline{2-6}
-    \macro{PF\_PACKET}    &     & si  & si   &     &     \\    
+    \const{PF\_PACKET}    &     & si  & si   &     &     \\    
      \cline{2-6}
   \end{tabular}
   \caption{Combinazioni valide di dominio e tipo di protocollo per la 
@@ -266,9 +280,11 @@ tabella che mostra le combinazioni valide 
   \label{tab:sock_sock_valid_combinations}
 \end{table}
 
-Dove per ogni combinazione valida si è indicato il tipo di protocollo, o la
-parola \textsl{si} qualora non il protocollo non abbia un nome definito,
-mentre si sono lasciate vuote le caselle per le combinazioni non supportate.
+In \secref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni
+valide possibili per le varie famiglie di protocolli. Per ogni combinazione
+valida si è indicato il tipo di protocollo, o la parola \textsl{si} qualora
+non il protocollo non abbia un nome definito, mentre si sono lasciate vuote le
+caselle per le combinazioni non supportate.
 
 
 
@@ -300,20 +316,23 @@ attraverso puntatori (cio
 maneggiare puntatori a strutture relative a tutti gli indirizzi possibili
 nelle varie famiglie di protocolli; questo pone il problema di come passare
 questi puntatori, il C ANSI risolve questo problema coi i puntatori generici
-(i \type{void *}), ma l'interfaccia dei socket è antecedente alla
-definizione dello standard ANSI, e per questo nel 1982 fu scelto di definire
-una struttura generica \type{sockaddr} per gli indirizzi dei socket mostrata
-in \nfig:
+(i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla definizione
+dello standard ANSI, e per questo nel 1982 fu scelto di definire una struttura
+generica per gli indirizzi dei socket, \struct{sockaddr}, che si è riportata in
+\figref{fig:sock_sa_gen_struct}.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 struct sockaddr {
     sa_family_t  sa_family;     /* address family: AF_xxx */
     char         sa_data[14];   /* address (protocol-specific) */
 };
-  \end{lstlisting}
-  \caption{La struttura generica degli indirizzi dei socket \type{sockaddr}}
+    \end{lstlisting}
+  \end{minipage} 
+  \caption{La struttura generica degli indirizzi dei socket
+    \structd{sockaddr}.} 
   \label{fig:sock_sa_gen_struct}
 \end{figure}
 
@@ -323,12 +342,13 @@ invocano dette funzioni passando l'indirizzo di un protocollo specifico
 occorrerà eseguire un casting del relativo puntatore.
 
 I tipi di dati che compongono la struttura sono stabiliti dallo standard
-POSIX.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono
-definiti; la struttura è invece definita nell'include file
-\file{sys/socket.h}
+POSIX.1g, riassunti in \tabref{tab:sock_data_types} con i rispettivi file di
+include in cui sono definiti; la struttura è invece definita nell'include file
+\file{sys/socket.h}.
 
 \begin{table}[!htb]
   \centering
+  \footnotesize
   \begin{tabular}{|l|l|l|}
     \hline
     \multicolumn{1}{|c|}{\textbf{Tipo}}& 
@@ -345,30 +365,30 @@ definiti; la struttura 
     \hline
     \type{sa\_family\_t} & famiglia degli indirizzi& \file{sys/socket.h}\\
     \type{socklen\_t} & lunghezza (\type{uint32\_t}) dell'indirizzo di
-    un socket& \type{sys/socket.h}\\
+    un socket& \file{sys/socket.h}\\
     \hline
-    \type{in\_addr\_t} & indirizzo IPv4 (\file{uint32\_t}) & 
-    \type{netinet/in.h}\\
-    \type{in\_port\_t} & porta TCP o UDP (\file{uint16\_t})& 
-    \type{netinet/in.h}\\
+    \type{in\_addr\_t} & indirizzo IPv4 (\type{uint32\_t}) & 
+    \file{netinet/in.h}\\
+    \type{in\_port\_t} & porta TCP o UDP (\type{uint16\_t})& 
+    \file{netinet/in.h}\\
     \hline
   \end{tabular}
   \caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto 
-    stabilito dallo standard POSIX.1g}
+    stabilito dallo standard POSIX.1g.}
   \label{tab:sock_data_types}
 \end{table}
 
 In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro
-aggiuntivo \var{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi
+aggiuntivo \code{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi
 libri). Questo campo non verrebbe usato direttamente dal programmatore e non è
 richiesto dallo standard POSIX.1g, in Linux pertanto non esiste. Il campo
-\type{sa\_family\_t} era storicamente un \type{unsigned short}.
+\type{sa\_family\_t} era storicamente un \ctyp{unsigned short}.
 
 Dal punto di vista del programmatore l'unico uso di questa struttura è quello
 di fare da riferimento per il casting, per il kernel le cose sono un po'
 diverse, in quanto esso usa il puntatore per recuperare il campo
 \var{sa\_family} con cui determinare il tipo di indirizzo; per questo
-motivo, anche se l'uso di un puntatore \type{void *} sarebbe più immediato
+motivo, anche se l'uso di un puntatore \ctyp{void *} sarebbe più immediato
 per l'utente (che non dovrebbe più eseguire il casting), è stato mantenuto
 l'uso di questa struttura.
 
@@ -376,15 +396,16 @@ l'uso di questa struttura.
 \subsection{La struttura degli indirizzi IPv4}
 \label{sec:sock_sa_ipv4}
 
-I socket di tipo \macro{PF\_INET} vengono usati per la comunicazione
+I socket di tipo \const{PF\_INET} vengono usati per la comunicazione
 attraverso internet; la struttura per gli indirizzi per un socket internet
-(IPv4) è definita come \type{sockaddr\_in} nell'header file
-\file{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig,
-conforme allo standard POSIX.1g.
+(IPv4) è definita come \struct{sockaddr\_in} nell'header file
+\file{netinet/in.h} e secondo le pagine di manuale ha la forma mostrata in
+\figref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+  \footnotesize\centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 struct sockaddr_in {
     sa_family_t     sin_family; /* address family: AF_INET */
     u_int16_t       sin_port;   /* port in network byte order */
@@ -394,9 +415,10 @@ struct sockaddr_in {
 struct in_addr {
     u_int32_t       s_addr;     /* address in network byte order */
 };
-  \end{lstlisting}
+    \end{lstlisting}
+  \end{minipage} 
   \caption{La struttura degli indirizzi dei socket internet (IPv4)
-    \type{sockaddr\_in}.}
+    \structd{sockaddr\_in}.}
   \label{fig:sock_sa_ipv4_struct}
 \end{figure}
 
@@ -405,18 +427,18 @@ internet di un'interfaccia pi
 prevede numeri di porta, che sono utilizzati solo dai protocolli di livello
 superiore come TCP e UDP. Questa struttura però viene usata anche per i socket
 RAW che accedono direttamente al livello di IP, nel qual caso il numero della
-porta viene settato al numero di protocollo.
+porta viene impostato al numero di protocollo.
 
-Il membro \var{sin\_family} deve essere sempre settato; \var{sin\_port}
+Il membro \var{sin\_family} deve essere sempre impostato; \var{sin\_port}
 specifica il numero di porta (vedi \secref{sec:TCPel_port_num}; i numeri di
 porta sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da
-servizi standard. Soltanto processi con i privilegi di root (effective uid
-uguale a zero) o con la capability \macro{CAP\_NET\_BIND\_SERVICE} possono
-usare la funzione \func{bind} su queste porte.
+servizi standard. Soltanto processi con i privilegi di root (con user-ID
+effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE}
+possono usare la funzione \func{bind} su queste porte.
 
 Il membro \var{sin\_addr} contiene l'indirizzo internet dell'altro capo
 della comunicazione, e viene acceduto sia come struttura (un resto di una
-implementazione precedente in cui questa era una \texttt{union} usata per
+implementazione precedente in cui questa era una \direct{union} usata per
 accedere alle diverse classi di indirizzi) che come intero.
 
 Infine è da sottolineare che sia gli indirizzi che i numeri di porta devono
@@ -430,14 +452,15 @@ problema e le relative soluzioni).
 \subsection{La struttura degli indirizzi IPv6}
 \label{sec:sock_sa_ipv6}
 
-Essendo IPv6 un'estensione di IPv4 i socket di tipo \macro{PF\_INET6} sono
+Essendo IPv6 un'estensione di IPv4 i socket di tipo \const{PF\_INET6} sono
 sostanzialmente identici ai precedenti; la parte in cui si trovano
 praticamente tutte le differenze è quella della struttura degli indirizzi. La
 struttura degli indirizzi è definita ancora in \file{netinet/in.h}.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 struct sockaddr_in6 {
     u_int16_t       sin6_family;   /* AF_INET6 */
     u_int16_t       sin6_port;     /* port number */
@@ -449,14 +472,15 @@ struct sockaddr_in6 {
 struct in6_addr {
     unsigned char   s6_addr[16];   /* IPv6 address */
 };
-  \end{lstlisting}
+    \end{lstlisting}
+  \end{minipage} 
   \caption{La struttura degli indirizzi dei socket IPv6 
-    \type{sockaddr\_in6}.}
+    \structd{sockaddr\_in6}.}
   \label{fig:sock_sa_ipv6_struct}
 \end{figure}
 
-Il campo \var{sin6\_family} deve essere sempre settato ad
-\macro{AF\_INET6}, il campo \var{sin6\_port} è analogo a quello di IPv4 e
+Il campo \var{sin6\_family} deve essere sempre impostato ad
+\const{AF\_INET6}, il campo \var{sin6\_port} è analogo a quello di IPv4 e
 segue le stesse regole; il campo \var{sin6\_flowinfo} è a sua volta diviso
 in tre parti di cui i 24 bit inferiori indicano l'etichetta di flusso, i
 successivi 4 bit la priorità e gli ultimi 4 sono riservati; questi valori
@@ -467,7 +491,7 @@ Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
 infine il campo \var{sin6\_scope\_id} è un campo introdotto con il kernel
 2.4 per gestire alcune operazioni riguardanti il multicasting.
  
-Si noti che questa struttura è più grande di una \var{sockaddr} generica,
+Si noti che questa struttura è più grande di una \struct{sockaddr} generica,
 quindi occorre stare attenti a non avere fatto assunzioni riguardo alla
 possibilità di contenere i dati nelle dimensioni di quest'ultima.
 
@@ -475,28 +499,31 @@ possibilit
 \subsection{La struttura degli indirizzi locali}
 \label{sec:sock_sa_local}
 
-I socket di tipo \macro{PF\_UNIX} vengono usati per una comunicazione
-efficiente fra processi che stanno sulla stessa macchina; essi rispetto ai
+I socket di tipo \const{PF\_UNIX} o \const{PF\_LOCAL} vengono usati per una
+comunicazione fra processi che stanno sulla stessa macchina (per vengono
+chiamati \textit{local domain} o anche \textit{Unix domain}); essi rispetto ai
 precedenti possono essere anche creati in maniera anonima attraverso la
-funzione \func{socketpair}. Quando però si vuole fare riferimento esplicito
-ad uno di questi socket si deve usare la seguente struttura di indirizzi
-definita nel file di header \file{sys/un.h}.
+funzione \func{socketpair} (vedi \secref{sec:ipc_socketpair}). Quando però si
+vuole fare riferimento esplicito ad uno di questi socket si deve usare la
+seguente struttura di indirizzi definita nel file di header \file{sys/un.h}.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 #define UNIX_PATH_MAX    108
 struct sockaddr_un {
     sa_family_t  sun_family;              /* AF_UNIX */
     char         sun_path[UNIX_PATH_MAX]; /* pathname */
 };
-  \end{lstlisting}
+    \end{lstlisting}
+  \end{minipage} 
   \caption{La struttura degli indirizzi dei socket locali 
-    \var{sockaddr\_un}.}
+    \structd{sockaddr\_un}.}
   \label{fig:sock_sa_local_struct}
 \end{figure}
 
-In questo caso il campo \var{sun\_family} deve essere \macro{AF\_UNIX},
+In questo caso il campo \var{sun\_family} deve essere \const{AF\_UNIX},
 mentre il campo \var{sun\_path} deve specificare un indirizzo; questo ha
 due forme un file (di tipo socket) nel filesystem o una stringa univoca
 (tenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene
@@ -536,7 +563,7 @@ cosa significa tutto ci
 utile anche in seguito.
 
 
-\subsection{La \textit{endianess}}
+\subsection{La \textit{endianess}\index{endianess}}
 \label{sec:sock_endianess}
 
 La rappresentazione di un numero binario in un computer può essere fatta in
@@ -555,12 +582,12 @@ significativi nell'indirizzo successivo; questo ordinamento 
 numero. Il caso opposto, in cui si parte dal bit meno significativo è detto
 per lo stesso motivo \textit{big endian}.
 
-La \textit{endianess} di un computer dipende essenzialmente dalla architettura
-hardware usata; Intel e Digital usano il \textit{little endian}, Motorola,
-IBM, Sun (sostanzialmente tutti gli altri) usano il \textit{big endian}. Il
-formato della rete è anch'esso \textit{big endian}, altri esempi sono quello
-del bus PC, che è \textit{little endian}, o quello del bus VME che è
-\textit{big endian}.
+La \textit{endianess}\index{endianess} di un computer dipende essenzialmente
+dalla architettura hardware usata; Intel e Digital usano il \textit{little
+  endian}, Motorola, IBM, Sun (sostanzialmente tutti gli altri) usano il
+\textit{big endian}. Il formato della rete è anch'esso \textit{big endian},
+altri esempi sono quello del bus PCI, che è \textit{little endian}, o quello
+del bus VME che è \textit{big endian}.
 
 Esistono poi anche dei processori che possono scegliere il tipo di formato
 all'avvio e alcuni che, come il PowerPC o l'Intel i860, possono pure passare
@@ -572,41 +599,45 @@ questi cambiamenti.
 \subsection{Le funzioni per il riordinamento}
 \label{sec:sock_func_ord}
 
-Il problema connesso all'endianess è che quando si passano dei dati da un tipo
-di architettura all'altra i dati vengono interpretati in maniera diversa, e ad
-esempio nel caso dell'intero a 16 bit ci si ritroverà con i due byte in cui è
-suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura
-per cui, per riavere il valore originale dovranno essere rovesciati.
-
-Per questo motivo si usano le seguenti funzioni di conversione che servono a
-tener conto automaticamente della possibile differenza fra l'ordinamento usato
-sul computer e quello che viene usato nelle trasmissione sulla rete; queste
-funzioni sono:
-\begin{prototype}{netinet/in.h}
-{unsigned long int htonl(unsigned long int hostlong)} 
-  Converte l'intero a 32 bit \var{hostlong} dal formato della macchina a
+Il problema connesso all'endianess\index{endianess} è che quando si passano
+dei dati da un tipo di architettura all'altra i dati vengono interpretati in
+maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà
+con i due byte in cui è suddiviso scambiati di posto, e ne sarà quindi
+invertito l'ordine di lettura per cui, per riavere il valore originale
+dovranno essere rovesciati.
+
+Per questo motivo si usano delle funzioni di conversione che servono a tener
+conto automaticamente della possibile differenza fra l'ordinamento usato sul
+computer e quello che viene usato nelle trasmissione sulla rete; queste
+funzioni sono \funcd{htonl}, \funcd{htons}, \funcd{ntonl} e \funcd{ntons} ed i
+rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{netinet/in.h}
+  \funcdecl{unsigned long int htonl(unsigned long int hostlong)} 
+  Converte l'intero a 32 bit \param{hostlong} dal formato della macchina a
   quello della rete.
-\end{prototype}
-\begin{prototype}{netinet/in.h}
-{unsigned short int htons(unsigned short int hostshort)}
-  Converte l'intero a 16 bit \var{hostshort} dal formato della macchina a
+  \funcdecl{unsigned short int htons(unsigned short int hostshort)}
+  Converte l'intero a 16 bit \param{hostshort} dal formato della macchina a
   quello della rete.
-\end{prototype}
-\begin{prototype}{netinet/in.h}
-{unsigned long int ntonl(unsigned long int netlong)}
-  Converte l'intero a 32 bit \var{netlong} dal formato della rete a quello
+
+  \funcdecl{unsigned long int ntonl(unsigned long int netlong)}
+  Converte l'intero a 32 bit \param{netlong} dal formato della rete a quello
   della macchina.
-\end{prototype}
-\begin{prototype}{netinet/in.h}
-{unsigned sort int ntons(unsigned short int netshort)}
-  Converte l'intero a 16 bit \var{netshort} dal formato della rete a quello
+
+  \funcdecl{unsigned sort int ntons(unsigned short int netshort)}
+  Converte l'intero a 16 bit \param{netshort} dal formato della rete a quello
   della macchina.
-\end{prototype}
+  
+  \bodydesc{Tutte le funzioni restituiscono il valore convertito, e non hanno
+    errori.}
+\end{functions}
+
 I nomi sono assegnati usando la lettera \texttt{n} come mnemonico per indicare
 l'ordinamento usato sulla rete (da \textit{network order}) e la lettera
 \texttt{h} come mnemonico per l'ordinamento usato sulla macchina locale (da
 \textit{host order}), mentre le lettere \texttt{s} e \texttt{l} stanno ad
-indicare i tipi di dato (\type{long} o \type{short}, riportati anche dai
+indicare i tipi di dato (\ctyp{long} o \ctyp{short}, riportati anche dai
 prototipi).
 
 Usando queste funzioni si ha la conversione automatica: nel caso in cui la
@@ -621,38 +652,54 @@ assicurare la portabilit
 \label{sec:sock_func_ipv4}
 
 Un secondo insieme di funzioni di manipolazione serve per passare dal formato
-binario usato nelle strutture degli indirizzi alla rappresentazione dei numeri
-IP che si usa normalmente.
+binario usato nelle strutture degli indirizzi alla rappresentazione simbolica
+dei numeri IP che si usa normalmente.
 
 Le prime tre funzioni di manipolazione riguardano la conversione degli
 indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la
 cosiddetta notazione \textit{dotted-decimal}, (cioè nella forma
 \texttt{192.160.0.1}) al formato binario (direttamente in \textit{network
   order}) e viceversa; in questo caso si usa la lettera \texttt{a} come
-mnemonico per indicare la stringa. Dette funzioni sono:
-\begin{prototype}{arpa/inet.h}
-  {int inet\_aton(const char *src, struct in\_addr *dest)} 
-  Converte la stringa puntata da \var{src} nell'indirizzo binario da
-  memorizzare all'indirizzo puntato da \var{dest}, restituendo 0 in caso di
-  successo e 1 in caso di fallimento (è espressa in questa forma in modo da
-  poterla usare direttamente con il puntatore usato per passare la struttura
-  degli indirizzi). Se usata con \var{dest} inizializzato a \macro{NULL}
-  effettua la validazione dell'indirizzo.
-\end{prototype}
-\begin{prototype}{arpa/inet.h}{in\_addr\_t inet\_addr(const char *strptr)}
-  Restituisce l'indirizzo a 32 bit in network order a partire dalla stringa
-  passata come parametro, in caso di errore restituisce il valore
-  \macro{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo
-  comporta che la stringa \texttt{255.255.255.255}, che pure è un indirizzo
-  valido, non può essere usata con questa funzione; per questo motivo essa è
-  generalmente deprecata in favore della precedente.
-\end{prototype}  
-\begin{prototype}{arpa/inet.h}{char *inet\_ntoa(struct in\_addr addrptr)}
-  Converte il valore a 32 bit dell'indirizzo (espresso in \textit{network
-    order}) restituendo il puntatore alla stringa che contiene l'espressione
-  in formato dotted decimal. Si deve tenere presente che la stringa risiede in
-  memoria statica, per cui questa funzione non è rientrante.
-\end{prototype}
+mnemonico per indicare la stringa. Dette funzioni sono \funcd{inet\_addr},
+\funcd{inet\_aton} e \funcd{inet\_ntoa}, ed i rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{arpa/inet.h}
+  
+  \funcdecl{in\_addr\_t inet\_addr(const char *strptr)} Converte la stringa
+  dell'indirizzo \textit{dotted decimal} in nel numero IP in network order.
+
+  \funcdecl{int inet\_aton(const char *src, struct in\_addr *dest)} Converte
+  la stringa dell'indirizzo \textit{dotted decimal} in un indirizzo IP.
+
+  \funcdecl{char *inet\_ntoa(struct in\_addr addrptr)}
+  Converte un indirizzo IP in una stringa \textit{dotted decimal}.
+
+  \bodydesc{Tutte queste le funzioni non generano codice di errore.}
+\end{functions}
+
+La prima funzione, \func{inet\_addr}, restituisce l'indirizzo a 32 bit in
+network order (del tipo \type{in\_addr\_t}) a partire dalla stringa passata
+nell'argomento \param{strptr}. In caso di errore (quando la stringa non esprime
+un indirizzo valido) restituisce invece il valore \const{INADDR\_NONE} che
+tipicamente sono trentadue bit a uno.  Questo però comporta che la stringa
+\texttt{255.255.255.255}, che pure è un indirizzo valido, non può essere usata
+con questa funzione; per questo motivo essa è generalmente deprecata in favore
+di \func{inet\_aton}.
+
+La funzione \func{inet\_aton} converte la stringa puntata da \param{src}
+nell'indirizzo binario che viene memorizzato nell'opportuna struttura
+\struct{in\_addr} (si veda \secref{fig:sock_sa_ipv4_struct}) situata
+all'indirizzo dato dall'argomento \param{dest} (è espressa in questa forma in
+modo da poterla usare direttamente con il puntatore usato per passare la
+struttura degli indirizzi). La funzione restituisce 0 in caso di successo e 1
+in caso di fallimento.  Se usata con \param{dest} inizializzato a \val{NULL}
+effettua la validazione dell'indirizzo.
+
+L'ultima funzione, \func{inet\_ntoa}, converte il valore a 32 bit
+dell'indirizzo (espresso in \textit{network order}) restituendo il puntatore
+alla stringa che contiene l'espressione in formato dotted decimal. Si deve
+tenere presente che la stringa risiede in memoria statica, per cui questa
+funzione non è rientrante.
 
 
 \subsection{Le funzioni \func{inet\_pton} e \func{inet\_ntop}}
@@ -675,45 +722,62 @@ e \textit{numeric}.
 % \end{figure}
 
 Entrambe le funzioni accettano l'argomento \param{af} che indica il tipo di
-indirizzo e può essere \macro{AF\_INET} o \macro{AF\_INET6}. Se la famiglia
-indicata non è valida entrambe le funzioni settano la variabile \var{errno}
-al valore \macro{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i
-seguenti:
+indirizzo e può essere soltanto \const{AF\_INET} o \const{AF\_INET6}. La prima
+funzione è \funcd{inet\_pton}, che serve a convertire una stringa in un
+indirizzo, il suo prototipo è:
 \begin{prototype}{sys/socket.h}
-  {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la
-  stringa puntata da \var{src} nell'indirizzo IP da memorizzare
-  all'indirizzo puntato da \var{addr\_ptr}, la funzione restituisce un
-  valore positivo in caso di successo, e zero se la stringa non rappresenta un
-  indirizzo valido, e negativo se \var{af} specifica una famiglia di indirizzi
-  non valida.
+{int inet\_pton(int af, const char *src, void *addr\_ptr)} 
+
+  Converte l'indirizzo espresso tramite una stringa nel valore numerico.
+  
+  \bodydesc{La funzione restituisce un valore negativo se \param{af} specifica
+    una famiglia di indirizzi non valida, con \var{errno} che assume il valore
+    \errcode{EAFNOSUPPORT}, un valore nullo se \param{src} non rappresenta un
+    indirizzo valido, ed un valore positivo in caso di successo.}
 \end{prototype}
+
+La funzione converte la stringa indicata tramite \param{src} nel valore
+numerico dell'indirizzo IP del tipo specificato da \param{af} che viene
+memorizzato all'indirizzo puntato da \param{addr\_ptr}, la funzione restituisce
+un valore positivo in caso di successo, e zero se la stringa non rappresenta
+un indirizzo valido, e negativo se \param{af} specifica una famiglia di
+indirizzi non valida.
+
+La seconda funzione è \funcd{inet\_ntop} che converte un indirizzo in una
+stringa; il suo prototipo è:
 \begin{prototype}{sys/socket.h}
   {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
-  Converte la struttura dell'indirizzo puntata da \var{addr\_ptr} in una
-  stringa che viene copiata nel buffer puntato dall'indirizzo \var{dest};
-  questo deve essere preallocato dall'utente e la lunghezza deve essere almeno
-  \macro{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
-  \macro{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
-  comunque venire specificata attraverso il parametro \var{len}.
+  Converte l'indirizzo dalla relativa struttura in una stringa simbolica.
  
-  \bodydesc{La funzione restituisce un puntatore non nullo a \var{dest} in
-    caso di successo e un puntatore nullo in caso di fallimento, in
-    quest'ultimo caso viene settata la variabile \var{errno} con il valore
-    \macro{ENOSPC} in caso le dimensioni dell'indirizzo eccedano la lunghezza
-    specificata da \var{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia
-    una famiglia di indirizzi valida.}
+  \bodydesc{La funzione restituisce un puntatore non nullo alla stringa
+    convertita in caso di successo e \val{NULL} in caso di fallimento, nel
+    qual caso \var{errno} assume i valori: 
+    \begin{errlist}
+    \item[\errcode{ENOSPC}] le dimensioni della stringa con la conversione
+      dell'indirizzo eccedono la lunghezza specificata da \param{len}.
+    \item[\errcode{ENOAFSUPPORT}] la famiglia di indirizzi \param{af} non è
+      una valida.
+  \end{errlist}}
 \end{prototype}
 
+La funzione converte la struttura dell'indirizzo puntata da \param{addr\_ptr}
+in una stringa che viene copiata nel buffer puntato dall'indirizzo
+\param{dest}; questo deve essere preallocato dall'utente e la lunghezza deve
+essere almeno \const{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
+\const{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
+comunque venire specificata attraverso il parametro \param{len}.
+
 Gli indirizzi vengono convertiti da/alle rispettive strutture di indirizzo
-(\var{struct  in\_addr} per IPv4, e \var{struct  in6\_addr} per IPv6), che
-devono essere precedentemente allocate e passate attraverso il puntatore
-\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere
-nullo e deve essere allocato precedentemente.
+(una struttura \struct{in\_addr} per IPv4, e una struttura \struct{in6\_addr}
+per IPv6), che devono essere precedentemente allocate e passate attraverso il
+puntatore \param{addr\_ptr}; l'argomento \param{dest} di \func{inet\_ntop} non
+può essere nullo e deve essere allocato precedentemente.
 
 Il formato usato per gli indirizzi in formato di presentazione è la notazione
-\textit{dotted decimal} per IPv4 e quella descritta in
+\textit{dotted decimal} per IPv4 e quello descritto in
 \secref{sec:IP_ipv6_notation} per IPv6.
 
+\index{socket|)}
 
 
 \section{Un esempio di applicazione}
@@ -721,8 +785,9 @@ Il formato usato per gli indirizzi in formato di presentazione 
 
 Per evitare di rendere questa introduzione ai socket puramente teorica
 iniziamo con il mostrare un esempio di un client TCP elementare.  Prima di
-passare agli esempi del client e del server, esamineremo una caratteristica
-delle funzioni di I/O sui socket che ci tornerà utile anche in seguito.
+passare agli esempi del client e del server, ritorniamo con maggiori dettagli
+su una caratteristica delle funzioni di I/O che nel caso dei socket è
+particolarmente rilevante, e che ci tornerà utile anche in seguito.
 
 
 \subsection{Il comportamento delle funzioni di I/O}
@@ -736,13 +801,15 @@ per i socket di tipo stream).
 Infatti con i socket è comune che funzioni come \func{read} o \func{write}
 possano restituire in input o scrivere in output un numero di byte minore di
 quello richiesto. Come già accennato in \secref{sec:file_read} questo è un
-comportamento normale anche per l'I/O su file, e succede
-perché si eccede in lettura o scrittura il limite di buffer del kernel.
+comportamento normale per l'I/O su file; con i normali file di dati il
+problema si avverte solo quando si incontra la fine del file, ma in generale
+non è così.
 
 In questo caso tutto quello che il programma chiamante deve fare è di ripetere
-la lettura (o scrittura) per la quantità di byte rimanenti (lo stesso può
-avvenire scrivendo più di 4096 byte in una pipe, dato che quello è il limite
-di solito adottato per il buffer di trasmissione del kernel).
+la lettura (o scrittura) per la quantità di byte rimanenti (e le funzioni si
+possono bloccare se i dati non sono disponibili): è lo stesso comportamento
+che si può avere scrivendo più di \const{PIPE\_BUF} byte in una pipe (si
+riveda quanto detto in \secref{sec:ipc_pipes}).
 
 \begin{figure}[htb]
   \centering
@@ -750,7 +817,7 @@ di solito adottato per il buffer di trasmissione del kernel).
   \begin{lstlisting}{}
 #include <unistd.h>
 
-ssize_t SockRead(int fd, void *buf, size_t count) 
+ssize_t FullRead(int fd, void *buf, size_t count) 
 {
     size_t nleft;
     ssize_t nread;
@@ -772,16 +839,17 @@ ssize_t SockRead(int fd, void *buf, size_t count)
     return (count - nleft);
 }  
   \end{lstlisting}
-  \caption{Funzione \func{SockRead}, legge \var{count} byte da un socket }
-  \label{fig:sock_SockRead_code}
+  \caption{Funzione \func{FullRead}, legge \var{count} byte da un socket }
+  \label{fig:sock_FullRead_code}
 \end{figure}
 
-Per questo motivo seguendo l'esempio di W. R. Stevens si sono definite due
-funzioni \func{SockRead} e \func{SockWrite} che eseguono la lettura da un
-socket tenendo conto di questa caratteristica, ed in grado di ritornare dopo
-avere letto o scritto esattamente il numero di byte specificato; il sorgente
-è riportato in \curfig\ e \nfig\ ed è disponibile fra i sorgenti allegati alla
-guida nei files \file{SockRead.c} e \file{SockWrite.c}.
+Per questo motivo, seguendo l'esempio di W. R. Stevens in \cite{UNP1}, si sono
+definite due funzioni \func{FullRead} e \func{FullWrite} che eseguono la
+lettura da un socket tenendo conto di questa caratteristica, ed in grado di
+ritornare dopo avere letto o scritto esattamente il numero di byte
+specificato; il sorgente è riportato in \figref{fig:sock_FullRead_code} e
+\figref{fig:sock_FullWrite_code} ed è disponibile fra i sorgenti allegati alla
+guida nei files \file{FullRead.c} e \file{FullWrite.c}.
 
 \begin{figure}[htb]
   \centering
@@ -789,7 +857,7 @@ guida nei files \file{SockRead.c} e \file{SockWrite.c}.
   \begin{lstlisting}{}
 #include <unistd.h>
 
-ssize_t SockWrite(int fd, const void *buf, size_t count) 
+ssize_t FullWrite(int fd, const void *buf, size_t count) 
 {
     size_t nleft;
     ssize_t nwritten;
@@ -809,19 +877,20 @@ ssize_t SockWrite(int fd, const void *buf, size_t count)
     return (count);
 }  
   \end{lstlisting}
-  \caption{Funzione \func{SockWrite}, scrive \var{count} byte su un socket }
-  \label{fig:sock_SockWrite_code}
+  \caption{Funzione \func{FullWrite}, scrive \var{count} byte su un socket.}
+  \label{fig:sock_FullWrite_code}
 \end{figure}
 
 Come si può notare le funzioni ripetono la lettura/scrittura in un ciclo fino
 all'esaurimento del numero di byte richiesti, in caso di errore viene
-controllato se questo è \macro{EINTR} (cioè un'interruzione della system call
+controllato se questo è \errcode{EINTR} (cioè un'interruzione della system call
 dovuta ad un segnale), nel qual caso l'accesso viene ripetuto, altrimenti
 l'errore viene ritornato interrompendo il ciclo.
 
 Nel caso della lettura, se il numero di byte letti è zero, significa che si è
-arrivati alla fine del file e pertanto si ritorna senza aver concluso la
-lettura di tutti i byte richiesti.
+arrivati alla fine del file (per i socket questo significa in genere che
+l'altro capo è stato chiuso, e non è quindi più possibile leggere niente) e
+pertanto si ritorna senza aver concluso la lettura di tutti i byte richiesti.
 
 
 
@@ -835,9 +904,10 @@ successivo; qui ci limiteremo a introdurre la nomenclatura senza fornire
 definizioni precise e dettagli di funzionamento che saranno trattati
 estensivamente più avanti.
 
-In \nfig\ è riportata la sezione principale del codice del nostro client
-elementare per il servizio \textit{daytime}, un servizio standard che
-restituisce l'ora locale della macchina a cui si effettua la richiesta.
+In \figref{fig:net_cli_code} è riportata la sezione principale del codice del
+nostro client elementare per il servizio \textit{daytime}, un servizio
+standard che restituisce l'ora locale della macchina a cui si effettua la
+richiesta.
 
 \begin{figure}[!htb]
   \footnotesize
@@ -907,13 +977,13 @@ comando (effettuata con le apposite routine illustrate in
 \capref{sec:proc_opt_handling}).
 
 Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4
-(\macro{AF\_INET}), di tipo TCP \macro{SOCK\_STREAM}. La funzione
-\macro{socket} ritorna il descrittore che viene usato per identificare il
+(\const{AF\_INET}), di tipo TCP \const{SOCK\_STREAM}. La funzione
+\func{socket} ritorna il descrittore che viene usato per identificare il
 socket in tutte le chiamate successive. Nel caso la chiamata fallisca si
 stampa un errore con la relativa routine e si esce.
 
 Il passo seguente (\texttt{\small 19--27}) è quello di costruire un'apposita
-struttura \type{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
+struttura \struct{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
 il numero della porta del servizio. Il primo passo è inizializzare tutto a
 zero, per poi inserire il tipo di protocollo e la porta (usando per
 quest'ultima la funzione \func{htons} per convertire il formato dell'intero
@@ -957,7 +1027,7 @@ necessario deve provvedere il programma stesso.
 
 Dopo aver illustrato il client daremo anche un esempio di un server
 elementare, in grado di rispondere al precedente client. Il listato è
-nuovamente mostrato in \nfig, il sorgente completo
+nuovamente mostrato in \figref{fig:net_serv_code}, il sorgente completo
 (\file{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella
 directory \file{sources}.
 
@@ -1031,9 +1101,9 @@ necessarie in seguito (\texttt{\small 1--18}), come nel caso precedente si
 sono omesse le parti relative al trattamento delle opzioni da riga di comando.
 
 La creazione del socket (\texttt{\small 22--26}) è analoga al caso precedente,
-come pure l'inizializzazione della struttura \type{sockaddr\_in}, anche in
+come pure l'inizializzazione della struttura \struct{sockaddr\_in}, anche in
 questo caso si usa la porta standard del servizio daytime, ma come indirizzo
-IP si il valore predefinito \macro{INET\_ANY} che corrisponde ad un indirizzo
+IP si il valore predefinito \const{INET\_ANY} che corrisponde ad un indirizzo
 generico (\texttt{\small 27--31}).
 
 Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione
@@ -1070,6 +1140,8 @@ come demone di sistema (che 
 attiva e il terminale da cui lo si è lanciato è stato sconnesso),
 occorrerebbero delle opportune modifiche.
 
+
+
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"