Riorganizzate varie parti, rimetto in linea la nuova versione
authorSimone Piccardi <piccardi@gnulinux.it>
Wed, 22 Aug 2001 17:24:14 +0000 (17:24 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Wed, 22 Aug 2001 17:24:14 +0000 (17:24 +0000)
elemtcp.tex
filedir.tex
fileintro.tex
filestd.tex
network.tex
process.tex
prochand.tex
signal.tex
socket.tex

index 9cfcb35fc356cfdfca660d1f7fff2638c244cbdb..3c4b2169d1637903a2e7feefd4e2d8ec852e7d0b 100644 (file)
@@ -13,7 +13,7 @@ connessione TCP.
 \label{sec:TCPel_connession}
 
 Prima di entrare nei dettagli delle funzioni usate nelle applicazioni che
-utilizzano i sokcet TCP, è fondamentale spiegare alcune basi del funzionamento
+utilizzano i socket TCP, è fondamentale spiegare alcune basi del funzionamento
 del TCP; la conoscenza del funzionamento del protocollo è infatti essenziale
 per capire il modello di programmazione ed il funzionamento delle API.
 
@@ -681,18 +681,21 @@ indirizzo di origine l'indirizzo di destinazione specificato dal SYN del
 client. 
 
 Per specificare un indirizzo generico con IPv4 si usa il valore
-\texttt{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
+\macro{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
 è pari a zero, nell'esempio \figref{fig:net_serv_code} si è usata
 un'assegnazione immediata del tipo:
-\begin{verbatim}
-   serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
-\end{verbatim}
 
-Si noti che si è usato \texttt{htonl} per assegnare il valore
-\texttt{INADDR\_ANY}; benché essendo questo pari a zero il riordinamento sia
-inutile; ma dato che tutte le costanti \texttt{INADDR\_} sono definite
+\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+  serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
+\end{lstlisting}
+\normalsize
+
+Si noti che si è usato \func{htonl} per assegnare il valore
+\macro{INADDR\_ANY}; benché essendo questo pari a zero il riordinamento sia
+inutile; ma dato che tutte le costanti \macro{INADDR\_} sono definite
 secondo l'ordinamento della macchina è buona norma usare sempre la funzione
-\texttt{htonl}.
+\macro{htonl}.
 
 L'esempio precedete funziona con IPv4 dato che l'indirizzo è rappresentabile
 anche con un intero a 32 bit; non si può usare lo stesso metodo con IPv6,
@@ -702,12 +705,14 @@ assegnazione.  Per questo nell'header \texttt{netinet/in.h} 
 variabile \texttt{in6addr\_any} (dichiarata come \texttt{extern}, ed
 inizializzata dal sistema al valore \texttt{IN6ADRR\_ANY\_INIT}) che permette
 di effettuare una assegnazione del tipo:
-\begin{verbatim}
+\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
    serv_add.sin6_addr = in6addr_any;   /* connect from anywhere */
-\end{verbatim}
+\end{lstlisting}
+\normalsize
 
 
-\subsection{La funzione \texttt{connect}}
+\subsection{La funzione \func{connect}}
 \label{sec:TCPel_func_connect}
 
 La funzione \texttt{connect} è usata da un client TCP per stabilire la
index cbd718bdc7582cb4c0d1f567a5405e8aba1ac1bc..1f0edcd66b40e82a0c62684b45025bd8aeb4170a 100644 (file)
@@ -34,7 +34,7 @@ controllo di accesso molto pi
 
 Ad ogni file unix associa sempre l'utente che ne è proprietario (il cosiddetto
 \textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli
-identificatori di utenti e gruppi (\textsl{uid} e \textsl{gid}). Questi valori
+identificatori di utenti e gruppi (\acr{uid} e \acr{gid}). Questi valori
 sono accessibili da programma tramite i campi \var{st\_uid} e \var{st\_gid}
 della struttura \var{stat} (si veda \secref{sec:file_stat}). Ad ogni file
 viene inoltre associato un insieme di permessi che sono divisi in tre classi,
@@ -47,7 +47,7 @@ sono espressi da un numero di 12 bit; di questi i nove meno significativi sono
 usati a gruppi di tre per indicare i permessi base di lettura, scrittura ed
 esecuzione (indicati nei comandi di sistema con le lettere \cmd{w}, \cmd{r} e
 \cmd{x}) ed applicabili rispettivamente al proprietario, al gruppo, a tutti
-gli altri.  I restanti tre bit (\textsl{suid}, \textsl{sgid}, e
+gli altri.  I restanti tre bit (\acr{suid}, \acr{sgid}, e
 \textsl{sticky}) sono usati per indicare alcune caratteristiche più complesse
 su cui torneremo in seguito (vedi \secref{sec:file_suid_sgid} e
 \secref{sec:file_sticky}).
@@ -149,22 +149,9 @@ del processo.
 Per una spiegazione dettagliata degli identificatori associati ai processi si
 veda \secref{sec:proc_perms}; normalmente, a parte quanto vedremo in
 \secref{sec:file_suid_sgid}, l'\textit{effective user id} e
-l'\textit{effective group id} corrispondono a uid e gid dell'utente che ha
-lanciato il processo, mentre i \textit{supplementary group id} sono quelli dei
-gruppi cui l'utente appartiene.
-
-% Quando un processo cerca l'accesso al file esso controlla i propri uid e gid
-% confrontandoli con quelli del file e se l'operazione richiesta è compatibile
-% con i permessi associati al file essa viene eseguita, altrimenti viene
-% bloccata ed è restituito un errore di \texttt{EPERM}. Questo procedimento non
-% viene eseguito per l'amministratore di sistema (il cui uid è zero) il quale
-% a
-% pertanto accesso senza restrizione a qualunque file del sistema.
-
-% In realtà il procedimento è più complesso di quanto descritto in maniera
-% elementare qui; inoltre ad un processo sono associati diversi identificatori,
-% torneremo su questo in maggiori dettagli in seguito in
-% \secref{sec:proc_perms}.
+l'\textit{effective group id} corrispondono a \acr{uid} e \acr{gid}
+dell'utente che ha lanciato il processo, mentre i \textit{supplementary group
+  id} sono quelli dei gruppi cui l'utente appartiene.
 
 I passi attraverso i quali viene stabilito se il processo possiede il diritto
 di accesso sono i seguenti:
@@ -184,15 +171,15 @@ di accesso sono i seguenti:
   \item altrimenti l'accesso è negato
   \end{itemize}
 \item Se l'\textit{effective group id} del processo o uno dei
-  \textit{supplementary group id} dei processi corrispondono al gid del file
-  allora:
+  \textit{supplementary group id} dei processi corrispondono al \acr{gid} del
+  file allora:
   \begin{itemize}
   \item se il bit dei permessi d'accesso del gruppo è settato, l'accesso è
     consentito, 
   \item altrimenti l'accesso è negato
   \end{itemize}
 \item se il bit dei permessi d'accesso per tutti gli altri è settato,
-  l'accesso è consentito,  altrimenti l'accesso è negato.
+  l'accesso è consentito, altrimenti l'accesso è negato.
 \end{itemize}
 
 Si tenga presente che questi passi vengono eseguiti esattamente in
@@ -203,22 +190,22 @@ processo appartiene ad un gruppo appropriato, in questo caso i permessi per
 tutti gli altri non vengono controllati.
 
 
-\subsection{I bit \textsl{suid} e \textsl{sgid}}
+\subsection{I bit \acr{suid} e \acr{sgid}}
 \label{sec:file_suid_sgid}
 
 Come si è accennato (in \secref{sec:file_perm_overview}) nei dodici bit del
 campo \var{st\_mode} usati per il controllo di accesso oltre ai bit dei
 permessi veri e propri, ci sono altri tre bit che vengono usati per indicare
 alcune proprietà speciali dei file.  Due di questi sono i bit detti
-\textsl{suid} (o \textit{set-user-ID bit}) e \textsl{sgid} (o
+\acr{suid} (o \textit{set-user-ID bit}) e \acr{sgid} (o
 \textit{set-group-ID bit}) che sono identificati dalle constanti
 \macro{S\_ISUID} e \macro{S\_ISGID}.
 
 Come spiegato in dettaglio in \secref{sec:proc_exec}, quando si lancia un
 programma il comportamendo normale del kernel è quello di settare
 l'\textit{effective user id} e l'\textit{effective group id} del nuovo
-processo all'uid e al gid del processo corrente, che normalmente corrispondono
-dell'utente con cui si è entrati nel sistema.
+processo all'\acr{uid} e al \acr{gid} del processo corrente, che normalmente
+corrispondono dell'utente con cui si è entrati nel sistema.
 
 Se però il file del programma\footnote{per motivi di sicurezza il kernel
   ignora i bit \acr{suid} e \acr{sgid} per gli script eseguibili} (che
@@ -258,8 +245,8 @@ con questi bit l'uso della semantica BSD nella creazione di nuovi file (si
 veda \secref{sec:file_ownership} per una spiegazione dettagliata al
 proposito).
 
-Infine Linux utilizza il bit \textsl{sgid} per una ulteriore estensione
-mutuata da SVR4. Il caso in cui il file abbia il bit \textsl{sgid} settato ma
+Infine Linux utilizza il bit \acr{sgid} per una ulteriore estensione
+mutuata da SVR4. Il caso in cui il file abbia il bit \acr{sgid} settato ma
 non il corrispondente bit di esecuzione viene utilizzato per attivare per
 quel file il \textit{mandatory locking} (argomento che affronteremo nei
 dettagli in \secref{sec:xxx_mandatory_lock}).
@@ -322,26 +309,28 @@ stesso problema di presenta per la creazione di nuove directory (procedimento
 descritto in \secref{sec:file_dir_creat_rem}).
 
 Lo standard POSIX prescrive che l'uid del nuovo file corrisponda
-all'\textit{effective user id} del processo che lo crea; per il gid invece
-prevede due diverse possibilità:
+all'\textit{effective user id} del processo che lo crea; per il \acr{gid}
+invece prevede due diverse possibilità:
 \begin{itemize}
-\item il gid del file corrisponde all'\textit{effective group id} del processo.
-\item il gid del file corrisponde al gid della directory in cui esso è creato.
+\item il \acr{gid} del file corrisponde all'\textit{effective group id} del
+  processo.
+\item il \acr{gid} del file corrisponde al gid della directory in cui esso è
+  creato.
 \end{itemize}
 in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
 semantica BSD. Linux invece segue quella che viene chiamata semantica SVR4; di
-norma cioè il nuovo file viene creato, seguendo la prima opzione, con il gid
-del processo, se però la directory in cui viene creato il file ha il bit
-\textsl{sgid} settato allora viene usata la seconda opzione..
+norma cioè il nuovo file viene creato, seguendo la prima opzione, con il
+\acr{gid} del processo, se però la directory in cui viene creato il file ha il
+bit \acr{sgid} settato allora viene usata la seconda opzione..
 
-Usare la semantica BSD ha il vantaggio che il gid viene sempre automaticamente
-propagato, restando coerente a quello della directory di partenza, in tutte le
-sottodirectory. La semantica SVR4 offre una maggiore possibilità di scelta, ma
-per ottenere lo stesso risultato necessita che per le nuove directory venga
-anche propagato anche il bit sgid. Questo è comunque il comportamento di
-default di \func{mkdir}, ed é in questo modo ad esempio che Debian assicura
-che le sottodirectory create nelle home di un utente restino sempre con il gid
-del gruppo primario dello stesso.
+Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre
+automaticamente propagato, restando coerente a quello della directory di
+partenza, in tutte le sottodirectory. La semantica SVR4 offre una maggiore
+possibilità di scelta, ma per ottenere lo stesso risultato necessita che per
+le nuove directory venga anche propagato anche il bit \acr{sgid}. Questo è
+comunque il comportamento di default di \func{mkdir}, ed é in questo modo ad
+esempio che Debian assicura che le sottodirectory create nelle home di un
+utente restino sempre con il \acr{gid} del gruppo primario dello stesso.
 
 
 \subsection{La funzione \texttt{access}}
@@ -489,7 +478,7 @@ particolare:
 \item per via della semantica SVR4 nella creazione dei nuovi file, si può
   avere il caso in cui il file creato da un processo è assegnato a un gruppo
   per il quale il processo non ha privilegi. Per evitare che si possa
-  assegnare il bit \textsl{sgid} ad un file appartenente a un gruppo per cui
+  assegnare il bit \acr{sgid} ad un file appartenente a un gruppo per cui
   non si hanno diritti, questo viene automaticamente cancellato (senza
   notifica di errore) da \var{mode} qualora il gruppo del file non corrisponda
   a quelli associati al processo (la cosa non avviene quando
@@ -591,8 +580,8 @@ Un'altra estensione rispetto allo standard POSIX 
 valore per \var{owner} e \var{group} i valori restano immutati. 
 
 Quando queste funzioni sono chiamate con successo da un processo senza i
-privilegi di root entrambi i bit \textsl{suid} e \textsl{sgid} vengono
-cancellati. Questo non avviene per il bit \textsl{sgid} nel caso in cui esso
+privilegi di root entrambi i bit \acr{suid} e \acr{sgid} vengono
+cancellati. Questo non avviene per il bit \acr{sgid} nel caso in cui esso
 sia usato (in assenza del corrispondente permesso di esecuzione) per indicare
 che per il file è attivo il \textit{mandatory locking}.
 
index d4d478522fa388caa6566451a5f9a1eddd9aebe2..4fc1e38854db8a4f24f4e1f0044a1382649c3f79 100644 (file)
@@ -56,17 +56,17 @@ percorso che si deve fare per accedere al file.
 Dopo la fase di inizializzazione il kernel riceve dal boot loader
 l'indicazione di quale dispositivo contiene il filesystem da usare come punto
 di partenza e questo viene montato come radice dell'albero (cioè nella
-directory \texttt{/}); tutti gli ulteriori dischi devono poi essere inseriti
+directory \file{/}); tutti gli ulteriori dischi devono poi essere inseriti
 nell'albero utilizzando opportune subdirectory.
 
-Alcuni filesystem speciali (come \texttt{/proc} che contiene un'interfaccia ad
+Alcuni filesystem speciali (come \file{/proc} che contiene un'interfaccia ad
 alcune strutture interne del kernel) sono generati automaticamente dal kernel
 stesso, ma anche essi devono essere montati all'interno dell'albero.
 
 All'interno dello stesso albero si potranno poi inserire anche gli altri
 oggetti visti attraverso l'interfaccia che manipola i files come le FIFO, i
 link, i socket e gli stessi i file di dispositivo (questi ultimi, per
-convenzione, sono inseriti nella directory \texttt{/dev}).
+convenzione, sono inseriti nella directory \file{/dev}).
 
 L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
 medesimi nell'albero descritto in precedenza; una directory comunque, come già
@@ -79,21 +79,22 @@ che contiene le informazioni che associano un nome al contenuto.
 
 I manuale delle glibc chiama i nomi contenuti nelle directory
 \textsl{componenti} (in inglese \textit{file name components}), noi li
-chiameremo più semplicemente nomi. Un file può essere indicato rispetto alla
-directory corrente semplicemente specificando il nome da essa contenuto. Una
-directory contiene semplicemente un elenco di questi nomi, che possono
-corrispondere a un qualunque oggetto del filesystem, compresa un'altra
+chiameremo più semplicemente \textit{nomi}. Un file può essere indicato
+rispetto alla directory corrente semplicemente specificando il nome da essa
+contenuto. Una directory contiene semplicemente un elenco di questi nomi, che
+possono corrispondere a un qualunque oggetto del filesystem, compresa un'altra
 directory; l'albero viene appunto creato inserendo directory in altre
 directory.
 
-Il nome completo di file generico è composto da una serie di questi
-\textsl{componenti} separati da una \texttt{/} (in Linux più \texttt{/}
-consecutive sono considerate equivalenti ad una sola). Il nome completo di un
-file viene usualmente chiamato \textit{pathname}, e anche se il manuale della
-glibc depreca questo nome (poiché genererebbe confusione, dato che con
-\textit{path} si indica anche un insieme di directory su cui effettuare una
-ricerca, come quello in cui si cercano i comandi); l'uso è ormai così comune
-che è senz'altro più chiaro dell'alternativa proposta.
+Il nome completo di file generico è composto da una serie di nomi separati da
+una \texttt{/} (in Linux più \texttt{/} consecutive sono considerate
+equivalenti ad una sola). Il nome completo di un file viene usualmente
+chiamato \textit{pathname}, e anche se il manuale della glibc depreca questo
+nome (poiché genererebbe confusione, dato che con \textit{path} si indica
+anche un insieme di directory su cui effettuare una ricerca, come quello in
+cui si cercano i comandi); non seguiremo questa scelta dato che l'uso della
+parola \textit{pathname} è ormai così comune che è senz'altro più chiaro
+dell'alternativa proposta.
 
 Il processo con cui si associa ad un pathname uno specifico file è chiamato
 risoluzione del nome (\textit{file name resolution} o \textit{pathname
@@ -112,11 +113,11 @@ equivale alla directory radice dell'albero (come descritto in
 cui torneremo più avanti in \secref{sec:file_work_dir}) ed il pathname è
 detto \textsl{relativo}.
 
-I nomi \texttt{.} e \texttt{..} hanno un significato speciale e vengono
-inseriti in ogni directory, il primo fa riferimento alla directory corrente e
-il secondo alla directory \textsl{genitore} (\textit{parent directory}) cioè
-la directory che contiene il riferimento alla directory corrente; nel caso
-questa sia la directory radice allora il riferimento è a se stessa.
+I nomi \file{.} e \file{..} hanno un significato speciale e vengono inseriti
+in ogni directory, il primo fa riferimento alla directory corrente e il
+secondo alla directory \textsl{genitrice} (\textit{parent directory}) cioè la
+directory che contiene il riferimento alla directory corrente; nel caso questa
+sia la directory radice allora il riferimento è a se stessa.
 
 
 \subsection{I tipi di files}
@@ -195,8 +196,8 @@ bufferizzato in quanto la lettura e la scrittura vengono eseguite chiamando
 direttamente le system call del kernel (in realtà il kernel effettua al suo
 interno alcune bufferizzazioni per aumentare l'efficienza nell'accesso ai
 dispositivi); i file descriptors sono rappresentati da numeri interi (cioè
-semplici variabili di tipo \texttt{int}).  L'interfaccia è definita
-nell'header \texttt{unistd.h}.
+semplici variabili di tipo \type{int}).  L'interfaccia è definita
+nell'header \file{unistd.h}.
 
 La seconda interfaccia è quella che il manuale della glibc chiama degli
 \textit{stream}, essa provvede funzioni più evolute e un accesso bufferizzato
@@ -207,10 +208,10 @@ Questa 
 anche su tutti i sistemi non unix. Gli stream sono oggetti complessi e sono
 rappresentati da puntatori ad un opportuna struttura definita dalle librerie
 del C, si accede ad essi sempre in maniera indiretta utilizzando il tipo
-\texttt{FILE *}.  L'interfaccia è definita nell'header \texttt{stdio.h}.
+\type{FILE *}.  L'interfaccia è definita nell'header \type{stdio.h}.
 
 Entrambe le interfacce possono essere usate per l'accesso ai file come agli
-altri oggetti del VFS (pipes, socket, device), ma per poter accedere alle
+altri oggetti del VFS (pipe, socket, device), ma per poter accedere alle
 operazioni di controllo sul particolare tipo di oggetto del VFS scelto occorre
 usare l'interfaccia standard di unix coi file descriptors. Allo stesso modo
 devono essere usati i file descriptor se si vuole ricorrere a modalità
@@ -305,7 +306,7 @@ tracciavamo al \capref{cha:intro_unix}.
 In questa sezione esamineremo come viene implementato l'accesso ai files in
 Linux, come il kernel può gestire diversi tipi di filesystem, descrivendo
 poi in maniera un po' più dettagliata il filesystem standard di Linux,
-l'\texttt{ext2}, come esempio di un filesystem unix-like.
+l'\acr{ext2}, come esempio di un filesystem unix-like.
 
 
 % in particolare si riprenderà, approfondendolo sul piano
@@ -415,18 +416,18 @@ files, ovviamente per non riempire tutta la memoria questa vista 
 richiesto l'accesso), quando si vuole risolvere un nuovo pathname il VFS deve
 creare una nuova dentry e caricare l'inode corrispondente in memoria. 
 
-Questo procedimento viene eseguito dal metodo \texttt{lookup()} dell'inode
+Questo procedimento viene eseguito dal metodo \func{lookup()} dell'inode
 della directory che contiene il file; questo viene installato nelle relative
 strutture in memoria quando si effettua il montaggio lo specifico filesystem
 su cui l'inode va a vivere.
 
 Una volta che il VFS ha a disposizione la dentry (ed il relativo inode)
 diventa possibile accedere alle varie operazioni sul file come la
-\texttt{open} per aprire il file o la \texttt{stat} per leggere i dati
+\func{open} per aprire il file o la \func{stat} per leggere i dati
 dell'inode e passarli in user space.
 
 L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
-una struttura di tipo \texttt{file} in cui viene inserito un puntatore alla
+una struttura di tipo \var{file} in cui viene inserito un puntatore alla
 dentry e una struttura \verb|f_ops| che contiene i puntatori ai metodi che
 implementano le operazioni disponibili sul file. In questo modo i processi in
 user space possono accedere alle operazioni attraverso detti metodi, che
@@ -527,8 +528,8 @@ torneremo in seguitp; in particolare 
 \item L'\textit{inode} contiene tutte le informazioni riguardanti il file: il
   tipo di file, i permessi di accesso, le dimensioni, i puntatori ai blocchi
   fisici che contengono i dati e così via; le informazioni che la funzione
-  \texttt{stat} fornisce provengono dall'\textit{inode}; dentro una directory
-  si troverà solo il nome del file e il numero dell'\textit{inode} ad esso
+  \func{stat} fornisce provengono dall'\textit{inode}; dentro una directory si
+  troverà solo il nome del file e il numero dell'\textit{inode} ad esso
   associato, cioè quella che da qui in poi chiameremo una \textsl{voce}
   (traduzione approssimata dell'inglese \textit{directory entry}, che non
   useremo anche per evitare confusione con le \textit{dentries} del kernel di
@@ -559,7 +560,7 @@ torneremo in seguitp; in particolare 
 
 Infine è bene avere presente che essendo file pure loro, esiste un numero di
 riferimenti anche per le directories; per cui se ad esempio a partire dalla
-situazione mostrata in \curfig\ creiamo una nuova directory \texttt{img} nella
+situazione mostrata in \curfig\ creiamo una nuova directory \file{img} nella
 directory \file{gapil}: avremo una situazione come quella in \nfig, dove per
 chiarezza abbiamo aggiunto dei numeri di inode.
 
@@ -587,7 +588,7 @@ caratteristiche di un filesystem standard unix, 
 filenames lunghi (256 caratteri, estendibili a 1012), una dimensione fino a
 4~Tb. 
 
-Oltre alle caratteristiche standard \textsl{ext2} fornisce alcune estensioni
+Oltre alle caratteristiche standard \acr{ext2} fornisce alcune estensioni
 che non sono presenti sugli altri filesystem unix, le cui principali sono le
 seguenti:
 \begin{itemize}
@@ -602,7 +603,7 @@ seguenti:
   gruppo primario del processo, eccetto il caso in cui la directory ha il bit
   di sgid settato (per una descrizione dettagliata del significato di questi
   termini si veda \secref{sec:file_access_control}), nel qual caso file e
-  sottodirectory ereditano sia il group id che il sgid.
+  sottodirectory ereditano sia il \acr{gid} che lo \acr{sgid}.
 \item l'amministratore può scegliere la dimensione dei blocchi del filesystem
   in fase di creazione, a seconda delle sue esigenze (blocchi più grandi
   permettono un accesso più veloce, ma sprecano più spazio disco).
@@ -617,7 +618,7 @@ seguenti:
   log).
 \end{itemize}
 
-La struttura di \textsl{ext2} è stata ispirata a quella del filesystem di BSD,
+La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD,
 un filesystem è composto da un insieme di blocchi, la struttura generale è
 quella riportata in \figref{fig:file_filesys_detail}, in cui la partizione
 è divisa in gruppi di blocchi.
index aa558786b3a12dbe192511402c8ce09484ddd4cd..5036909f9a90026d71e2c5721f52395eeaa5347f 100644 (file)
@@ -4,7 +4,7 @@
 %
 % Questa va per ultima. Va bene che e` la più usata, ma è basata sulle altre
 %
-\section{I file stream e gli oggetti \texttt{FILE}}
+\section{I file stream e gli oggetti \type{FILE}}
 \label{sec:file_stream}
 
 Esamineremo in questa sezione l'interfaccia per i file stream, le modalità per
@@ -13,13 +13,13 @@ operazioni connesse all'uso dei file. L'interfaccia 
 l'header file \texttt{stdio.h}.
 
 Per ragioni storiche la struttura di dati che rappresenta un stream è stata
-chiamata \texttt{FILE}, questi oggetti sono creati dalle funzioni di libreria
-contengono tutte le informazioni necessarie a gestire le operazioni sugli
+chiamata \type{FILE}, questi oggetti sono creati dalle funzioni di libreria e
+contengono tutte le informazioni necessarie a gestire le operazioni sugli
 stream, come la posizione corrente, lo stato del buffer e degli indicatori di
 stato e di fine del file. Per questo motivo gli utenti non devono mai
 utilizzare direttamente o allocare queste strutture, ma usare sempre puntatori
-del tipo \texttt{FILE *} (tanto che in certi caso il termine di puntatore a
-file è diventato sinonimo di stream). 
+del tipo \type{FILE *} (tanto che in certi caso il termine di puntatore a file
+è diventato sinonimo di stream).
 
 \subsection{Gli stream standard}
 \label{sec:file_stdfiles}
@@ -27,7 +27,7 @@ file 
 Quando un programma viene lanciato il processo ha sempre tre stream
 predefiniti aperti, che rappresentano i canali standard di input/output
 prestabiliti per il processo; anche questi tre stream sono definiti
-nell'header \texttt{stdio.h} e sono:
+nell'header \file{stdio.h} e sono:
 
 \begin{itemize}
 \item \texttt{FILE * stdin} Lo \textit{standard input} cioè lo stream da cui
index 879f9708bda4d2ccc59f534e7806865604d9aaab..de8376f830c29db41bae36c0b933a046d434bbca 100644 (file)
@@ -2,15 +2,15 @@
 \label{cha:network}
 
 In questo capitolo sarà fatta un'introduzione ai concetti generali che servono
-come prerequisiti per capire la programmazione di rete, per evitare un
-capitolo puramente teorico partiremo con due semplici esempi per poi passare
-ad un esame a grandi linee dei protocolli di rete e di come questi sono
-organizzati e interagiscono.
+come prerequisiti per capire la programmazione di rete, non tratteremo quindi
+aspetti specifici ma faremo una breve introduzione al modello più comune usato
+nella programmazione di rete, per poi passare ad un esame a grandi linee dei
+protocolli di rete e di come questi sono organizzati e interagiscono. 
 
 In particolare, avendo assunto l'ottica di un'introduzione mirata alla
 programmazione, ci concentreremo sul protocollo più diffuso, il TCP/IP, che è
-quello che sta alla base di internet, con un'ottica improntata a sottolineare
-i concetti più importanti da conoscere ai fini della programmazione.
+quello che sta alla base di internet, avendo cura di sottolineare i concetti
+più importanti da conoscere per la scrittura dei programmi.
 
 \section{Il modello client-server}
 \label{sec:net_cliserv}
@@ -49,261 +49,10 @@ soddisfatte contemporaneamente; una volta che il processo figlio ha concluso
 il suo lavoro viene terminato, mentre il server originale resta sempre attivo.
 
 
-\subsection{Un primo esempio di client}
-\label{sec:net_cli_sample}
-
-Per evitare di rendere l'esposizione dei concetti generali sulla rete
-puramente teorica iniziamo con il mostrare un esempio di un client TCP
-elementare.  Scopo di questo esempio è fornire un primo approccio alla
-programmazione di rete, tutto questo sarà esaminato in dettaglio nei capitoli
-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.
-
-
-\begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <sys/types.h>   /* predefined types */
-#include <unistd.h>      /* include unix standard library */
-#include <arpa/inet.h>   /* IP addresses conversion utiliites */
-#include <sys/socket.h>  /* socket library */
-#include <stdio.h>       /* include standard I/O library */
-
-int main(int argc, char *argv[])
-{
-    int sock_fd;
-    int i, nread;
-    struct sockaddr_in serv_add;
-    char buffer[MAXLINE];
-     ...
-    /* create socket */
-    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        return -1;
-    }
-    /* initialize address */
-    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                   /* address type is INET */
-    serv_add.sin_port = htons(13);                   /* daytime post is 13 */
-    /* build address using inet_pton */
-    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
-        perror("Address creation error");
-        return -1;
-    }
-    /* extablish connection */
-    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("Connection error");
-        return -1;
-    }
-    /* read daytime from server */
-    while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) {
-        buffer[nread]=0;
-        if (fputs(buffer, stdout) == EOF) {          /* write daytime */
-            perror("fputs error");
-            return -1;
-        }
-    }
-    /* error on read */
-    if (nread < 0) {
-        perror("Read error");
-        return -1;
-    }
-    /* normal exit */
-    return 0;
-}
-  \end{lstlisting}
-  \caption{Esempio di codice di un client elementare per il servizio daytime.}
-  \label{fig:net_cli_code}
-\end{figure}
-
-Il sorgente completo del programma (\texttt{ElemDaytimeTCPClient.c}, che
-comprende il trattamento delle opzioni e una funzione per stampare un
-messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e
-può essere compilato su una qualunque macchina Linux.
-
-Il programma anzitutto include gli header necessari (\texttt{\small 1--5});
-dopo la dichiarazione delle variabili (\texttt{\small 9--12}) si è omessa
-tutta la parte relativa al trattamento degli argomenti passati dalla linea di
-comando (effettuata con le apposite routines illustrate in
-\capref{sec:proc_opt_handling}).
-
-Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4
-(\texttt{AF\_INET}), di tipo TCP \texttt{SOCK\_STREAM} (in sostanza un canale
-di comunicazione attraverso internet, questi termini verranno spiegati con
-precisione più avanti). La funzione \texttt{socket} ritorna un descrittore,
-analogo a quello dei file, 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 una apposita
-struttura \texttt{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 \texttt{htons} per convertire il formato dell'intero
-usato dal computer a quello usato nella rete), infine si utilizza la funzione
-\texttt{inet\_pton} per convertire l'indirizzo numerico passato dalla linea di
-comando.
-
-Usando la funzione \texttt{connect} sul socket creato in precedenza
-(\texttt{\small 28--32}) si provvede poi a stabilire la connessione con il
-server specificato dall'indirizzo immesso nella struttura passata come secondo
-argomento, il terzo argomento è la dimensione di detta struttura. Dato che
-esistono diversi tipi di socket, si è dovuto effettuare un cast della
-struttura inizializzata in precedenza, che è specifica per i socket IPv4.  Un
-valore di ritorno negativo implica il fallimento della connessione.
-
-Completata con successo la connessione il passo successivo (\texttt{\small
-  34--40}) è leggere la data dal socket; il server invierà sempre una stringa
-di 26 caratteri della forma \verb|Wed Apr 4 00:53:00 2001\r\n|, che viene
-letta dalla funzione \texttt{read} e scritta su \texttt{stdout}.
-
-Dato il funzionamento di TCP la risposta potrà tornare in un unico pacchetto
-di 26 byte (come avverrà senz'altro nel caso in questione) ma potrebbe anche
-arrivare in 26 pacchetti di un byte.  Per questo nel caso generale non si può
-mai assumere che tutti i dati arrivino con una singola lettura, pertanto
-quest'ultima deve essere effettuata in un loop in cui si continui a leggere
-fintanto che la funzione \texttt{read} non ritorni uno zero (che significa che
-l'altro capo ha chiuso la connessione) o un numero minore di zero (che
-significa un errore nella connessione).
-
-Si noti come in questo caso la fine dei dati sia specificata dal server che
-chiude la connessione; questa è una delle tecniche possibili (è quella usata
-pure dal protocollo HTTP), ma ce ne possono essere altre, ad esempio FTP marca
-la conclusione di un blocco di dati con la sequenza ASCII \verb|\r\n|
-(carriage return e line feed), mentre il DNS mette la lunghezza in testa ad
-ogni blocco che trasmette. Il punto essenziale è che TCP non provvede nessuna
-indicazione che permetta di marcare dei blocchi di dati, per cui se questo è
-necessario deve provvedere il programma stesso.
-
-\subsection{Un primo esempio di server}
-\label{sec:net_serv_sample}
-
-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
-(\texttt{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella
-directory \texttt{sources}.
-
-\begin{figure}[!htbp]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <sys/types.h>   /* predefined types */
-#include <unistd.h>      /* include unix standard library */
-#include <arpa/inet.h>   /* IP addresses conversion utiliites */
-#include <sys/socket.h>  /* socket library */
-#include <stdio.h>       /* include standard I/O library */
-#include <time.h>
-#define MAXLINE 80
-#define BACKLOG 10
-int main(int argc, char *argv[])
-{
-/* 
- * Variables definition  
- */
-    int list_fd, conn_fd;
-    int i;
-    struct sockaddr_in serv_add;
-    char buffer[MAXLINE];
-    time_t timeval;
-    ...
-    /* create socket */
-    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        exit(-1);
-    }
-    /* initialize address */
-    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                  /* address type is INET */
-    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
-    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
-    /* bind socket */
-    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("bind error");
-        exit(-1);
-    }
-    /* listen on socket */
-    if (listen(list_fd, BACKLOG) < 0 ) {
-        perror("listen error");
-        exit(-1);
-    }
-    /* write daytime to client */
-    while (1) {
-        if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
-            perror("accept error");
-            exit(-1);
-        }
-        timeval = time(NULL);
-        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
-        if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
-            perror("write error");
-            exit(-1);
-        }
-        close(conn_fd);
-    }
-    /* normal exit */
-    exit(0);
-}
-  \end{lstlisting}
-  \caption{Esempio di codice di un semplice server per il servizio daytime.}
-  \label{fig:net_serv_code}
-\end{figure}
-
-Come per il client si includono gli header necessari a cui è aggiunto quello
-per trattare i tempi, e si definiscono alcune costanti e le variabili
-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 \texttt{sockaddr\_in}, anche in
-questo caso si usa la porta standard del servizio daytime, ma come indirizzo
-IP si il valore predefinito \texttt{INET\_ANY} che corrisponde ad un indirizzo
-generico (\texttt{\small 27--31}).
-
-Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione
-\texttt{bind} che permette di associare la precedente struttura al socket, in
-modo che quest'ultimo possa essere usato per accettare connessioni su una
-qualunque delle interfacce di rete locali.
-
-Il passo successivo (\texttt{\small 37--41}) è mettere ``in ascolto'' il
-socket, questo viene effettuato con la funzione \texttt{listen} che dice al
-kernel di accettare connessioni per il socket specificato, la funzione indica
-inoltre, con il secondo parametro, il numero massimo di connessioni che il
-kernel accetterà di mettere in coda per il suddetto socket.
-
-Questa ultima chiamata completa la preparazione del socket per l'ascolto (che
-viene chiamato anche \textit{listening descriptor}) a questo punto il processo
-è mandato in sleep (\texttt{\small 44--47}) con la successiva chiamata alla
-funzione \texttt{accept}, fin quando non arriva e viene accettata una
-connessione da un client.
-
-Quando questo avviene \texttt{accept} ritorna un secondo descrittore di
-socket, che viene chiamato \textit{connected descriptor} che è quello che
-viene usato dalla successiva chiamata alla \texttt{write} per scrivere la
-risposta al client, una volta che si è opportunamente (\texttt{\small 48--49})
-costruita la stringa con la data da trasmettere. Completata la trasmissione il
-nuovo socket viene chiuso (\texttt{\small 54}).
-Il tutto è inserito in un loop infinito (\texttt{\small 42--55}) in modo da
-poter ripetere l'invio della data ad una successiva connessione.
-
-È importante notare che questo server è estremamente elementare, infatti a
-parte il fatto di essere dipendente da IPv4, esso è in grado di servire solo
-un client alla volta, è cioè un \textsl{server iterativo}, inoltre esso è
-scritto per essere lanciato da linea di comando, se lo si volesse utilizzare
-come demone di sistema (che è in esecuzione anche quando non c'è nessuna shell
-attiva e il terminale da cui lo si è lanciato è stato sconnesso),
-occorrerebbero delle opportune modifiche.
 
 \section{I protocolli di rete}
 \label{sec:net_protocols}
 
-Visto un primo esempio di programmazione, passiamo ora ad una introduzione più
-dettagliata del funzionamento delle reti e dei relativi protocolli.
-
 Parlando di reti di computer si parla in genere di un insieme molto vasto ed
 eterogeneo di mezzi di comunicazione che vanno dal cavo telefonico, alla fibra
 ottica, alle comunicazioni via satellite; per rendere possibile la
@@ -553,7 +302,7 @@ I vari protocolli mostrati in figura sono i seguenti:
   se ICMP può venire usato direttamente da alcuni programmi come
   \texttt{ping}. A volte ci si riferisce ad esso come ICPMv4 per distinguerlo
   da ICMPv6.
-\item \textsl{ICMP} \textit{Internet Group Management Protocol}. É un
+\item \textsl{IGMP} \textit{Internet Group Management Protocol}. É un
   protocollo usato per il \textit{multicasting} (vedi
   \secref{sec:xxx_multicast}), che è opzionale in IPv4.
 \item \textsl{ARP} \textit{Address Resolution Protocol}. È il protocollo che
@@ -838,7 +587,7 @@ conoscere il \textit{path MTU}.
 
 
 Infine TCP definisce una \textit{maximum segment size} MSS che annuncia
-all'altro capo la dimensione massima del segmento di dati 
+all'altro capo la dimensione massima del segmento di dati.
 
 
 \subsection{Il passaggio dei dati in TCP}
index dafdef803099fa791a30d9c35055588980bbc376..776a025b828df11dafd3c84e230b14092cea7fcf 100644 (file)
@@ -9,7 +9,7 @@ richiedere servizi al sistema, su cosa deve fare quando ha finito la sua
 esecuzione.
 
 In genere un programma viene eseguito quando un processo lo fa partire
-eseguendo una funzione della famiglia \texttt{exec}; torneremo su questo e
+eseguendo una funzione della famiglia \func{exec}; torneremo su questo e
 sulla la creazione e gestione dei processi nel prossimo capitolo, in questo
 affronteremo l'avvio e il funzionamento di un singolo processo partendo dal
 punto di vista del programma posto in esecuzione.
@@ -32,25 +32,25 @@ posto in esecuzione esso apparir
 discorso dei \textit{thread} comunque in Linux necessita di una trattazione a
 parte per la peculiarità dell'implementazione).
 
-\section{La funzione \texttt{main}} 
+\subsection{La funzione \func{main}} 
 \label{sec:proc_main}
 
 Quando un programma viene lanciato il kernel esegue una opportuna routine di
-avvio, usando il programma \texttt{ld-linux.so}, è questo programma che prima
+avvio, usando il programma \cmd{ld-linux.so}, è questo programma che prima
 carica le librerie condivise che servono al programma, effettua il link
 dinamico del codice e poi alla fine lo esegue. Infatti, a meno di non aver
 specificato il flag \texttt{-static} durante la compilazione, tutti i
 programmi in Linux sono incompleti e necessitano di essere linkati alle
 librerie condivise quando vengono avviati.  La procedura è controllata da
-alcune variabili di ambiente e dal contenuto di \texttt{/etc/ld.so.conf}, i
-dettagli sono riportati nella man page di \texttt{ld.so}.
+alcune variabili di ambiente e dal contenuto di \file{/etc/ld.so.conf}, i
+dettagli sono riportati nella man page di \cmd{ld.so}.
 
-Il sistema fa partire qualunque programma chiamando la funzione \texttt{main};
+Il sistema fa partire qualunque programma chiamando la funzione \func{main};
 sta al programmatore chiamare così la funzione principale del programma da cui
 si suppone iniziale l'esecuzione; in ogni caso senza questa funzione lo stesso
 linker darebbe luogo ad errori.
 
-Lo standard ISO C specifica che la funzione \texttt{main} può non avere 
+Lo standard ISO C specifica che la funzione \func{main} può non avere 
 argomenti o prendere due argomenti che rappresentano gli argomenti passati da
 linea di comando, in sostanza un prototipo che va sempre bene è il seguente:
 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
@@ -58,7 +58,7 @@ linea di comando, in sostanza un prototipo che va sempre bene 
 \end{lstlisting}
 
 In realtà nei sistemi unix esiste un'altro modo per definire la funzione
-\texttt{main}, che prevede la presenza di un terzo parametro, \texttt{char
+\func{main}, che prevede la presenza di un terzo parametro, \var{char
   *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{sec:proc_environ})
 del programma; questa forma però non è prevista dallo standard POSIX.1 per cui
 se si vogliono scrivere programmi portabili è meglio evitarla.
@@ -67,20 +67,20 @@ se si vogliono scrivere programmi portabili 
 \subsection{Come chiudere un programma}
 \label{sec:proc_termination}
 
-La via normale per la quale un programma finisce è quando la funzione main
-ritorna, una modalità equivalente di conclusione è quella di chiamare
-direttamente la funzione \texttt{exit} (che viene comunque chiamata dalla
-routine di avvio del programma quando la funzione main ritorna). Una forma
-alternativa è quella di chiamare direttamente la system call \texttt{\_exit}
-che passa il controllo direttamente al kernel.
+La via normale per la quale un programma finisce è quando la funzione
+\func{main} ritorna, una modalità equivalente di conclusione è quella di
+chiamare direttamente la funzione \func{exit} (che viene comunque chiamata
+dalla routine di avvio del programma quando la funzione \func{main} ritorna).
+Una forma alternativa è quella di chiamare direttamente la system call
+\func{\_exit} che passa il controllo direttamente al kernel.
 
 Oltre alla conclusione ``normale'' esiste anche la possibilità di una
 conclusione ``anomala'' del programma a causa di segnali o della chiamata alla
-funzione \texttt{abort} (che comunque genera un segnale che termina il
+funzione \func{abort} (che comunque genera un segnale che termina il
 programma); torneremo su questo in \secref{sec:sig_prog_error}.
 
 Il valore di ritorno della funzione main, o quello usato nelle chiamate ad
-\texttt{exit} e \texttt{\_exit}, viene chiamato \textit{exit status} e passato
+\func{exit} e \func{\_exit}, viene chiamato \textit{exit status} e passato
 al processo padre che aveva lanciato il programma (in genere la shell). In
 generale si usa questo valore per fornire un'informazione generica sulla
 riuscita o il fallimento del programma; l'informazione è necessariamente
@@ -88,11 +88,11 @@ generica, ed il valore deve essere compreso fra 0 e 255.
 
 In generale si usa la convenzione di restituire 0 in caso di successo e 1 in
 caso di fallimento, i programmi che effettuano dei confronti (come
-\texttt{diff}) usano invece una notazione leggermente diversa, usando 0 per
+\cmd{diff}) usano invece una notazione leggermente diversa, usando 0 per
 indicare la corrispondenza, 1 per indicare la non corrispondenza e 2 per
 indicare l'incapacità di effettuare il confronto. È opportuno adottare una di
 queste convenzioni a seconda dei casi. Si tenga presente che se si raggiunge
-la fine della funzione \texttt{main} senza ritornare esplicitamente si ha un
+la fine della funzione \func{main} senza ritornare esplicitamente si ha un
 valore di uscita indefinito, è pertanto consigliabile di concludere sempre in
 maniera esplicita detta funzione.
 
@@ -102,13 +102,13 @@ programma in un sottoprocesso. Bench
 universalmente seguita è una buona idea tenerne conto.
 
 Si tenga presente inoltre che non è una buona idea usare il valore dell'errore
-restituito dalla variabile \texttt{errno} come stato di uscita, in generale
+restituito dalla variabile \var{errno} come stato di uscita, in generale
 una shell non si cura di tutto questo e comunque il valore dello stato di
 uscita è sempre troncato ad 8 bit, per cui si potrebbe incorrere nel caso in
 cui l'errore 256, diventando zero, verrebbe interpretato come un successo. In
-\texttt{stdlib.h} sono definite due macro \texttt{EXIT\_SUCCESS} e
-\texttt{EXIT\_FAILURE}, che in Linux sono poste rispettivamente ai valori 0 e
-1 (di tipo \texttt{int}), seguendo lo standard POSIX.
+\file{stdlib.h} sono definite due macro \macro{EXIT\_SUCCESS} e
+\macro{EXIT\_FAILURE}, che in Linux sono poste rispettivamente ai valori 0 e
+1 (di tipo \type{int}), seguendo lo standard POSIX.
 
 Infine occorre distinguere fra lo stato di uscita di un programma
 (l'\textit{exit status}) e lo stato di conclusione di un processo (il
@@ -119,51 +119,51 @@ programma per
 processo (vedi \secref{sec:proc_xxx}).
 
 
-\subsection{Le funzioni \texttt{exit} e \texttt{\_exit}}
+\subsection{Le funzioni \func{exit} e \func{\_exit}}
 \label{sec:proc_exit}
 
 Come accennato funzioni per l'uscita ``normale'' da un programma sono due, la
-prima è la funzione \texttt{exit} che è definita dallo standard ANSI C; il
+prima è la funzione \func{exit} che è definita dallo standard ANSI C; il
 prototipo della funzione è il seguente:
 \begin{prototype}{stdlib.h}{void exit(int status)}
   Causa la conclusione ordinaria del programma restituendo il valore
-  \texttt{status} al processo padre.
+  \var{status} al processo padre.
 
   La funzione non ritorna. Il processo viene terminato
 \end{prototype}
 
-La funzione \texttt{exit} è pensata per una conclusione pulita di un programma
+La funzione \func{exit} è pensata per una conclusione pulita di un programma
 che usa le librerie standard del C; essa esegue tutte le funzioni che sono
-state registrate con \texttt{atexit} e \texttt{on\_exit} (vedi
+state registrate con \func{atexit} e \func{on\_exit} (vedi
 \secref{sec:proc_atexit}), e chiude tutti gli stream di I/O effettuando il
-salvataggio dei dati sospesi (chiamando \texttt{fclose}, vedi
+salvataggio dei dati sospesi (chiamando \func{fclose}, vedi
 \secref{sec:file_fclose}), infine ripassa il controllo al kernel chiamando
-\texttt{\_exit} e passando il valore \texttt{status} come stato di uscita.
+\func{\_exit} e passando il valore \var{status} come stato di uscita.
 
-La system call \texttt{\_exit} restituisce direttamente il controllo al
+La system call \func{\_exit} restituisce direttamente il controllo al
 kernel, concludendo immediatamente il processo, le eventuali funzioni
-registrate con \texttt{atexit} e \texttt{on\_exit} non vengono eseguite. Il
+registrate con \func{atexit} e \func{on\_exit} non vengono eseguite. Il
 prototipo della funzione è il seguente:
 \begin{prototype}{unistd.h}{void \_exit(int status)}
   Causa la conclusione immediata del programma restituendo il valore
-  \texttt{status} al processo padre.
+  \var{status} al processo padre.
 
   La funzione non ritorna. Il processo viene terminato.
 \end{prototype}
 
 La funzione chiude tutti i file descriptor appartenenti al processo (sui tenga
 presente che questo non comporta il salvataggio dei dati bufferizzati degli
-stream), fa si che ogni figlio del processo sia ereditato da \texttt{init}
-(vedi \secref{cha:process_handling}), manda un segnale \texttt{SIGCHLD} al
+stream), fa si che ogni figlio del processo sia ereditato da \cmd{init}
+(vedi \secref{cha:process_handling}), manda un segnale \macro{SIGCHLD} al
 processo padre (vedi \ref{sec:sig_job_control}) ed infine ritorna lo stato di
-uscita specificato in \texttt{status} che può essere raccolto usando la
-funzione \texttt{wait} (vedi \secref{sec:proc_wait}).
+uscita specificato in \var{status} che può essere raccolto usando la
+funzione \func{wait} (vedi \secref{sec:proc_wait}).
 
 
-\subsection{Le funzioni \texttt{atexit} e \texttt{on\_exit}}
+\subsection{Le funzioni \func{atexit} e \func{on\_exit}}
 \label{sec:proc_atexit}
 
-Come accennato l'uso di \texttt{exit} al posto della \texttt{\_exit} è fatto
+Come accennato l'uso di \func{exit} al posto della \func{\_exit} è fatto
 principalmente per permettere una uscita pulita dalle funzioni delle librerie
 standard del C (in particolare per quel che riguarda la chiusura degli
 stream). 
@@ -177,10 +177,10 @@ di una funzione che effettui tali operazioni all'uscita dal programma.
 
 A questo scopo lo standard ANSI C prevede la possibilità di registrare un
 certo numero funzioni che verranno eseguite all'uscita dal programma (sia per
-la chiamata ad \textit{exit} che per il ritorno di \texttt{main}). La prima
+la chiamata ad \func{exit} che per il ritorno di \func{main}). La prima
 funzione che si può utilizzare a tal fine è:
 \begin{prototype}{stdlib.h}{void atexit(void (*function)(void))}
-  Registra la funzione \texttt{function} per essere chiamata all'uscita dal
+  Registra la funzione \var{function} per essere chiamata all'uscita dal
   programma. 
 
   La funzione restituisce 0 in caso di successo e -1 in caso di fallimento,
@@ -189,28 +189,28 @@ funzione che si pu
 
 La funzione richiede come argomento l'indirizzo della opportuna da chiamare
 all'uscita che non deve prendere argomenti e non deve ritornare niente. Una
-estensione di \texttt{atexit} è la funzione \texttt{on\_exit} (che la glibc
+estensione di \func{atexit} è la funzione \func{on\_exit} (che la glibc
 include per compatibilità con SunOS e che non è detto sia definita su altri
 sistemi), il cui prototipo è:
 \begin{prototype}{stdlib.h}
 {void on\_exit(void (*function)(int status, void *arg), void *arg)}
-  Registra la funzione \texttt{function} per essere chiamata all'uscita dal
+  Registra la funzione \var{function} per essere chiamata all'uscita dal
   programma. Tutte le funzioni registrate vengono chiamate in ordine inverso
   rispetto a quello di registrazione.
 
   La funzione restituisce 0 in caso di successo e -1 in caso di fallimento,
-  \texttt{errno} non viene settata.
+  \var{errno} non viene settata.
 \end{prototype}
 
 In questo caso la funzione da chiamare prende due parametri, il primo dei
 quali sarà inizializzato allo stato di uscita con cui è stata chiamata
-\texttt{exit} ed il secondo al puntatore generico specificato come secondo
-argomento nella chiamata di \texttt{on\_exit}.
+\func{exit} ed il secondo al puntatore generico specificato come secondo
+argomento nella chiamata di \func{on\_exit}.
 
 Nella sequenza di chiusura tutte le funzioni registrate verranno chiamate in
 ordine inverso rispetto a quello di registrazione (ed una stessa funzione
 registrata più volte sarà chiamata più volte); poi verranno chiusi tutti gli
-stream aperti, infine verrà chiamata \texttt{\_exit}.
+stream aperti, infine verrà chiamata \func{\_exit}.
 
 
 \subsection{Conclusioni}
@@ -218,14 +218,14 @@ stream aperti, infine verr
 
 Data l'importanza dell'argomento è opportuno sottolineare ancora una volta che
 in un sistema unix l'unico modo in cui un programma può essere eseguito dal
-kernel è attraverso la chiamata alla system call \texttt{execve} (in genere
-attraverso una delle funzioni \texttt{exec} che vedremo in
+kernel è attraverso la chiamata alla system call \func{execve} (in genere
+attraverso una delle funzioni \func{exec} che vedremo in
 \secref{sec:proc_exec}).
 
 Allo stesso modo l'unico modo in cui un programma può concludere
 volontariamente la sua esecuzione è attraverso una chiamata alla system call
-\texttt{\_exit} sia esplicitamente o che in maniera indiretta attraverso l'uso
-di \texttt{exit} o il ritorno della funzione \texttt{main}.
+\func{\_exit} sia esplicitamente o che in maniera indiretta attraverso l'uso
+di \func{exit} o il ritorno della funzione \func{main}.
 
 Lo schema delle modalità con cui si avvia e conclude normalmente un programma
 è riportato in \nfig.
@@ -279,7 +279,7 @@ spazio disco riservato alla swap, o i file che contengono il codice).
 Lo stesso pezzo di memoria reale (o di spazio disco) può fare da supporto a
 diverse pagine di memoria virtuale appartenenti a processi diversi (come
 accade in genere per le pagine che contengono il codice delle librerie
-condivise). Ad esempio il codice della funzione \texttt{printf} starà su una
+condivise). Ad esempio il codice della funzione \func{printf} starà su una
 sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria
 virtuale di tutti i processi hanno detta funzione nel loro codice. 
 
@@ -322,7 +322,7 @@ commette quando si 
 chiamato un \textit{segmentation fault}. Se si tenta cioè di leggere o
 scrivere da un indirizzo per il quale non esiste una associazione della pagina
 virtuale il kernel risponde al relativo \textit{page fault}, mandando un
-segnale \texttt{SIGSEGV} al processo, che normalmente ne causa la terminazione
+segnale \macro{SIGSEGV} al processo, che normalmente ne causa la terminazione
 immediata.
 
 È pertanto importante capire come viene strutturata la memoria virtuale di un
@@ -337,7 +337,7 @@ programma C viene suddiviso nei seguenti segmenti:
   utilizzarlo, e viene marcato in sola lettura per evitare sovrascritture
   accidentali (o maliziose) che ne modifichino le istruzioni.
   
-  Viene allocato da \texttt{exec} all'avvio del programma e resta invariato
+  Viene allocato da \func{exec} all'avvio del programma e resta invariato
   per tutto il tempo dell'esecuzione.
   
 \item Il segmento dei dati (\textit{data segment}). Contiene le variabili
@@ -351,7 +351,7 @@ programma C viene suddiviso nei seguenti segmenti:
     double pi = 3.14;
 \end{lstlisting}
   questo valore sarà immagazzinato in questo segmento. La memoria di questo
-  segmento viene preallocato dalla \texttt{exec} e inizializzata ai valori
+  segmento viene preallocato dalla \func{exec} e inizializzata ai valori
   specificati.
   
   La seconda parte è il segmento dei dati non inizializzati, che contiene le
@@ -362,7 +362,7 @@ programma C viene suddiviso nei seguenti segmenti:
 \end{lstlisting}
   questo valore sarà immagazzinato in questo segmento. Anch'esso viene
   allocato all'avvio, e tutte le variabili vengono inizializzate a
-  zero (ed i puntatori a \texttt{NULL}). 
+  zero (ed i puntatori a \macro{NULL}). 
   
   Storicamente questo segmento viene chiamato BBS (da \textit{block started by
     symbol}. La sua dimensione è fissa.
@@ -394,7 +394,7 @@ programma C viene suddiviso nei seguenti segmenti:
 \end{figure}
 
 Una disposizione tipica di questi segmenti è riportata in \nfig. Usando il
-comando \texttt{size} su un programma se ne può stampare le dimensioni dei
+comando \cmd{size} su un programma se ne può stampare le dimensioni dei
 segmenti di testo e di dati (inizializzati e BSS); il BSS però non è mai
 salvato sul file, in quanto viene inizializzato a zero al caricamento del
 programma.
@@ -407,7 +407,7 @@ Il C supporta due tipi di allocazione della memoria, l'allocazione statica 
 quella in cui vanno le variabili globali e le variabili statiche (e viene
 effettuata nel segmento dei dati), lo spazio per queste variabili viene
 allocati all'avvio del programma (come parte delle operazioni svolte da
-\texttt{exec}) e non viene liberato fino alla sua conclusione.
+\func{exec}) e non viene liberato fino alla sua conclusione.
 
 L'allocazione automatica è quella che avviene per le cosiddette variabili
 automatiche, cioè gli argomenti delle funzioni o le variabili locali. Lo
@@ -425,12 +425,12 @@ cio
 possano essere modificate durante l'esecuzione del programma; però le librerie
 del C forniscono una serie opportuna di funzioni per permettere l'allocazione
 dinamica di spazio in memoria (in genere nello heap, usando la system call
-\texttt{sbrk}), solo che a questo punto detto spazio sarà accessibile solo in
+\func{sbrk}), solo che a questo punto detto spazio sarà accessibile solo in
 maniera indiretta attraverso dei puntatori.
 
 
-\subsection{Le funzioni \texttt{malloc}, \texttt{calloc}, \texttt{realloc} e
-  \texttt{free}}  
+\subsection{Le funzioni \func{malloc}, \func{calloc}, \func{realloc} e
+  \func{free}}
 \label{sec:proc_mem_malloc}
 
 Le funzioni previste dallo standard ANSI C per la gestione della memoria sono
@@ -438,26 +438,26 @@ quattro, i prototipi sono i seguenti:
 \begin{functions}
 \headdecl{stdlib.h}
 \funcdecl{void *calloc(size\_t size)}
-  Alloca \texttt{size} bytes nello heap. La memoria viene inizializzata a 0.
+  Alloca \var{size} bytes nello heap. La memoria viene inizializzata a 0.
   
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \texttt{NULL} in caso di fallimento, nel qual caso
-  \texttt{errno} viene settata a \texttt{ENOMEM}.
+  di successo e \macro{NULL} in caso di fallimento, nel qual caso
+  \var{errno} viene settata a \macro{ENOMEM}.
 \funcdecl{void *malloc(size\_t size)}
-  Alloca \texttt{size} bytes nello heap. La memoria non viene inizializzata.
+  Alloca \var{size} bytes nello heap. La memoria non viene inizializzata.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \texttt{NULL} in caso di fallimento, nel qual caso
-  \texttt{errno} viene settata a \texttt{ENOMEM}.
+  di successo e \macro{NULL} in caso di fallimento, nel qual caso
+  \var{errno} viene settata a \macro{ENOMEM}.
 \funcdecl{void *realloc(void *ptr, size\_t size)}
-  Cambia la dimensione del blocco allocato all'indirizzo \texttt{ptr}
-  portandola a \texttt{size}.
+  Cambia la dimensione del blocco allocato all'indirizzo \var{ptr}
+  portandola a \var{size}.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \texttt{NULL} in caso di fallimento, nel qual caso
-  \texttt{errno} viene settata a \texttt{ENOMEM}.
+  di successo e \macro{NULL} in caso di fallimento, nel qual caso
+  \var{errno} viene settata a \macro{ENOMEM}.
 \funcdecl{void free(void *ptr)}
-  Disalloca lo spazio di memoria puntato da \texttt{ptr}.
+  Disalloca lo spazio di memoria puntato da \var{ptr}.
 
   La funzione non ritorna nulla.
 \end{functions}
@@ -466,29 +466,29 @@ sempre correttamente allineato per tutti i tipi di dati; ad esempio sulle
 macchine a 32 bit in genere è allineato a multipli di 4 byte e sulle macchine
 a 64 bit a multipli di 8 byte. 
 
-In genere su usano le funzioni \texttt{malloc} e \texttt{calloc} per allocare
+In genere su usano le funzioni \func{malloc} e \func{calloc} per allocare
 dinamicamente la memoria necessaria al programma, siccome i puntatori
 ritornati sono di tipo generico non è necessario effettuare un cast per
 assegnarli a puntatori al tipo di variabile per la quale si effettua la
 allocazione.
 
 La memoria allocata dinamicamente deve essere esplicitamente rilasciata usando
-\texttt{free}\footnote{le glibc provvedono anche una funzione \texttt{cfree}
+\func{free}\footnote{le glibc provvedono anche una funzione \func{cfree}
   defininita per compatibilità con SunOS, che è deprecata} una volta che non
 sia più necessaria. Questa funzione vuole come parametro un puntatore
 restituito da una precedente chiamata a una qualunque delle funzioni di
 allocazione e che non sia già stato liberato da un'altra chiamata a
-\texttt{free}, in caso contrario il comportamento della funzione è indefinito.
+\func{free}, in caso contrario il comportamento della funzione è indefinito.
 
-La funzione \texttt{realloc} si usa invece per cambiare (in genere aumentare)
+La funzione \func{realloc} si usa invece per cambiare (in genere aumentare)
 la dimensione di un'area di memoria precedentemente allocata, la funzione
 vuole in ingresso il puntatore restituito dalla precedente chiamata ad una
-\texttt{malloc} (se è passato un valore \texttt{NULL} allora la funzione si
-comporta come \texttt{malloc}\footnote{questo è vero per linux e
+\func{malloc} (se è passato un valore \macro{NULL} allora la funzione si
+comporta come \func{malloc}\footnote{questo è vero per linux e
   l'implementazione secondo lo standard ANSI C, ma non è vero per alcune
   vecchie implementazioni, inoltre alcune versioni delle librerie del C
-  consentivano di usare \texttt{realloc} anche per un puntatore liberato con
-  \texttt{free} purché non ci fossero state altre chiamate a funzioni di
+  consentivano di usare \func{realloc} anche per un puntatore liberato con
+  \func{free} purché non ci fossero state altre chiamate a funzioni di
   allocazione, questa funzionalità è totalmente deprecata e non è consentita
   sotto linux}), ad esempio quando si deve far crescere la dimensione di un
 vettore; in questo caso se è disponibile dello spazio adiacente al precedente
@@ -503,20 +503,26 @@ essere altri puntatori che puntino all'interno di un'area che si vuole
 ridimensionare.
 
 Uno degli errori più comuni (specie se si ha a che fare con array di
-puntatori) è infatti quello di chiamare \texttt{free} più di una volta sullo
+puntatori) è infatti quello di chiamare \func{free} più di una volta sullo
 stesso puntatore; per evitare questo problema una soluzione di ripiego è
-quella di assegnare sempre a \texttt{NULL} ogni puntatore liberato con
-\texttt{free}, dato che, quando il parametro è un puntatore nullo,
-\texttt{free} non esegue nessuna operazione. 
+quella di assegnare sempre a \macro{NULL} ogni puntatore liberato con
+\func{free}, dato che, quando il parametro è un puntatore nullo,
+\func{free} non esegue nessuna operazione. 
 
 Linux e le glibc hanno una implementazione delle routine di allocazione che è
 controllabile dall'utente attraverso alcune variabili di ambiente, in
 particolare diventa possibile tracciare questo tipo di errori usando la
-variabile \texttt{MALLOC\_CHECK\_} che quando viene settata mette in uso una
+variabile \macro{MALLOC\_CHECK\_} che quando viene settata mette in uso una
 versione meno efficiente delle funzioni, che però è più tollerante nei
-confronti di piccoli errori come quello di chiamate doppie a \texttt{free}; in
-particolare se la variabile è posta a zero gli errori vengono ignorati, se è
-posta ad 1 viene stampato un avviso sullo standard error e se 
+confronti di piccoli errori come quello di chiamate doppie a \func{free}; in
+particolare:
+\begin{itemize}
+\item se la variabile è posta a zero gli errori vengono ignorati.
+\item se è posta ad 1 viene stampato un avviso sullo \textit{standard error}
+  (vedi \secref{sec:file_stdfiles}).
+\item se è posta a 2 viene chiamata \func{abort}, che in genere causa
+  l'immediata conclusione del programma.
+\end{itemize}
 
 Il problema più comune e più difficile da tracciare che si incontra con
 l'allocazione della memoria è però quando la memoria non più utilizzata non
@@ -698,7 +704,7 @@ annidate occorre usare la funzione \func{longjump}.
 
 Il passaggio dei parametri e delle variabili di ambiente dalla riga di comando
 al singolo programma quando viene lanciato è effettuato attraverso le
-variabili \texttt{argc}, \texttt{argv} che vengono passate al programma
+variabili \var{argc}, \var{argv} che vengono passate al programma
 come argomenti della funzione principale.
 
 \subsection{Il formato dei parametri}
@@ -710,9 +716,9 @@ ciascuna delle quali viene considerata un parametro; di default per
 individuare le parole viene usato come separatore lo spazio (comportamento
 modificabile attraverso il settaggio della variabile di ambiente IFS).
 
-Nella scansione viene costruito il vettore di puntatori \texttt{argv} inserendo
+Nella scansione viene costruito il vettore di puntatori \var{argv} inserendo
 in successione il puntatore alla stringa costituente l'$n$-simo parametro; la
-variabile \texttt{argc} viene inizializzata al numero di parametri trovati, in
+variabile \var{argc} viene inizializzata al numero di parametri trovati, in
 questo modo il primo parametro è sempre il nome del programma (vedi \nfig).
 
 \subsection{La gestione delle opzioni}
@@ -720,7 +726,7 @@ questo modo il primo parametro 
 
 In generale un programma unix riceve da linea di comando sia i parametri che
 le opzioni, queste ultime sono standardizzate per essere riconosciute come
-tali: un elemento di \texttt{argv} che inizia con \texttt{-} e che non sia un
+tali: un elemento di \var{argv} che inizia con \texttt{-} e che non sia un
 singolo \texttt{-} o \texttt{--} viene considerato un'opzione.  In in genere
 le opzioni sono costituite da una lettera preceduta dal meno e possono avere o
 no un parametro associato; un comando tipico può essere cioè qualcosa del
@@ -730,20 +736,26 @@ touch -r riferimento.txt -m questofile.txt
 \end{verbatim}
 ed in questo caso le opzioni sono \texttt{m} ed \texttt{r}.
 
-Per gestire le opzioni all'interno dei parametri passati in \texttt{argv} le
-librerie standard del C forniscono la funzione \texttt{getopt} (accessibile
-includendo \texttt{unistd.h}), che ha il prototipo:
-\begin{verbatim}
-int getopt(int argc, char * const argv[], const char * optstring);
-\end{verbatim}
+Per gestire le opzioni all'interno dei parametri passati in \func{argv} le
+librerie standard del C forniscono la funzione \func{getopt} che ha il
+prototipo:
+\begin{prototype}{unistd.h}
+{int getopt(int argc, char * const argv[], const char * optstring)}
+La funzione esegue il parsing degli argomenti passati da linea di comando
+riconoscendo le possibili opzioni segnalate con \var{optstring}.
+
+Ritorna il carattere che segue l'opzione, \cmd{:} se manca un paramatro
+all'opzione, \cmd{?} se l'opzione è sconosciuta, e -1 se non esistono altre
+opzioni.
+\end{prototype}
 
-Questa funzione prende come argomenti le due variabili \texttt{argc} e
-\texttt{argv} ed una stringa che indica quali sono le opzioni valide; la
+Questa funzione prende come argomenti le due variabili \var{argc} e
+\var{argv} ed una stringa che indica quali sono le opzioni valide; la
 funzione effettua la scansione della lista dei parametri ricercando ogni
-stringa che comincia con \texttt{-} e ritorna ogni volta che trova una opzione
+stringa che comincia con \cmd{-} e ritorna ogni volta che trova una opzione
 valida.
 
-La stringa \texttt{optstring} indica quali sono le opzioni riconosciute ed è
+La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è
 costituita da tutti i caratteri usati per identificare le singole opzioni, se
 l'opzione ha un parametro al carattere deve essere fatto seguire un segno di
 due punti \texttt{:} nel caso appena accennato ad esempio la stringa di
@@ -755,7 +767,8 @@ all'interno di un ciclo di while fintanto che essa non ritorna il valore
 un'opzione non dichiarata in \texttt{optstring} viene ritornato un \texttt{?}
 mentre se l'opzione non è seguita da un parametro viene ritornato un
 \texttt{:} infine se viene incontrato il valore \texttt{--} la scansione viene
-considerata conclusa.
+considerata conclusa, anche se vi sono altri parametri che cominciano con
+\texttt{-}.
 
 Quando la funzione trova un'opzione essa ritorna il valore numerico del
 carattere, in questo modo si possono prendere le azioni relative usando un
@@ -770,8 +783,7 @@ case; la funzione inizializza inoltre alcune variabili globali:
 \item \texttt{int optopt} contiene il carattere dell'opzione non riconosciuta.
 \end{itemize}
 
-In \nfig\ è mostrato un programma di esempio, 
-
+In \nfig\ è mostrato un programma di esempio:
 \begin{figure}[htbp]
   \footnotesize
     \begin{lstlisting}{}
@@ -823,8 +835,9 @@ In \nfig\ 
 Un'estensione di questo schema è costituito dalle cosiddette
 \textit{long-options} espresse nella forma \texttt{--option=parameter}, anche
 la gestione di queste ultime è stata standardizzata attraverso l'uso di una
-versione estesa di \texttt{getopt}.
+versione estesa di \func{getopt}.
 
+(NdA: da finire).
 
 \subsection{Le variabili di ambiente}
 \label{sec:proc_environ}
@@ -878,4 +891,3 @@ comuni), come riportato in \ntab. GNU/Linux le supporta tutte e ne definisce
 anche altre per una lista parziale si può controllare \cmd{man environ}
 
 
-
index 1dddba1edf3092f2fd1ee7b33b1e0dd1b4de49b4..b2f7b9ae409f9c1d5a86cae01ba2d4f4de095e17 100644 (file)
@@ -70,9 +70,9 @@ processo \cmd{init} che 
 
 I processi vengono creati dalla funzione \func{fork}; in molti unix questa è
 una system call, Linux però usa un'altra nomenclatura, e la funzione fork è
-basata a sua volta sulla system call \func{clone}, che viene usata anche per
-generare i \textit{thread}.  Il processo figlio creato dalla \func{fork} è una
-copia identica del processo processo padre, ma ha nuovo \acr{pid} e viene
+basata a sua volta sulla system call \func{\_\_clone}, che viene usata anche
+per generare i \textit{thread}.  Il processo figlio creato dalla \func{fork} è
+una copia identica del processo processo padre, ma ha nuovo \acr{pid} e viene
 eseguito in maniera indipendente (le differenze fra padre e figlio sono
 affrontate in dettaglio in \secref{sec:proc_fork}).
 
@@ -157,6 +157,12 @@ cui diventa possibile garantire l'unicit
 generare un pathname univoco, che non potrà essere replicato da un'altro
 processo che usi la stessa funzione. 
 
+Tutti i processi figli dello stesso processo padre sono detti
+\textit{sibling}, questa è un'altra delle relazioni usate nel controllo di
+sessione, in cui si raggruppano tutti i processi creati su uno stesso
+terminale una volta che si è effettuato il login. Torneremo su questo
+argomento in \secref{cap:terminal}, dove esamineremo tutti gli altri
+identificativi associati ad un processo.
 
 \subsection{Utente e gruppo di un processo}
 \label{sec:proc_user_group}
@@ -164,18 +170,14 @@ processo che usi la stessa funzione.
 Come accennato in \secref{sec:intro_multiuser} ad ogni utente ed gruppo sono
 associati due identificatori univoci, lo \acr{uid} e il \acr{gid} che li
 contraddistinguono nei confonti del kernel. Questi identificatori stanno alla
-base del sistema di permessi e protezioni di un sistema unix.
-
- a ciascun
-processo venfon
-
-
-Come accennato in \secref{sec:file_perm_overview} a processo viene associato
-un certo numero di identificatori (riportati in \ntab) che vengono usati sia
-per il controllo di accesso ai file che per la gestione dei privilegi
-associati ai processi stessi.
-
-
+base del sistema di permessi e protezioni di un sistema unix, e vengono usati
+anche nella gestione dei privilegi di accesso dei processi.
+
+Abbiamo già accennato in \secref{sec:file_perm_overview} che ad ogni processo
+associato un certo numero di identificatori (riportati \ntab) che fanno
+riferimento all'utente che ha lanciato il processo (attraverso i valori di
+\acr{uid} e \acr{gid}), e vengono usati sia per il controllo di accesso ai
+file che per la gestione dei privilegi associati ai processi stessi.
 \begin{table}[htb]
   \centering
   \begin{tabular}[c]{|c|l|l|}
@@ -222,23 +224,25 @@ della funzione 
   \headdecl{unistd.h} 
   
   \funcdecl{pid\_t fork(void)} 
-
-  Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
-  caso di errore \texttt{errno} può assumere i valori:
+  
+  Restituisce zero al padre e il \acr{pid} al figlio in caso di successo,
+  ritorna -1 al padre (senza creare il figlio) in caso di errore;
+  \texttt{errno} può assumere i valori:
   \begin{errlist}
-  \item \macro{EAGAIN}
-  \item \macro{ENOMEM}
+  \item \macro{EAGAIN} non ci sono risorse sufficienti per creare un'altro
+    processo (per allocare la tabella delle pagine e le strutture del task) o
+    si è esaurito il numero di processi disponibili.
+  \item \macro{ENOMEM} non è stato possibile allocare la memoria per le
+    strutture necessarie al kernel per creare il nuovo processo.
   \end{errlist}
 \end{functions}
 
-
-Dopo l'esecuzione di una fork sia il processo padre che il processo figlio
-continuano ad essere eseguiti normalmente, ed il processo figlio esegue
+Dopo l'esecuzione di una \func{fork} sia il processo padre che il processo
+figlio continuano ad essere eseguiti normalmente, ed il processo figlio esegue
 esattamente lo stesso codice del padre. La sola differenza è che nel processo
-padre il valore di ritorno della funzione fork è il pid del processo figlio,
-mentre nel figlio è zero; in questo modo il programma può identificare se
-viene eseguito dal padre o dal figlio. 
-
+padre il valore di ritorno della funzione fork è il \acr{pid} del processo
+figlio, mentre nel figlio è zero; in questo modo il programma può identificare
+se viene eseguito dal padre o dal figlio.
 
 
 
@@ -255,37 +259,6 @@ viene eseguito dal padre o dal figlio.
 \label{sec:proc_perms}
 
 
-
-
-
-Come accennato in \secref{sec:file_perm_overview} ciascun processo porta con
-se un gruppo di identificatori (riportati in \ntab) utilizzati per i controllo
-degli accessi, 
-
-
-\begin{table}[htb]
-  \centering
-  \begin{tabular}[c]{|c|l|l|}
-    \hline
-    Sigla & Significato & Utilizzo \\ 
-    \hline
-    \hline
-    \acr{ruid} & \textit{real user id} & indica l'utente reale \\ 
-    \acr{rgid} & \textit{real group id} & indica il gruppo reale \\ 
-    \acr{euid} & \textit{effective user id} & indica l'utente reale \\ 
-    \acr{egid} & \textit{effective group id} & indica il gruppo reale \\ 
-               & \textit{supplementaru group id} & indica il gruppo  \\ 
-    \acr{suid} & \textit{saved user id} & indica l'utente reale \\ 
-    \acr{sgid} & \textit{daved group id} & indica il gruppo reale \\ 
-    \acr{fsuid} & \textit{real user id} & indica l'utente reale \\ 
-    \acr{fsgid} & \textit{real group id} & indica il gruppo reale \\ 
-    \hline
-  \end{tabular}
-  \caption{Identificatori di utente e gruppo associati a ciascun processo.}
-  \label{tab:proc_uid_gid}
-\end{table}
-
-
 \subsection{Le funzioni \texttt{setuid} e \texttt{setgid}}
 \label{sec:proc_setuid}
 
index b362ad870de28b7e17c0360b0042a01f657dfadf..cc8e1af890ae765241e6da580477ddb5571ab75f 100644 (file)
@@ -346,7 +346,11 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
 
 \begin{table}[htb]
   \centering
-  \begin{tabular}[c]{c p{10cm}}
+  \begin{tabular}[c]{|c|p{8cm}|}
+    \hline
+    Sigla & Significato \\
+    \hline
+    \hline
     A & L'azione di default è terminare il processo. \\
     B & L'azione di default è ignorare il segnale. \\
     C & L'azione di default è terminare il processo e scrivere un \textit{core
@@ -354,13 +358,15 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
     D & L'azione di default è fermare il processo. \\
     E & Il segnale non può essere intercettato. \\
     F & Il segnale non può essere ignorato.\\
+    \hline
   \end{tabular}
   \caption{Legenda delle caratteristiche dei segnali riportate in 
     \tabref{tab:sig_signal_list}. }
   \label{tab:sig_action_leg}
 \end{table}
-la descrizione dettagliata del significato dei vari segnali, raggruppati per
-tipologia, è a seguire.
+
+La descrizione dettagliata del significato dei vari segnali, raggruppati per
+tipologia, verrà affrontate nel seguito.
 
 \subsection{Segnali di errore di programma}
 \label{sec:sig_prog_error}
@@ -383,13 +389,13 @@ non ci fosse stato.
 L'azione di default per tutti questi segnali è causare la terminazione del
 processo che li ha causati. In genere oltre a questo il segnale provoca pure
 la registrazione su disco di un file di \textit{core dump} che viene scritto
-in un file \texttt{core} nella directory corrente del processo al momento
+in un file \file{core} nella directory corrente del processo al momento
 dell'errore, che il debugger può usare per ricostruire lo stato del programma
 al momento della terminazione.
 
 Questi segnali sono:
 \begin{description}
-\item \texttt{SIGFPE} Riporta un errore aritmetico fatale. Benché il nome
+\item \macro{SIGFPE} Riporta un errore aritmetico fatale. Benché il nome
   derivi da \textit{floating point exception} si applica a tutti gli errori
   aritmetici compresa la divisione per zero e l'overflow. 
 
@@ -398,7 +404,7 @@ Questi segnali sono:
 %   standard IEEE per le operazioni in virgola mobile definisce vaire eccezioni
 %   aritmetiche e richiede che esse siano notificate.  
 
-\item \texttt{SIGILL} Il nome deriva da \textit{illegal instruction},
+\item \macro{SIGILL} Il nome deriva da \textit{illegal instruction},
   significa che il programma sta cercando di eseguire una istruzione
   privilegiata o inesistente, in generale del codice illegale. Poiché il
   compilatore del C genera del codice valido si ottiene questo segnale se il
@@ -408,7 +414,7 @@ Questi segnali sono:
   una variabile locale, andando a corrompere lo stack. Lo stesso segnale viene
   generato in caso di overflow dello stack o di problemi nell'esecuzione di di
   un signal handler.
-\item \texttt{SIGSEGV} Il nome deriva da \textit{segment violation}, e
+\item \macro{SIGSEGV} Il nome deriva da \textit{segment violation}, e
   significa che il programma sta cercando di leggere o scrivere in una zona di
   memoria protetta al di fuori di quella che gli è stata riservata dal
   sistema. In genere è il meccanismo della protezione della memoria che si
@@ -416,20 +422,20 @@ Questi segnali sono:
 
   È tipico ottenere questo segnale dereferenziando un puntatore nullo o non
   inizializzato leggendo al di la della fine di un vettore. 
-\item \texttt{SIGBUS} Il nome deriva da \textit{bus error}. Come
-  \texttt{SIGSEGV} questo è un segnale che viene generato di solito quando si
-  dereferenzia un puntatore non inzializzato, la differenza è
-  che\texttt{SIGSEGV} indica un accesso non permesso su un indirizzo esistente
-  (tipo fuori dallo heap o dallo stack), mentre \texttt{SIGBUS} indica
+\item \macro{SIGBUS} Il nome deriva da \textit{bus error}. Come
+  \macro{SIGSEGV} questo è un segnale che viene generato di solito quando si
+  dereferenzia un puntatore non inzializzato, la differenza è che
+  \macro{SIGSEGV} indica un accesso non permesso su un indirizzo esistente
+  (tipo fuori dallo heap o dallo stack), mentre \macro{SIGBUS} indica
   l'accesso ad un indirizzo non valido, come nel caso di un puntatore non
   allineato.
-\item \texttt{SIGABRT} Il nome deriva da \textit{abort}. Il segnale indica che
+\item \macro{SIGABRT} Il nome deriva da \textit{abort}. Il segnale indica che
   il programma stesso ha rilevato un errore che viene riportato chiamando la
-  funzione \texttt{abort} che genera questo segnale.
-\item \texttt{SIGTRAP} È il segnale generato da un'istruzione di breakpoint o
+  funzione \func{abort} che genera questo segnale.
+\item \macro{SIGTRAP} È il segnale generato da un'istruzione di breakpoint o
   dall'attivazione del tracciamento per il processo. È usato dai programmi per
   il debugging e se un programma normale non dovrebbe ricevere questo segnale.
-\item \texttt{SIGSYS} Sta ad indicare che si è eseguita una istruzione che
+\item \macro{SIGSYS} Sta ad indicare che si è eseguita una istruzione che
   richiede l'esecuzione di una system call, ma si è fornito un codice
   sbagliato per quest'ultima.
 \end{description}
@@ -505,13 +511,13 @@ di default 
 segnali la scelta di default è irrilevante, in quanto il loro uso presuppone
 sempre la necessità di un manipolatore.  Questi segnali sono:
 \begin{description}
-\item \texttt{SIGALRM} Il nome sta per \textit{alarm}. Segnale la scadenza di
+\item \macro{SIGALRM} Il nome sta per \textit{alarm}. Segnale la scadenza di
   un timer misurato sul tempo reale o sull'orologio di sistema. È normalmente
   usato dalla funzione \func{alarm}.
-\item  \texttt{SIGVTALRM} Il nome sta per \textit{virtual alarm}. È analogo al
+\item  \macro{SIGVTALRM} Il nome sta per \textit{virtual alarm}. È analogo al
   precedente ma segnala la scadenza di un timer sul tempo di CPU usato dal
   processo. 
-\item \texttt{SIGPROF} Il nome sta per \textit{profiling}. Indica la scadenza
+\item \macro{SIGPROF} Il nome sta per \textit{profiling}. Indica la scadenza
   di un timer che misura sia il tempo di CPU speso direttamente dal processo
   che quello che il sistema ha speso per conto di quest'ultimo. In genere
   viene usato dai tool che servono a fare il profilo d'uso della CPU da parte
@@ -528,14 +534,14 @@ generare questi segnali.
 
 L'azione di default è di essere ignorati. Questi segnali sono:
 \begin{description}
-\item \texttt{SIGIO} Questo segnale viene inviato quando un file descriptor è
+\item \macro{SIGIO} Questo segnale viene inviato quando un file descriptor è
   pronto per eseguire dell'input/output. In molti sistemi solo i socket e i
   terminali possono generare questo segnale, in Linux questo può essere usato
   anche per i file, posto che la \func{fcntl} abbia avuto successo.
-\item \texttt{SIGURG} Questo segnale è inviato quando arrivano dei dati
+\item \macro{SIGURG} Questo segnale è inviato quando arrivano dei dati
   urgenti o \textit{out of band} su di un socket; per maggiori dettagli al
   proposito si veda \secref{sec:xxx_urgent_data}.
-\item \texttt{SIGPOLL} Questo segnale è equivalente a \macro{SIGIO}, è
+\item \macro{SIGPOLL} Questo segnale è equivalente a \macro{SIGIO}, è
   definito solo per compatibilità con i sistemi System V.
 \end{description}
 
@@ -590,16 +596,16 @@ resto del sistema.
 L'azione di default di questi segnali è di terminare il processo, questi
 segnali sono:
 \begin{description}
-\item \texttt{SIGPIPE} Sta per \textit{Broken pipe}. Se si usano delle pipes o
+\item \macro{SIGPIPE} Sta per \textit{Broken pipe}. Se si usano delle pipe o
   delle FIFO è necessario che, prima che un processo inizi a scrivere su di
   essa, un'altro abbia aperto la pipe in lettura (si veda
   \secref{sec:ipc_pipes}). Se il processo in lettura non è partito o è
   terminato inavvertitamente alla scrittura sulla pipe il kernel genera questo
   segnale. Se il segnale è bloccato, intercettato o ignorato la chiamata che
   lo ha causato fallisce restituendo l'errore \macro{EPIPE} 
-\item  \texttt{SIGLOST} Sta per \textit{Resource lost}. 
-\item  \texttt{SIGXCPU} Sta per \textit{CPU time limit exceeded}.
-\item  \texttt{SIGXFSZ} Sta per \textit{File size limit exceeded}.
+\item \macro{SIGLOST} Sta per \textit{Resource lost}.
+\item \macro{SIGXCPU} Sta per \textit{CPU time limit exceeded}.
+\item \macro{SIGXFSZ} Sta per \textit{File size limit exceeded}.
 \end{description}
 
 
@@ -609,17 +615,17 @@ segnali sono:
 Raccogliamo qui infine usa serie di segnali che hanno scopi differenti non
 classificabili in maniera omogenea. Questi segnali sono:
 \begin{description}
-\item  \texttt{SIGUSR1} e \texttt{SIGUSR2} Sono due segnali a disposizione
+\item \macro{SIGUSR1} e \macro{SIGUSR2} Sono due segnali a disposizione
   dell'utente che li può usare per quello che vuole. Possono essere utili per
   implementare una comunicazione elementare fra processi diversi, o per
   eseguire a richiesta una operazione utilizzando un manipolatore. L'azione di
-  default è terminare il processo.  
-\item \texttt{SIGWINCH} Il nome sta per \textit{window (size) change} ed è
+  default è terminare il processo.
+\item \macro{SIGWINCH} Il nome sta per \textit{window (size) change} ed è
   generato da molti sistemi (GNU/Linux compreso) quando le dimensioni (in
   righe e colonne) di un terminale vengono cambiate. Viene usato da alcuni
   programmi testuali per riformattare l'uscita su schermo quando si cambia
   dimensione a quest'ultimo. L'azione di default è di essere ignorato.
-\item  \texttt{SIGINFO} Il segnale indica una richiesta di informazioni. È
+\item  \macro{SIGINFO} Il segnale indica una richiesta di informazioni. È
   usato con il controllo di sessione, causa la stampa di informazioni da parte
   del processo leader del gruppo associato al terminale di controllo, gli
   altri processi lo ignorano.
@@ -646,7 +652,7 @@ contenuto, che resta valido solo fino alla successiva chiamata di
 necessario copiarlo.
 
 La seconda funzione deriva da BSD ed è analoga alla funzione \func{perror}
-descritta in \secref{}
+descritta in \secref{sec:intro_strerror}.
 
 
 \section{La gestione dei segnali}
index e20c38800ce3e087de70946678e1a2854d80be31..e0057fd3bd8fc20126605cec1b49035e4ac20713 100644 (file)
@@ -1,14 +1,35 @@
 \chapter{Introduzione ai socket}
 \label{cha:socket_intro}
 
-Il \textit{socket} (traducibile liberamente come \textsl{manicotto}) è uno dei
-principali meccanismi di comunicazione fra programmi utilizzato in ambito unix
-(e non solo). 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.
+In questo capitolo inizieremo a spiegare le caratteristiche principali della
+principale interfaccia per la programmazione di rete, quella dei
+\textit{socket}, che pur essendo nata in unix è usata ormai da tutti i sistemi
+operativi.
+
+Dopo una breve panoramica sulle caratteristiche di questa interfaccia vedremo
+come creare un socket e come collegarlo allo specifico protocollo di rete che
+utilizzerà per la comunicazione. Per evitare una introduzione puramente teorica
+concluderemo il capitolo con un primo esempio di applicazione.
+
+\section{Una panoramica}
+\label{sec:sock_overview}
+
+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.
+
+\subsection{I \textit{socket}}
+\label{sec:sock_socket_def}
+
+Il \textit{socket}\footnote{una traduzione letterale potrebbe essere
+  \textsl{manicotto}, ma essendo universalmente noti come socket utilizzeremo
+  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.
 
 Quella dei socket costituisce infatti la principale API (\textit{Application
   Program Interface}) usata nella programmazione di rete.  La loro origine
@@ -25,7 +46,7 @@ solo con la suite dei protocolli TCP/IP, che sar
 tratteremo in maniera più estesa.
 
 
-\section{Concetti base}
+\subsection{Concetti base}
 \label{sec:sock_gen}
 
 Per capire il funzionamento dei socket occorre avere presente il funzionamento
@@ -64,13 +85,21 @@ la comunicazione, ad esempio se 
 gestire la perdita o il rimescolamento dei dati.
 
 
-\section{La funzione \texttt{socket}}
+\section{La creazione di un \textit{socket}}
+\label{sec:sock_creation}
+
+Come accennato l'interfaccia dei socket è estremamente flessibile e permette
+di interagire con protocolli di comunicazione anche molto diversi fra di loro;
+in questa sezione vedremo come è possibile creare un socket e come specificare
+il tipo di comunicazione che esso deve utilizzare.
+
+\subsection{La funzione \texttt{socket}}
 \label{sec:sock_socket}
 
 La creazione di un socket avviene attraverso l'uso della funzione
 \texttt{socket} questa restituisce un \textit{socket descriptor} (un valore
-intero non negativo) che come gli analoghi file descriptor di files e alle
-pipes serve come riferimento al socket; in sostanza è l'indice nella tabella
+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!]).
@@ -137,7 +166,9 @@ protocolli disponibili sono riportate in \ntab.
   \footnotesize
   \centering
   \begin{tabular}[c]{lll}
-       Nome               & Utilizzo                       & Man page   \\
+       \hline
+       \textsl{Nome}      & \textsl{Utilizzo}             &\textsl{Man page} \\
+       \hline
        \hline
        PF\_UNIX,PF\_LOCAL & Local communication            & unix(7)    \\
        PF\_INET           & IPv4 Internet protocols        & ip(7)      \\
@@ -149,15 +180,16 @@ protocolli disponibili sono riportate in \ntab.
        PF\_ATMPVC         & Access to raw ATM PVCs         &            \\
        PF\_APPLETALK      & Appletalk                      & ddp(7)     \\
        PF\_PACKET         & Low level packet interface     & packet(7)  \\    
+       \hline
   \end{tabular}
   \caption{Famiglie di protocolli definiti in Linux}
   \label{tab:net_pf_names}
 \end{table}
 
 Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad
-esempio in generale tutti i socket di tipo \texttt{SOCK\_RAW} possono essere
+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 \texttt{CAP\_NET\_RAW}.
+uguale a zero) o la capability \macro{CAP\_NET\_RAW}.
 
 
 \subsection{Il tipo, o stile}
@@ -168,26 +200,26 @@ comunicazione, questo infatti viene a dipendere dal protocollo che si andr
 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 \texttt{int} in \texttt{socket.h}:
+glibc chiama \textit{styles}) definiti come \type{int} in \file{socket.h}:
 
 \begin{list}{}{}
-\item \texttt{SOCK\_STREAM} Provvede un canale di trasmissione dati
+\item \macro{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 \texttt{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza
+\item \macro{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 \texttt{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati
+\item \macro{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 \texttt{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di
+\item \macro{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 \texttt{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
+\item \macro{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
   affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti.
-\item \texttt{SOCK\_PACKET} Obsoleto, non deve essere usato.
+\item \macro{SOCK\_PACKET} Obsoleto, non deve essere usato.
 \end{list}
 
 Si tenga presente che non tutte le combinazioni di famiglia di protocolli e
@@ -199,34 +231,35 @@ tabella che mostra le combinazioni valide 
   \footnotesize
   \centering
   \begin{tabular}{l|c|c|c|c|c|}
-   \multicolumn{1}{c}{} &\multicolumn{1}{c}{\texttt{SOCK\_STREAM}}& 
-     \multicolumn{1}{c}{\texttt{SOCK\_DGRAM}} & 
-     \multicolumn{1}{c}{\texttt{SOCK\_RAW}} & 
-     \multicolumn{1}{c}{\texttt{SOCK\_PACKET}}& 
-     \multicolumn{1}{c}{\texttt{SOCK\_SEQPACKET}} \\
+   \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}} \\
      \cline{2-6}
-    \texttt{PF\_UNIX}      &  si & si  &      &     &     \\
+    \macro{PF\_UNIX}      &  si & si  &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_INET}      & TCP & UDP & IPv4 &     &     \\
+    \macro{PF\_INET}      & TCP & UDP & IPv4 &     &     \\
      \cline{2-6}
-    \texttt{PF\_INET6}     & TCP & UDP & IPv6 &     &     \\
+    \macro{PF\_INET6}     & TCP & UDP & IPv6 &     &     \\
      \cline{2-6}
-    \texttt{PF\_IPX}       &     &     &      &     &     \\
+    \macro{PF\_IPX}       &     &     &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_NETLINK}   &     &  si &  si  &     &     \\
+    \macro{PF\_NETLINK}   &     &  si &  si  &     &     \\
      \cline{2-6}
-    \texttt{PF\_X25}       &     &     &      &     &  si \\
+    \macro{PF\_X25}       &     &     &      &     &  si \\
      \cline{2-6}
-    \texttt{PF\_AX25}      &     &     &      &     &     \\
+    \macro{PF\_AX25}      &     &     &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_ATMPVC}    &     &     &      &     &     \\
+    \macro{PF\_ATMPVC}    &     &     &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_APPLETALK} &     & si  &  si  &     &     \\
+    \macro{PF\_APPLETALK} &     & si  &  si  &     &     \\
      \cline{2-6}
-    \texttt{PF\_PACKET}    &     & si  & si   &     &     \\    
+    \macro{PF\_PACKET}    &     & si  & si   &     &     \\    
      \cline{2-6}
   \end{tabular}
-  \caption{Combinazioni valide di dominio e tipo di protocollo per la funzione \texttt{socket}.}
+  \caption{Combinazioni valide di dominio e tipo di protocollo per la 
+    funzione \func{socket}.}
   \label{tab:sock_sock_valid_combinations}
 \end{table}
 
@@ -234,6 +267,8 @@ Dove per ogni combinazione valida si 
 parola \textsl{si} qualora non il protocollo non abbia un nome definito,
 mentre si sono lasciate vuote le caselle per le combinazioni non supportate.
 
+
+
 \section{Le strutture degli indirizzi dei socket}
 \label{sec:sock_sockaddr}
 
@@ -253,6 +288,7 @@ tutte queste strutture iniziano per \texttt{sockaddr\_}, quelli propri di
 ciascuna famiglia vengono identificati dal suffisso finale, aggiunto al nome
 precedente.
 
+
 \subsection{La struttura generica}
 \label{sec:sock_sa_gen}
 
@@ -261,12 +297,12 @@ 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 \texttt{void *}), ma l'interfaccia dei socket è antecendente alla
+(i \type{void *}), ma l'interfaccia dei socket è antecendente alla
 definizione dello standard ANSI, e per questo nel 1982 fu scelto di definire
-una struttura generica \texttt{sockaddr} per gli indirizzi dei socket mostrata
+una struttura generica \type{sockaddr} per gli indirizzi dei socket mostrata
 in \nfig:
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr {
@@ -274,7 +310,7 @@ struct sockaddr {
     char         sa_data[14];   /* address (protocol-specific) */
 };
   \end{lstlisting}
-  \caption{La struttura generica degli indirizzi dei socket \texttt{sockaddr}}
+  \caption{La struttura generica degli indirizzi dei socket \type{sockaddr}}
   \label{fig:sock_sa_gen_struct}
 \end{figure}
 
@@ -286,9 +322,9 @@ occorrer
 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
-\texttt{sys/socket.h}
+\file{sys/socket.h}
 
-\begin{table}[!htbp]
+\begin{table}[!htb]
   \centering
   \begin{tabular}{|l|l|l|}
     \hline
@@ -321,8 +357,8 @@ definiti; la struttura 
 In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro
 aggiuntivo \texttt{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 sussiste. Il campo
-\texttt{sa\_family\_t} era storicamente un \texttt{unsigned short}.
+richiesto dallo standard POSIX.1g, in Linux pertanto non esiste. Il campo
+\type{sa\_family\_t} era storicamente un \type{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'
@@ -336,14 +372,13 @@ l'uso di questa struttura.
 \subsection{La struttura degli indirizzi IPv4}
 \label{sec:sock_sa_ipv4}
 
-I socket di tipo \texttt{PF\_INET} vengono usati per la comunicazione
+I socket di tipo \macro{PF\_INET} vengono usati per la comunicazione
 attraverso internet; la struttura per gli indirizzi per un socket internet
-(IPv4) è definita come \texttt{sockaddr\_in} nell'header file
+(IPv4) è definita come \type{sockaddr\_in} nell'header file
 \texttt{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig,
 conforme allo standard POSIX.1g.
 
-
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in {
@@ -373,12 +408,12 @@ 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 \texttt{CAP\_NET\_BIND\_SERVICE} possono
-usare la funzione \texttt{bind} su queste porte.
+usare la funzione \func{bind} su queste porte.
 
 Il membro \texttt{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 accedere alle
-diverse classi di indirizzi) che come intero. 
+implementazione precedente in cui questa era una \texttt{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
 essere specificati in quello che viene chiamato \textit{network order}, cioè
@@ -387,6 +422,7 @@ necessit
 portabilità del codice (vedi \secref{sec:sock_addr_func} per i dettagli del
 problema e le relative soluzioni).
 
+
 \subsection{La struttura degli indirizzi IPv6}
 \label{sec:sock_sa_ipv6}
 
@@ -395,7 +431,7 @@ 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 \texttt{netinet/in.h}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in6 {
@@ -442,7 +478,7 @@ funzione \texttt{socketpair}. Quando per
 ad uno di questi socket si deve usare la seguente struttura di indirizzi
 definita nel file di header \texttt{sys/un.h}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 #define UNIX_PATH_MAX    108
@@ -483,6 +519,7 @@ vengono usati i restanti bytes come stringa (senza terminazione).
 % \texttt{getpeername} invece ricevono i valori del kernel 
 
 
+
 \section{Le funzioni di conversione degli indirizzi}
 \label{sec:sock_addr_func}
 
@@ -541,29 +578,29 @@ 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 \texttt{hostlong} dal formato della macchina a
+  Converte l'intero a 32 bit \var{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 \texttt{hostshort} dal formato della macchina a
+  Converte l'intero a 16 bit \var{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 \texttt{netlong} dal formato della rete a quello
+  Converte l'intero a 32 bit \var{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 \texttt{netshort} dal formato della rete a quello
+  Converte l'intero a 16 bit \var{netshort} dal formato della rete a quello
   della macchina.
 \end{prototype}
 I nomi sono assegnati usando la lettera $n$ come mnemonico per indicare
 l'ordinamento usato sulla rete (da \textit{network order}) e la lettera $h$
 come mnemonico per l'ordinamento usato sulla macchina locale (da \textit{host
   order}), mentre le lettere $s$ e $l$ stanno ad indicare i tipi di dato
-(\texttt{long} o \texttt{short}, riportati anche dai prototipi).
+(\type{long} o \type{short}, riportati anche dai prototipi).
 
 Usando queste funzioni si ha la conversione automatica (nel caso pure la
 macchina sia in big endian queste funzioni sono definite come macro che non
@@ -571,8 +608,8 @@ fanno nulla); esse vanno sempre utilizzate per assicurare la portabilit
 codice su tutte le architetture.
 
 
-\subsection{Le funzioni \texttt{inet\_aton}, \texttt{inet\_addr} e 
-  \texttt{inet\_ntoa}}
+\subsection{Le funzioni \func{inet\_aton}, \func{inet\_addr} e 
+  \func{inet\_ntoa}}
 \label{sec:sock_func_ipv4}
 
 Un secondo insieme di funzioni di manipolazione serve per passare dal formato
@@ -587,17 +624,17 @@ cosiddetta notazione \textit{dotted-decimal}, (cio
 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 \texttt{src} nell'indirizzo binario da memorizzare all'indirizzo
-  puntato da \texttt{dest}, restituendo 0 in caso di successo e 1 in caso di
+  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 \texttt{dest} inizializzato a \texttt{NULL} effettua la validazione
+  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
-  \texttt{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo
+  \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.
@@ -610,12 +647,12 @@ indicare la stringa. Dette funzioni sono:
 \end{prototype}
 
 
-\subsection{Le funzioni \texttt{inet\_pton} e \texttt{inet\_ntop}}
+\subsection{Le funzioni \func{inet\_pton} e \func{inet\_ntop}}
 \label{sec:sock_conv_func_gen}
 
 Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo
-motivo è preferibile usare le due nuove funzioni \texttt{inet\_pton} e
-\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
+motivo è preferibile usare le due nuove funzioni \func{inet\_pton} e
+\func{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
 questo caso le lettere $n$ e $p$ sono degli mnemonici per ricordare il tipo di
 conversione effettuata e stanno per \textit{presentation} e \textit{numeric}.
 
@@ -635,8 +672,8 @@ al valore \texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i
 seguenti:
 \begin{prototype}{sys/socket.h}
   {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la
-  stringa puntata da \texttt{src} nell'indirizzo IP da memorizzare
-  all'indirizzo puntato da \texttt{addr\_ptr}, la funzione restituisce un
+  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.
@@ -644,18 +681,18 @@ seguenti:
 
 \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 \texttt{addr\_ptr} in una
-  stringa che viene copiata nel buffer puntato dall'indirizzo \texttt{dest};
+  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
-  \texttt{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
-  \texttt{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
-  comunque venire specificata attraverso il parametro \texttt{len}.
+  \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}.
  
-  La funzione restituisce un puntatore non nullo a \texttt{dest} in caso di
+  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 \texttt{errno} con il valore \texttt{ENOSPC} in
+  viene settata la variabile \texttt{errno} con il valore \macro{ENOSPC} in
   caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da
-  \texttt{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di
+  \var{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di
   indirizzi valida.
 \end{prototype}
 
@@ -669,7 +706,17 @@ Il formato usato per gli indirizzi in formato di presentazione 
 \textit{dotted decimal} per IPv4 e quella descritta in
 \secref{sec:IP_ipv6_notation} per IPv6.
 
-\section{Il comportamento delle funzioni di I/O}
+
+\section{Un esempio di applicazione}
+\label{sec:sock_appplication}
+
+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, esamimeremo una caratteristica
+delle funzioni di I/O sui socket che ci tornerà utile anche in seguito.
+
+
+\subsection{Il comportamento delle funzioni di I/O}
 \label{sec:sock_io_behav}
 
 Una cosa di cui non sempre si è consapevoli quando si ha a che fare con i
@@ -677,8 +724,8 @@ socket 
 comportamento che avrebbero con i normali files (in particolare questo accade
 per i socket di tipo stream). 
 
-Infatti con i socket può accadere che funzioni come \texttt{read} o
-\texttt{write} possano restituire in input o scrivere in output un numero di
+Infatti con i socket può accadere che funzioni come \func{read} o
+\func{write} possano restituire in input o scrivere in output un numero di
 bytes minore di quello richiesto. Questo è un comportamento normale e non un
 errore, e succede perché si eccede in lettura o scrittura il limite di buffer
 del kernel. 
@@ -767,3 +814,249 @@ Nel caso della lettura se il numero di bytes letti 
 arrivati alla fine del file e pertanto si ritorna senza aver concluso la
 lettura di tutti i bytes richiesti. 
 
+
+
+\subsection{Un primo esempio di client}
+\label{sec:net_cli_sample}
+
+Lo scopo di questo esempio è fornire un primo approccio alla programmazione di
+rete e vedere come si usano le funzioni descritte in precedenza, alcune delle
+funzioni usate nell'esempio saranno trattate in dettaglio nel capitolo
+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.
+
+\begin{figure}[!htbp]
+  \footnotesize
+  \begin{lstlisting}{}
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utiliites */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+
+int main(int argc, char *argv[])
+{
+    int sock_fd;
+    int i, nread;
+    struct sockaddr_in serv_add;
+    char buffer[MAXLINE];
+     ...
+    /* create socket */
+    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        return -1;
+    }
+    /* initialize address */
+    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                   /* address type is INET */
+    serv_add.sin_port = htons(13);                   /* daytime post is 13 */
+    /* build address using inet_pton */
+    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
+        perror("Address creation error");
+        return -1;
+    }
+    /* extablish connection */
+    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("Connection error");
+        return -1;
+    }
+    /* read daytime from server */
+    while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) {
+        buffer[nread]=0;
+        if (fputs(buffer, stdout) == EOF) {          /* write daytime */
+            perror("fputs error");
+            return -1;
+        }
+    }
+    /* error on read */
+    if (nread < 0) {
+        perror("Read error");
+        return -1;
+    }
+    /* normal exit */
+    return 0;
+}
+  \end{lstlisting}
+  \caption{Esempio di codice di un client elementare per il servizio daytime.}
+  \label{fig:net_cli_code}
+\end{figure}
+
+Il sorgente completo del programma (\texttt{ElemDaytimeTCPClient.c}, che
+comprende il trattamento delle opzioni e una funzione per stampare un
+messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e
+può essere compilato su una qualunque macchina Linux.
+
+Il programma anzitutto include gli header necessari (\texttt{\small 1--5});
+dopo la dichiarazione delle variabili (\texttt{\small 9--12}) si è omessa
+tutta la parte relativa al trattamento degli argomenti passati dalla linea di
+comando (effettuata con le apposite routines 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
+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 una apposita
+struttura \type{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
+usato dal computer a quello usato nella rete), infine si utilizza la funzione
+\texttt{inet\_pton} per convertire l'indirizzo numerico passato dalla linea di
+comando.
+
+Usando la funzione \func{connect} sul socket creato in precedenza
+(\texttt{\small 28--32}) si provvede poi a stabilire la connessione con il
+server specificato dall'indirizzo immesso nella struttura passata come secondo
+argomento, il terzo argomento è la dimensione di detta struttura. Dato che
+esistono diversi tipi di socket, si è dovuto effettuare un cast della
+struttura inizializzata in precedenza, che è specifica per i socket IPv4.  Un
+valore di ritorno negativo implica il fallimento della connessione.
+
+Completata con successo la connessione il passo successivo (\texttt{\small
+  34--40}) è leggere la data dal socket; il server invierà sempre una stringa
+di 26 caratteri della forma \verb|Wed Apr 4 00:53:00 2001\r\n|, che viene
+letta dalla funzione \func{read} e scritta su \texttt{stdout}.
+
+Dato il funzionamento di TCP la risposta potrà tornare in un unico pacchetto
+di 26 byte (come avverrà senz'altro nel caso in questione) ma potrebbe anche
+arrivare in 26 pacchetti di un byte.  Per questo nel caso generale non si può
+mai assumere che tutti i dati arrivino con una singola lettura, pertanto
+quest'ultima deve essere effettuata in un loop in cui si continui a leggere
+fintanto che la funzione \func{read} non ritorni uno zero (che significa che
+l'altro capo ha chiuso la connessione) o un numero minore di zero (che
+significa un errore nella connessione).
+
+Si noti come in questo caso la fine dei dati sia specificata dal server che
+chiude la connessione; questa è una delle tecniche possibili (è quella usata
+pure dal protocollo HTTP), ma ce ne possono essere altre, ad esempio FTP marca
+la conclusione di un blocco di dati con la sequenza ASCII \verb|\r\n|
+(carriage return e line feed), mentre il DNS mette la lunghezza in testa ad
+ogni blocco che trasmette. Il punto essenziale è che TCP non provvede nessuna
+indicazione che permetta di marcare dei blocchi di dati, per cui se questo è
+necessario deve provvedere il programma stesso.
+
+\subsection{Un primo esempio di server}
+\label{sec:net_serv_sample}
+
+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
+(\texttt{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella
+directory \texttt{sources}.
+
+\begin{figure}[!htbp]
+  \footnotesize
+  \begin{lstlisting}{}
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utiliites */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+#include <time.h>
+#define MAXLINE 80
+#define BACKLOG 10
+int main(int argc, char *argv[])
+{
+/* 
+ * Variables definition  
+ */
+    int list_fd, conn_fd;
+    int i;
+    struct sockaddr_in serv_add;
+    char buffer[MAXLINE];
+    time_t timeval;
+    ...
+    /* create socket */
+    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        exit(-1);
+    }
+    /* initialize address */
+    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                  /* address type is INET */
+    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
+    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
+    /* bind socket */
+    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("bind error");
+        exit(-1);
+    }
+    /* listen on socket */
+    if (listen(list_fd, BACKLOG) < 0 ) {
+        perror("listen error");
+        exit(-1);
+    }
+    /* write daytime to client */
+    while (1) {
+        if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
+            perror("accept error");
+            exit(-1);
+        }
+        timeval = time(NULL);
+        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
+        if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
+            perror("write error");
+            exit(-1);
+        }
+        close(conn_fd);
+    }
+    /* normal exit */
+    exit(0);
+}
+  \end{lstlisting}
+  \caption{Esempio di codice di un semplice server per il servizio daytime.}
+  \label{fig:net_serv_code}
+\end{figure}
+
+Come per il client si includono gli header necessari a cui è aggiunto quello
+per trattare i tempi, e si definiscono alcune costanti e le variabili
+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
+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
+generico (\texttt{\small 27--31}).
+
+Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione
+\func{bind} che permette di associare la precedente struttura al socket, in
+modo che quest'ultimo possa essere usato per accettare connessioni su una
+qualunque delle interfacce di rete locali.
+
+Il passo successivo (\texttt{\small 37--41}) è mettere ``in ascolto'' il
+socket, questo viene effettuato con la funzione \func{listen} che dice al
+kernel di accettare connessioni per il socket specificato, la funzione indica
+inoltre, con il secondo parametro, il numero massimo di connessioni che il
+kernel accetterà di mettere in coda per il suddetto socket.
+
+Questa ultima chiamata completa la preparazione del socket per l'ascolto (che
+viene chiamato anche \textit{listening descriptor}) a questo punto il processo
+è mandato in sleep (\texttt{\small 44--47}) con la successiva chiamata alla
+funzione \func{accept}, fin quando non arriva e viene accettata una
+connessione da un client.
+
+Quando questo avviene \func{accept} ritorna un secondo descrittore di socket,
+che viene chiamato \textit{connected descriptor} che è quello che viene usato
+dalla successiva chiamata alla \func{write} per scrivere la risposta al
+client, una volta che si è opportunamente (\texttt{\small 48--49}) costruita
+la stringa con la data da trasmettere. Completata la trasmissione il nuovo
+socket viene chiuso (\texttt{\small 54}).  Il tutto è inserito in un loop
+infinito (\texttt{\small 42--55}) in modo da poter ripetere l'invio della data
+ad una successiva connessione.
+
+È importante notare che questo server è estremamente elementare, infatti a
+parte il fatto di essere dipendente da IPv4, esso è in grado di servire solo
+un client alla volta, è cioè un \textsl{server iterativo}, inoltre esso è
+scritto per essere lanciato da linea di comando, se lo si volesse utilizzare
+come demone di sistema (che è in esecuzione anche quando non c'è nessuna shell
+attiva e il terminale da cui lo si è lanciato è stato sconnesso),
+occorrerebbero delle opportune modifiche.