Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due
-file standard \file{/etc/fstab} e \file{/etc/mtab}, che convenzionalmente sono
-usati in quasi tutti i sistemi unix-like per mantenere rispettivamente le
-informazioni riguardo ai filesystem da montare e a quelli correntemente
-montati. Le funzioni servono a leggere il contenuto di questi file in
-opportune strutture \var{struct fstab} e \var{struct mntent}, e, per
-\file{/etc/mtab} per inserire e rimuovere le voci presenti nel file.
-
-In generale si dovrebbero usare queste funzioni (in particolar modo quelle
+file \file{/etc/fstab} ed \file{/etc/mtab}, che convenzionalmente sono usati in
+quasi tutti i sistemi unix-like per mantenere rispettivamente le informazioni
+riguardo ai filesystem da montare e a quelli correntemente montati. Le
+funzioni servono a leggere il contenuto di questi file in opportune strutture
+\var{struct fstab} e \var{struct mntent}, e, per \file{/etc/mtab} per inserire
+e rimuovere le voci presenti nel file.
+
+In generale si dovrebbero usare queste funzioni (in particolare quelle
relative a \file{/etc/mtab}), quando si debba scrivere un programma che
effettua il montaggio di un filesystem; in realtà in questi casi è molto più
semplice invocare direttamente il programma \cmd{mount}, per cui ne
sostituite da \func{gettimeofday} e \func{settimeofday},\footnote{le due
funzioni \func{time} e \func{stime} sono più antiche e derivano da SVr4,
\func{gettimeofday} e \func{settimeofday} sono state introdotte da BSD, ed
- in BSD4.3 sono indicate come sostitute delle precedenti.} mentre i cui
-prototipi sono:
+ in BSD4.3 sono indicate come sostitute delle precedenti.} i cui prototipi
+sono:
\begin{functions}
\headdecl{sys/time.h}
\headdecl{time.h}
Queste funzioni utilizzano una struttura di tipo \var{timeval}, la cui
definizione, insieme a quella della analoga \var{timespec}, è riportata in
-\figref{fig:sys_timeval_struct}. Le \acr{glibc} infatti provvedono queste due
+\figref{fig:sys_timeval_struct}. Le \acr{glibc} infatti forniscono queste due
rappresentazioni alternative del \textit{calendar time} che rispetto a
\type{time\_t} consentono rispettivamente precisioni del microsecondo e del
nanosecondo.\footnote{la precisione è solo teorica, la precisione reale della
pertanto deve essere sempre settato a \macro{NULL}.
Modificare l'orologio di sistema con queste funzioni è comunque problematico,
-in quanto esse effettuano un cambiamento immediato. Ad esempio se si porta
-avanti l'orologio si possono perdere delle esecuzioni di \cmd{cron}
-programmate nell'intervallo che si è saltato. Per questo motivo la modalità
-più corretta per settare l'ora è quella di usare la funzione \func{adjtime},
-il cui prototipo è:
+in quanto esse effettuano un cambiamento immediato. Questo può creare dei
+buchi o delle ripetizioni nello scorrere dell'orologio di sistema, con
+conseguenze indesiderate; ad esempio se si porta avanti l'orologio si possono
+perdere delle esecuzioni di \cmd{cron} programmate nell'intervallo che si è
+saltato. Per questo motivo la modalità più corretta per settare l'ora è quella
+di usare la funzione \func{adjtime}, il cui prototipo è:
\begin{prototype}{sys/time.h}
{int adjtime(const struct timeval *delta, struct timeval *olddelta)}
\end{prototype}
Questa funzione permette di avere un aggiustamento graduale del tempo di
-sistema in modo che esso sia sempre monotonicamente crescente. Il valore di
-\param{delta} esprime il valore di cui si vuole spostare l'orologio; se è
+sistema in modo che esso sia sempre crescente in maniera monotona. Il valore
+di \param{delta} esprime il valore di cui si vuole spostare l'orologio; se è
positivo l'orologio sarà accelerato per un certo tempo in modo da guadagnare
il tempo richiesto, altrimenti sarà rallentato. Il secondo parametro viene
usato, se non nullo, per ricevere il valore dell'ultimo aggiustamento
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)}
- Ritorna una stringa (statica) che descrive l'errore il cui codice è passato
- come parametro.
+ Restituisce una stringa con il messaggio di errore relativo ad
+ \param{errnum}.
+
+ \bodydesc{La funzione ritorna il puntatore alla stringa col messaggio di
+ errore in caso di successo e \macro{NULL} in caso di errore, nel qual caso
+ \var{errno} sarà settata a \macro{EINVAL} se si è specificato un numero di
+ errore non valido.}
\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:
+errore sconosciuto, e la funzione restituirà come errore \macro{EINVAL}. La
+funzione tiene conto del valore della variabile di ambiente
+\macro{LC\_MESSAGES} per usare eventuali traduzioni dei messaggi d'errore
+nella localizzazione presente.
+
+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}; per questo motivo non è rientrante e nel caso si usino i
+thread è provvista\footnote{questa funzione è la versione prevista dalle
+ \acr{glibc}, ed effettivamente definita in \file{string.h}, ne esiste una
+ analoga nello standard SUSv3 (quella riportata dalla man page), che
+ restituisce \code{int} al posto di \code{char *}, e che tronca la stringa
+ restituita a \param{size}.} una versione apposita:
\begin{prototype}{string.h}
-{char *strerror\_r(int errnum, char *buff, size\_t size)}
- Analoga a \func{strerror} ma ritorna il messaggio in un buffer
- specificato da \param{buff} di lunghezza massima (compreso il terminatore)
- \param{size}.
+ {char * strerror\_r(int errnum, char *buf, size\_t size)}
+
+ Analoga a \func{strerror} ma usa il buffer \param{buf} di lunghezza massima
+ (compreso il terminatore) \param{size}.
+
+ \bodydesc{La funzione restitusce il puntatore alla stringa; in caso di
+ errore \var{errno} oltre a \macro{EINVAL} può assumere anche il valore
+ \macro{ERANGE} per indicare che non c'è sufficiente memoria per contenere
+ la stringa di descrizione.}
\end{prototype}
\noindent
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 è un'estensione GNU.}
-\var{program\_invocation\_short\_name} che riporta il nome del programma
-attualmente in esecuzione.
+problemi connessi alla condivisione del buffer statico. La funzione
+restituisce l'indirizzo della stringa usata, che può essere contenuta nel
+buffer specificato da \param{buf}, per una lunghezza non superiore a
+\param{size}, nel qual caso la stringa sarebbe troncata e terminata con
+\macro{NUL}.
+
Una seconda funzione usata per riportare i codici di errore in maniera
automatizzata sullo standard error (vedi \secref{sec:file_std_descr}) è
\func{perror}, il cui prototipo è:
-\begin{prototype}{stdio.h}{void perror (const char *message)}
+\begin{prototype}{stdio.h}{void perror(const char *message)}
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
+
+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
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}{}
\label{fig:sys_err_mess}
\end{figure}
+In \figref{fig:sys_err_mess} è 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.
+
+
+
+\subsection{Alcune estensioni GNU}
+\label{sec:sys_err_GNU}
+
+Le precedenti funzioni sono quelle definite ed usate nei vari standard; le
+\acr{glibc} hanno però introdotto una serie di estensioni ``GNU'' che
+forniscono alcune funzionalità aggiuntive per una gestione degli errori
+semplificata e più efficiente.
+
+La prima estenzione consiste in due variabili, \code{char *
+ program\_invocation\_name} e \code{char * program\_invocation\_short\_name}
+servono per ricavare il nome del programma; queste sono utili quando si deve
+aggiungere il nome del programma (cosa comune quando si ha un programma che
+non viene lanciato da linea di comando e salva gli errori in un file di log)
+al messaggio d'errore. La prima contiene il nome usato per lanciare il
+programma (ed è equivalente ad \code{argv[0]}); la seconda mantiene solo il
+nome del programma (senza eventuali directory in testa).
+
+Uno dei problemi che si hanno con l'uso di \func{perror} è che non c'è
+flessibilità su quello che si può aggiungere al messaggio di errore, che può
+essere solo una stringa. In molte occasioni invece serve poter scrivere dei
+messaggi con maggiore informazione; ad esempio negli standard di
+programmazione GNU si richiede che ogni messaggio di errore sia preceduto dal
+nome del programma, ed in generale si può voler stampare il contenuto di
+qualche variabile; per questo le \acr{glibc} definiscono la funzione
+\func{error}, il cui prototipo è:
+\begin{prototype}{stdio.h}
+{void error(int status, int errnum, const char *format, ...)}
+
+Stampa un messaggio di errore formattato.
+
+\bodydesc{La funzione non restituisce nulla e non riporta errori.}
+\end{prototype}
+
+
+
+
%%% Local Variables: