Dopo un introduzione sulle caratteristiche principali di un sistema di tipo
unix passeremo ad illustrare alcuni dei concetti basi dell'architettura di
Linux (che sono comunque comuni a tutti i sistemi \textit{unix-like}) ed
-introdurremo alcunoi degli standard princincipali a cui si fa riferimento.
+introdurremo alcuni degli standard princincipali a cui si fa riferimento.
\section{Una panoramica sulla struttura}
\label{sec:intro_unix_struct}
In questa prima sezione faremo una panoramica sulla struttura di un sistema
-\textit{unix-like} come Linux. Chi avesse già una conoscenza di questa
+\textit{unix-like} come GNU/Linux. Chi avesse già una conoscenza di questa
materia può tranquillamente saltare questa sezione.
Il concetto base di un sistema unix-like é quello di un nucleo del sistema (il
terminale o una interfaccia grafica) che mette a disposizione dell'utente un
meccanismo con cui questo può impartire comandi o eseguire altri programmi.
-Ogni utente appartiene anche ad almeno un gruppo (\textit{group}), ma può
-essere associato a più gruppi, questo permette di gestire i permessi di
+Ogni utente appartiene anche ad almeno un gruppo (il cosiddetto
+\textit{default group}), ma può essere associato ad altri gruppi (i
+\textit{supplementary group}), questo permette di gestire i permessi di
accesso ai file e quindi anche alle periferiche, in maniera più flessibile,
definendo gruppi di lavoro, di accesso a determinate risorse, etc.
L'utente e il gruppo sono identificati da due numeri (la cui corrispondenza ad
-un nome in espresso in caratteri \`e inserita nei due files
-\texttt{/etc/passwd} e \texttt{/etc/groups}). Questi numeri sono
-l'\textit{user identifier}, detto in breve \textit{uid} e il \textit{group
- identifier}, detto in breve \textit{gid} che sono quelli che identificano
-l'utente di fronte al sistema.
+un nome in espresso in caratteri è inserita nei due files \file{/etc/passwd}
+e \file{/etc/groups}). Questi numeri sono l'\textit{user identifier}, detto
+in breve \acr{uid} e il \textit{group identifier}, detto in breve \acr{gid}
+che sono quelli che identificano l'utente di fronte al sistema.
In questo modo il sistema è in grado di tenere traccia per ogni processo
dell'utente a cui appartiene ed impedire ad altri utenti di interferire con
\secref{sec:file_access_control}) è regolato da questo meccanismo di
identificazione.
-Un utente speciale del sistema è \textit{root}, il cui uid è zero. Esso
+Un utente speciale del sistema è \textit{root}, il cui \acr{uid} è zero. Esso
identifica l'amministratore del sistema, che deve essere in grado di fare
-qualunque operazione; pertanto per l'utente root i meccanismi di controllo
-descritti in precedenza sono disattivati.
+qualunque operazione; pertanto per l'utente \textit{root} i meccanismi di
+controllo descritti in precedenza sono disattivati.
\section{Gli standard di unix e GNU/Linux}
\subsection{Tipi di dati primitivi}
\label{sec:intro_data_types}
+
+
+
\section{La gestione degli errori}
\label{sec:intro_errors}
Esamineremo in questa sezione le sue caratteristiche principali.
-
\subsection{La variabile \func{errno}}
\label{sec:intro_errno}
problemi (ad esempio nel caso dei thread) ma lo standard ISO C consente
anche di definire \var{errno} come un \textit{modifiable lvalue}, quindi si
può anche usare una macro, e questo è infatti il modo usato da Linux per
- renderla locale ai singoli thread
-}, 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:signals}), ma
-dato che un manipolatore di segnale scritto bene salva e ripristina il valore
-della varibile, di questo non è necessario preoccuparsi nella programmazione
-normale.
+ renderla locale ai singoli thread }, 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:signals}), ma dato che un manipolatore di segnale scritto
+bene salva e ripristina il valore della variabile, di questo non è necessario
+preoccuparsi nella programmazione normale.
I valori che può assumere \var{errno} sono riportati in \capref{cha:errors},
nell'header \file{errno.h} sono anche definiti i nomi simbolici per le
-costanti numeriche che identificano i vari errori. In seguito faremo sempre
-rifermento a tali valori, quando descriveremo i possibili errori restituiti
-dalle funzioni.
+costanti numeriche che identificano i vari errori; essi iniziano tutti per
+\macro{E} e si possono considerare come nomi riservati. In seguito faremo
+sempre rifermento a tali valori, quando descriveremo i possibili errori
+restituiti dalle funzioni. Il programma di esempio \cmd{errcode} stampa il
+codice relativo ad un valore numerico con l'opzione \cmd{-l}.
-\subsection{Le funzioni \func{strerror} e \func{perror}}
-\label{sec:intro_strerror}
+Il valore di \var{errno} viene sempre settato a zero all'avvio di un
+programma, gran parte delle funzioni di libreria settano \var{errno} ad un
+valore diverso da zero in caso di errore. Il valore è invece indefinito in
+caso di successo, perché anche se una funzione ha successo, può chiamarne
+altre al suo interno che falliscono, modificando così \var{errno}.
+
+Pertanto un valore non nullo di \var{errno} non è sintomo di errore (potrebbe
+essere il risultato di un errore precedente) e non lo si può usare per
+determinare quando o se una chiamata a funzione è fallita. La procedura da
+seguire è sempre quella di controllare \var{errno} immediatamente dopo aver
+verificato il fallimento della funzione attraverso il suo codice di ritorno.
+\subsection{Le funzioni \func{strerror} e \func{perror}}
+\label{sec:intro_strerror}
+Benché gli errori siano identificati univocamente dal valore numerico di
+\var{errno} le librerie provvedono alcune funzioni e variabili utili per
+riportare in opportuni messaggi le condizioni di errore verificatesi. La
+prima funzione che si può usare per ricavare i messaggi di errore è
+\func{strerror}, il cui prototipo è:
+\begin{prototype}{string.h}{char * strerror(int errnum)}
+ La funzione ritorna una stringa (statica) che descrive l'errore il cui
+ codice è passato come parametro.
+\end{prototype}
+
+In generale \func{strerror} viene usata passando \var{errno} come parametro;
+nel caso si specifichi un codice sbagliato verrà restituito un messaggio di
+errore sconosciuto. La funzione utilizza una stringa statica che non deve
+essere modificata dal programma e che è utilizzabile solo fino ad una chiamata
+successiva a \func{strerror}; nel caso si usino i thread è
+provvista\footnote{questa funzione è una estensione GNU, non fa parte dello
+ standard POSIX} una versione apposita:
+\begin{prototype}{string.h}
+{char * strerror\_r(int errnum, char * buff, size\_t size)}
+ La funzione è analoga a \func{strerror} ma ritorna il messaggio in un buffer
+ specificato da \var{buff} di lunghezza massima (compreso il terminatore)
+ \var{size}.
+\end{prototype}
+che utilizza un buffer che il singolo thread deve allocare, per evitare i
+problemi connessi alla condivisione del buffer statico. Infine, per completare
+la caratterizzazione dell'errore, si può usare anche la variabile
+globale\footnote{anche questa è una estensione GNU}
+\var{program\_invocation\_short\_name} che riporta il nome del programma
+attualmente in esecuzione.
+
+Una seconda funzione usata per riportare i codici di errore in maniera
+automatizzata sullo standard error (vedi \secref{sec:file_stdfiles}) è
+\func{perror}, il cui prototipo è:
+\begin{prototype}{stdio.h}{void perror (const char *message)}
+ La funzione stampa il messaggio di errore relativo al valore corrente di
+ \var{errno} sullo standard error; preceduto dalla stringa \var{message}.
+\end{prototype}
+i messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati
+in \capref{cha:errors}), e, usando il valore corrente di \var{errno}, si
+riferiscono all'ultimo errore avvenuto. La stringa specificata con
+\var{message} viene stampato prime del messaggio d'errore, seguita dai due
+punti e da uno spazio, il messaggio è terminato con un a capo.
+
+Il messaggio può essere riportato anche usando altre variabili globali
+dichiarate in \file{errno.h}:
+\begin{verbatim}
+ const char *sys_errlist[];
+ int sys_nerr;
+\end{verbatim}
+la prima contiene i puntatori alle stringhe di errore indicizzati da
+\var{errno}; la seconda esprime il valore più alto per un codice di errore,
+l'utilizzo di questa stringa è sostanzialmente equivalente a quello di
+\func{strerror}.
+
+
+
+
+In \nfig\ si sono riportate le sezioni attinenti del codice del programma
+\cmd{errcode}, che può essere usato per stampare i messaggi di errore e le
+costanti usate per identificare i singoli errori; il sorgente completo del
+programma è allegato nel file \file{ErrCode.c} e contiene pure la gestione
+delle opzioni e tutte le definizioni necessarie ad associare il valore
+numerico alla costante simbolica. In particolare si è riportata
+
+\begin{figure}[!htb]
+ \footnotesize
+ \begin{lstlisting}{}
+
+
+
+ \end{lstlisting}
+ \caption{Codice per la stampa del messaggio di errore standard.}
+ \label{fig:proc_fork_code}
+\end{figure}