From: Simone Piccardi Date: Mon, 30 Jul 2001 18:17:36 +0000 (+0000) Subject: Scritto qualcosa sugli errori X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=827c08ae9cc068b139a45cf5e7c8763a654c1da5 Scritto qualcosa sugli errori --- diff --git a/intro.tex b/intro.tex index ebbc5e2..f287e9c 100644 --- a/intro.tex +++ b/intro.tex @@ -301,3 +301,40 @@ time viene chiamato \textit{CPU time}. \subsection{Tipi di dati primitivi} \label{sec:intro_data_types} +\section{La gestione degli errori} +\label{sec:intro_errors} + +La gestione degli errori è in genere una materia complessa. Inoltre il modello +utilizzato dai sistema unix-like è basato sull'architettura a processi, e +presenta una serie di problemi nel caso lo si debba usare con i thread. +Esamineremo in questa sezione le sue caratteristiche principali. + + + +\subsection{La variabile \func{errno}} +\label{sec:intro_errno} + +Quasi tutte le funzioni delle librerie del C sono in grado di individuare e +riportare condizioni di errore, ed è una buona norma di programmazione +controllare sempre che le funzioni chiamate si siano concluse correttamente. + +In genere le funzioni di libreria usano un valore speciale per indicare che +c'è stato un errore. Di solito questo valore è -1 o un puntatore nullo o la +costante \macro{EOF} (a seconda della funzione); ma questo valore segnala solo +che c'è stato un errore, non il tipo di errore. + +Per riportare il tipo di errore il sistema usa la variabile globale +\var{errno}\footnote{L'uso di una variabile globale può comportare alcuni + problemi (ad esempio nel caso dei thread) ma lo standard ISO C consente + anche di definire \var{errno} come un \textit{modifible lvalue}, quindi su + può anche usare + +}, definita nell'header \file{errno.h}, la variabile è in genere +definita come \var{volatile} dato che può essere cambiata in modo asincrono da +un segnale (per una descrizione dei segnali si veda \secref{cha:signal}), ma +dato che un manipolatore di segnale scritto bene salva e ripristina il valore +della varibile, di questo non è necessario preoccuparsi nella programmazione +normale. + + + diff --git a/signal.tex b/signal.tex index a0e73df..37243ad 100644 --- a/signal.tex +++ b/signal.tex @@ -626,6 +626,28 @@ classificabili in maniera omogenea. Questi segnali sono: \end{description} +\subsection{Le funzioni \func{strsignal} e \func{psignal}} +\label{sec:sig_strsignal} + +Per la descrizione dei segnali il sistema mette a disposizione due funzioni +che stampano un messaggio di descrizione dato il numero. In genere si usano +quando si vuole notificare all'utente il segnale avvenuto (nel caso di +terminazione di un processo figlio o di un manipolatore che gestisce più +segnali); la prima funzione è una estensione GNU ed è analoga alla funzione +\func{strerr} per gli errori: +\begin{prototype}{string.h}{char * strsignal (int signum)} + Ritorna il puntatore ad una stringa allocata staticamente che contiene la + descrizione del segnale \var{signum}. +\end{prototype} + +Dato che la stringa è allocata staticamente non se ne deve modificare il +contenuto, che resta valido solo fino alla successiva chiamata di +\func{strsignal}; nel caso si debba mantenere traccia del messaggio sarà +necessario copiarlo. + +La seconda funzione deriva da BSD ed è analoga alla funzione \func{perror} +descritta in \secref{ + \section{La gestione dei segnali} \label{sec:sig_handlers} diff --git a/simpltcp.tex b/simpltcp.tex index 38df63e..3c10daa 100644 --- a/simpltcp.tex +++ b/simpltcp.tex @@ -309,7 +309,7 @@ mentre per quanto riguarda l'esecuzione dei programmi avremo che: \begin{itemize} \item il client chiama la funzione \texttt{ClientEcho} che si blocca sulla \texttt{fgets} dato che non si è ancora scritto nulla sul terminale. -\item il server eseguirà una \texttt{fork} facendo chiamare al processo figlo +\item il server eseguirà una \texttt{fork} facendo chiamare al processo figlio la funzione \texttt{ServEcho}, quest'ultima si bloccherà sulla \texttt{read} dal socket sul quale ancora non sono presenti dati. \item il processo padre del server chiamerà di nuovo \texttt{accept} @@ -364,10 +364,10 @@ terminazione normale della connessione, che ci servir casi seguenti: \begin{enumerate} -\item Inviando un carattere di EOF da terminale la \texttt{fgets} ritorna +\item inviando un carattere di EOF da terminale la \texttt{fgets} ritorna restituendo un puntatore nullo che causa l'uscita dal ciclo di \texttt{while}, così la \texttt{ClientEcho} ritorna. -\item Al ritorno di \texttt{ClientEcho} ritorna anche la funzione +\item al ritorno di \texttt{ClientEcho} ritorna anche la funzione \texttt{main}, e come parte del processo terminazione tutti i file descriptor vengono chiusi (si ricordi quanto visto in \secref{sec:proc_term_conclusion}), il che causa la chiusura del socket di @@ -375,11 +375,11 @@ casi seguenti: risponderà con un ACK. A questo punto il client verrà a trovarsi nello stato \texttt{FIN\_WAIT\_2} ed il server nello stato \texttt{CLOSE\_WAIT} (si riveda quanto spiegato in \secref{sec:TCPel_conn_term}). -\item Quando il server riceve il FIN la la \texttt{read} del processo figlio +\item quando il server riceve il FIN la la \texttt{read} del processo figlio che gestisce la connessione ritorna restituendo 0 causando così l'uscita dal ciclo di \texttt{while} e il ritorno di \texttt{ServEcho}, a questo punto il processo figlio termina chiamando \texttt{exit}. -\item All'uscita del figlio tutti i file descriptor vengono chiusi, la +\item all'uscita del figlio tutti i file descriptor vengono chiusi, la chiusura del socket connesso fa sì che venga effettuata la sequenza finale di chiusura della connessione, viene emesso un FIN dal server che riceverà un ACK dal client, a questo punto la connessione è conclusa e il client