Messe adjtime e adjtimex
[gapil.git] / system.tex
index fd0284d05b0bb478454b75868ad852c70142c0d9..b617a0c7a15a76af716c1cdbfb0338ac89611afe 100644 (file)
@@ -882,18 +882,18 @@ nome del filesystem stesso.
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
   \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-    struct statfs {
-       long    f_type;     /* tipo di filesystem */
-       long    f_bsize;    /* dimensione ottimale dei blocchi di I/O */
-       long    f_blocks;   /* blocchi totali nel filesystem */
-       long    f_bfree;    /* blocchi liberi nel filesystem */
-       long    f_bavail;   /* blocchi liberi agli utenti normali */
-       long    f_files;    /* inodes totali nel filesystem */
-       long    f_ffree;    /* inodes liberi nel filesystem */
-       fsid_t  f_fsid;     /* filesystem id */
-       long    f_namelen;  /* lunghezza massima dei nomi dei file */
-       long    f_spare[6]; /* riservati per uso futuro */
-    };
+struct statfs {
+   long    f_type;     /* tipo di filesystem */
+   long    f_bsize;    /* dimensione ottimale dei blocchi di I/O */
+   long    f_blocks;   /* blocchi totali nel filesystem */
+   long    f_bfree;    /* blocchi liberi nel filesystem */
+   long    f_bavail;   /* blocchi liberi agli utenti normali */
+   long    f_files;    /* inodes totali nel filesystem */
+   long    f_ffree;    /* inodes liberi nel filesystem */
+   fsid_t  f_fsid;     /* filesystem id */
+   long    f_namelen;  /* lunghezza massima dei nomi dei file */
+   long    f_spare[6]; /* riservati per uso futuro */
+};
 \end{lstlisting}
   \end{minipage}
   \normalsize 
@@ -1455,10 +1455,10 @@ corrente e massimo.
   \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-    struct rlimit {
-         rlim_t    rlim_cur;
-         rlim_t    rlim_max;
-    };
+struct rlimit {
+     rlim_t    rlim_cur;
+     rlim_t    rlim_max;
+};
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
@@ -1617,7 +1617,7 @@ informazioni riguardo la memoria; i loro prototipi sono:
   
   Legge il numero di pagine di memoria disponibili nel sistema. 
   
-  \bodydesc{Le funzioni restituiscono il numero di pagine, }
+  \bodydesc{Le funzioni restituiscono un numero di pagine.}
 \end{functions}
 
 Queste funzioni sono equivalenti all'uso della funzione \func{sysconf}
@@ -1782,12 +1782,12 @@ struttura di tipo \var{tms}, la cui definizione 
   \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-    struct tms {
-           clock_t tms_utime;  /* user time */
-           clock_t tms_stime;  /* system time */
-           clock_t tms_cutime; /* user time of children */
-           clock_t tms_cstime; /* system time of children */
-    };
+struct tms {
+       clock_t tms_utime;  /* user time */
+       clock_t tms_stime;  /* system time */
+       clock_t tms_cutime; /* user time of children */
+       clock_t tms_cstime; /* system time of children */
+};
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
@@ -1812,12 +1812,66 @@ questi ``nipoti'' non potranno essere considerati nel calcolo di questi tempi.
 \subsection{Le funzioni per il \textit{calendar time}}
 \label{sec:sys_time_base}
 
-Normalmente il \textit{calendar time} è mantenuto in una variabile di tipo
-\type{time\_t}, che usualmente corrisponde ad un tipo nativo (in Linux è un
-intero a 32 bit).  Le \acr{glibc} provvedono delle rappresentazioni
-alternative che consentono un suo utilizzo per diversi scopi; in particolare
-quando necessita manipolare
+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 è:
+\begin{prototype}{time.h}{time\_t time(time\_t *t)}
+  Legge il valore corrente del \textit{calendar time}.
+  
+  \bodydesc{La funzione ritorna il valore del \textit{calendar time} in caso
+    di successo e -1 in caso di errore, che può essere solo \macro{EFAULT}.}
+\end{prototype}
+\noindent dove \param{t}, se non nullo, è l'indirizzo su cui salvare il valore
+di ritorno.
+
+Analoga a \func{time} è la funzione \func{stime} che serve per effettuare
+l'operazione inversa, e cioè per settare il tempo di sistema qualora questo
+sia necessario; il suo prototipo è:
+\begin{prototype}{time.h}{int stime(time\_t *t)}
+  Setta a \param{t} il valore corrente del \textit{calendar time}.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore,
+    che può essere \macro{EFAULT} o \macro{EPERM}.}
+\end{prototype}
+\noindent dato che modificare l'ora ha un impatto su tutto il sistema 
+il cambiamento dell'orologio è una operazione privilegiata e questa funzione
+può essere usata solo da un processo con i privilegi di amministratore,
+altrimenti la chiamata fallirà con un errore di \macro{EPERM}.
+
+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}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{sys/time.h}
+  \headdecl{time.h}
+  
+  \funcdecl{int gettimeofday(struct timeval *tv, struct timezone *tz)} 
 
