\subsection{Prototipi e puntatori}
\label{sec:intro_function}
-\subsection{La misura del tempo in unix}
-\label{sec:intro_unix_time}
-
-Storicamente i sistemi unix-like hanno sempre mantenuto due distinti valori
-per i tempi all'interno del sistema, essi sono rispettivamente chiamati
-\textit{calendar time} e \textit{process time}, secondo le definizioni:
-\begin{itemize}
-\item \textit{calendar time}: è il numero di secondi dalla mezzanotte del
- primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene
- usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the
- Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time)
- dato che l'UTC corrisponde all'ora locale di Greenwich. È il tempo su cui
- viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per
- indicare le date di modifica dei file o quelle di avvio dei processi. Per
- memorizzare questo tempo è stato riservato il tipo primitivo \func{time\_t}.
-\item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato
- in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate
- dal timer di sistema, e che per Linux avvengono ogni centesimo di
- secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni
- millesimo di secondo}. Il dato primitivo usato per questo tempo è
- \func{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di
- operazione del timer, e corrisponde dunque al numero di tick al secondo. Lo
- standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK});
- questo valore può comunque essere ottenuto con \func{sysconf} (vedi
- \secref{sec:intro_limits}).
-\end{itemize}
-
-In genere si usa il \textit{calendar time} per tenere le date dei file e le
-informazioni analoghe che riguardano i tempi di ``orologio'', usati ad esempio
-per i demoni che compiono lavori amministrativi ad ore definite, come
-\cmd{cron}. Di solito questo vene convertito automaticamente dal valore in UTC
-al tempo locale, utilizzando le opportune informazioni di localizzazione
-(specificate in \file{/etc/timezone}). E da tenere presente che questo tempo è
-mantenuto dal sistema e non corrisponde all'orologio hardware del calcolatore.
-
-Il \textit{process time} di solito si esprime in secondi e viene usato appunto
-per tenere conto dei tempi di esecuzione dei processi. Per ciascun processo il
-kernel tiene tre di questi tempi:
-\begin{itemize*}
-\item \textit{clock time}
-\item \textit{user time}
-\item \textit{system time}
-\end{itemize*}
-il primo è il tempo ``reale'' (viene anche chiamato \textit{wall clock time})
-dall'avvio del processo, e misura il tempo trascorso fino alla sua
-conclusione; chiaramente un tale tempo dipende anche dal carico del sistema e
-da quanti altri processi stavano girando nello stesso periodo. Il secondo
-tempo è quello che la CPU ha speso nell'esecuzione delle istruzioni del
-processo in user space. Il terzo è il tempo impiegato dal kernel per eseguire
-delle system call per conto del processo medesimo (tipo quello usato per
-eseguire una \func{write} su un file). In genere la somma di user e system
-time viene chiamato \textit{CPU time}.
\subsection{Lo standard ANSI C}
\label{sec:intro_ansiC}
+Lo standard ANSI C è stato definito nel 1989 dall'\textit{American National
+ Standard Institute}, come standard del linguaggio C ed è stato
+successivamente adottatto dalla \textit{International Standard Organisation}
+come standard internazionale con la sigla ISO/IEC 9899:1990.
+
+Scopo dello standard è quello di garantire la portabilità dei programmi C fra
+sistemi operativi diversi, ma oltre alla sintassi e alla semantica del
+linguaggio C (operatori, parole chiave, tipi di dati) lo standard prevede
+anche una libreria di funzioni standard che devono poter essere implementate
+su qualunque sistema operativo.
+
+Linux, come molti unix moderni, provvede la compatibilità con questo standard,
+fornendo le funzioni di libreria da esso previste; queste sono dichiarate in
+quindici header files, uno per ciascuna delle quindici aree in cui è stata
+suddivisa la libreria. In \ntab\ si sono riportati questi header, insieme a
+quelli definiti negli altri standard descritti nelle sezioni successive.
+
\subsection{Lo standard POSIX}
\label{sec:intro_posix}
+In realtà POSIX è una famiglia di standard diversi, il nome, suggerito da
+Richard Stallman, sta per \textit{Portable Operating System Interface}, ma la
+X finale denuncia la sua stretta relazione con i sistemi unix. Esso nasce dal
+lavoro dell'IEEE (\textit{Institute of Electrical and Electronics Engeneers})
+che ne ha prodotto un primo una prima versione, nota come IEEE 1003.1-1988,
+mirante a standardizzare l'interfaccia con il sistema operativo.
+
+Ma gli standard POSIX non si limitano alla standardizzazione delle funzioni di
+libreria, e in seguito sono stati prodotti anche altri standard per la shell e
+le utilities di sistema (1003.2), per le estensioni realtime e per i thread
+(1003.1d e 1003.1c) e molti altri.
+
+Benchè lo standard POSIX sia basato sui sistemi unix esso definisce comunque
+una interfaccia e non fa riferimento ad una specifica implementazione (per cui
+esiste ad esempio anche una implementazione di questo standard pure sotto
+Windows NT). Lo standard si è evoluto nel tempo ed una nuova versione (quella
+che viene normalmente denominata POSIX.1) è stata rilasciata come standard
+internazionale con la sigla ISO/IEC 9945-1:1990.
+
+
+\subsection{Lo standard X/Open -- XPG3}
+\label{sec:intro_xopen}
+
+Il consorzio X/Open nasce come consorzio di venditori di sistemi unix, che nel
+1989 produsse una voluminosa guida chiamata \textit{X/Open Portability Guide,
+ Issue 3} al cui interno definiva una ulteriore standardizzazione
+dell'interfaccia ad un sistema unix.
+
+Questo standard, detto anche XPG3 dal nome della suddetta guida, è sempre
+basato sullo standard POSIX.1, ma prevede una serie di funzionalità
+aggiuntive.
+
+Il consorzio
+
+
\subsection{Valori e limiti del sistema}
\label{sec:intro_limits}
\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{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 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; 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}.
-
-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\ è riportata la sezione attinente 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 la sezione che
-converte la stringa passata come parametro in un intero (\texttt{\small
- 1--2}), controllando con i valori di ritorno di \func{strtol} che la
-conversione sia avvenuta correttamente (\texttt{\small 4--10}), e poi stampa,
-a seconda dell'opzione scelta il messaggio di errore (\texttt{\small 11--14})
-o la macro (\texttt{\small 15--17}) associate a quel codice.
-
-\begin{figure}[!htb]
- \footnotesize
- \begin{lstlisting}{}
- /* convert string to number */
- err = strtol(argv[optind], NULL, 10);
- /* testing error condition on conversion */
- if (err==LONG_MIN) {
- perror("Underflow on error code");
- return 1;
- } else if (err==LONG_MIN) {
- perror("Overflow on error code");
- return 1;
- }
- /* conversion is fine */
- if (message) {
- printf("Error message for %d is %s\n", err, strerror(err));
- }
- if (label) {
- printf("Error label for %d is %s\n", err, err_code[err]);
- }
- \end{lstlisting}
- \caption{Codice per la stampa del messaggio di errore standard.}
- \label{fig:intro_err_mess}
-\end{figure}
-