%% license is included in the section entitled "GNU Free Documentation
%% License".
%%
-\chapter{La gestione del sistema, delle risorse, e degli errori}
+\chapter{La gestione del sistema, del tempo e degli errori}
\label{cha:system}
In questo capitolo tratteremo varie interfacce che attengono agli aspetti più
\subsection{Limiti e parametri di sistema}
\label{sec:sys_limits}
-Quando si devono determinare le le caratteristiche generali del sistema ci si
+Quando si devono determinare le caratteristiche generali del sistema ci si
trova di fronte a diverse possibilità; alcune di queste infatti possono
dipendere dall'architettura dell'hardware (come le dimensioni dei tipi
interi), o dal sistema operativo (come la presenza o meno del gruppo degli
caratteristiche del sistema può variare, per non dover essere costretti a
ricompilare un programma tutte le volte che si cambiano le opzioni con cui è
compilato il kernel, o alcuni dei parametri modificabili a run time, è
-necessario ottenerne il valore attraverso la funzione \func{sysconf}. Il
+necessario ottenerne il valore attraverso la funzione \funcd{sysconf}. Il
prototipo di questa funzione è:
\begin{prototype}{unistd.h}{long sysconf(int name)}
Restituisce il valore del parametro di sistema \param{name}.
rispetto ai limiti generali del sistema; ad esempio parametri come la
lunghezza del nome del file o il numero di link possono variare da filesystem
a filesystem; per questo motivo questi limiti devono essere sempre controllati
-con la funzione \func{pathconf}, il cui prototipo è:
+con la funzione \funcd{pathconf}, il cui prototipo è:
\begin{prototype}{unistd.h}{long pathconf(char *path, int name)}
Restituisce il valore del parametro \param{name} per il file \param{path}.
E si noti come la funzione in questo caso richieda un parametro che specifichi
a quale file si fa riferimento, dato che il valore del limite cercato può
variare a seconda del filesystem. Una seconda versione della funzione,
-\func{fpathconf}, opera su un file descriptor invece che su un pathname. Il
+\funcd{fpathconf}, opera su un file descriptor invece che su un pathname. Il
suo prototipo è:
\begin{prototype}{unistd.h}{long fpathconf(int fd, int name)}
Restituisce il valore del parametro \param{name} per il file \param{fd}.
\label{sec:sys_uname}
Un'altra funzione che si può utilizzare per raccogliere informazioni sia
-riguardo al sistema che al computer su cui esso sta girando è \func{uname}; il
-suo prototipo è:
+riguardo al sistema che al computer su cui esso sta girando è \funcd{uname};
+il suo prototipo è:
\begin{prototype}{sys/utsname.h}{int uname(struct utsname *info)}
Restituisce informazioni sul sistema nella struttura \param{info}.
\label{sec:sys_sysctl}
La funzione che permette la lettura ed l'impostazione dei parametri del
-sistema è \func{sysctl}; è una funzione derivata da BSD4.4, ma
+sistema è \funcd{sysctl}; è una funzione derivata da BSD4.4, ma
l'implementazione è specifica di Linux; il suo prototipo è:
\begin{functions}
\headdecl{unistd.h}
\end{functions}
I parametri a cui la funzione permettere di accedere sono organizzati in
-maniera gerarchica all'interno un albero;\footnote{si tenga presente che
+maniera gerarchica all'interno di un albero;\footnote{si tenga presente che
includendo solo \file{unistd.h}, saranno definiti solo i parametri generici;
dato che ce ne sono molti specifici dell'implementazione, nel caso di Linux
occorrerà includere anche i file \file{linux/unistd.h} e
attraverso l'array \param{name}, di lunghezza \param{nlen}, che contiene la
sequenza dei vari nodi da attraversare. Ogni parametro ha un valore in un
formato specifico che può essere un intero, una stringa o anche una struttura
-complessa, per questo motivo il valori vengono passati come puntatori
+complessa, per questo motivo i valori vengono passati come puntatori
\ctyp{void}.
L'indirizzo a cui il valore corrente del parametro deve essere letto è
all'altra; per questo è sempre il caso di evitare l'uso di \func{sysctl}
quando esistono modalità alternative per ottenere le stesse informazioni.
Alcuni esempi di parametri ottenibili sono:
-\begin{itemize*}
+\begin{itemize}
\item il nome di dominio
\item i parametri del meccanismo di \textit{paging}.
\item il filesystem montato come radice
\item la data di compilazione del kernel
\item i parametri dello stack TCP
\item il numero massimo di file aperti
-\end{itemize*}
+\end{itemize}
Come accennato in Linux si ha una modalità alternativa per accedere alle
stesse informazioni di \func{sysctl} attraverso l'uso del filesystem
occorre prima rendere disponibile al sistema il filesystem su cui essi sono
memorizzati; l'operazione di attivazione del filesystem è chiamata
\textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica
- di Linux e non è portabile.} si usa la funzione \func{mount} il cui prototipo
-è:
+ di Linux e non è portabile.} si usa la funzione \funcd{mount} il cui
+prototipo è:
\begin{prototype}{sys/mount.h}
{mount(const char *source, const char *target, const char *filesystemtype,
unsigned long mountflags, const void *data)}
viene ignorato.
Una volta che non si voglia più utilizzare un certo filesystem è possibile
-\textsl{smontarlo} usando la funzione \func{umount}, il cui prototipo è:
+\textsl{smontarlo} usando la funzione \funcd{umount}, il cui prototipo è:
\begin{prototype}{sys/mount.h}{umount(const char *target)}
Smonta il filesystem montato sulla directory \param{target}.
processo o il mount point di un altro filesystem; in questo caso l'errore
restituito è \errcode{EBUSY}.
-Linux provvede inoltre una seconda funzione, \func{umount2}, che in alcuni
+Linux provvede inoltre una seconda funzione, \funcd{umount2}, che in alcuni
casi permette di forzare lo smontaggio di un filesystem, anche quando questo
risulti occupato; il suo prototipo è:
\begin{prototype}{sys/mount.h}{umount2(const char *target, int flags)}
Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
ma con una struttura diversa.} utili per ottenere in maniera diretta
informazioni riguardo al filesystem su cui si trova un certo file, sono
-\func{statfs} e \func{fstatfs}, i cui prototipi sono:
+\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
\begin{functions}
\headdecl{sys/vfs.h}
\funcdecl{int statfs(const char *path, struct statfs *buf)}
\cmd{man 5 passwd} e \cmd{man 5 group}).
Per leggere le informazioni relative ad un utente si possono usare due
-funzioni, \func{getpwuid} e \func{getpwnam}, i cui prototipi sono:
+funzioni, \funcd{getpwuid} e \funcd{getpwnam}, i cui prototipi sono:
\begin{functions}
\headdecl{pwd.h}
\headdecl{sys/types.h}
Restituiscono le informazioni relative all'utente specificato.
\bodydesc{Le funzioni ritornano il puntatore alla struttura contenente le
- informazioni in caso di successo e \val{null} nel caso non sia stato
+ informazioni in caso di successo e \val{NULL} nel caso non sia stato
trovato nessun utente corrispondente a quanto specificato.}
\end{functions}
un massimo di \param{buflen} byte, sarà utilizzata per contenere le stringhe
puntate dai campi di \param{password}. Infine all'indirizzo puntato da
\param{result} viene restituito il puntatore ai dati ottenuti, cioè
-\param{buffer} nel caso l'utente esista, o \val{null} altrimenti. Qualora i
+\param{buffer} nel caso l'utente esista, o \val{NULL} altrimenti. Qualora i
dati non possano essere contenuti nei byte specificati da \param{buflen}, la
funzione fallirà restituendo \errcode{ERANGE} (e \param{result} sarà comunque
-impostato a \val{null}).
+impostato a \val{NULL}).
-Del tutto analoghe alle precedenti sono le funzioni \func{getgrnam} e
-\func{getgrgid} (e le relative analoghe rientranti con la stessa estensione
+Del tutto analoghe alle precedenti sono le funzioni \funcd{getgrnam} e
+\funcd{getgrgid} (e le relative analoghe rientranti con la stessa estensione
\code{\_r}) che permettono di leggere le informazioni relative ai gruppi, i
loro prototipi sono:
\begin{functions}
solo che in questo caso la struttura del database di accounting è molto più
complessa, dato che contiene diversi tipi di informazione.
-Le prime tre funzioni, \func{setutent}, \func{endutent} e \func{utmpname}
+Le prime tre funzioni, \funcd{setutent}, \funcd{endutent} e \funcd{utmpname}
servono rispettivamente a aprire e a chiudere il file che contiene il
database, e a specificare su quale file esso viene mantenuto. I loro prototipi
sono:
precedenza.
Una volta aperto il file si può eseguire una scansione leggendo o scrivendo
-una voce con le funzioni \func{getutent}, \func{getutid}, \func{getutline} e
-\func{pututline}, i cui prototipi sono:
+una voce con le funzioni \funcd{getutent}, \funcd{getutid}, \funcd{getutline}
+e \funcd{pututline}, i cui prototipi sono:
\begin{functions}
\headdecl{utmp.h}
**result)} viene usato per restituire il puntatore allo stesso buffer.
Infine le \acr{glibc} forniscono come estensione per la scrittura delle voci
-in \file{wmtp} altre due funzioni, \func{updwtmp} e \func{logwtmp}, i cui
+in \file{wmtp} altre due funzioni, \funcd{updwtmp} e \funcd{logwtmp}, i cui
prototipi sono:
\begin{functions}
\headdecl{utmp.h}
\label{fig:sys_rusage_struct}
\end{figure}
-La struttura è ripresa da BSD 4.3, ma attualmente (con i kernel della serie
-2.4.x) i soli campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime},
-\var{ru\_minflt}, \var{ru\_majflt}, e \var{ru\_nswap}. I primi due indicano
-rispettivamente il tempo impiegato dal processo nell'eseguire le istruzioni in
-user space, e quello impiegato dal kernel nelle system call eseguite per conto
-del processo.
+La definizione della struttura in \figref{fig:sys_rusage_struct} è ripresa da
+BSD 4.3, ma attualmente (con i kernel della serie 2.4.x) i soli campi che sono
+mantenuti sono: \var{ru\_utime}, \var{ru\_stime}, \var{ru\_minflt},
+\var{ru\_majflt}, e \var{ru\_nswap}. I primi due indicano rispettivamente il
+tempo impiegato dal processo nell'eseguire le istruzioni in user space, e
+quello impiegato dal kernel nelle system call eseguite per conto del processo.
Gli altri tre campi servono a quantificare l'uso della memoria
virtuale\index{memoria virtuale} e corrispondono rispettivamente al numero di
ed al numero di volte che il processo è stato completamente tolto dalla
memoria per essere inserito nello swap.
-In genere includere esplicitamente \file{<sys/time.h>} non è più necessario,
-ma aumenta la portabilità, e serve comunque quando, come nella maggior parte
-dei casi, si debba accedere ai campi di \struct{rusage} relativi ai tempi di
-utilizzo del processore, che sono definiti come strutture \struct{timeval}.
-
+In genere includere esplicitamente \file{<sys/time.h>} non è più strettamente
+necessario, ma aumenta la portabilità, e serve comunque quando, come nella
+maggior parte dei casi, si debba accedere ai campi di \struct{rusage} relativi
+ai tempi di utilizzo del processore, che sono definiti come strutture
+\struct{timeval}.
-Questa è la stessa struttura utilizzata da \func{wait4} per ricavare la
-quantità di risorse impiegato dal processo di cui si è letto lo stato di
-terminazione, ma essa può anche essere letta direttamente utilizzando la
-funzione \func{getrusage}, il cui prototipo è:
+Questa è la stessa struttura utilizzata da \func{wait4} (si ricordi quando
+visto in \secref{sec:proc_wait4}) per ricavare la quantità di risorse
+impiegate dal processo di cui si è letto lo stato di terminazione, ma essa può
+anche essere letta direttamente utilizzando la funzione \funcd{getrusage}, il
+cui prototipo è:
\begin{functions}
\headdecl{sys/time.h}
\headdecl{sys/resource.h}
può modificarne il valore. Il valore di questi limiti è mantenuto in una
struttura \struct{rlimit}, la cui definizione è riportata in
\figref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a limite
-corrente e massimo.
+corrente e limite massimo.
\begin{figure}[!htb]
\footnotesize
\end{figure}
In genere il superamento di un limite comporta o l'emissione di un segnale o
-il fallimento della system call che lo ha provocato; per far leggere o
-impostare i limiti di utilizzo delle risorse da parte di un processo le
-\acr{glibc} prevedono due funzioni, \func{getrlimit} e \func{setrlimit}, i cui
+il fallimento della system call che lo ha provocato; per permettere di leggere
+e di impostare i limiti di utilizzo delle risorse da parte di un processo
+Linux prevede due funzioni, \funcd{getrlimit} e \funcd{setrlimit}, i cui
prototipi sono:
\begin{functions}
\headdecl{sys/time.h}
ed \errval{EFAULT}.}
\end{functions}
-Entrambe le funzioni permettono di specificare su quale risorsa si vuole
-operare attraverso \param{resource}, i cui possibili valori sono elencati in
-\secref{tab:sys_rlimit_values}, e utilizzano una struttura \struct{rlimit} per
-specificarne i valori.
+Entrambe le funzioni permettono di specificare, attraverso l'argomento
+\param{resource}, su quale risorsa si vuole operare: i possibili valori di
+questo argomento sono elencati in \secref{tab:sys_rlimit_values}. L'acceso
+(rispettivamente in lettura e scrittura) ai valori effettivi dei limiti viene
+poi effettuato attraverso la struttura \struct{rlimit} puntata da
+\param{rlim}.
\begin{table}[htb]
\footnotesize
aprire. L'apertura di un ulteriore file fallirà
con un errore \errcode{EMFILE}.\\
\const{RLIMIT\_MEMLOCK}& L'ammontare massimo di memoria che può essere
- bloccata (vedi \secref{sec:proc_mem_lock}).\\
+ bloccata in RAM senza
+ paginazione\index{paginazione} (vedi
+ \secref{sec:proc_mem_lock}).\\
\const{RLIMIT\_AS} & La dimensione massima di tutta la memoria che il
processo può ottenere. Se il processo tenta di
allocarne di più funzioni come \func{brk},
\end{table}
\footnotetext{Impostare questo limite a zero è la maniera più semplice per
- evitare la creazione di \file{core} file.}
+ evitare la creazione di \file{core} file (al proposito si veda
+ \secref{sec:sig_prog_error}).}
-È inoltre definita la costante \const{RLIM\_INFINITY} che permette di
-sbloccare l'uso di una risorsa, ma solo un processo con i privilegi di
-amministratore può innalzare un limite al di sopra del valore corrente del
-limite massimo. Si tenga conto infine che tutti i limiti vengono ereditati dal
-processo padre attraverso una \func{fork} (vedi \secref{sec:proc_fork}) e
-mantenuti attraverso una \func{exec} (vedi \secref{sec:proc_exec}).
+Nello specificare un limite, oltre a dei valori specifici, si può anche usare
+la costante \const{RLIM\_INFINITY} che permette di sbloccare l'uso di una
+risorsa; ma si ricordi che solo un processo con i privilegi di amministratore
+può innalzare un limite al di sopra del valore corrente del limite massimo. Si
+tenga conto infine che tutti i limiti vengono ereditati dal processo padre
+attraverso una \func{fork} (vedi \secref{sec:proc_fork}) e mantenuti per gli
+altri programmi eseguiti attraverso una \func{exec} (vedi
+\secref{sec:proc_exec}).
\subsection{Le risorse di memoria e processore}
meccanismo della memoria virtuale\index{memoria virtuale} attraverso la
divisione della memoria fisica in pagine.
-In genere questo è del tutto trasparente al singolo processo, ma in certi
+In genere tutto ciò è del tutto trasparente al singolo processo, ma in certi
casi, come per l'I/O mappato in memoria (vedi \secref{sec:file_memory_map})
che usa lo stesso meccanismo per accedere ai file, è necessario conoscere le
dimensioni delle pagine usate dal kernel. Lo stesso vale quando si vuole
-gestire in maniera ottimale l'interazione della memoria allocata con il
-meccanismo della paginazione.
+gestire in maniera ottimale l'interazione della memoria che si sta allocando
+con il meccanismo della paginazione\index{paginazione}.
Di solito la dimensione delle pagine di memoria è fissata dall'architettura
-hardware, per cui in genere la dimensione delle pagine di memoria era una
-costante definita in fase di compilazione, ma oggi alcune architetture (ad
-esempio su Sun Sparc) permettono di variare questa dimensione, e non volendo
-dover fornire binari diversi per ogni possibile modello, è necessario poter
-utilizzare una funzione.
-
-In genere questa dimensione può essere ottenuta attraverso una chiamata a
-\func{sysconf} come \code{sysconf(\_SC\_PAGESIZE)}, ma in BSD 4.2 è stata
-introdotta una apposita funzione, \func{getpagesize}, che restituisce la
+hardware, per cui il suo valore di norma veniva mantenuto in una costante che
+bastava utilizzare in fase di compilazione, ma oggi, con la presenza di alcune
+architetture (ad esempio Sun Sparc) che permettono di variare questa
+dimensione, per non dover ricompilare i programmi per ogni possibile modello e
+scelta di dimensioni, è necessario poter utilizzare una funzione.
+
+Dato che si tratta di una caratteristica generale del sistema, questa
+dimensione può essere ottenuta come tutte le altre attraverso una chiamata a
+\func{sysconf} (nel caso \code{sysconf(\_SC\_PAGESIZE)}, ma in BSD 4.2 è stata
+introdotta una apposita funzione, \funcd{getpagesize}, che restituisce la
dimensione delle pagine di memoria; il suo prototipo è:
\begin{prototype}{unistd.h}{int getpagesize(void)}
Legge le dimensioni delle pagine di memoria.
sempre un valore statico.
Le \acr{glibc} forniscono, come specifica estensione GNU, altre due funzioni,
-\func{get\_phys\_pages} e \func{get\_avphys\_pages} che permettono di ottenere
-informazioni riguardo la memoria; i loro prototipi sono:
+\funcd{get\_phys\_pages} e \funcd{get\_avphys\_pages} che permettono di
+ottenere informazioni riguardo la memoria; i loro prototipi sono:
\begin{functions}
\headdecl{sys/sysinfo.h}
\func{sysconf} utilizzando rispettivamente i parametri
\const{\_SC\_NPROCESSORS\_CONF} e \const{\_SC\_NPROCESSORS\_ONLN}.
-Infine le \acr{glibc} riprendono da BSD la funzione \func{getloadavg} che
+Infine le \acr{glibc} riprendono da BSD la funzione \funcd{getloadavg} che
permette di ottenere il carico di processore della macchina, in questo modo è
possibile prendere decisioni su quando far partire eventuali nuovi processi.
Il suo prototipo è:
dal sistema con una granularità di un secondo) e viene usato per tenere conto
dei tempi di esecuzione dei processi. Per ciascun processo il kernel calcola
tre tempi diversi:
-\begin{description*}
+\begin{description}
\item[\textit{clock time}]: il tempo \textsl{reale} (viene chiamato anche
\textit{wall clock time}) passato dall'avvio del processo. Chiaramente tale
tempo dipende anche dal carico del sistema e da quanti altri processi
delle istruzioni del processo in user space.
\item[\textit{system time}]: il tempo che la CPU ha impiegato nel kernel per
eseguire delle system call per conto del processo.
-\end{description*}
+\end{description}
In genere la somma di \textit{user time} e \textit{system time} indica il
tempo di processore totale in cui il sistema è stato effettivamente impegnato
operazione di I/O.
La funzione più semplice per leggere il \textit{process time} di un processo è
-\func{clock}, che da una valutazione approssimativa del tempo di CPU
+\funcd{clock}, che da una valutazione approssimativa del tempo di CPU
utilizzato dallo stesso; il suo prototipo è:
\begin{prototype}{time.h}{clock\_t clock(void)}
Legge il valore corrente del tempo di CPU.
Come accennato in \secref{sec:sys_unix_time} il tempo di CPU è la somma di
altri due tempi, l'\textit{user time} ed il \textit{system time} che sono
quelli effettivamente mantenuti dal kernel per ciascun processo. Questi
-possono essere letti attraverso la funzione \func{times}, il cui prototipo è:
+possono essere letti attraverso la funzione \funcd{times}, il cui prototipo è:
\begin{prototype}{sys/times.h}{clock\_t times(struct tms *buf)}
Legge in \param{buf} il valore corrente dei tempi di processore.
verranno considerati nel calcolo di questi tempi.
-
\subsection{Le funzioni per il \textit{calendar time}}
\label{sec:sys_time_base}
Come anticipato in \secref{sec:sys_unix_time} il \textit{calendar time} è
mantenuto dal kernel in una variabile di tipo \type{time\_t}, che usualmente
-corrisponde ad un tipo nativo (in Linux è un intero a 32 bit). Il valore
-corrente del \textit{calendar time}, che indicheremo come \textsl{tempo di
- sistema}, può essere ottenuto con la funzione \func{time} che lo restituisce
-in nel suddetto formato; il suo prototipo è:
+corrisponde ad un tipo elementare (in Linux è definito come \ctyp{long int},
+che di norma corrisponde a 32 bit). Il valore corrente del \textit{calendar
+ time}, che indicheremo come \textsl{tempo di sistema}, può essere ottenuto
+con la funzione \funcd{time} che lo restituisce nel suddetto formato; il suo
+prototipo è:
\begin{prototype}{time.h}{time\_t time(time\_t *t)}
Legge il valore corrente del \textit{calendar time}.
\noindent dove \param{t}, se non nullo, deve essere l'indirizzo di una
variabile su cui duplicare il valore di ritorno.
-Analoga a \func{time} è la funzione \func{stime} che serve per effettuare
+Analoga a \func{time} è la funzione \funcd{stime} che serve per effettuare
l'operazione inversa, e cioè per impostare il tempo di sistema qualora questo
sia necessario; il suo prototipo è:
\begin{prototype}{time.h}{int stime(time\_t *t)}
Data la scarsa precisione nell'uso di \type{time\_t} (che ha una risoluzione
massima di un secondo) quando si devono effettuare operazioni sui tempi di
norma l'uso delle funzioni precedenti è sconsigliato, ed esse sono di solito
-sostituite da \func{gettimeofday} e \func{settimeofday},\footnote{le due
+sostituite da \funcd{gettimeofday} e \funcd{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.} i cui prototipi
\label{fig:sys_timeval_struct}
\end{figure}
-Come nel caso di \func{stime} anche \func{settimeofday} (e qualunque funzione
-vada a modificare l'orologio di sistema, come quelle che tratteremo in
-seguito) può essere utilizzata solo da un processo coi privilegi di
-amministratore. Il secondo parametro di entrambe le funzioni è una struttura
+Come nel caso di \func{stime} anche \func{settimeofday} (la cosa continua a
+valere per qualunque funzione che vada a modificare l'orologio di sistema,
+quindi anche per quelle che tratteremo in seguito) può essere utilizzata solo
+da un processo coi privilegi di amministratore.
+
+Il secondo parametro di entrambe le funzioni è una struttura
\struct{timezone}, che storicamente veniva utilizzata per specificare appunto
la \textit{time zone}, cioè l'insieme del fuso orario e delle convenzioni per
l'ora legale che permettevano il passaggio dal tempo universale all'ora
-locale. Questo parametro è obsoleto e in Linux non è mai stato utilizzato e
-non è supportato né dalle vecchie \textsl{libc5}, né dalle \textsl{glibc}:
-pertanto deve essere sempre impostato a \val{null}.
+locale. Questo parametro oggi è obsoleto ed in Linux non è mai stato
+utilizzato; esso non è supportato né dalle vecchie \textsl{libc5}, né dalle
+\textsl{glibc}: pertanto quando si chiama questa funzione deve essere sempre
+impostato a \val{NULL}.
Modificare l'orologio di sistema con queste funzioni è comunque problematico,
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
+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 impostare l'ora è
-quella di usare la funzione \func{adjtime}, il cui prototipo è:
+saltato. Oppure se si porta indietro l'orologio si possono eseguire due volte
+delle operazioni previste nell'intervallo di tempo che viene ripetuto.
+
+Per questo motivo la modalità più corretta per impostare l'ora è quella di
+usare la funzione \funcd{adjtime}, il cui prototipo è:
\begin{prototype}{sys/time.h}
{int adjtime(const struct timeval *delta, struct timeval *olddelta)}
usato, se non nullo, per ricevere il valore dell'ultimo aggiustamento
effettuato.
-Linux poi prevede un'altra funzione, \func{adjtimex}, che consente un
-aggiustamento molto più dettagliato, permettendo ad esempio anche di
-modificare anche la velocità dell'orologio di sistema. Il suo prototipo è:
-\begin{prototype}{sys/timex.h}
-{int adjtimex(struct timex *buf)}
-
- Aggiusta del valore \param{delta} l'orologio di sistema.
-
- \bodydesc{La funzione restituisce lo stato dell'orologio (un valore $>0$) in
- caso di successo e -1 in caso di errore, nel qual caso \var{errno}
- assumerà i valori \errval{EFAULT}, \errval{EINVAL} ed \errval{EPERM}.}
-\end{prototype}
-
-La funzione richiede una struttura di tipo \struct{timex}, la cui definizione,
-così come effettuata in \file{sys/timex.h}, è riportata in
-\figref{fig:sys_timex_struct}. L'azione della funzione dipende dal valore del
-campo \var{mode}, che specifica quale parametro dell'orologio di sistema,
-specificato in un opportuno campo di \struct{timex}, deve essere impostato. Un
-valore nullo serve per leggere i parametri correnti; i valori diversi da zero
-devono essere specificati come OR binario delle costanti riportate in
-\secref{tab:sys_timex_mode}.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:sys_timex_struct}
\end{figure}
+Linux poi prevede un'altra funzione, che consente un aggiustamento molto più
+dettagliato del tempo, permettendo ad esempio anche di modificare anche la
+velocità dell'orologio di sistema. La funzione è \funcd{adjtimex} ed il suo
+prototipo è:
+\begin{prototype}{sys/timex.h}
+{int adjtimex(struct timex *buf)}
+
+ Aggiusta del valore \param{delta} l'orologio di sistema.
+
+ \bodydesc{La funzione restituisce lo stato dell'orologio (un valore $>0$) in
+ caso di successo e -1 in caso di errore, nel qual caso \var{errno}
+ assumerà i valori \errval{EFAULT}, \errval{EINVAL} ed \errval{EPERM}.}
+\end{prototype}
+
+La funzione richiede una struttura di tipo \struct{timex}, la cui definizione,
+così come effettuata in \file{sys/timex.h}, è riportata in
+\figref{fig:sys_timex_struct}. L'azione della funzione dipende dal valore del
+campo \var{mode}, che specifica quale parametro dell'orologio di sistema,
+specificato in un opportuno campo di \struct{timex}, deve essere impostato. Un
+valore nullo serve per leggere i parametri correnti; i valori diversi da zero
+devono essere specificati come OR binario delle costanti riportate in
+\secref{tab:sys_timex_mode}.
+
La funzione utilizza il meccanismo di David L. Mills, descritto nell'RFC~1305,
che è alla base del protocollo NTP; la funzione è specifica di Linux e non
deve essere usata se la portabilità è un requisito, le \acr{glibc} provvedono
\begin{table}[htb]
\footnotesize
\centering
- \begin{tabular}[c]{|l|c| p{10cm}|}
+ \begin{tabular}[c]{|l|c| p{9cm}|}
\hline
\textbf{Nome} & \textbf{Valore} & \textbf{Significato}\\
\hline
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
long int tm_gmtoff; /* Seconds east of UTC. */
- cost char *tm_zone; /* Timezone abbreviation. */
+ const char *tm_zone; /* Timezone abbreviation. */
};
\end{lstlisting}
\end{minipage}
Converte il \textit{broken-down time} in formato \type{time\_t}.
\bodydesc{Tutte le funzioni restituiscono un puntatore al risultato in caso
- di successo e \val{null} in caso di errore, tranne che \func{mktime} che
+ di successo e \val{NULL} in caso di errore, tranne che \func{mktime} che
restituisce direttamente il valore o -1 in caso di errore.}
\end{functions}
Benché la funzione \func{asctime} fornisca la modalità più immediata per
stampare un tempo o una data, la flessibilità non fa parte delle sue
caratteristiche; quando si vuole poter stampare solo una parte (l'ora, o il
-gionrno) di un tempo si può ricorrere alla più sofisticata \func{strftime}, il
-cui prototipo è:
+giorno) di un tempo si può ricorrere alla più sofisticata \funcd{strftime},
+il cui prototipo è:
\begin{prototype}{time.h}
{size\_t strftime(char *s, size\_t max, const char *format,
const struct tm *tm)}
\param{format}.
\bodydesc{La funzione ritorna il numero di caratteri stampati in \param{s},
- altrimenti restuisce 0.}
+ altrimenti restituisce 0.}
\end{prototype}
La funzione converte opportunamente il tempo \param{tm} in una stringa di
le \acr{glibc} provvedono tutte le estensioni introdotte da POSIX.2 per il
comando \cmd{date}, i valori introdotti da SVID3 e ulteriori estensioni GNU;
l'elenco completo dei possibili valori è riportato nella pagina di manuale
- della funzione.} dei possibili valori che esso può assumere sono ripotati in
+ della funzione.} dei possibili valori che esso può assumere sono riportati in
\tabref{tab:sys_strftime_format}. La funzione tiene conto anche della presenza
di una localizzazione per stampare in maniera adeguata i vari nomi.
variabile è in genere definita come \direct{volatile} dato che può essere
cambiata in modo asincrono da un segnale (si veda \secref{sec:sig_sigchld} per
un esempio, ricordando quanto trattato in \secref{sec:proc_race_cond}), ma
-dato che un manipolatore di segnale scritto bene salva e ripristina il valore
+dato che un gestore di segnale scritto bene salva e ripristina il valore
della variabile, di questo non è necessario preoccuparsi nella programmazione
normale.
\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 è:
+\funcd{strerror}, il cui prototipo è:
\begin{prototype}{string.h}{char *strerror(int errnum)}
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 \val{null} in caso di errore, nel qual caso
+ errore in caso di successo e \val{NULL} in caso di errore, nel qual caso
\var{errno} assumerà il valore \errval{EINVAL} se si è specificato un
numero di errore non valido.}
\end{prototype}
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 è:
+\funcd{perror}, il cui prototipo è:
\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 \param{message}.
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 è:
+\funcd{error}, il cui prototipo è:
\begin{prototype}{stdio.h}
{void error(int status, int errnum, const char *format, ...)}
quanti errori ci sono stati.
Un'altra funzione per la stampa degli errori, ancora più sofisticata, è
-\func{error\_at\_line}, che prende due argomenti aggiuntivi per indicare linea
-e file su cui è avvenuto l'errore; il suo prototipo è:
+\funcd{error\_at\_line}, che prende due argomenti aggiuntivi per indicare
+linea e file su cui è avvenuto l'errore; il suo prototipo è:
\begin{prototype}{stdio.h}
{void error\_at\_line(int status, int errnum, const char *fname,
unsigned int lineno, const char *format, ...)}