+  Legge il tempo corrente del sistema.
+  
+  \funcdecl{int settimeofday(const struct timeval *tv, const struct timezone
+    *tz)}
+  
+  Setta il tempo di sistema.
+  
+  \bodydesc{Entrambe le funzioni restituiscono 0 in caso di successo e -1 in
+    caso di errore, nel qual caso \var{errno} può assumere il valori
+    \macro{EINVAL} \macro{EFAULT} e per \func{settimeofday} anche
+    \macro{EPERM}.}
+\end{functions}
+
+Queste funzioni utilizzano una struttura di tipo \var{timeval} che consente di
+indicare intervalli o tempi con precisioni maggiori del secondo, in realtà le
+\acr{glibc} provvedono due rappresentazioni alternative del \textit{calendar
+  time}, le strutture \var{timeval} e \var{timespec}, le cui definizioni sono
+riportate in \figref{fig:sys_timeval_struct} e che consentono rispettivamente
+precisioni del microsecondo e del nanosecondo.\footnote{la precisione è solo
+  astratta, l'orologio di sistema normalmente non è in grado di misuare dei
+  tempi con precisioni simili.}
 
 \begin{figure}[!htb]
   \footnotesize
@@ -1826,16 +1880,66 @@ quando necessita manipolare
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 struct timeval 
 {
-    long tv_sec;                /* seconds */
-    long tv_usec;               /* microseconds */
+    long tv_sec;            /* seconds */
+    long tv_usec;           /* microseconds */
+};
+struct timespec {
+    time_t  tv_sec;         /* seconds */
+    long    tv_nsec;        /* nanoseconds */
 };
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \var{timeval} per il calendar time.}
+  \caption{Le strutture \var{timeval} e \var{timespec} usate per una
+    rappresetnazione ad alta risoluzione del \textit{calendar time}.}
   \label{fig:sys_timeval_struct}
 \end{figure}
 
+Come nel caso di \func{stime} anche \func{settimeofday} può essere utilizzata
+solo da un processo coi privilegi di amministratore.  Il secondo parametro di
+entrambe le funzioni è una struttura \var{timezone}, che storicamente veniva
+utilizzata per specificare appunto la \textit{timezone}, cioè l'insieme del
+fuso orario e delle convenzioni per l'ora legale. Questo parametro è obsoleto
+e in Linux non è mai stato utilizzato e non è supportato né dalle vecchie
+\textsl{libc5}, né dalle \textsl{glibc}, e deve essere settato a \macro{NULL}.
+
+Modificare l'orologio di sistema con queste funzioni è comunque problematico,
+in quanto esse effettuano un cambiamento immediato, così 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)} 
+  
+  Aggiusta del valore \param{delta} l'orologio di sistema.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà il valore \macro{EPERM}.}
+\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 è
+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 ricavare il valore del precedente aggiustamento.
+
+Linux poi prevede un'altra funzione, \func{adjtimex}, che consente un
+aggiustamento più dettagliato permettendo anche di modificare anche la
+velocità dell'orologio di sistema. Il suo prototipo è:
+\begin{prototype}{sys/time.h}
+{int adjtimex(struct timex *buf)} 
+  
+  Aggiusta del valore \param{delta} l'orologio di sistema.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+  errore, nel qual caso \var{errno} assumerà il valore \macro{EPERM}.}
+\end{prototype}
+
+
+\subsection{La gestione delle date.}
+\label{sec:sys_date}