%% system.tex
%%
%% Copyright (C) 2000-2015 Simone Piccardi.  Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
%% license is included in the section entitled "GNU Free Documentation
%% License".
%%

\chapter{La gestione del sistema, del tempo e degli errori}
\label{cha:system}

In questo capitolo tratteremo varie interfacce che attengono agli aspetti più
generali del sistema, come quelle per la gestione dei parametri e della
configurazione dello stesso, quelle per la lettura dei limiti e delle
caratteristiche, quelle per il controllo dell'uso delle risorse dei processi,
quelle per la gestione ed il controllo dei filesystem, degli utenti, dei tempi
e degli errori.


\section{La gestione di caratteristiche e parametri del sistema}
\label{sec:sys_characteristics}

In questa sezione tratteremo le varie modalità con cui un programma può
ottenere informazioni riguardo alle capacità del sistema, e, per quelle per
cui è possibile, sul come modificarle. Ogni sistema unix-like infatti è
contraddistinto da un gran numero di limiti e costanti che lo caratterizzano,
e che possono dipendere da fattori molteplici, come l'architettura hardware,
l'implementazione del kernel e delle librerie, le opzioni di
configurazione. Il kernel inoltre mette a disposizione l'accesso ad alcuni
parametri che possono modificarne il comportamento.

La definizione di queste caratteristiche ed il tentativo di provvedere dei
meccanismi generali che i programmi possono usare per ricavarle è uno degli
aspetti più complessi e controversi con cui le diverse standardizzazioni si
sono dovute confrontare, spesso con risultati spesso tutt'altro che chiari.
Daremo comunque una descrizione dei principali metodi previsti dai vari
standard per ricavare sia le caratteristiche specifiche del sistema, che
quelle della gestione dei file e prenderemo in esame le modalità con cui è
possibile intervenire sui parametri del kernel.

\subsection{Limiti e caratteristiche del sistema}
\label{sec:sys_limits}

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
identificatori \textit{saved}), altre invece possono dipendere dalle opzioni
con cui si è costruito il sistema (ad esempio da come si è compilato il
kernel), o dalla configurazione del medesimo; per questo motivo in generale
sono necessari due tipi diversi di funzionalità:
\begin{itemize*}
\item la possibilità di determinare limiti ed opzioni al momento della
  compilazione.
\item la possibilità di determinare limiti ed opzioni durante l'esecuzione.
\end{itemize*}

La prima funzionalità si può ottenere includendo gli opportuni header file che
contengono le costanti necessarie definite come macro di preprocessore, per la
seconda invece sono ovviamente necessarie delle funzioni. La situazione è
complicata dal fatto che ci sono molti casi in cui alcuni di questi limiti
sono fissi in un'implementazione mentre possono variare in un altra: tutto
questo crea una ambiguità che non è sempre possibile risolvere in maniera
chiara. In generale quello che succede è che quando i limiti del sistema sono
fissi essi vengono definiti come macro di preprocessore nel file
\headfile{limits.h}, se invece possono variare, il loro valore sarà ottenibile
tramite la funzione \func{sysconf} (che esamineremo a breve).

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|r|l|}
    \hline
    \textbf{Costante}&\textbf{Valore}&\textbf{Significato}\\
    \hline
    \hline
    \const{MB\_LEN\_MAX}&       16  & Massima dimensione di un 
                                      carattere esteso.\\
    \const{CHAR\_BIT} &          8  & Numero di bit di \ctyp{char}.\\
    \const{UCHAR\_MAX}&        255  & Massimo di \ctyp{unsigned char}.\\
    \const{SCHAR\_MIN}&       -128  & Minimo di \ctyp{signed char}.\\
    \const{SCHAR\_MAX}&        127  & Massimo di \ctyp{signed char}.\\
    \const{CHAR\_MIN} &   0 o -128  & Minimo di \ctyp{char}.\footnotemark\\
    \const{CHAR\_MAX} &  127 o 255  & Massimo di \ctyp{char}.\footnotemark\\
    \const{SHRT\_MIN} &     -32768  & Minimo di \ctyp{short}.\\
    \const{SHRT\_MAX} &      32767  & Massimo di \ctyp{short}.\\
    \const{USHRT\_MAX}&      65535  & Massimo di \ctyp{unsigned short}.\\
    \const{INT\_MAX}  & 2147483647  & Minimo di \ctyp{int}.\\
    \const{INT\_MIN}  &-2147483648  & Minimo di \ctyp{int}.\\
    \const{UINT\_MAX} & 4294967295  & Massimo di \ctyp{unsigned int}.\\
    \const{LONG\_MAX} & 2147483647  & Massimo di \ctyp{long}.\\
    \const{LONG\_MIN} &-2147483648  & Minimo di \ctyp{long}.\\
    \const{ULONG\_MAX}& 4294967295  & Massimo di \ctyp{unsigned long}.\\
    \hline                
  \end{tabular}
  \caption{Costanti definite in \headfile{limits.h} in conformità allo standard
    ANSI C.}
  \label{tab:sys_ansic_macro}
\end{table}

\footnotetext[1]{il valore può essere 0 o \const{SCHAR\_MIN} a seconda che il
  sistema usi caratteri con segno o meno.} 

\footnotetext[2]{il valore può essere \const{UCHAR\_MAX} o \const{SCHAR\_MAX}
  a seconda che il sistema usi caratteri con segno o meno.}

Lo standard ANSI C definisce dei limiti che sono tutti fissi, pertanto questo
saranno sempre disponibili al momento della compilazione. Un elenco, ripreso
da \headfile{limits.h}, è riportato in tab.~\ref{tab:sys_ansic_macro}. Come si
può vedere per la maggior parte questi limiti attengono alle dimensioni dei
dati interi, che sono in genere fissati dall'architettura hardware, le
analoghe informazioni per i dati in virgola mobile sono definite a parte, ed
accessibili includendo \headfile{float.h}. 

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|r|l|}
    \hline
    \textbf{Costante}&\textbf{Valore}&\textbf{Significato}\\
    \hline
    \hline
    \const{LLONG\_MAX}& 9223372036854775807& Massimo di \ctyp{long long}.\\
    \const{LLONG\_MIN}&-9223372036854775808& Minimo di \ctyp{long long}.\\
    \const{ULLONG\_MAX}&18446744073709551615&
                                    Massimo di \ctyp{unsigned long long}.\\
    \hline                
  \end{tabular}
  \caption{Macro definite in \headfile{limits.h} in conformità allo standard
    ISO C90.}
  \label{tab:sys_isoc90_macro}
\end{table}

Lo standard prevede anche un'altra costante, \const{FOPEN\_MAX}, che può non
essere fissa e che pertanto non è definita in \headfile{limits.h}, essa deve
essere definita in \headfile{stdio.h} ed avere un valore minimo di 8. A questi
valori lo standard ISO C90 ne aggiunge altri tre, relativi al tipo \ctyp{long
  long} introdotto con il nuovo standard, i relativi valori sono in
tab.~\ref{tab:sys_isoc90_macro}.

Ovviamente le dimensioni dei vari tipi di dati sono solo una piccola parte
delle caratteristiche del sistema; mancano completamente tutte quelle che
dipendono dalla implementazione dello stesso. Queste, per i sistemi unix-like,
sono state definite in gran parte dallo standard POSIX.1, che tratta anche i
limiti relativi alle caratteristiche dei file che vedremo in
sez.~\ref{sec:sys_file_limits}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|r|p{8cm}|}
    \hline
    \textbf{Costante}&\textbf{Valore}&\textbf{Significato}\\
    \hline
    \hline
    \const{ARG\_MAX} &131072& Dimensione massima degli argomenti
                              passati ad una funzione della famiglia
                              \func{exec}.\\ 
    \const{CHILD\_MAX} & 999& Numero massimo di processi contemporanei
                              che un utente può eseguire.\\
    \const{OPEN\_MAX}  & 256& Numero massimo di file che un processo
                              può mantenere aperti in contemporanea.\\
    \const{STREAM\_MAX}&   8& Massimo numero di stream aperti per
                              processo in contemporanea.\\
    \const{TZNAME\_MAX}&   6& Dimensione massima del nome di una
                              \itindex{timezone} \textit{timezone} (vedi
                              sez.~\ref{sec:sys_time_base})).\\  
    \const{NGROUPS\_MAX}& 32& Numero di gruppi supplementari per
                              processo (vedi sez.~\ref{sec:proc_access_id}).\\
    \const{SSIZE\_MAX}&32767& Valore massimo del tipo \type{ssize\_t}.\\
    \hline
  \end{tabular}
  \caption{Costanti per i limiti del sistema.}
  \label{tab:sys_generic_macro}
\end{table}

Purtroppo la sezione dello standard che tratta questi argomenti è una delle
meno chiare, tanto che Stevens, in \cite{APUE}, la porta come esempio di
``\textsl{standardese}''. Lo standard prevede che ci siano 13 macro che
descrivono le caratteristiche del sistema: 7 per le caratteristiche generiche,
riportate in tab.~\ref{tab:sys_generic_macro}, e 6 per le caratteristiche dei
file, riportate in tab.~\ref{tab:sys_file_macro}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|r|p{8cm}|}
    \hline
    \textbf{Costante}&\textbf{Valore}&\textbf{Significato}\\
    \hline
    \hline
    \const{\_POSIX\_ARG\_MAX}    & 4096& Dimensione massima degli argomenti
                                         passati ad una funzione della famiglia
                                         \func{exec}.\\ 
    \const{\_POSIX\_CHILD\_MAX}  &    6& Numero massimo di processi
                                         contemporanei che un utente può 
                                         eseguire.\\
    \const{\_POSIX\_OPEN\_MAX}   &   16& Numero massimo di file che un processo
                                         può mantenere aperti in 
                                         contemporanea.\\
    \const{\_POSIX\_STREAM\_MAX} &    8& Massimo numero di stream aperti per
                                         processo in contemporanea.\\
    \const{\_POSIX\_TZNAME\_MAX} &    6& Dimensione massima del nome di una
                                         \itindex{timezone} \textit{timezone}
                                         (vedi sez.~\ref{sec:sys_date}). \\ 
    \const{\_POSIX\_RTSIG\_MAX}  &    8& Numero massimo di segnali
                                         \textit{real-time} (vedi
                                         sez.~\ref{sec:sig_real_time}).\\
    \const{\_POSIX\_NGROUPS\_MAX}&    0& Numero di gruppi supplementari per
                                         processo (vedi 
                                         sez.~\ref{sec:proc_access_id}).\\
    \const{\_POSIX\_SSIZE\_MAX}  &32767& Valore massimo del tipo 
                                         \type{ssize\_t}.\\
    % \const{\_POSIX\_AIO\_LISTIO\_MAX}&2& \\
    % \const{\_POSIX\_AIO\_MAX}    &    1& \\
    \hline                
  \end{tabular}
  \caption{Macro dei valori minimi di alcune caratteristiche generali del
    sistema per la conformità allo standard POSIX.1.}
  \label{tab:sys_posix1_general}
\end{table}

Lo standard dice che queste macro devono essere definite in
\headfile{limits.h} quando i valori a cui fanno riferimento sono fissi, e
altrimenti devono essere lasciate indefinite, ed i loro valori dei limiti
devono essere accessibili solo attraverso \func{sysconf}.  In realtà queste
vengono sempre definite ad un valore generico. Si tenga presente poi che
alcuni di questi limiti possono assumere valori molto elevati (come
\const{CHILD\_MAX}), e non è pertanto il caso di utilizzarli per allocare
staticamente della memoria.

A complicare la faccenda si aggiunge il fatto che POSIX.1 prevede una serie di
altre costanti (il cui nome inizia sempre con \code{\_POSIX\_}) che
definiscono i valori minimi le stesse caratteristiche devono avere, perché una
implementazione possa dichiararsi conforme allo standard, alcuni dei questi
valori sono riportati in tab.~\ref{tab:sys_posix1_general}.

In genere questi valori non servono a molto, la loro unica utilità è quella di
indicare un limite superiore che assicura la portabilità senza necessità di
ulteriori controlli. Tuttavia molti di essi sono ampiamente superati in tutti
i sistemi POSIX in uso oggigiorno. Per questo è sempre meglio utilizzare i
valori ottenuti da \func{sysconf}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Macro}&\textbf{Significato}\\
    \hline
    \hline
    \macro{\_POSIX\_JOB\_CONTROL}& Il sistema supporta il 
                                   \textit{job control} (vedi 
                                   sez.~\ref{sec:sess_job_control}).\\
    \macro{\_POSIX\_SAVED\_IDS}  & Il sistema supporta gli identificatori del 
                                   gruppo \textit{saved} (vedi 
                                   sez.~\ref{sec:proc_access_id})
                                   per il controllo di accesso dei processi.\\
    \const{\_POSIX\_VERSION}     & Fornisce la versione dello standard POSIX.1
                                   supportata nel formato YYYYMML (ad esempio 
                                   199009L).\\
    \hline
  \end{tabular}
  \caption{Alcune macro definite in \headfile{limits.h} in conformità allo
    standard POSIX.1.}
  \label{tab:sys_posix1_other}
\end{table}

Oltre ai precedenti valori e a quelli relativi ai file elencati in
tab.~\ref{tab:sys_posix1_file},, che devono essere obbligatoriamente definiti,
lo standard POSIX.1 ne prevede molti altri. La lista completa si trova
dall'header file \file{bits/posix1\_lim.h}, da non usare mai direttamente (è
incluso automaticamente all'interno di \headfile{limits.h}). Di questi vale la
pena menzionarne alcune macro di uso comune, riportate in
tab.~\ref{tab:sys_posix1_other}, che non indicano un valore specifico, ma
denotano la presenza di alcune funzionalità nel sistema, come il supporto del
\textit{job control} o degli identificatori del gruppo \textit{saved}.

Oltre allo standard POSIX.1, anche lo standard POSIX.2 definisce una serie di
altre costanti. Siccome queste sono principalmente attinenti a limiti relativi
alle applicazioni di sistema presenti, come quelli su alcuni parametri delle
espressioni regolari o del comando \cmd{bc}, non li tratteremo esplicitamente,
se ne trova una menzione completa nell'header file \file{bits/posix2\_lim.h},
e alcuni di loro sono descritti nella pagina di manuale di \func{sysconf} e
nel manuale delle \acr{glibc}.

Quando uno dei limiti o delle 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 al momento dell'esecuzione, è necessario ottenerne il valore
attraverso la funzione \funcd{sysconf}, cui prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{long sysconf(int name)}
\fdesc{Restituisce il valore di un parametro di sistema.} 
}

{La funzione ritorna in caso di successo il valore del parametro richiesto, o
  1 se si tratta di un'opzione disponibile, 0 se l'opzione non è disponibile e
  $-1$ per un errore, nel qual caso però \var{errno} non viene impostata.}  
\end{funcproto}

La funzione prende come argomento un intero che specifica quale dei limiti si
vuole conoscere. Uno specchietto contenente i principali valori disponibili in
Linux è riportato in tab.~\ref{tab:sys_sysconf_par}, l'elenco completo è
contenuto in \file{bits/confname.h}, ed una lista più esaustiva, con le
relative spiegazioni, si può trovare nel manuale delle \acr{glibc}.

\begin{table}[htb]
  \centering
  \footnotesize
    \begin{tabular}[c]{|l|l|p{8cm}|}
      \hline
      \textbf{Parametro}&\textbf{Macro sostituita} &\textbf{Significato}\\
      \hline
      \hline
      \texttt{\_SC\_ARG\_MAX}   & \const{ARG\_MAX}&
                                  La dimensione massima degli argomenti passati
                                  ad una funzione della famiglia \func{exec}.\\
      \texttt{\_SC\_CHILD\_MAX} & \const{CHILD\_MAX}&
                                  Il numero massimo di processi contemporanei
                                  che un utente può eseguire.\\
      \texttt{\_SC\_OPEN\_MAX}  & \const{OPEN\_MAX}&
                                  Il numero massimo di file che un processo può
                                  mantenere aperti in contemporanea.\\
      \texttt{\_SC\_STREAM\_MAX}& \const{STREAM\_MAX}&
                                  Il massimo numero di stream che un processo
                                  può mantenere aperti in contemporanea. Questo
                                  limite previsto anche dallo standard ANSI C,
                                  che specifica la macro {FOPEN\_MAX}.\\
      \texttt{\_SC\_TZNAME\_MAX}& \const{TZNAME\_MAX}&
                                  La dimensione massima di un nome di una
                                  \itindex{timezone} \texttt{timezone} (vedi
                                  sez.~\ref{sec:sys_date}).\\
      \texttt{\_SC\_NGROUPS\_MAX}&\const{NGROUP\_MAX}&
                                  Massimo numero di gruppi supplementari che
                                  può avere un processo (vedi
                                  sez.~\ref{sec:proc_access_id}).\\
      \texttt{\_SC\_SSIZE\_MAX} & \const{SSIZE\_MAX}& 
                                  Valore massimo del tipo di dato
                                  \type{ssize\_t}.\\ 
      \texttt{\_SC\_CLK\_TCK}   & \const{CLK\_TCK} &
                                  Il numero di \itindex{clock~tick}
                                  \textit{clock tick} al secondo, 
                                  cioè l'unità di misura del
                                  \itindex{process~time} \textit{process
                                    time} (vedi
                                  sez.~\ref{sec:sys_unix_time}).\\  
      \texttt{\_SC\_JOB\_CONTROL}&\macro{\_POSIX\_JOB\_CONTROL}&
                                  Indica se è supportato il \textit{job
                                    control} (vedi
                                  sez.~\ref{sec:sess_job_control}) in stile
                                  POSIX.\\ 
      \texttt{\_SC\_SAVED\_IDS} & \macro{\_POSIX\_SAVED\_IDS}&
                                  Indica se il sistema supporta i
                                  \textit{saved id} (vedi
                                  sez.~\ref{sec:proc_access_id}).\\  
      \texttt{\_SC\_VERSION}    & \const{\_POSIX\_VERSION} &
                                  Indica il mese e l'anno di approvazione
                                  della revisione dello standard POSIX.1 a cui
                                  il sistema fa riferimento, nel formato
                                  YYYYMML, la revisione più recente è 199009L,
                                  che indica il Settembre 1990.\\ 
     \hline
    \end{tabular}
  \caption{Parametri del sistema leggibili dalla funzione \func{sysconf}.}
  \label{tab:sys_sysconf_par}
\end{table}

In generale ogni limite o caratteristica del sistema per cui è definita una
macro, sia dagli standard ANSI C e ISO C90, che da POSIX.1 e POSIX.2, può
essere ottenuto attraverso una chiamata a \func{sysconf}. Il nome della
costante da utilizzare come valore dell'argomento \param{name} si otterrà
aggiungendo \code{\_SC\_} ai nomi delle costanti definite dai primi due
standard (quelle di tab.~\ref{tab:sys_generic_macro}), o sostituendolo a
\code{\_POSIX\_} per le costanti definite dagli altri due standard (quelle di
tab.~\ref{tab:sys_posix1_general}).

In linea teorica si dovrebbe fare uso di \func{sysconf} solo quando la
relativa costante di sistema non è definita, quindi con un codice analogo al
seguente:
\includecodesnip{listati/get_child_max.c}
ma in realtà con Linux queste costanti sono comunque definite, indicando però
un limite generico che non è detto sia corretto; per questo motivo è sempre
meglio usare i valori restituiti da \func{sysconf}.


\subsection{Limiti e caratteristiche dei file}
\label{sec:sys_file_limits}

Come per le caratteristiche generali del sistema anche per i file esistono una
serie di limiti (come la lunghezza del nome del file o il numero massimo di
link) che dipendono sia dall'implementazione che dal filesystem in uso. Anche
in questo caso lo standard prevede alcune macro che ne specificano il valore,
riportate in tab.~\ref{tab:sys_file_macro}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|r|l|}
    \hline
    \textbf{Costante}&\textbf{Valore}&\textbf{Significato}\\
    \hline
    \hline                
    \const{LINK\_MAX}   &8  & Numero massimo di link a un file.\\
    \const{NAME\_MAX}&  14  & Lunghezza in byte di un nome di file. \\
    \const{PATH\_MAX}& 256  & Lunghezza in byte di un \textit{pathname}.\\
    \const{PIPE\_BUF}&4096  & Byte scrivibili atomicamente in una pipe
                              (vedi sez.~\ref{sec:ipc_pipes}).\\
    \const{MAX\_CANON}&255  & Dimensione di una riga di terminale in modo 
                              canonico (vedi sez.~\ref{sec:term_io_design}).\\
    \const{MAX\_INPUT}&255  & Spazio disponibile nella coda di input 
                              del terminale (vedi 
                              sez.~\ref{sec:term_io_design}).\\
    \hline                
  \end{tabular}
  \caption{Costanti per i limiti sulle caratteristiche dei file.}
  \label{tab:sys_file_macro}
\end{table}

Come per i limiti di sistema, lo standard POSIX.1 detta una serie di valori
minimi anche per queste caratteristiche, che ogni sistema che vuole essere
conforme deve rispettare. Le relative macro sono riportate in
tab.~\ref{tab:sys_posix1_file} e per esse vale lo stesso discorso fatto per le
analoghe di tab.~\ref{tab:sys_posix1_general}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|r|l|}
    \hline
    \textbf{Macro}&\textbf{Valore}&\textbf{Significato}\\
    \hline
    \hline
    \const{\_POSIX\_LINK\_MAX}   &8  & Numero massimo di link a un file.\\
    \const{\_POSIX\_NAME\_MAX}&  14  & Lunghezza in byte di un nome di file.\\
    \const{\_POSIX\_PATH\_MAX}& 256  & Lunghezza in byte di un 
                                       \textit{pathname}.\\
    \const{\_POSIX\_PIPE\_BUF}& 512  & Byte scrivibili atomicamente in una
                                       pipe.\\
    \const{\_POSIX\_MAX\_CANON}&255  & Dimensione di una riga di
                                       terminale in modo canonico.\\
    \const{\_POSIX\_MAX\_INPUT}&255  & Spazio disponibile nella coda di input 
                                       del terminale.\\
%    \const{\_POSIX\_MQ\_OPEN\_MAX}&  8& \\
%    \const{\_POSIX\_MQ\_PRIO\_MAX}& 32& \\
%    \const{\_POSIX\_FD\_SETSIZE}& 16 & \\
%    \const{\_POSIX\_DELAYTIMER\_MAX}& 32 & \\
    \hline
  \end{tabular}
  \caption{Costanti dei valori minimi delle caratteristiche dei file per la
    conformità allo standard POSIX.1.}
  \label{tab:sys_posix1_file}
\end{table}

Tutti questi limiti sono definiti in \headfile{limits.h}; come nel caso
precedente il loro uso è di scarsa utilità in quanto ampiamente superati in
tutte le implementazioni moderne. In generale i limiti per i file sono molto
più soggetti ad essere variabili 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 quando si ha a che fare con limiti relativi ai file questi
devono essere sempre controllati con la funzione \funcd{pathconf}, il cui
prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{long pathconf(char *path, int name)}
\fdesc{Restituisce il valore di un parametro dei file.} 
}

{La funzione ritorna il valore del parametro richiesto in caso di successo e
  $-1$ per un errore, nel qual caso \var{errno} viene impostata ad uno degli
  errori possibili relativi all'accesso a \param{path}.}
\end{funcproto}

La funzione richiede che si specifichi il limite che si vuole controllare con
l'argomento \param{name}, per il quale si deve usare la relativa costante
identificativa, il cui nome si ottiene da quelle descritte in
tab.~\ref{tab:sys_file_macro} e tab.~\ref{tab:sys_posix1_file} con la stessa
convenzione già vista con \func{sysconf}, ma un questo caso con l'uso del
suffisso ``\texttt{\_PC\_}''.

In questo caso la funzione richiede anche un secondo argomento \param{path}
che specifichi a quale file si fa riferimento, dato che il valore del limite
cercato può variare a seconda del filesystem su cui si trova il file. Una
seconda versione della funzione, \funcd{fpathconf}, opera su un file
descriptor invece che su un \textit{pathname}, il suo prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{long fpathconf(int fd, int name)}
\fdesc{Restituisce il valore di un parametro dei file.} 
}

{È identica a \func{pathconf} solo che utilizza un file descriptor invece di
  un \textit{pathname}; pertanto gli errori restituiti in \var{errno} cambiano
  di conseguenza.}
\end{funcproto}
\noindent ed il suo comportamento è identico a quello di \func{pathconf} a
parte quello di richiedere l'indicazione di un file descriptor
nell'argomento \param{fd}.



\subsection{I parametri del kernel ed il filesystem \texttt{/proc}}
\label{sec:sys_sysctl}

Tradizionalmente la funzione che permette la lettura ed l'impostazione dei
parametri del sistema è \funcm{sysctl}. Si tratta di una funzione derivata da
BSD4.4 ed introdotta su Linux a partire dal kernel 1.3.57, ma oggi il suo uso
è totalmente deprecato.  Una \textit{system call} \funcm{\_sysctl} continua ad
esistere, ma non dispone più di una interfaccia nella \acr{glibc} ed il suo
utilizzo può essere effettuato solo tramite \func{syscall}, ma di nuovo questo
viene sconsigliato in quanto la funzionalità non è più mantenuta e molto
probabilmente sarà rimossa nel prossimo futuro. Per questo motivo eviteremo di
trattarne i particolari.

Lo scopo di \funcm{sysctl} era quello di fornire ai programmi una modalità per
modificare i parametri di sistema. Questi erano organizzati in maniera
gerarchica all'interno di un albero e per accedere a ciascuno di essi
occorreva specificare un percorso attraverso i vari nodi dell'albero, in
maniera analoga a come avviene per la risoluzione di un \textit{pathname}.

I parametri accessibili e modificabili attraverso questa funzione sono
moltissimi, dipendendo anche dallo stato corrente del kernel, ad esempio dai
moduli che sono stati caricati nel sistema. Inoltre non essendo standardizzati
i loro nomi possono variare da una versione di kernel all'altra, alcuni esempi
di questi parametri sono:
\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*}



\index{file!filesystem~\texttt  {/proc}!definizione|(}

Dato che fin dall'inizio i parametri erano organizzati in una struttura
albero, è parso naturale rimappare questa organizzazione utilizzando il
filesystem \file{/proc}. Questo è un filesystem completamente virtuale, il cui
contenuto è generato direttamente dal kernel, che non fa riferimento a nessun
dispositivo fisico, ma presenta in forma di file e directory i dati di alcune
delle strutture interne del kernel stesso. Il suo utilizzo principale, come
denuncia il nome stesso, è quello di fornire una interfaccia per ottenere i
dati relativi ai processi (venne introdotto a questo scopo su BSD), ma nel
corso del tempo il suo uso è stato ampliato.

All'interno di questo filesystem sono pertanto presenti una serie di file che
riflettono il contenuto dei parametri del kernel (molti dei quali accessibili
in sola lettura) e in altrettante directory, nominate secondo il relativo
\ids{PID}, vengono mantenute le informazioni relative a ciascun processo
attivo nel sistema.

In particolare l'albero dei valori dei parametri di sistema impostabili con
\func{sysctl} viene presentato in forma di una gerarchia di file e directory a
partire dalla directory \file{/proc/sys}, cosicché è possibile accedere al
valore di un parametro del kernel tramite il \textit{pathname} ad un file
sotto \file{/proc/sys} semplicemente leggendone il contenuto, così come si può
modificare un parametro scrivendo sul file ad esso corrispondente.

Il kernel si occupa di generare al volo il contenuto ed i nomi dei file
corrispondenti ai vari parametri che sono presenti, e questo ha il grande
vantaggio di rendere accessibili gli stessi ad un qualunque comando di shell e
di permettere la navigazione dell'albero in modo da riconoscere quali
parametri sono presenti senza dover cercare un valore all'interno di una
pagina di manuale.

Inizialmente l'uso del filesystem \file{/proc} serviva soltanto a replicare
l'accesso, con altrettante corrispondenze ai file presenti in
\file{/proc/sys}, ai parametri impostabili tradizionalmente con \func{sysctl},
ma vista la assoluta naturalità dell'interfaccia, e la sua maggiore
efficienza, nelle versioni più recenti del kernel questa è diventata la
modalità canonica per modificare i parametri del kernel, evitando di dover
ricorrere all'uso di una \textit{system call} specifica che pur essendo ancora
presente, prima o poi verrà eliminata.

Nonostante la semplificazione nella gestione ottenuta con l'uso di
\file{/proc/sys} resta il problema generale di conoscere il significato di
ciascuno degli innumerevoli parametri che vi si trovano. Purtroppo la
documentazione degli stessi spesso risulta incompleta e non aggiornata, ma
buona parte di quelli può importanti sono descritti dalla documentazione
inclusa nei sorgenti del kernel, nella directory \file{Documentation/sysctl}.

Ma oltre alle informazioni che sostituiscono quelle ottenibili dalla ormai
deprecata \func{sysctl} dentro \file{/proc} sono disponibili moltissime altre
informazioni, fra cui ad esempio anche quelle fornite dalla funzione di
sistema \funcd{uname},\footnote{con Linux ci sono in realtà 3 \textit{system
    call} diverse per le dimensioni delle stringhe restituite, le prime due
  usano rispettivamente delle lunghezze di 9 e 65 byte, la terza usa anch'essa
  65 byte, ma restituisce anche l'ultimo campo, \var{domainname}, con una
  lunghezza di 257 byte, la \acr{glibc} provvede a mascherare questi dettagli
  usando la versione più recente disponibile.} il cui prototipo è:

\begin{funcproto}{
\fhead{sys/utsname.h}
\fdecl{int uname(struct utsname *info)}
\fdesc{Restituisce informazioni generali sul sistema.} 
}

{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} può assumere solo il valore \errval{EFAULT}.}  
\end{funcproto}

La funzione, che viene usata dal comando \cmd{uname}, restituisce una serie di
informazioni relative al sistema nelle stringhe che costituiscono i campi
della struttura \struct{utsname} (la cui definizione è riportata in
fig.~\ref{fig:sys_utsname}) che viene scritta nel buffer puntato
dall'argomento \param{info}.

\begin{figure}[!ht!b]
  \footnotesize \centering
  \begin{minipage}[c]{0.8\textwidth}
    \includestruct{listati/ustname.h}
  \end{minipage}
  \normalsize 
  \caption{La struttura \structd{utsname}.} 
  \label{fig:sys_utsname}
\end{figure}

Si noti come in fig.~\ref{fig:sys_utsname} le dimensioni delle stringhe di
\struct{utsname} non sono specificate.  Il manuale delle \acr{glibc} indica
due costanti per queste dimensioni, \const{\_UTSNAME\_LENGTH} per i campi
standard e \const{\_UTSNAME\_DOMAIN\_LENGTH} per quello relativo al nome di
dominio, altri sistemi usano nomi diversi come \const{SYS\_NMLN} o
\const{\_SYS\_NMLN} o \const{UTSLEN} che possono avere valori diversi. Dato
che il buffer per \struct{utsname} deve essere preallocato l'unico modo per
farlo in maniera sicura è allora usare come dimensione il valore ottenuto con
\code{sizeof(utsname)}.

Le informazioni vengono restituite in ciascuno dei singoli campi di
\struct{utsname} in forma di stringhe terminate dal carattere NUL. In
particolare dette informazioni sono:
\begin{itemize*}
\item il nome del sistema operativo;
\item il nome della macchine (l'\textit{hostname});
\item il nome della release del kernel;
\item il nome della versione del kernel;
\item il tipo di hardware della macchina;
\item il nome del domino (il \textit{domainname});
\end{itemize*}
ma l'ultima di queste informazioni è stata aggiunta di recente e non è
prevista dallo standard POSIX, per questo essa è accessibile, come mostrato in
fig.~\ref{fig:sys_utsname}, solo se si è definita la macro
\macro{\_GNU\_SOURCE}.

Come accennato queste stesse informazioni, anche se a differenza di
\func{sysctl} la funzione continua ad essere mantenuta, si possono ottenere
direttamente tramite il filesystem \file{/proc}, esse infatti sono mantenute
rispettivamente nei file \sysctlrelfile{kernel}{ostype},
\sysctlrelfile{kernel}{hostname}, \sysctlrelfile{kernel}{osrelease},
\sysctlrelfile{kernel}{version} e \sysctlrelfile{kernel}{domainname} che si
trovano sotto la directory \file{/proc/sys/kernel/}.

\index{file!filesystem~\texttt  {/proc}!definizione|)}



\section{La gestione del sistema}
\label{sec:sys_management}

In questa sezione prenderemo in esame le interfacce di programmazione messe a
disposizione per affrontare una serie di tematiche attinenti la gestione
generale del sistema come quelle relative alla gestione di utenti e gruppi, al
trattamento delle informazioni relative ai collegamenti al sistema, alle
modalità per effettuare lo spegnimento o il riavvio di una macchina.


\subsection{La gestione delle informazioni su utenti e gruppi}
\label{sec:sys_user_group}

Tradizionalmente le informazioni utilizzate nella gestione di utenti e gruppi
(password, corrispondenze fra nomi simbolici e \ids{UID} numerici, home
directory, ecc.)  venivano registrate all'interno dei due file di testo
\conffile{/etc/passwd} ed \conffile{/etc/group}, il cui formato è descritto
dalle relative pagine del manuale\footnote{nella quinta sezione, quella dei
  file di configurazione (esistono comandi corrispondenti), una trattazione
  sistemistica dell'intero argomento coperto in questa sezione si consulti
  sez.~4.3 di \cite{AGL}.} e tutte le funzioni che richiedevano l'accesso a
queste informazione andavano a leggere direttamente il contenuto di questi
file.

In realtà oltre a questi due file da molto tempo gran parte dei sistemi
unix-like usano il cosiddetto sistema delle \textit{shadow password} che
prevede anche i due file \conffile{/etc/shadow} e \conffile{/etc/gshadow}, in
cui sono state spostate le informazioni di autenticazione (ed inserite alcune
estensioni di gestione avanzata) per toglierle dagli altri file che devono
poter essere letti da qualunque processo per poter effettuare l'associazione
fra username e \ids{UID}.

Col tempo però questa impostazione ha incominciato a mostrare dei limiti. Da
una parte il meccanismo classico di autenticazione è stato ampliato, ed oggi
la maggior parte delle distribuzioni di GNU/Linux usa la libreria PAM (sigla
che sta per \textit{Pluggable Authentication Method}) che fornisce una
interfaccia comune per i processi di autenticazione, svincolando completamente
le singole applicazioni dai dettagli del come questa viene eseguita e di dove
vengono mantenuti i dati relativi. Si tratta di un sistema modulare, in cui è
possibile utilizzare anche più meccanismi insieme, diventa così possibile
avere vari sistemi di riconoscimento (biometria, chiavi hardware, ecc.),
diversi formati per le password e diversi supporti per le informazioni. Il
tutto avviene in maniera trasparente per le applicazioni purché per ciascun
meccanismo si disponga della opportuna libreria che implementa l'interfaccia
di PAM.

Dall'altra parte, il diffondersi delle reti e la necessità di centralizzare le
informazioni degli utenti e dei gruppi per insiemi di macchine e servizi
all'interno di una stessa organizzazione, in modo da mantenere coerenti i
dati, ha portato anche alla necessità di poter recuperare e memorizzare dette
informazioni su supporti diversi dai file citati, introducendo il sistema del
\itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch} (che
tratteremo brevemente in sez.~\ref{sec:sock_resolver}) dato che la sua
applicazione è cruciale nella procedura di risoluzione di nomi di rete.

In questo paragrafo ci limiteremo comunque a trattare le funzioni classiche
per la lettura delle informazioni relative a utenti e gruppi tralasciando
completamente quelle relative all'autenticazione. 
%  Per questo non tratteremo
% affatto l'interfaccia di PAM, ma approfondiremo invece il sistema del
% \textit{Name Service Switch}, un meccanismo messo a disposizione dalle
% \acr{glibc} per modularizzare l'accesso a tutti i servizi in cui sia
% necessario trovare una corrispondenza fra un nome ed un numero (od altra
% informazione) ad esso associato, come appunto, quella fra uno username ed un
% \ids{UID} o fra un \ids{GID} ed il nome del gruppo corrispondente.
Le prime funzioni che vedremo sono quelle previste dallo standard POSIX.1;
queste sono del tutto generiche e si appoggiano direttamente al \textit{Name
  Service Switch}, per cui sono in grado di ricevere informazioni qualunque
sia il supporto su cui esse vengono mantenute.  Per leggere le informazioni
relative ad un utente si possono usare due funzioni, \funcd{getpwuid} e
\funcd{getpwnam}, i cui prototipi sono:

\begin{funcproto}{
\fhead{pwd.h} 
\fhead{sys/types.h} 
\fdecl{struct passwd *getpwuid(uid\_t uid)}
\fdecl{struct passwd *getpwnam(const char *name)} 
\fdesc{Restituiscono le informazioni relative all'utente specificato.} 
}

{Le funzioni ritornano il puntatore alla struttura contenente le informazioni
  in caso di successo e \val{NULL} nel caso non sia stato trovato nessun
  utente corrispondente a quanto specificato, nel qual caso \var{errno}
  assumerà il valore riportato dalle funzioni di sistema sottostanti.}
\end{funcproto}

Le due funzioni forniscono le informazioni memorizzate nel registro degli
utenti (che nelle versioni più recenti per la parte di credenziali di
autenticazione vengono ottenute attraverso PAM) relative all'utente
specificato attraverso il suo \ids{UID} o il nome di login. Entrambe le
funzioni restituiscono un puntatore ad una struttura di tipo \struct{passwd}
la cui definizione (anch'essa eseguita in \headfile{pwd.h}) è riportata in
fig.~\ref{fig:sys_passwd_struct}, dove è pure brevemente illustrato il
significato dei vari campi.

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{0.8\textwidth}
    \includestruct{listati/passwd.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{passwd} contenente le informazioni relative
    ad un utente del sistema.}
  \label{fig:sys_passwd_struct}
\end{figure}

La struttura usata da entrambe le funzioni è allocata staticamente, per questo
motivo viene sovrascritta ad ogni nuova invocazione, lo stesso dicasi per la
memoria dove sono scritte le stringhe a cui i puntatori in essa contenuti
fanno riferimento. Ovviamente questo implica che dette funzioni non possono
essere \index{funzioni!rientranti} rientranti; per questo motivo ne esistono
anche due versioni alternative (denotate dalla solita estensione \code{\_r}),
i cui prototipi sono:

\begin{funcproto}{
\fhead{pwd.h} 
\fhead{sys/types.h} 
\fdecl{struct passwd *getpwuid\_r(uid\_t uid, struct passwd *password,
    char *buffer,\\
\phantom{struct passwd *getpwuid\_r(}size\_t buflen, struct passwd **result)}
\fdecl{struct passwd *getpwnam\_r(const char *name, struct passwd
    *password, char *buffer,\\
\phantom{struct passwd *getpwnam\_r(}size\_t buflen, struct passwd **result)}
\fdesc{Restituiscono le informazioni relative all'utente specificato.} 
}

{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà il valore riportato dalle di sistema funzioni
  sottostanti.}
\end{funcproto}

In questo caso l'uso è molto più complesso, in quanto bisogna prima allocare
la memoria necessaria a contenere le informazioni. In particolare i valori
della struttura \struct{passwd} saranno restituiti all'indirizzo
\param{password} mentre la memoria allocata all'indirizzo \param{buffer}, per
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
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}).

Sia queste versioni rientranti che precedenti gli errori eventualmente
riportati in \var{errno} in caso di fallimento dipendono dalla sottostanti
funzioni di sistema usate per ricavare le informazioni (si veda quanto
illustrato in sez.~\ref{sec:sys_errno}) per cui se lo si vuole utilizzare è
opportuno inizializzarlo a zero prima di invocare le funzioni per essere
sicuri di non avere un residuo di errore da una chiamata precedente. Il non
aver trovato l'utente richiesto infatti può essere dovuto a diversi motivi (a
partire dal fatto che non esista) per cui si possono ottenere i valori di
errore più vari a seconda dei casi.

Del tutto analoghe alle precedenti sono le funzioni \funcd{getgrnam} e
\funcd{getgrgid} che permettono di leggere le informazioni relative ai gruppi,
i loro prototipi sono:

\begin{funcproto}{
\fhead{grp.h}
\fhead{sys/types.h}
\fdecl{struct group *getgrgid(gid\_t gid)} 
\fdecl{struct group *getgrnam(const char *name)} 
\fdesc{Restituiscono le informazioni relative al gruppo specificato.} 
}

{Le funzioni ritornano il puntatore alla struttura contenente le informazioni
  in caso di successo e \val{NULL} nel caso non sia stato trovato nessun
  utente corrispondente a quanto specificato, nel qual caso \var{errno}
  assumerà il valore riportato dalle funzioni di sistema sottostanti.}
\end{funcproto}

Come per le precedenti per gli utenti esistono anche le analoghe versioni
\index{funzioni!rientranti} rientranti che di nuovo utilizzano la stessa
estensione \code{\_r}; i loro prototipi sono:

\begin{funcproto}{
\fhead{grp.h}
\fhead{sys/types.h}
\fdecl{int getgrgid\_r(gid\_t gid, struct group *grp, char *buf, 
  size\_t buflen,\\
\phantom{int getgrgid\_r(}struct group **result)}
\fdecl{int getgrnam\_r(const char *name, struct group *grp, char *buf, 
  size\_t buflen,\\
\phantom{int getgrnam\_r(}struct group **result)}
\fdesc{Restituiscono le informazioni relative al gruppo specificato.} 
}

{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà il valore riportato dalle funzioni di sistema
  sottostanti.}
\end{funcproto}


Il comportamento di tutte queste funzioni è assolutamente identico alle
precedenti che leggono le informazioni sugli utenti, l'unica differenza è che
in questo caso le informazioni vengono restituite in una struttura di tipo
\struct{group}, la cui definizione è riportata in
fig.~\ref{fig:sys_group_struct}.

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{0.8\textwidth}
    \includestruct{listati/group.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{group} contenente le informazioni relative ad
    un gruppo del sistema.}
  \label{fig:sys_group_struct}
\end{figure}

Le funzioni viste finora sono in grado di leggere le informazioni sia
direttamente dal file delle password in \conffile{/etc/passwd} che tramite il
sistema del \textit{Name Service Switch} e sono completamente generiche. Si
noti però che non c'è una funzione che permetta di impostare direttamente una
password.\footnote{in realtà questo può essere fatto ricorrendo alle funzioni
  della libreria PAM, ma questo non è un argomento che tratteremo qui.} Dato
che POSIX non prevede questa possibilità esiste un'altra interfaccia che lo
fa, derivata da SVID le cui funzioni sono riportate in
tab.~\ref{tab:sys_passwd_func}. Questa interfaccia però funziona soltanto
quando le informazioni sono mantenute su un apposito file di \textsl{registro}
di utenti e gruppi, con il formato classico di \conffile{/etc/passwd} e
\conffile{/etc/group}.

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Funzione} & \textbf{Significato}\\
    \hline
    \hline
    \funcm{fgetpwent}   & Legge una voce dal file di registro degli utenti
                          specificato.\\
    \funcm{fgetpwent\_r}& Come la precedente, ma \index{funzioni!rientranti}
                          rientrante.\\ 
    \funcm{putpwent}    & Immette una voce in un file di registro degli
                          utenti.\\ 
    \funcm{getpwent}    & Legge una voce da \conffile{/etc/passwd}.\\
    \funcm{getpwent\_r} & Come la precedente, ma \index{funzioni!rientranti}
                          rientrante.\\ 
    \funcm{setpwent}    & Ritorna all'inizio di \conffile{/etc/passwd}.\\
    \funcm{endpwent}    & Chiude \conffile{/etc/passwd}.\\
    \funcm{fgetgrent}   & Legge una voce dal file di registro dei gruppi 
                         specificato.\\
    \funcm{fgetgrent\_r}& Come la precedente, ma \index{funzioni!rientranti}
                          rientrante.\\
    \funcm{putgrent}    & Immette una voce in un file di registro dei gruppi.\\
    \funcm{getgrent}    & Legge una voce da \conffile{/etc/group}.\\ 
    \funcm{getgrent\_r} & Come la precedente, ma \index{funzioni!rientranti} 
                          rientrante.\\
    \funcm{setgrent}    & Ritorna all'inizio di \conffile{/etc/group}.\\
    \funcm{endgrent}    & Chiude \conffile{/etc/group}.\\
    \hline
  \end{tabular}
  \caption{Funzioni per la manipolazione dei campi di un file usato come
    registro per utenti o gruppi nel formato di \conffile{/etc/passwd} e
    \conffile{/etc/group}.} 
  \label{tab:sys_passwd_func}
\end{table}

% TODO mancano i prototipi di alcune delle funzioni

Dato che oramai tutte le distribuzioni di GNU/Linux utilizzano le
\textit{shadow password} (quindi con delle modifiche rispetto al formato
classico del file \conffile{/etc/passwd}), si tenga presente che le funzioni
di questa interfaccia che permettono di scrivere delle voci in un
\textsl{registro} degli utenti (cioè \func{putpwent} e \func{putgrent}) non
hanno la capacità di farlo specificando tutti i contenuti necessari rispetto a
questa estensione.

Per questo motivo l'uso di queste funzioni è deprecato, in quanto comunque non
funzionale rispetto ad un sistema attuale, pertanto ci limiteremo a fornire
soltanto l'elenco di tab.~\ref{tab:sys_passwd_func}, senza nessuna spiegazione
ulteriore.  Chi volesse insistere ad usare questa interfaccia può fare
riferimento alle pagine di manuale delle rispettive funzioni ed al manuale
delle \acr{glibc} per i dettagli del funzionamento.



\subsection{Il registro della \textsl{contabilità} degli utenti}
\label{sec:sys_accounting}

Un altro insieme di funzioni relative alla gestione del sistema che
esamineremo è quello che permette di accedere ai dati del registro della
cosiddetta \textsl{contabilità} (o \textit{accounting}) degli utenti.  In esso
vengono mantenute una serie di informazioni storiche relative sia agli utenti
che si sono collegati al sistema, tanto per quelli correntemente collegati,
che per la registrazione degli accessi precedenti, sia relative all'intero
sistema, come il momento di lancio di processi da parte di \cmd{init}, il
cambiamento dell'orologio di sistema, il cambiamento di runlevel o il riavvio
della macchina.

I dati vengono usualmente memorizzati nei due file \file{/var/run/utmp} e
\file{/var/log/wtmp}. che sono quelli previsti dal \textit{Linux Filesystem
  Hierarchy Standard}, adottato dalla gran parte delle distribuzioni.  Quando
un utente si collega viene aggiunta una voce a \file{/var/run/utmp} in cui
viene memorizzato il nome di login, il terminale da cui ci si collega,
l'\ids{UID} della shell di login, l'orario della connessione ed altre
informazioni.  La voce resta nel file fino al logout, quando viene cancellata
e spostata in \file{/var/log/wtmp}.

In questo modo il primo file viene utilizzato per registrare chi sta
utilizzando il sistema al momento corrente, mentre il secondo mantiene la
registrazione delle attività degli utenti. A quest'ultimo vengono anche
aggiunte delle voci speciali per tenere conto dei cambiamenti del sistema,
come la modifica del runlevel, il riavvio della macchina, ecc. Tutte queste
informazioni sono descritte in dettaglio nel manuale delle \acr{glibc}.

Questi file non devono mai essere letti direttamente, ma le informazioni che
contengono possono essere ricavate attraverso le opportune funzioni di
libreria. Queste sono analoghe alle precedenti funzioni (vedi
tab.~\ref{tab:sys_passwd_func}) usate per accedere al registro degli utenti,
solo che in questo caso la struttura del registro della \textsl{contabilità} è
molto più complessa, dato che contiene diversi tipi di informazione.

Le prime tre funzioni, \funcd{setutent}, \funcd{endutent} e \funcd{utmpname}
servono rispettivamente a aprire e a chiudere il file che contiene il registro
della \textsl{contabilità} degli, e a specificare su quale file esso viene
mantenuto. I loro prototipi sono:

\begin{funcproto}{
\fhead{utmp.h} 
\fdecl{void utmpname(const char *file)}
\fdesc{Specifica il file da usare come registro.} 
\fdecl{void setutent(void)}
\fdesc{Apre il file del registro.} 
\fdecl{void endutent(void)}
\fdesc{Chiude il file del registro.} 
}

{Le funzioni non ritornano nulla.}  
\end{funcproto}

Si tenga presente che le funzioni non restituiscono nessun valore, pertanto
non è possibile accorgersi di eventuali errori, ad esempio se si è impostato
un nome di file sbagliato con \func{utmpname}.

Nel caso non si sia utilizzata \func{utmpname} per specificare un file di
registro alternativo, sia \func{setutent} che \func{endutent} operano usando
il default che è \sysfile{/var/run/utmp} il cui nome, così come una serie di
altri valori di default per i \textit{pathname} di uso più comune, viene
mantenuto nei valori di una serie di costanti definite includendo
\headfile{paths.h}, in particolare quelle che ci interessano sono:
\begin{basedescript}{\desclabelwidth{2.0cm}}
\item[\const{\_PATH\_UTMP}] specifica il file che contiene il registro per gli
  utenti correntemente collegati, questo è il valore che viene usato se non si
  è utilizzato \func{utmpname} per modificarlo;
\item[\const{\_PATH\_WTMP}] specifica il file che contiene il registro per
  l'archivio storico degli utenti collegati;
\end{basedescript}
che nel caso di Linux hanno un valore corrispondente ai file
\sysfile{/var/run/utmp} e \sysfile{/var/log/wtmp} citati in precedenza.

Una volta aperto il file del registro degli utenti si può eseguire una
scansione leggendo o scrivendo una voce con le funzioni \funcd{getutent},
\funcd{getutid}, \funcd{getutline} e \funcd{pututline}, i cui prototipi sono:


\begin{funcproto}{
\fhead{utmp.h}
\fdecl{struct utmp *getutent(void)}
\fdesc{Legge una voce dalla posizione corrente nel registro.} 
\fdecl{struct utmp *getutid(struct utmp *ut)}
\fdesc{Ricerca una voce sul registro.} 
\fdecl{struct utmp *getutline(struct utmp *ut)}
\fdesc{Ricerca una voce sul registro attinente a un terminale.} 
\fdecl{struct utmp *pututline(struct utmp *ut)}
\fdesc{Scrive una voce nel registro.} 
}

{Le funzioni ritornano il puntatore ad una struttura \struct{utmp} in caso di
  successo e \val{NULL} in caso di errore, nel qual caso \var{errno} assumerà
  il valore riportato dalle funzioni di sistema sottostanti.}
\end{funcproto}

Tutte queste funzioni fanno riferimento ad una struttura di tipo
\struct{utmp}, la cui definizione in Linux è riportata in
fig.~\ref{fig:sys_utmp_struct}. Le prime tre funzioni servono per leggere una
voce dal registro: \func{getutent} legge semplicemente la prima voce
disponibile, le altre due permettono di eseguire una ricerca. Aprendo il
registro con \func{setutent} ci si posiziona al suo inizio, ogni chiamata di
queste funzioni eseguirà la lettura sulle voci seguenti, pertanto la posizione
sulla voce appena letta, in modo da consentire una scansione del file. Questo
vale anche per \func{getutid} e \func{getutline}, il che comporta che queste
funzioni effettuano comunque una ricerca ``\textsl{in avanti}''.

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{0.9\textwidth}
    \includestruct{listati/utmp.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{utmp} contenente le informazioni di una voce
    del registro di \textsl{contabilità}.}
  \label{fig:sys_utmp_struct}
\end{figure}

Con \func{getutid} si può cercare una voce specifica, a seconda del valore del
campo \var{ut\_type} dell'argomento \param{ut}.  Questo può assumere i valori
riportati in tab.~\ref{tab:sys_ut_type}, quando assume i valori
\const{RUN\_LVL}, \const{BOOT\_TIME}, \const{OLD\_TIME}, \const{NEW\_TIME},
verrà restituito la prima voce che corrisponde al tipo determinato; quando
invece assume i valori \const{INIT\_PROCESS}, \const{LOGIN\_PROCESS},
\const{USER\_PROCESS} o \const{DEAD\_PROCESS} verrà restituita la prima voce
corrispondente al valore del campo \var{ut\_id} specificato in \param{ut}.

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Valore} & \textbf{Significato}\\
    \hline
    \hline
    \const{EMPTY}         & Non contiene informazioni valide.\\
    \const{RUN\_LVL}      & Identica il runlevel del sistema.\\
    \const{BOOT\_TIME}    & Identifica il tempo di avvio del sistema.\\
    \const{OLD\_TIME}     & Identifica quando è stato modificato l'orologio di
                            sistema.\\
    \const{NEW\_TIME}     & Identifica da quanto è stato modificato il 
                            sistema.\\
    \const{INIT\_PROCESS} & Identifica un processo lanciato da \cmd{init}.\\
    \const{LOGIN\_PROCESS}& Identifica un processo di login.\\
    \const{USER\_PROCESS} & Identifica un processo utente.\\
    \const{DEAD\_PROCESS} & Identifica un processo terminato.\\
%    \const{ACCOUNTING}    & ??? \\
    \hline
  \end{tabular}
  \caption{Classificazione delle voci del registro a seconda dei
    possibili valori del campo \var{ut\_type}.} 
  \label{tab:sys_ut_type}
\end{table}

La funzione \func{getutline} esegue la ricerca sulle voci che hanno
\var{ut\_type} uguale a \const{LOGIN\_PROCESS} o \const{USER\_PROCESS},
restituendo la prima che corrisponde al valore di \var{ut\_line}, che
specifica il dispositivo di terminale che interessa, da indicare senza il
\file{/dev/} iniziale. Lo stesso criterio di ricerca è usato da
\func{pututline} per trovare uno spazio dove inserire la voce specificata;
qualora questo spazio non venga trovato la voce viene aggiunta in coda al
registro.

In generale occorre però tenere conto che queste funzioni non sono
completamente standardizzate, e che in sistemi diversi possono esserci
differenze; ad esempio \func{pututline} restituisce \code{void} in vari
sistemi (compreso Linux, fino alle \acr{libc5}). Qui seguiremo la sintassi
fornita dalle \acr{glibc}, ma gli standard POSIX 1003.1-2001 e XPG4.2 hanno
introdotto delle nuove strutture (e relativi file) di tipo \struct{utmpx}, che
sono un sovrainsieme della \struct{utmp} usata tradizionalmente ed altrettante
funzioni che le usano al posto di quelle citate.

Le \acr{glibc} utilizzavano già una versione estesa di \struct{utmp}, che
rende inutili queste nuove strutture, per questo su Linux \struct{utmpx} viene
definita esattamente come \struct{utmp}, con gli stessi campi di
fig.~\ref{fig:sys_utmp_struct}. Altrettanto dicasi per le nuove funzioni di
gestione previste dallo standard: \funcm{getutxent}, \funcm{getutxid},
\funcm{getutxline}, \funcm{pututxline}, \funcm{setutxent} e \funcm{endutxent}.

Tutte queste funzioni, definite con \struct{utmpx} dal file di dichiarazione
\headfile{utmpx.h}, su Linux sono ridefinite come sinonimi delle funzioni
appena viste, con argomento di tipo \struct{utmpx} anziché \struct{utmp} ed
hanno lo stesso identico comportamento. Per completezza viene definita anche
\funcm{utmpxname} che non è prevista da POSIX.1-2001.

Come già visto in sez.~\ref{sec:sys_user_group}, l'uso di strutture allocate
staticamente rende le funzioni di lettura dei dati appena illustrate non
\index{funzioni!rientranti} rientranti. Per questo motivo le \acr{glibc}
forniscono anche delle versioni \index{funzioni!rientranti} rientranti:
\func{getutent\_r}, \func{getutid\_r}, \func{getutline\_r}, che invece di
restituire un puntatore restituiscono un intero e prendono due argomenti
aggiuntivi, i rispettivi prototipi sono:

\begin{funcproto}{
\fhead{utmp.h}
\fdecl{int *getutent\_r(struct utmp *buffer, struct utmp **result)}
\fdesc{Legge una voce dalla posizione corrente nel registro.} 
\fdecl{int *getutid\_r(struct utmp *buffer, struct utmp **result, struct utmp
  *ut)} 
\fdesc{Ricerca una voce sul registro.} 
\fdecl{int *getutline\_r(struct utmp *buffer, struct utmp **result, struct utmp
  *ut)} 
\fdesc{Ricerca una voce sul registro attinente a un terminale.}
}

{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà il valore riportato dalle funzioni di sistema
  sottostanti.}
\end{funcproto}

Le funzioni si comportano esattamente come le precedenti analoghe non
\index{funzioni!rientranti} rientranti, solo che restituiscono il risultato
all'indirizzo specificato dal primo argomento aggiuntivo \param{buffer} mentre
il secondo, \param{result)} viene usato per restituire il puntatore al buffer
stesso.

Infine le \acr{glibc} forniscono altre due funzioni, \funcd{updwtmp} e
\funcd{logwtmp}, come estensione per scrivere direttamente delle voci nel file
sul registro storico \sysfile{/var/log/wtmp}; i rispettivi prototipi sono:

\begin{funcproto}{
\fhead{utmp.h}
\fdecl{void updwtmp(const char *wtmp\_file, const struct utmp *ut)}
\fdesc{Aggiunge una voce in coda al registro.} 
\fdecl{void logwtmp(const char *line, const char *name, const char *host)}
\fdesc{Aggiunge nel registro una voce con i valori specificati.} 
}

{Le funzioni non restituiscono nulla.}
\end{funcproto}

La prima funzione permette l'aggiunta di una voce in coda al file del registro
storico, indicato dal primo argomento, specificando direttamente una struttura
\struct{utmp}.  La seconda invece utilizza gli argomenti \param{line},
\param{name} e \param{host} per costruire la voce che poi aggiunge chiamando
\func{updwtmp}.

Queste funzioni non sono previste da POSIX.1-2001, anche se sono presenti in
altri sistemi (ad esempio Solaris e NetBSD), per mantenere una coerenza con le
altre funzioni definite nello standard che usano la struttura \struct{utmpx}
la \acr{glibc} definisce anche una funzione \funcm{updwtmpx}, che come in
precedenza è identica a \func{updwtmp} con la sola differenza di richiedere
l'uso di \headfile{utmpx.h} e di una struttura \struct{utmpx} come secondo
argomento. 


\subsection{La gestione dello spegnimento e del riavvio}
\label{sec:sys_reboot}

Una delle operazioni di gestione generale del sistema è quella che attiene
alle modalità con cui se ne può gestire lo spegnimento ed il riavvio.  Perché
questo avvenga in maniera corretta, in particolare per le parti che comportano
lo spegnimento effettivo della macchina, occorre che il kernel effettui le
opportune operazioni interagendo con il BIOS ed i dispositivi che controllano
l'erogazione della potenza.

La funzione di sistema che controlla lo spegnimento ed il riavvio (ed altri
aspetti della relativa procedura) è \funcd{reboot},\footnote{la funzione
  illustrata è quella fornita dalla \acr{glibc} che maschera i dettagli di
  basso livello della \textit{system call} la quale richiede attualmente tre
  argomenti; fino al kernel 2.1.30 la \textit{system call} richiedeva un
  ulteriore quarto argomento, i primi due indicano dei \textit{magic number}
  interi che possono assumere solo alcuni valori predefiniti, il terzo un
  comando, corrispondente all'unico argomento della funzione della \acr{glibc}
  ed il quarto argomento aggiuntivo, ora ignorato, un puntatore generico ad
  ulteriori dati.}  il cui prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fhead{sys/reboot.h}
\fdecl{int reboot(int cmd)}
\fdesc{Controlla il riavvio o l'arresto della macchina.}
}

{La funzione non ritorna o ritorna $0$ in caso di successo e $-1$ per un
  errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EFAULT}] c'è un indirizzo non valido nel passaggio degli
    argomenti con il comando \const{LINUX\_REBOOT\_CMD\_RESTART2} (obsoleto).
  \item[\errcode{EINVAL}] si sono specificati valori non validi per gli
    argomenti.
  \item[\errcode{EPERM}] il chiamante non ha i privilegi di amministratore (la
    \textit{capability} \const{CAP\_SYS\_BOOT}).
  \end{errlist}
}  
\end{funcproto}

La funzione, oltre al riavvio ed allo spegnimento, consente anche di
controllare l'uso della combinazione di tasti tradizionalmente usata come
scorciatoia da tastiera per richiedere il riavvio (\texttt{Ctrl-Alt-Del},
denominata in breve nella documentazione CAD) ed i suoi effetti specifici
dipendono dalla architettura hardware. Se si è richiesto un riavvio o uno
spegnimento in caso di successo la funzione, non esistendo più il programma,
ovviamente non ritorna, pertanto bisogna avere cura di aver effettuato tutte
le operazioni preliminari allo spegnimento prima di eseguirla.

Il comportamento della funzione viene controllato dall'argomento \param{cmd}
e deve assumere indicato con una delle costanti seguente elenco, che
illustra i comandi attualmente disponibili:

\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
\item[\const{LINUX\_REBOOT\_CMD\_CAD\_OFF}] Disabilita l'uso diretto della
  combinazione \texttt{Ctrl-Alt-Del}, la cui pressione si traduce nell'invio
  del segnale \const{SIGINT} a \texttt{init} (o più in generale al processo
  con \ids{PID} 1) il cui effetto dipende dalla configurazione di
  quest'ultimo.
\item[\const{LINUX\_REBOOT\_CMD\_CAD\_ON}] Attiva l'uso diretto della
  combinazione \texttt{Ctrl-Alt-Del}, la cui pressione si traduce
  nell'esecuzione dell'azione che si avrebbe avuto chiamando \func{reboot} con
  il comando \const{LINUX\_REBOOT\_CMD\_RESTART}.
\item[\const{LINUX\_REBOOT\_CMD\_HALT}] Viene inviato sulla console il
  messaggio ``\textit{System halted.}'' l'esecuzione viene bloccata
  immediatamente ed il controllo passato al monitor nella ROM (se esiste e
  l'architettura lo consente). Se non si è eseguita una sincronizzazione dei
  dati su disco con \func{sync} questi saranno perduti.
\item[\const{LINUX\_REBOOT\_CMD\_KEXEC}] viene eseguito direttamente il nuovo
  kernel che è stato opportunamente caricato in memoria da una
  \func{kexec\_load} (che tratteremo a breve) eseguita in precedenza. La
  funzionalità è disponibile solo a partire dal kernel 2.6.13 e se il kernel
  corrente è stato compilato includendo il relativo supporto.\footnote{deve
    essere stata abilitata l'opzione di compilazione \texttt{CONFIG\_KEXEC}.}
  Questo meccanismo consente di eseguire una sorta di riavvio rapido che evita
  di dover ripassare dalla inizializzazione da parte del BIOS ed il lancio del
  kernel attraverso un bootloader. Se non si è eseguita una sincronizzazione
  dei dati su disco con \func{sync} questi saranno perduti.
\item[\const{LINUX\_REBOOT\_CMD\_POWER\_OFF}] Viene inviato sulla console il
  messaggio ``\textit{Power down.}'' l'esecuzione viene bloccata
  immediatamente e la macchina, se possibile, viene spenta.  Se non si è
  eseguita una sincronizzazione dei dati su disco con \func{sync} questi
  saranno perduti.
\item[\const{LINUX\_REBOOT\_CMD\_RESTART}] Viene inviato sulla console il
  messaggio ``\textit{Restarting system.}'' ed avviata immediatamente la
  procedura di riavvio ordinaria. Se non si è eseguita una sincronizzazione
  dei dati su disco con \func{sync} questi saranno perduti.
\item[\const{LINUX\_REBOOT\_CMD\_RESTART2}] Viene inviato sulla console il
  messaggio ``\textit{Restarting system with command '\%s'.}'' ed avviata
  immediatamente la procedura di riavvio usando il comando fornito
  nell'argomento \param{arg} che viene stampato al posto di \textit{'\%s'}
  (veniva usato per lanciare un altro programma al posto di \cmd{init}). Nelle
  versioni recenti questo argomento viene ignorato ed il riavvio può essere
  controllato dall'argomento di avvio del kernel \texttt{reboot=...}  Se non
  si è eseguita una sincronizzazione dei dati su disco con \func{sync} questi
  saranno perduti.
\end{basedescript}


Come appena illustrato usando il comando \const{LINUX\_REBOOT\_CMD\_KEXEC} si
può eseguire un riavvio immediato pre-caricando una immagine del kernel, che
verrà eseguita direttamente. Questo meccanismo consente di evitare la
reinizializzazione della macchina da parte del BIOS, ed oltre a velocizzare un
eventuale riavvio, ha il vantaggio poter accedere allo stato corrente della
macchina e della memoria, per cui viene usato spesso per installare un kernel
di emergenza da eseguire in caso di crollo del sistema per recuperare il
maggior numero di informazioni possibili.

La funzione di sistema che consente di caricare questa immagine del kernel è
\funcd{kexec\_load}, la funzione non viene definita nella \acr{glibc} e deve
pertanto essere invocata con \func{syscall}, il suo prototipo è:

\begin{funcproto}{
\fhead{linux/kexec.h}
\fdecl{long kexec\_load(unsigned long entry, unsigned long nr\_segments,
struct kexec\_segment\\
\phantom{long kexec\_load(}*segments, unsigned long flags)} 

\fdesc{Carica un kernel per un riavvio immediato.}
}

{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EBUSY}] c'è già un caricamento in corso, o un altro kernel è
    già in uso.
  \item[\errcode{EINVAL}] il valore di \param{flags} non è valido o si è
    indicato un valore eccessivo per \param{nr\_segments}.
  \item[\errcode{EPERM}] il chiamante non ha i privilegi di amministratore (la
    \textit{capability} \const{CAP\_SYS\_BOOT}).
  \end{errlist}
}  
\end{funcproto}

Il primo argomento indica l'indirizzo fisico di esecuzione del nuovo kernel
questo viene caricato usando un vettore di strutture \struct{kexec\_segment}
(la cui definizione è riportata in fig.~\ref{fig:kexec_segment}) che
contengono i singoli segmenti dell'immagine. I primi due campi indicano
indirizzo e dimensione del segmento di memoria in \textit{user space}, i
secondi indirizzo e dimensione in \textit{kernel space}. 


\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{0.8\textwidth}
    \includestruct{listati/kexec_segment.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{kexec\_segment} per il caricamento di un
    segmento di immagine del kernel.}
  \label{fig:kexec_segment}
\end{figure}

L'argomento \param{flags} è una maschera binaria contenente i flag che
consentono di indicare le modalità con cui dovrà essere eseguito il nuovo
kernel. La parte meno significativa viene usata per impostare l'architettura
di esecuzione. Il valore \const{KEXEC\_ARCH\_DEFAULT} indica l'architettura
corrente, ma se ne può specificare anche una diversa, con i valori della
seconda parte di tab.~\ref{tab:kexec_load_flags}, e questa verrà usato posto
che sia effettivamente eseguibile sul proprio processore.

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Valore} & \textbf{Significato}\\
    \hline
    \hline
    \const{KEXEC\_ON\_CRASH}        & Il kernel caricato sarà eseguito
                                      automaticamente in caso di crollo del
                                      sistema.\\
    \const{KEXEC\_PRESERVE\_CONTEXT}& Viene preservato lo stato dei programmi 
                                      e dei dispositivi prima dell'esecuzione
                                      del nuovo kernel. Viene usato
                                      principalmente per l'ibernazione del
                                      sistema ed ha senso solo se si è
                                      indicato un numero di segmento maggiore
                                      di zero.\\
    \hline
    \const{KEXEC\_ARCH\_DEFAULT}    & Il kernel caricato verrà eseguito nella
                                      architettura corrente. \\
    \texttt{KEXEC\_ARCH\_XXX}       & Il kernel caricato verrà eseguito nella
                                      architettura indicata (con \texttt{XXX}
                                      che può essere: \texttt{386},
                                      \texttt{X86\_64}, \texttt{PPC}, 
                                      \texttt{PPC64}, \texttt{IA\_64},
                                      \texttt{ARM}, \texttt{S390},
                                      \texttt{SH}\texttt{MIPS}
                                      e \texttt{MIPS\_LE}).\\ 
%    \const{}    &  \\
    \hline
  \end{tabular}
  \caption{Valori per l'argomento \param{flags} di \func{kexec\_load}.} 
  \label{tab:kexec_load_flags}
\end{table}

I due valori più importanti sono però quelli della parte più significativa
(riportati nella prima sezione di tab.~\ref{tab:kexec_load_flags}). Il primo,
\const{KEXEC\_ON\_CRASH}, consente di impostare l'esecuzione automatica del
nuovo kernel caricato in caso di crollo del sistema, e viene usato quando si
carica un kernel di emergenza da utilizzare per poter raccogliere informazioni
diagnostiche che altrimenti verrebbero perdute non essendo il kernel ordinario
più in grado di essere eseguito in maniera coerente.  Il secondo valore,
\const{KEXEC\_PRESERVE\_CONTEXT}, indica invece di preservare lo stato dei
programmi e dei dispositivi, e viene in genere usato per realizzare la
cosiddetta ibernazione in RAM.

% TODO: introdotta con il kernel 3.17 è stata introdotta
% kexec_file_load, per caricare immagine firmate per il secure boot,
% vedi anche http://lwn.net/Articles/603116/

% TODO documentare keyctl ????
% (fare sezione dedicata ????)

% TODO documentare la Crypto API del kernel

% TODO documentare la syscall getrandom, introdotta con il kernel 3.17, vedi
% http://lwn.net/Articles/606141/ 

%\subsection{La gestione delle chiavi crittografiche}
%\label{sec:keyctl_management}

%TODO non è chiaro se farlo qui, ma documentare la syscall bpf aggiunta con il
%kernel 3.18, vedi http://lwn.net/Articles/612878/

\section{Il controllo dell'uso delle risorse}
\label{sec:sys_res_limits}


Dopo aver esaminato in sez.~\ref{sec:sys_management} le funzioni che
permettono di controllare le varie caratteristiche, capacità e limiti del
sistema a livello globale, in questa sezione tratteremo le varie funzioni che
vengono usate per quantificare le risorse (CPU, memoria, ecc.) utilizzate da
ogni singolo processo e quelle che permettono di imporre a ciascuno di essi
vincoli e limiti di utilizzo.


\subsection{L'uso delle risorse}
\label{sec:sys_resource_use}

Come abbiamo accennato in sez.~\ref{sec:proc_wait} le informazioni riguardo
l'utilizzo delle risorse da parte di un processo è mantenuto in una struttura
di tipo \struct{rusage}, la cui definizione (che si trova in
\headfile{sys/resource.h}) è riportata in fig.~\ref{fig:sys_rusage_struct}. Si
ricordi che questa è una delle informazioni preservate attraverso una
\func{exec}.

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{0.8\textwidth}
    \includestruct{listati/rusage.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{rusage} per la lettura delle informazioni dei 
    delle risorse usate da un processo.}
  \label{fig:sys_rusage_struct}
\end{figure}

La definizione della struttura in fig.~\ref{fig:sys_rusage_struct} è ripresa
da BSD 4.3,\footnote{questo non ha a nulla a che fare con il cosiddetto
  \textit{BSD accounting} (vedi sez. \ref{sec:sys_bsd_accounting}) che si
  trova nelle opzioni di compilazione del kernel (e di norma è disabilitato)
  che serve per mantenere una contabilità delle risorse usate da ciascun
  processo in maniera molto più dettagliata.} ma attualmente solo alcuni dei
campi definiti sono effettivamente mantenuti. Con i kernel della serie 2.4 i
soli campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime},
\var{ru\_minflt} e \var{ru\_majflt}. Con i kernel della serie 2.6 si
aggiungono anche \var{ru\_nvcsw} e \var{ru\_nivcsw}, a partire dal 2.6.22
anche \var{ru\_inblock} e \var{ru\_oublock} e dal 2.6.32 anche
\var{ru\_maxrss}.

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 di tipo
\struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct}).

La struttura \struct{rusage} è la struttura utilizzata da \func{wait4} (si
ricordi quando visto in sez.~\ref{sec:proc_wait}) 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 di sistema
\funcd{getrusage}, il cui prototipo è:

\begin{funcproto}{
\fhead{sys/time.h}
\fhead{sys/resource.h}
\fhead{unistd.h}
\fdecl{int getrusage(int who, struct rusage *usage)}

\fdesc{Legge la quantità di risorse usate da un processo.}
}

{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] l'argomento \param{who} non è valido
  \end{errlist}
  ed inoltre \errval{EFAULT} nel suo significato generico.
}  
\end{funcproto}

La funzione ritorna i valori per l'uso delle risorse nella struttura
\struct{rusage} puntata dall'argomento \param{usage}.  L'argomento \param{who}
permette di specificare il soggetto di cui si vuole leggere l'uso delle
risorse; esso può assumere solo i valori illustrati in
tab.~\ref{tab:getrusage_who}, di questi \const{RUSAGE\_THREAD} è specifico di
Linux ed è disponibile solo a partire dal kernel 2.6.26. La funzione è stata
recepita nello standard POSIX.1-2001, che però indica come campi di
\struct{rusage} soltanto \var{ru\_utime} e \var{ru\_stime}.

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Valore} & \textbf{Significato}\\
    \hline
    \hline
    \const{RUSAGE\_SELF}     & Ritorna l'uso delle risorse del processo
                               corrente, che in caso di uso dei
                               \textit{thread} ammonta alla somma delle 
                               risorse utilizzate da tutti i \textit{thread}
                               del processo.\\ 
    \const{RUSAGE\_CHILDREN} & Ritorna l'uso delle risorse dell'insieme dei
                               processi figli di cui è ricevuto lo stato di
                               terminazione, che a loro volta comprendono
                               quelle dei loro figli e così via.\\ 
    \const{RUSAGE\_THREAD}   & Ritorna l'uso delle risorse del \textit{thread}
                               chiamante.\\ 
    \hline
  \end{tabular}
  \caption{Valori per l'argomento \param{who} di \func{getrusage}.} 
  \label{tab:getrusage_who}
\end{table}

I campi più utilizzati sono comunque \var{ru\_utime} e \var{ru\_stime} che
indicano rispettivamente il tempo impiegato dal processo nell'eseguire le
istruzioni in \textit{user space}, e quello impiegato dal kernel nelle
\textit{system call} eseguite per conto del processo (vedi
sez.~\ref{sec:sys_unix_time}). I campi \var{ru\_minflt} e \var{ru\_majflt}
servono a quantificare l'uso della memoria virtuale e corrispondono
rispettivamente al numero di \textit{page fault} (vedi
sez.~\ref{sec:proc_mem_gen}) avvenuti senza richiedere I/O su disco (i
cosiddetti \textit{minor page fault}), a quelli che invece han richiesto I/O
su disco (detti invece \textit{major page
  fault}).% mentre \var{ru\_nswap} ed al numero di volte che
% il processo è stato completamente tolto dalla memoria per essere inserito
% nello swap.
% TODO verificare \var{ru\_nswap} non citato nelle pagine di manuali recenti e
% dato per non utilizzato.

I campi \var{ru\_nvcsw} e \var{ru\_nivcsw} indicano il numero di volte che un
processo ha subito un \textit{context switch} da parte dello
\textit{scheduler} rispettivamente nel caso un cui questo avviene prima
dell'esaurimento della propria \textit{time-slice} (in genere a causa di una
\textit{system call} bloccante), o per averla esaurita o essere stato
interrotto da un processo a priorità maggiore. I campi \var{ru\_inblock} e
\var{ru\_oublock} indicano invece il numero di volte che è stata eseguita una
attività di I/O su un filesystem (rispettivamente in lettura e scrittura) ed
infine \var{ru\_maxrss} indica il valore più alto della
\itindex{Resident~Set~Size~(RSS)} \textit{Resident Set Size} raggiunto dal
processo stesso o, nel caso sia stato usato \const{RUSAGE\_CHILDREN}, da uno
dei suoi figli.
 
Si tenga conto che per un errore di implementazione nei i kernel precedenti il
2.6.9, nonostante questo fosse esplicitamente proibito dallo standard POSIX.1,
l'uso di \const{RUSAGE\_CHILDREN} comportava l'inserimento dell'ammontare
delle risorse usate dai processi figli anche quando si era impostata una
azione di \const{SIG\_IGN} per il segnale \const{SIGCHLD} (per i segnali si
veda cap.~\ref{cha:signals}). Il comportamento è stato corretto per aderire
allo standard a partire dal kernel 2.6.9.


\subsection{Limiti sulle risorse}
\label{sec:sys_resource_limit}

Come accennato nell'introduzione il kernel mette a disposizione delle
funzionalità che permettono non solo di mantenere dati statistici relativi
all'uso delle risorse, ma anche di imporre dei limiti precisi sul loro
utilizzo da parte sia dei singoli processi che degli utenti.

Per far questo sono definite una serie di risorse e ad ogni processo vengono
associati due diversi limiti per ciascuna di esse; questi sono il
\textsl{limite corrente} (o \textit{current limit}) che esprime un valore
massimo che il processo non può superare ad un certo momento, ed il
\textsl{limite massimo} (o \textit{maximum limit}) che invece esprime il
valore massimo che può assumere il \textsl{limite corrente}. In generale il
primo viene chiamato anche \textit{soft limit} dato che il suo valore può
essere aumentato dal processo stesso durante l'esecuzione, ciò può però essere
fatto solo fino al valore del secondo, che per questo viene detto \textit{hard
  limit}.

In generale il superamento di un limite corrente comporta o l'emissione di uno
specifico segnale o il fallimento della \textit{system call} che lo ha
provocato. A questo comportamento generico fanno eccezione \const{RLIMIT\_CPU}
in cui si ha in comportamento diverso per il superamento dei due limiti e
\const{RLIMIT\_CORE} che influenza soltanto la dimensione o l'eventuale
creazione dei file di \textit{core dump} (vedi sez.~\ref{sec:sig_standard}).

Per permettere di leggere e di impostare i limiti di utilizzo delle risorse da
parte di un processo sono previste due funzioni di sistema, \funcd{getrlimit}
e \funcd{setrlimit}, i cui prototipi sono:

\begin{funcproto}{
\fhead{sys/time.h}
\fhead{sys/resource.h}
\fhead{unistd.h}
\fdecl{int getrlimit(int resource, struct rlimit *rlim)}
\fdesc{Legge i limiti di una risorsa.}
\fdecl{int setrlimit(int resource, const struct rlimit *rlim)}
\fdesc{Imposta i limiti di una risorsa.}
}

{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] i valori per \param{resource} non sono validi o
    nell'impostazione si è specificato \var{rlim->rlim\_cur} maggiore di
    \var{rlim->rlim\_max}.
    \item[\errcode{EPERM}] un processo senza i privilegi di amministratore ha
    cercato di innalzare i propri limiti.
  \end{errlist}
  ed inoltre \errval{EFAULT} nel suo significato generico.  
}  
\end{funcproto}

Entrambe le funzioni permettono di specificare attraverso l'argomento
\param{resource} su quale risorsa si vuole operare. L'accesso (rispettivamente
in lettura e scrittura) ai valori effettivi dei limiti viene poi effettuato
attraverso la struttura \struct{rlimit} puntata da
\param{rlim}, la cui definizione è riportata in
fig.~\ref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a
limite corrente e limite massimo.

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{0.8\textwidth}
    \includestruct{listati/rlimit.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{rlimit} per impostare i limiti di utilizzo 
    delle risorse usate da un processo.}
  \label{fig:sys_rlimit_struct}
\end{figure}

Come accennato processo ordinario può alzare il proprio limite corrente fino
al valore del limite massimo, può anche ridurre, irreversibilmente, il valore
di quest'ultimo.  Nello specificare un limite, oltre a fornire dei valori
specifici, si può anche usare la costante \const{RLIM\_INFINITY} che permette
di sbloccare completamente l'uso di una risorsa. Si ricordi però che solo un
processo con i privilegi di amministratore\footnote{per essere precisi in
  questo caso quello che serve è la \textit{capability}
  \const{CAP\_SYS\_RESOURCE} (vedi sez.~\ref{sec:proc_capabilities}).} può
innalzare un limite al di sopra del valore corrente del limite massimo ed
usare un valore qualsiasi per entrambi i limiti.

Ciascuna risorsa su cui si possono applicare dei limiti è identificata da uno
specifico valore dell'argomento \param{resource}, i valori possibili per
questo argomento, ed il significato della risorsa corrispondente, dei
rispettivi limiti e gli effetti causati dal superamento degli stessi sono
riportati nel seguente elenco:

\begin{basedescript}{\desclabelwidth{2.2cm}}%\desclabelstyle{\nextlinelabel}}
\item[\const{RLIMIT\_AS}] Questa risorsa indica, in byte, la dimensione
  massima consentita per la memoria virtuale di un processo, il cosiddetto
  \textit{Address Space}, (vedi sez.~\ref{sec:proc_mem_gen}). Se il limite
  viene superato dall'uso di funzioni come \func{brk}, \func{mremap} o
  \func{mmap} esse falliranno con un errore di \errcode{ENOMEM}, mentre se il
  superamento viene causato dalla crescita dello \itindex{stack}
  \textit{stack} il processo riceverà un segnale di \signal{SIGSEGV}. Dato che
  il valore usato è un intero di tipo \ctyp{long} nelle macchine a 32 bit
  questo può assumere un valore massimo di 2Gb (anche se la memoria
  disponibile può essere maggiore), in tal caso il limite massimo indicabile
  resta 2Gb, altrimenti la risorsa si dà per non limitata.

\item[\const{RLIMIT\_CORE}] Questa risorsa indica, in byte, la massima
  dimensione per un file di \textit{core dump} (vedi
  sez.~\ref{sec:sig_standard}) creato nella terminazione di un processo. File
  di dimensioni maggiori verranno troncati a questo valore, mentre con un
  valore nullo si bloccherà la creazione dei \textit{core dump}.

\item[\const{RLIMIT\_CPU}] Questa risorsa indica, in secondi, il massimo tempo
  di CPU (vedi sez.~\ref{sec:sys_cpu_times}) che il processo può usare. Il
  superamento del limite corrente comporta l'emissione di un segnale di
  \signal{SIGXCPU}, la cui azione predefinita (vedi
  sez.~\ref{sec:sig_classification}) è terminare il processo. Il segnale però
  può essere intercettato e ignorato, in tal caso esso verrà riemesso una
  volta al secondo fino al raggiungimento del limite massimo. Il superamento
  del limite massimo comporta comunque l'emissione di un segnale di
  \signal{SIGKILL}. Si tenga presente che questo è il comportamento presente
  su Linux dai kernel della serie 2.2 ad oggi, altri kernel possono avere
  comportamenti diversi per quanto avviene quando viene superato il
  \textit{soft limit}, pertanto per avere operazioni portabili è suggerito di
  intercettare sempre \signal{SIGXCPU} e terminare in maniera ordinata il
  processo con la prima ricezione.

\item[\const{RLIMIT\_DATA}] Questa risorsa indica, in byte, la massima
  dimensione del \index{segmento!dati} segmento dati di un processo (vedi
  sez.~\ref{sec:proc_mem_layout}).  Il tentativo di allocare più memoria di
  quanto indicato dal limite corrente causa il fallimento della funzione di
  allocazione eseguita (\func{brk} o \func{sbrk}) con un errore di
  \errcode{ENOMEM}.

\item[\const{RLIMIT\_FSIZE}] Questa risorsa indica, in byte, la massima
  dimensione di un file che un processo può usare. Se il processo cerca di
  scrivere o di estendere il file oltre questa dimensione riceverà un segnale
  di \signal{SIGXFSZ}, che di norma termina il processo. Se questo segnale
  viene intercettato la \textit{system call} che ha causato l'errore fallirà
  con un errore di \errcode{EFBIG}.

\item[\const{RLIMIT\_LOCKS}] Questa risorsa indica il numero massimo di
  \itindex{file~locking} \textit{file lock} (vedi sez.~\ref{sec:file_locking})
  e di \textit{file lease} (vedi sez.~\ref{sec:file_asyncronous_lease}) che un
  processo poteva effettuare.  È un limite presente solo nelle prime versioni
  del kernel 2.4, pertanto non deve essere più utilizzato.

\item[\const{RLIMIT\_MEMLOCK}] Questa risorsa indica, in byte, l'ammontare
  massimo di memoria che può essere bloccata in RAM da un processo (vedi
  sez.~\ref{sec:proc_mem_lock}). Dato che il \itindex{memory~locking}
  \textit{memory locking} viene effettuato sulle pagine di memoria, il valore
  indicato viene automaticamente arrotondato al primo multiplo successivo
  della dimensione di una pagina di memoria. Il limite comporta il fallimento
  delle \textit{system call} che eseguono il \textit{memory locking}
  (\func{mlock}, \func{mlockall} ed anche, vedi
  sez.~\ref{sec:file_memory_map}, \func{mmap} con l'operazione
  \const{MAP\_LOCKED}). 

  Dal kernel 2.6.9 questo limite comprende anche la memoria che può essere
  bloccata da ciascun utente nell'uso della memoria condivisa (vedi
  sez.~\ref{sec:ipc_sysv_shm}) con \func{shmctl}, che viene contabilizzata
  separatamente ma sulla quale viene applicato questo stesso limite. In
  precedenza invece questo limite veniva applicato sulla memoria condivisa per
  processi con privilegi amministrativi, il limite su questi è stato rimosso e
  la semantica della risorsa cambiata.


\item[\const{RLIMIT\_MSGQUEUE}] Questa risorsa indica il numero massimo di
  byte che possono essere utilizzati da un utente, identificato con
  l'\ids{UID} reale del processo chiamante, per le code di messaggi POSIX
  (vedi sez.~\ref{sec:ipc_posix_mq}). Per ciascuna coda che viene creata viene
  calcolata un'occupazione pari a:
\includecodesnip{listati/mq_occupation.c}
dove \var{attr} è la struttura \struct{mq\_attr} (vedi
fig.~\ref{fig:ipc_mq_attr}) usata nella creazione della coda. Il primo addendo
consente di evitare la creazione di una coda con un numero illimitato di
messaggi vuoti che comunque richiede delle risorse di gestione. Questa risorsa
è stata introdotta con il kernel 2.6.8.

\item[\const{RLIMIT\_NICE}] Questa risorsa indica il numero massimo a cui può
  essere il portato il valore di \textit{nice} (vedi
  sez.~\ref{sec:proc_sched_stand}). Dato che non possono essere usati numeri
  negativi per specificare un limite, il valore di \textit{nice} viene
  calcolato come \code{20-rlim\_cur}. Questa risorsa è stata introdotta con il
  kernel 2.6.12.

\item[\const{RLIMIT\_NOFILE}] Questa risorsa indica il numero massimo di file
  che un processo può aprire. Il tentativo di creazione di un ulteriore file
  descriptor farà fallire la funzione (\func{open}, \func{dup}, \func{pipe},
  ecc.) con un errore \errcode{EMFILE}.

\item[\const{RLIMIT\_NPROC}] Questa risorsa indica il numero massimo di
  processi che possono essere creati dallo stesso utente, che viene
  identificato con l'\ids{UID} reale (vedi sez.~\ref{sec:proc_access_id}) del
  processo chiamante. Se il limite viene raggiunto \func{fork} fallirà con un
  \errcode{EAGAIN}.

\item[\const{RLIMIT\_RSS}] Questa risorsa indica, in pagine di memoria, la
  dimensione massima della memoria residente (il cosiddetto RSS
  \itindex{Resident~Set~Size~(RSS)} \textit{Resident Set Size}) cioè
  l'ammontare della memoria associata al processo che risiede effettivamente
  in RAM e non a quella eventualmente portata sulla \textit{swap} o non ancora
  caricata dal filesystem per il \index{segmento!testo} segmento testo del
  programma.  Ha effetto solo sulle chiamate a \func{madvise} con
  \const{MADV\_WILLNEED} (vedi sez.~\ref{sec:file_memory_map}). Presente solo
  sui i kernel precedenti il 2.4.30.

\item[\const{RLIMIT\_RTPRIO}] Questa risorsa indica il valore massimo della
  priorità statica che un processo può assegnarsi o assegnare con
  \func{sched\_setscheduler} e \func{sched\_setparam} (vedi
  sez.~\ref{sec:proc_real_time}). Il limite è stato introdotto a partire dal
  kernel 2.6.12 (ma per un bug è effettivo solo a partire dal 2.6.13). In
  precedenza solo i processi con privilegi amministrativi potevano avere una
  priorità statica ed utilizzare una politica di \textit{scheduling} di tipo
  \textit{real-time}.

\item[\const{RLIMIT\_RTTIME}] Questa risorsa indica, in microsecondi, il tempo
  massimo di CPU che un processo eseguito con una priorità statica può
  consumare. Il superamento del limite corrente comporta l'emissione di un
  segnale di \signal{SIGXCPU}, e quello del limite massimo di \signal{SIGKILL}
  con le stesse regole viste \const{RLIMIT\_CPU}: se \signal{SIGXCPU} viene
  intercettato ed ignorato il segnale verrà riemesso ogni secondo fino al
  superamento del limite massimo. Questo limite è stato introdotto con il
  kernel 2.6.25 per impedire che un processo \textit{real-time} possa bloccare
  il sistema.

\item[\const{RLIMIT\_SIGPENDING}] Questa risorsa indica il numero massimo di
  segnali che possono essere mantenuti in coda per ciascun utente,
  identificato per \ids{UID} reale. Il limite comprende sia i segnali normali
  che quelli \textit{real-time} (vedi sez.~\ref{sec:sig_real_time}) ed è
  attivo solo per \func{sigqueue}, con \func{kill} si potrà sempre inviare un
  segnale che non sia già presente su una coda. Questo limite è stato
  introdotto con il kernel 2.6.8.

\item[\const{RLIMIT\_STACK}] Questa risorsa indica, in byte, la massima
  dimensione dello \itindex{stack} \textit{stack} del processo. Se il processo
  esegue operazioni che estendano lo \textit{stack} oltre questa dimensione
  riceverà un segnale di \signal{SIGSEGV}. 

  A partire dal kernel 2.6.23 questo stesso limite viene applicato per la gran
  parte delle architetture anche ai dati che possono essere passati come
  argomenti e variabili di ambiente ad un programma posto in esecuzione con
  \func{execve}, nella misura di un quarto del valore indicato per lo
  \textit{stack}.  Questo valore in precedenza era fisso e pari a 32 pagine di
  memoria, corrispondenti per la gran parte delle architetture a 128kb di
  dati, dal 2.6.25, per evitare problemi di compatibilità quando
  \const{RLIMIT\_STACK} è molto basso, viene comunque garantito uno spazio
  base di 32 pagine qualunque sia l'architettura.

\end{basedescript}

Si tenga conto infine che tutti i limiti eventualmente presenti su un processo
vengono ereditati dai figli da esso creati attraverso una \func{fork} (vedi
sez.~\ref{sec:proc_fork}) e mantenuti invariati per i programmi messi in
esecuzione attraverso una \func{exec} (vedi sez.~\ref{sec:proc_exec}).

Si noti come le due funzioni \func{getrlimit} e \func{setrlimit} consentano di
operare solo sul processo corrente. Per questo motivo a partire dal kernel
2.6.36 (e dalla \acr{glibc} 2.13) è stata introdotta un'altra funzione di
sistema \funcd{prlimit} il cui scopo è quello di estendere e sostituire le
precedenti.  Il suo prototipo è:

\begin{funcproto}{
\fhead{sys/resource.h}
\fdecl{int prlimit(pid\_t pid, int resource, const struct rlimit *new\_limit,\\
\phantom{int prlimit(}struct rlimit *old\_limit}
\fdesc{Legge e imposta i limiti di una risorsa.} 
}

{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] i valori per \param{resource} non sono validi o
    nell'impostazione si è specificato \var{rlim->rlim\_cur} maggiore di
    \var{rlim->rlim\_max}.
  \item[\errcode{EPERM}] un processo senza i privilegi di amministratore ha
    cercato di innalzare i propri limiti o si è cercato di modificare i limiti
    di un processo di un altro utente.
  \item [\errcode{ESRCH}] il process \param{pid} non esiste.
  \end{errlist}
  ed inoltre \errval{EFAULT} nel suo significato generico.
}
\end{funcproto}

La funzione è specifica di Linux e non portabile; per essere usata richiede
che sia stata definita la macro \macro{\_GNU\_SOURCE}. Il primo argomento
indica il \ids{PID} del processo di cui si vogliono cambiare i limiti e si può
usare un valore nullo per indicare il processo chiamante.  Per modificare i
limiti di un altro processo, a meno di non avere privilegi
amministrativi,\footnote{anche in questo caso la \textit{capability}
  necessaria è \const{CAP\_SYS\_RESOURCE} (vedi
  sez.~\ref{sec:proc_capabilities}).}  l'\ids{UID} ed il \ids{GID} reale del
chiamante devono coincidere con \ids{UID} e \ids{GID} del processo indicato
per i tre gruppi reale, effettivo e salvato.

Se \param{new\_limit} non è \val{NULL} verrà usato come puntatore alla
struttura \struct{rlimit} contenente i valori dei nuovi limiti da impostare,
mentre se \param{old\_limit} non è \val{NULL} verranno letti i valori correnti
del limiti nella struttura \struct{rlimit} da esso puntata. In questo modo è
possibile sia leggere che scrivere, anche in contemporanea, i valori dei
limiti. Il significato dell'argomento \param{resource} resta identico rispetto
a \func{getrlimit} e \func{setrlimit}, così come i restanti requisiti. 


\subsection{Le informazioni sulle risorse di memoria e processore}
\label{sec:sys_memory_res}

La gestione della memoria è già stata affrontata in dettaglio in
sez.~\ref{sec:proc_memory}; abbiamo visto allora che il kernel provvede il
meccanismo della memoria virtuale attraverso la divisione della memoria fisica
in pagine.  In genere tutto ciò è del tutto trasparente al singolo processo,
ma in certi casi, come per l'I/O mappato in memoria (vedi
sez.~\ref{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 che si sta allocando con il meccanismo della paginazione.

Un tempo la dimensione delle pagine di memoria era fissata una volta per tutte
dall'architettura hardware, per cui il relativo valore veniva mantenuto in una
costante che bastava utilizzare in fase di compilazione. Oggi invece molte
architetture permettono di variare questa dimensione (ad esempio sui PC
recenti si possono usare pagine di 4kb e di 4 Mb) per cui per non dover
ricompilare i programmi per ogni possibile caso e relativa scelta di
dimensioni, è necessario poter utilizzare una funzione che restituisca questi
valori quando il programma viene eseguito.

Dato che si tratta di una caratteristica generale del sistema come abbiamo
visto in sez.~\ref{sec:sys_characteristics} questa dimensione può essere
ottenuta come tutte le altre attraverso una chiamata a \func{sysconf}, nel
caso specifico si dovrebbe utilizzare il parametro \const{\_SC\_PAGESIZE}. Ma
in BSD 4.2 è stata introdotta una apposita funzione di sistema
\funcd{getpagesize} che restituisce la dimensione delle pagine di memoria. La
funzione è disponibile anche su Linux (ma richiede che sia definita la macro
\macro{\_BSD\_SOURCE}) ed il suo prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int getpagesize(void)}
\fdesc{Legge la dimensione delle pagine di memoria.} 
}

{La funzione ritorna la dimensione di una pagina in byte, e non sono previsti
  errori.}
\end{funcproto}

La funzione è prevista in SVr4, BSD 4.4 e SUSv2, anche se questo ultimo
standard la etichetta come obsoleta, mentre lo standard POSIX 1003.1-2001 la
ha eliminata, ed i programmi che intendono essere portabili devono ricorrere
alla chiamata a \func{sysconf}. 

In Linux è implementata come una \textit{system call} nelle architetture in
cui essa è necessaria, ed in genere restituisce il valore del simbolo
\const{PAGE\_SIZE} del kernel, che dipende dalla architettura hardware, anche
se le versioni delle librerie del C precedenti le \acr{glibc} 2.1
implementavano questa funzione restituendo sempre un valore statico.

% TODO verificare meglio la faccenda di const{PAGE\_SIZE} 

Le \textsl{glibc} forniscono, come specifica estensione GNU, altre due
funzioni, \funcd{get\_phys\_pages} e \funcd{get\_avphys\_pages} che permettono
di ottenere informazioni riguardo le pagine di memoria; i loro prototipi sono:

\begin{funcproto}{
\fhead{sys/sysinfo.h} 
\fdecl{long int get\_phys\_pages(void)}
\fdesc{Legge il numero totale di pagine di memoria.} 
\fdecl{long int get\_avphys\_pages(void)} 
\fdesc{Legge il numero di pagine di memoria disponibili nel sistema.} 
}

{La funzioni ritornano il numero di pagine, e non sono previsti
  errori.}  
\end{funcproto}

Queste funzioni sono equivalenti all'uso della funzione \func{sysconf}
rispettivamente con i parametri \const{\_SC\_PHYS\_PAGES} e
\const{\_SC\_AVPHYS\_PAGES}. La prima restituisce il numero totale di pagine
corrispondenti alla RAM della macchina; la seconda invece la memoria
effettivamente disponibile per i processi.

Le \acr{glibc} supportano inoltre, come estensioni GNU, due funzioni che
restituiscono il numero di processori della macchina (e quello dei processori
attivi); anche queste sono informazioni comunque ottenibili attraverso
\func{sysconf} utilizzando rispettivamente i parametri
\const{\_SC\_NPROCESSORS\_CONF} e \const{\_SC\_NPROCESSORS\_ONLN}.

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 è:

\begin{funcproto}{
\fhead{stdlib.h}
\fdecl{int getloadavg(double loadavg[], int nelem)}
\fdesc{Legge il carico medio della macchina.} 
}

{La funzione ritorna il numero di campionamenti restituiti e $-1$ se non
  riesce ad ottenere il carico medio, \var{errno} non viene modificata.}
\end{funcproto}

La funzione restituisce in ciascun elemento di \param{loadavg} il numero medio
di processi attivi sulla coda dello \textit{scheduler}, calcolato su diversi
intervalli di tempo.  Il numero di intervalli che si vogliono leggere è
specificato da \param{nelem}, dato che nel caso di Linux il carico viene
valutato solo su tre intervalli (corrispondenti a 1, 5 e 15 minuti), questo è
anche il massimo valore che può essere assegnato a questo argomento.


\subsection{La \textsl{contabilità} in stile BSD}
\label{sec:sys_bsd_accounting}

Una ultima modalità per monitorare l'uso delle risorse è, se si è compilato il
kernel con il relativo supporto,\footnote{se cioè si è abilitata l'opzione di
  compilazione \texttt{CONFIG\_BSD\_PROCESS\_ACCT}.} quella di attivare il
cosiddetto \textit{BSD accounting}, che consente di registrare su file una
serie di informazioni\footnote{contenute nella struttura \texttt{acct}
  definita nel file \texttt{include/linux/acct.h} dei sorgenti del kernel.}
riguardo alla \textsl{contabilità} delle risorse utilizzate da ogni processo
che viene terminato.

Linux consente di salvare la contabilità delle informazioni relative alle
risorse utilizzate dai processi grazie alla funzione \funcd{acct}, il cui
prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int acct(const char *filename)}
\fdesc{Abilita il \textit{BSD accounting}.} 
}

{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
    \item[\errcode{EACCES}] non si hanno i permessi per accedere a
      \param{pathname}.
    \item[\errcode{ENOSYS}] il kernel non supporta il \textit{BSD accounting}.
    \item[\errcode{EPERM}] il processo non ha privilegi sufficienti ad
      abilitare il \textit{BSD accounting}.
    \item[\errcode{EUSERS}] non sono disponibili nel kernel strutture per il
      file o si è finita la memoria.
    \end{errlist}
    ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP},
    \errval{ENAMETOOLONG}, \errval{ENFILE}, \errval{ENOENT}, \errval{ENOMEM},
    \errval{ENOTDIR}, \errval{EROFS} nel loro significato generico.}
\end{funcproto}

La funzione attiva il salvataggio dei dati sul file indicato dal
\textit{pathname} contenuti nella stringa puntata da \param{filename}; la
funzione richiede che il processo abbia i privilegi di amministratore (è
necessaria la \textit{capability} \const{CAP\_SYS\_PACCT}, vedi
sez.~\ref{sec:proc_capabilities}). Se si specifica il valore \val{NULL} per
\param{filename} il \textit{BSD accounting} viene invece disabilitato. Un
semplice esempio per l'uso di questa funzione è riportato nel programma
\texttt{AcctCtrl.c} dei sorgenti allegati alla guida.

Quando si attiva la contabilità, il file che si indica deve esistere; esso
verrà aperto in sola scrittura e le informazioni verranno registrate in
\textit{append} in coda al file tutte le volte che un processo termina. Le
informazioni vengono salvate in formato binario, e corrispondono al contenuto
della apposita struttura dati definita all'interno del kernel.

Il funzionamento di \func{acct} viene inoltre modificato da uno specifico
parametro di sistema, modificabile attraverso \sysctlfile{kernel/acct} (o
tramite la corrispondente \func{sysctl}). Esso contiene tre valori interi, il
primo indica la percentuale di spazio disco libero sopra il quale viene
ripresa una registrazione che era stata sospesa per essere scesi sotto il
minimo indicato dal secondo valore (sempre in percentuale di spazio disco
libero). Infine l'ultimo valore indica la frequenza in secondi con cui deve
essere controllata detta percentuale.

% TODO: bassa priorità, trattare la lettura del file di accounting, da
% programma, vedi man 5 acct


\section{La gestione dei tempi del sistema}
\label{sec:sys_time}

In questa sezione, una volta introdotti i concetti base della gestione dei
tempi da parte del sistema, tratteremo le varie funzioni attinenti alla
gestione del tempo in un sistema unix-like, a partire da quelle per misurare i
veri tempi di sistema associati ai processi, a quelle per convertire i vari
tempi nelle differenti rappresentazioni che vengono utilizzate, a quelle della
gestione di data e ora.


\subsection{La misura del tempo in Unix}
\label{sec:sys_unix_time}

\itindbeg{calendar~time}

Tradizionalmente nei sistemi unix-like sono sempre stati previsti due tipi
distinti di tempi, caratterizzati da altrettante modalità di misura ed
espressi con diversi tipi di dati, chiamati rispettivamente \textit{calendar
  time} e \textit{process time}, secondo le seguenti definizioni:
\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}

\item[\textit{calendar time}] detto anche \textsl{tempo di calendario}, 
  \textsl{tempo d'orologio} o \textit{tempo reale}. Si tratta di un
  tempo assoluto o di un intervallo di tempo come lo intende
  normalmente per le misure fatte con un orologio. Per esprimere
  questo tempo è stato riservato il tipo \type{time\_t}, e viene
  tradizionalmente misurato in secondi a partire dalla mezzanotte del
  primo gennaio 1970, data che viene chiamata \textit{the Epoch}.

\item[\textit{process time}] \itindex{process~time} detto anche \textsl{tempo
    di processore} o \textsl{tempo di CPU}. Si tratta del tempo impiegato da
  un processore nell'esecuzione del codice di un programma all'interno di un
  processo. Per esprimere questo tempo è stato riservato il tipo
  \type{clock\_t}, e viene misurato nei cosiddetti \itindex{clock~tick}
  \textit{clock tick}, tradizionalmente corrispondenti al numero di
  interruzioni del processore da parte del timer di sistema. A differenza del
  precedente indica soltanto un intervallo di durata.
\end{basedescript}

Il \textit{calendar time} viene sempre mantenuto facendo riferimento
al cosiddetto \textit{tempo universale coordinato} UTC, anche se
talvolta viene usato il cosiddetto GMT (\textit{Greenwich Mean Time})
dato che l'UTC corrisponde all'ora locale di Greenwich. Si tratta del
tempo su cui viene mantenuto il cosiddetto \textsl{orologio di
  sistema}, e viene usato per indicare i tempi dei file (quelli di
sez.~\ref{sec:file_file_times}) o le date di avvio dei processi, ed è
il tempo che viene usato dai demoni che compiono lavori amministrativi
ad orari definito, come \cmd{cron}.

Si tenga presente che questo tempo è mantenuto dal kernel e non è detto che
corrisponda al tempo misurato dall'orologio hardware presente su praticamente
tutte le piastre madri dei computer moderni (il cosiddetto \textit{hardware
  clock}), il cui valore viene gestito direttamente dall'hardware in maniera
indipendente e viene usato dal kernel soltanto all'avvio per impostare un
valore iniziale dell'orologio di sistema. La risoluzione tradizionale data dal
tipo di dato \type{time\_t} è di un secondo, ma nei sistemi più recenti sono
disponibili altri tipi di dati con precisioni maggiori.

Si tenga presente inoltre che a differenza di quanto avviene con altri sistemi
operativi,\footnote{è possibile, ancorché assolutamente sconsigliabile,
  forzare l'orologio di sistema all'ora locale per compatibilità con quei
  sistemi operativi che han fatto questa deprecabile scelta.}  l'orologio di
sistema viene mantenuto sempre in UTC e che la conversione all'ora locale del
proprio fuso orario viene effettuata dalle funzioni di libreria utilizzando le
opportune informazioni di localizzazione (specificate in
\conffile{/etc/timezone}). In questo modo si ha l'assicurazione che l'orologio
di sistema misuri sempre un tempo monotono crescente come nella realtà, anche
in presenza di cambi di fusi orari.

\itindend{calendar~time}

Il \itindex{process~time} \textit{process time} invece indica sempre una
misura di un lasso di tempo e viene usato per tenere conto dei tempi di
esecuzione dei processi. Esso viene sempre diviso in \textit{user time} e
\textit{system time}, per misurare la durata di ciascun processo il kernel
infatti calcola tre tempi:
\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
\item[\textit{clock time}] il tempo \textsl{reale}, viene chiamato anche
  \textit{wall clock time} o \textit{elapsed time}, passato dall'avvio del
  processo. Questo tempo fa riferimento al 
  \textit{calendar time} e dice la durata effettiva dell'esecuzione del
  processo, ma chiaramente dipende dal carico del sistema e da quanti altri
  processi stanno girando nello stesso momento.
  
\item[\textit{user time}] il tempo effettivo che il processore ha impiegato
  nell'esecuzione delle istruzioni del programma in \textit{user space}. È
  anche quello riportato nella risorsa \var{ru\_utime} di \struct{rusage}
  vista in sez.~\ref{sec:sys_resource_use}.
  
\item[\textit{system time}] il tempo effettivo che il processore ha impiegato
  per eseguire codice delle \textit{system call} nel kernel per conto del
  processo.  È anche quello riportato nella risorsa \var{ru\_stime} di
  \struct{rusage} vista in sez.~\ref{sec:sys_resource_use}.
\end{basedescript}

La somma di \textit{user time} e \textit{system time} indica il
\itindex{process~time} \textit{process time}, vale a dire il tempo di
processore totale che il sistema ha effettivamente utilizzato per eseguire il
programma di un certo processo. Si può ottenere un riassunto dei valori di
questi tempi quando si esegue un qualsiasi programma lanciando quest'ultimo
come argomento del comando \cmd{time}.

Come accennato il \itindex{process~time} \textit{process time} viene misurato
nei cosiddetti \itindex{clock~tick} \textit{clock tick}. Un tempo questo
corrispondeva al numero di interruzioni effettuate dal timer di sistema, oggi
lo standard POSIX richiede che esso sia espresso come multiplo della costante
\const{CLOCKS\_PER\_SEC} che deve essere definita come 1000000, qualunque sia
la risoluzione reale dell'orologio di sistema e la frequenza delle
interruzioni del timer che, come accennato in sez.~\ref{sec:proc_hierarchy} e
come vedremo a breve, è invece data dalla costante \const{HZ}.

Il tipo di dato usato per questo tempo, \type{clock\_t}, con questa
convenzione ha una risoluzione del microsecondo. Ma non tutte le funzioni di
sistema come vedremo seguono questa convenzione, in tal caso il numero di
\itindex{clock~tick} \textit{clock tick} al secondo può essere ricavato anche
attraverso \func{sysconf} richiedendo il valore della costante
\const{\_SC\_CLK\_TCK} (vedi sez.~\ref{sec:sys_limits}).  Il vecchio simbolo
\const{CLK\_TCK} definito in \headfile{time.h} è ormai considerato obsoleto e
non deve essere usato.

In realtà tutti calcoli dei tempi vengono effettuati dal kernel per il
cosiddetto \textit{software clock}, utilizzando il \textit{timer di sistema} e
facendo i conti in base al numero delle interruzioni generate dello stesso, i
cosiddetti \itindex{jiffies} ``\textit{jiffies}''. La durata di un
``\textit{jiffy}'' è determinata dalla frequenza di interruzione del timer,
indicata in Hertz, come accennato in sez.~\ref{sec:proc_hierarchy}, dal valore
della costante \const{HZ} del kernel, definita in \file{asm/param.h}.

Fino al kernel 2.4 il valore di \const{HZ} era 100 su tutte le architetture
tranne l'alpha, per cui era 1000. Con il 2.6.0 è stato portato a 1000 su tutte
le architetture, ma dal 2.6.13 il valore è diventato una opzione di
compilazione del kernel, con un default di 250 e valori possibili di 100, 250,
1000. Dal 2.6.20 è stato aggiunto anche il valore 300 che è divisibile per le
frequenze di refresh della televisione (50 o 60 Hz). Si può pensare che questi
valori determinino anche la corrispondente durata dei \itindex{clock~tick}
\textit{clock tick}, ma in realtà questa granularità viene calcolata in
maniera indipendente usando la costante del kernel \const{USER\_HZ}.

Fino al kernel 2.6.21 la durata di un \textit{jiffy} costituiva la risoluzione
massima ottenibile nella misura dei tempi impiegabile in una \textit{system
  call} (ad esempio per i timeout). Con il 2.6.21 e l'introduzione degli
\itindex{High~Resolution~Timer~(HRT)} \textit{high-resolution timers} (HRT) è
divenuto possibile ottenere, per le funzioni di attesa ed i timer, la massima
risoluzione possibile fornita dall'hardware. Torneremo su questo in
sez.~\ref{sec:sig_timer_adv}.



\subsection{La gestione del \textit{process time}}
\label{sec:sys_cpu_times}

\itindbeg{process~time}

Di norma tutte le operazioni del sistema fanno sempre riferimento al
\textit{calendar time}, l'uso del \textit{process time} è riservato a
quei casi in cui serve conoscere i tempi di esecuzione di un processo
(ad esempio per valutarne l'efficienza). In tal caso infatti fare
ricorso al \textit{calendar time} è inutile in quanto il tempo può
essere trascorso mentre un altro processo era in esecuzione o in
attesa del risultato di una operazione di I/O.

La funzione più semplice per leggere il \textit{process time} di un processo è
\funcd{clock}, che da una valutazione approssimativa del tempo di CPU
utilizzato dallo stesso; il suo prototipo è:

\begin{funcproto}{
\fhead{time.h}
\fdecl{clock\_t clock(void)}
\fdesc{Legge il valore corrente del tempo di CPU.} 
}

{La funzione ritorna il tempo di CPU in caso di successo e $-1$ se questo non
  è ottenibile o rappresentabile in un valore di tipo \type{clock\_t},
  \var{errno} non viene usata.}  
\end{funcproto}

La funzione restituisce il tempo in \itindex{clock~tick} \textit{clock tick}
ma la \acr{glibc} segue lo standard POSIX e quindi se si vuole il tempo in
secondi occorre dividere il risultato per la costante
\const{CLOCKS\_PER\_SEC}. In genere \type{clock\_t} viene rappresentato come
intero a 32 bit, il che comporta un valore massimo corrispondente a circa 72
minuti, dopo i quali il contatore riprenderà lo stesso valore iniziale.

La funzione è presente anche nello standard ANSI C, ma in tal caso non è
previsto che il valore ritornato indichi un intervallo di tempo ma solo un
valore assoluto, per questo se si vuole la massima portabilità anche al di
fuori di kernel unix-like, può essere opportuno chiamare la funzione
all'inizio del programma ed ottenere il valore del tempo con una differenza.

Si tenga presente inoltre che con altri kernel unix-like il valore riportato
dalla funzione può includere anche il tempo di processore usato dai processi
figli di cui si è ricevuto lo stato di terminazione con \func{wait} e
affini. Questo non vale per Linux, in cui questa informazione deve essere
ottenuta separatamente.

Come accennato in sez.~\ref{sec:sys_unix_time} il tempo di processore è 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 separatamente attraverso la funzione \funcd{times}, il
cui prototipo è:

\begin{funcproto}{
\fhead{sys/times.h}
\fdecl{clock\_t times(struct tms *buf)}
\fdesc{Legge il valore corrente dei tempi di processore.} 
}

{La funzione ritorna un numero di \textit{clock tick} in caso di successo e
  $-1$ per un errore, nel qual caso \var{errno} potrà assumere solo il valore
  \errval{EFAULT} nel suo significato generico.}
\end{funcproto} 

La funzione restituisce i valori di \textit{process time} del processo
corrente in una struttura di tipo \struct{tms}, la cui definizione è riportata
in fig.~\ref{fig:sys_tms_struct}. La struttura prevede quattro campi; i primi
due, \var{tms\_utime} e \var{tms\_stime}, sono l'\textit{user time} ed il
\textit{system time} del processo, così come definiti in
sez.~\ref{sec:sys_unix_time}.  Gli altri due campi, \var{tms\_cutime} e
\var{tms\_cstime}, riportano la somma dell'\textit{user time} e del
\textit{system time} di tutti processi figli di cui si è ricevuto lo stato di
terminazione. 

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{0.8\textwidth}
    \includestruct{listati/tms.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{tms} dei tempi di processore associati a un
    processo.} 
  \label{fig:sys_tms_struct}
\end{figure}


Si tenga presente che i tempi di processore dei processi figli di un processo
vengono sempre sommati al valore corrente ogni volta che se ne riceve lo stato
di terminazione, e detto valore è quello che viene a sua volta ottenuto dal
processo padre. Pertanto nei campi \var{tms\_cutime} e \var{tms\_cstime} si
sommano anche i tempi di ulteriori discendenti di cui i rispettivi genitori
abbiano ricevuto lo stato di terminazione.

Si tenga conto che l'aggiornamento di \var{tms\_cutime} e \var{tms\_cstime}
viene eseguito solo quando una chiamata a \func{wait} o \func{waitpid} è
ritornata. Per questo motivo se un processo figlio termina prima di ricevere
lo stato di terminazione di tutti i suoi figli, questi processi
``\textsl{nipoti}'' non verranno considerati nel calcolo di questi tempi e
così via per i relativi ``\textsl{discendenti}''. 

Come accennato in sez.~\ref{sec:sys_resource_use} per i kernel precedenti la
versione 2.6.9 il tempo di processore dei processi figli veniva sommato
comunque chiedendo di ignorare \const{SIGCHLD} anche se lo standard POSIX
richiede esplicitamente che questo avvenga solo quando si riceve lo stato di
uscita con una funzione della famiglia delle \func{wait}, anche in questo caso
il comportamento è stato adeguato allo standard a partire dalla versione
2.6.9.

A differenza di quanto avviene per \func{clock} i valori restituiti nei campi
di una struttura \struct{tms} sono misurati in numero di \itindex{clock~tick}
\textit{clock tick} effettivi e non in multipli di \const{CLOCKS\_PER\_SEC},
pertanto per ottenere il valore effettivo in secondi occorrerà dividere per il
risultato di \code{sysconf(\_SC\_CLK\_TCK)}.

Lo stesso vale per il valore di ritorno della funzione, il cui significato fa
riferimento ad un tempo relativo ad un certo punto nel passato la cui
definizione dipende dalle diverse implementazioni, e varia anche fra diverse
versioni del kernel. Fino al kernel 2.4 si faceva infatti riferimento al
momento dell'avvio del kernel. Con il kernel 2.6 si fa riferimento a
$2^{32}/\mathtt{HZ}-300$ secondi prima dell'avvio. 

Considerato che il numero dei \itindex{clock~tick} \textit{clock tick} per un
kernel che è attivo da molto tempo può eccedere le dimensioni per il tipo
\type{clock\_t} il comportamento più opportuno per i programmi è di ignorare
comunque il valore di ritorno della funzione e ricorrere alle funzioni per il
tempo di calendario del prossimo paragrafo qualora si voglia calcolare il
tempo effettivamente trascorso dall'inizio del programma.

Infine si tenga presente che per dei limiti nelle convenzioni per il ritorno
dei valori delle \textit{system call} su alcune architetture hardware (ed in
particolare la \texttt{i386} dei PC a 32 bit) nel kernel della serie 2.6 il
valore di ritorno della funzione può risultare erroneamente uguale a $-1$,
indicando un errore, nei primi secondi dopo il boot (per la precisione nei
primi 41 secondi) e se il valore del contatore eccede le dimensione del tipo
\type{clock\_t}.

\itindend{process~time}


\subsection{Le funzioni per il \textit{calendar time}}
\label{sec:sys_time_base}

\itindbeg{calendar~time}

Come anticipato in sez.~\ref{sec:sys_unix_time} il \textit{calendar time}
viene espresso normalmente con una variabile di tipo \type{time\_t}, che
usualmente 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{funcproto}{
\fhead{time.h}
\fdecl{time\_t time(time\_t *t)}
\fdesc{Legge il valore corrente del \textit{calendar time}.} 
}

{La funzione ritorna il valore del \textit{calendar time} in caso di successo
  e $-1$ per un errore, nel qual caso \var{errno} potrà assumere solo il
  valore \errval{EFAULT} nel suo significato generico.}
\end{funcproto}

L'argomento \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 \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{funcproto}{
\fhead{time.h}
\fdecl{int stime(time\_t *t)}
\fdesc{Imposta il valore corrente del \textit{calendar time}.} 
}

{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
  \item[\errcode{EPERM}] non si hanno i permessi di amministrazione.
  \end{errlist}
  ed inoltre \errval{EFAULT} nel suo significato generico.}
\end{funcproto}


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 (per la precisione la
\textit{capability} \const{CAP\_SYS\_TIME}), altrimenti la chiamata fallirà
con un errore di \errcode{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 due funzioni precedenti è sconsigliato, ed esse sono di
solito 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, \func{gettimeofday}
  viene descritta anche in POSIX.1-2001.} i cui prototipi sono:

\begin{funcproto}{
\fhead{sys/time.h}
\fhead{time.h}
\fdecl{int gettimeofday(struct timeval *tv, struct timezone *tz)} 
\fdesc{Legge il tempo corrente del sistema.}
\fdecl{int settimeofday(const struct timeval *tv, const struct timezone *tz)} 
\fdesc{Imposta il tempo di sistema.} 
}

{La funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà i valori \errval{EINVAL}, \errval{EFAULT} e per
  \func{settimeofday} anche \errval{EPERM}, nel loro significato generico.}
\end{funcproto}


Si noti come queste funzioni utilizzino per indicare il tempo una struttura di
tipo \struct{timeval}, la cui definizione si è già vista in
fig.~\ref{fig:sys_timeval_struct}, questa infatti permette una espressione
alternativa dei valori del \textit{calendar time}, con una precisione,
rispetto a \type{time\_t}, fino al microsecondo, ma la precisione è solo
teorica, e la precisione reale della misura del tempo dell'orologio di sistema
non dipende dall'uso di queste strutture.

Come nel caso di \func{stime} anche \func{settimeofday} può essere utilizzata
solo da un processo coi privilegi di amministratore e più precisamente con la
capacità \const{CAP\_SYS\_TIME}. Si tratta comunque di una condizione generale
che continua a valere per qualunque funzione che vada a modificare l'orologio
di sistema, comprese tutte quelle che tratteremo in seguito.

Il secondo argomento di entrambe le funzioni è una struttura
\struct{timezone}, che storicamente veniva utilizzata per specificare appunto
la \itindex{timezone} \textit{timezone}, cioè l'insieme del fuso orario e
delle convenzioni per l'ora legale che permettevano il passaggio dal tempo
universale all'ora locale. Questo argomento 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
perdere delle esecuzioni di \cmd{cron} programmate nell'intervallo che si è
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{funcproto}{
\fhead{sys/time.h}
\fdecl{int adjtime(const struct timeval *delta, struct timeval *olddelta)}
\fdesc{Aggiusta l'orologio di sistema.} 
}

{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
  \item[\errcode{EINVAL}] il valore di \param{delta} eccede il massimo
    consentito.
  \item[\errcode{EPERM}] il processo non i privilegi di amministratore.
  \end{errlist}
}  
\end{funcproto}


Questa funzione permette di avere un aggiustamento graduale del tempo di
sistema in modo che esso sia sempre crescente in maniera monotona. Il valore
indicato nella struttura \struct{timeval} puntata da \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. 

La funzione è intesa per piccoli spostamenti del tempo di sistema, ed esistono
pertanto dei limiti massimi per i valori che si possono specificare
per \param{delta}. La \acr{glibc} impone un intervallo compreso fra
\code{INT\_MIN/1000000 + 2} e \code{INT\_MAX/1000000 - 2}, corrispondente, su
una architettura PC ordinaria a 32 bit, ad un valore compreso fra $-2145$ e
$2145$ secondi.

Inoltre se si invoca la funzione prima che una precedente richiesta di
aggiustamento sia stata completata, specificando un altro valore, il
precedente aggiustamento viene interrotto, ma la parte dello stesso che è già
stata completata non viene rimossa. Però è possibile in questo caso farsi
restituire nella struttura puntata da \param{olddelta} il tempo restante della
precedente richiesta. Fino al kernel 2.6.26 ed alla \acr{glibc} 2.8 questo
però era possibile soltanto specificando un diverso aggiustamento
per \param{delta}, il bug è stato corretto a partire dalle versioni citate e
si può ottenere l'informazione relativa alla frazione di aggiustamento
mancante usando il valore \val{NULL} per \param{delta}.

Linux poi prevede una specifica funzione di sistema che consente un
aggiustamento molto più dettagliato del tempo, permettendo ad esempio anche di
regolare anche la velocità e le derive dell'orologio di sistema.  La funzione
è \funcd{adjtimex} ed il suo prototipo è:

\begin{funcproto}{
\fhead{sys/timex.h}
\fdecl{int adjtimex(struct timex *buf)} 
\fdesc{Regola l'orologio di sistema.} 
}

{La funzione ritorna lo stato dell'orologio (un valore $\ge 0$) in caso di
  successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
  valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] si sono indicati valori fuori dall'intervallo
    consentito per qualcuno dei campi di \param{buf}.
  \item[\errcode{EPERM}] si è richiesta una modifica dei parametri ed il
    processo non ha i privilegi di amministratore.
  \end{errlist}
  ed inoltre \errval{EFAULT} nel suo significato generico.}
\end{funcproto}

In caso di successo la funzione restituisce un valore numerico non negativo
che indica lo stato dell'orologio, che può essere controllato con i valori
delle costanti elencate in tab.~\ref{tab:adjtimex_return}.

\begin{table}[!htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|c|l|}
    \hline
    \textbf{Nome} & \textbf{Valore} & \textbf{Significato}\\
    \hline
    \hline
    \const{TIME\_OK}   & 0 & Orologio sincronizzato.\\ 
    \const{TIME\_INS}  & 1 & Inserimento di un \textit{leap second}.\\ 
    \const{TIME\_DEL}  & 2 & Cancellazione di un \textit{leap second}.\\ 
    \const{TIME\_OOP}  & 3 & \textit{leap second} in corso.\\ 
    \const{TIME\_WAIT} & 4 & \textit{leap second} avvenuto.\\ 
    \const{TIME\_BAD}  & 5 & Orologio non sincronizzato.\\ 
    \hline
  \end{tabular}
  \caption{Possibili valori ritornati da \func{adjtimex} in caso di successo.} 
  \label{tab:adjtimex_return}
\end{table}

La funzione richiede come argomento il puntatore ad una struttura di tipo
\struct{timex}, la cui definizione, effettuata in \headfile{sys/timex.h}, è
riportata in fig.~\ref{fig:sys_timex_struct} per i campi che interessano la
possibilità di essere modificati documentati anche nella pagina di manuale. In
realtà la struttura è stata estesa con ulteriori campi, i cui valori sono
utilizzabili solo in lettura, la cui definizione si può trovare direttamente

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/timex.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{timex} per il controllo dell'orologio di
    sistema.} 
  \label{fig:sys_timex_struct}
\end{figure}

L'azione della funzione dipende dal valore del campo \var{mode}
di \param{buf}, che specifica quale parametro dell'orologio di sistema,
specificato nel corrispondente 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 tab.~\ref{tab:sys_timex_mode}.

\begin{table}[!htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|c|p{8cm}|}
    \hline
    \textbf{Nome} & \textbf{Valore} & \textbf{Significato}\\
    \hline
    \hline
    \const{ADJ\_OFFSET}         & 0x0001 & Imposta la differenza fra il tempo
                                           reale e l'orologio di sistema: 
                                           deve essere indicata in microsecondi
                                           nel campo \var{offset} di
                                           \struct{timex}.\\ 
    \const{ADJ\_FREQUENCY}      & 0x0002 & Imposta la differenza in frequenza
                                           fra il tempo reale e l'orologio di
                                           sistema: deve essere indicata
                                           in parti per milione nel campo
                                           \var{frequency} di \struct{timex}.\\
    \const{ADJ\_MAXERROR}       & 0x0004 & Imposta il valore massimo 
                                           dell'errore sul tempo, espresso in
                                           microsecondi nel campo
                                           \var{maxerror} di \struct{timex}.\\ 
    \const{ADJ\_ESTERROR}       & 0x0008 & Imposta la stima dell'errore
                                           sul tempo, espresso in microsecondi 
                                           nel campo \var{esterror} di
                                           \struct{timex}.\\
    \const{ADJ\_STATUS}         & 0x0010 & Imposta alcuni valori di stato
                                           interni usati dal 
                                           sistema nella gestione
                                           dell'orologio specificati nel campo
                                           \var{status} di \struct{timex}.\\ 
    \const{ADJ\_TIMECONST}      & 0x0020 & Imposta la larghezza di banda del 
                                           PLL implementato dal kernel,
                                           specificato nel campo
                                           \var{constant} di \struct{timex}.\\ 
    \const{ADJ\_TICK}           & 0x4000 & Imposta il valore dei \textit{tick}
                                           \itindex{clock~tick} del timer in
                                           microsecondi, espresso nel campo
                                           \var{tick} di \struct{timex}.\\  
    \const{ADJ\_OFFSET\_SINGLESHOT}&0x8001&Chiede uno spostamento una tantum 
                                           dell'orologio secondo il valore del
                                           campo \var{offset} simulando il
                                           comportamento di \func{adjtime}.\\ 
    \hline
  \end{tabular}
  \caption{Costanti per l'assegnazione del valore del campo \var{mode} della
    struttura \struct{timex}.} 
  \label{tab:sys_timex_mode}
\end{table}

La funzione utilizza il meccanismo di David L. Mills, descritto
nell'\href{http://www.ietf.org/rfc/rfc1305.txt}{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 anche un suo omonimo
\func{ntp\_adjtime}.  La trattazione completa di questa funzione necessita di
una lettura approfondita del meccanismo descritto nell'RFC~1305, ci limitiamo
a descrivere in tab.~\ref{tab:sys_timex_mode} i principali valori utilizzabili
per il campo \var{mode}, un elenco più dettagliato del significato dei vari
campi della struttura \struct{timex} può essere ritrovato in \cite{GlibcMan}.

Il valore delle costanti per \var{mode} può essere anche espresso, secondo la
sintassi specificata per la forma equivalente di questa funzione definita come
\func{ntp\_adjtime}, utilizzando il prefisso \code{MOD} al posto di
\code{ADJ}.

Si tenga presente infine che con l'introduzione a partire dal kernel 2.6.21
degli \itindex{High~Resolution~Timer~(HRT)} \textit{high-resolution timer} ed
il supporto per i cosiddetti POSIX \textit{real-time clock}, si può ottenere
il \textit{calendar time} direttamente da questi, come vedremo in
sez.~\ref{sec:sig_timer_adv}, con la massima risoluzione possibile per
l'hardware della macchina.



\subsection{La gestione delle date.}
\label{sec:sys_date}

\itindbeg{broken-down~time}

Le funzioni viste al paragrafo precedente sono molto utili per trattare le
operazioni elementari sui tempi, però le rappresentazioni del tempo ivi
illustrate, se han senso per specificare un intervallo, non sono molto
intuitive quando si deve esprimere un'ora o una data.  Per questo motivo è
stata introdotta una ulteriore rappresentazione, detta \textit{broken-down
  time}, che permette appunto di \textsl{suddividere} il \textit{calendar
  time} usuale in ore, minuti, secondi, ecc. e  viene usata tenendo conto
anche dell'eventuale utilizzo di un fuso orario.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{.8\textwidth}
    \includestruct{listati/tm.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{tm} per una rappresentazione del tempo in
    termini di ora, minuti, secondi, ecc.}
  \label{fig:sys_tm_struct}
\end{figure}

Questo viene effettuato attraverso una opportuna struttura \struct{tm}, la cui
definizione è riportata in fig.~\ref{fig:sys_tm_struct}, ed è in genere questa
struttura che si utilizza quando si deve specificare un tempo a partire dai
dati naturali (ora e data), dato che essa consente anche di tenere conto della
gestione del fuso orario e dell'ora legale. In particolare gli ultimi due
campi, \var{tm\_gmtoff} e \var{tm\_zone}, sono estensioni previste da BSD e
supportate dalla \acr{glibc} quando è definita la macro \macro{\_BSD\_SOURCE}.

Ciascuno dei campi di \struct{tm} ha dei precisi intervalli di valori
possibili, con convenzioni purtroppo non troppo coerenti. Ad esempio
\var{tm\_sec} che indica i secondi deve essere nell'intervallo da 0 a 59, ma è
possibile avere anche il valore 60 per un cosiddetto \textit{leap second} (o
\textsl{secondo intercalare}), cioè uno di quei secondi aggiunti al calcolo
dell'orologio per effettuare gli aggiustamenti del calendario per tenere conto
del disallineamento con il tempo solare.\footnote{per dettagli si consulti
  \url{http://it.wikipedia.org/wiki/Leap_second}.}

I campi \var{tm\_min} e\var{tm\_hour} che indicano rispettivamente minuti ed
ore hanno valori compresi rispettivamente fra 0 e 59 e fra 0 e 23. Il campo
\var{tm\_mday} che indica il giorno del mese prevede invece un valore compreso
fra 1 e 31, ma la \acr{glibc} supporta pure il valore 0 come indicazione
dell'ultimo giorno del mese precedente. Il campo \var{tm\_mon} indica il mese
dell'anno a partire da gennaio con valori compresi fra 0 e 11.

I campi \var{tm\_wday} e \var{tm\_yday} indicano invece rispettivamente il
giorno della settimana, a partire dalla Domenica, ed il giorno dell'anno, a
partire del primo gennaio, ed hanno rispettivamente valori compresi fra 0 e 6
e fra 0 e 365. L'anno espresso da \var{tm\_year} viene contato come numero di
anni a partire dal 1900. Infine \var{tm\_isdst} è un valore che indica se per
gli altri campi si intende come attiva l'ora legale ed influenza il
comportamento di \func{mktime}.


Le funzioni per la gestione del \textit{broken-down time} sono varie e vanno
da quelle usate per convertire gli altri formati in questo, usando o meno
l'ora locale o il tempo universale, a quelle per trasformare il valore di un
tempo in una stringa contenente data ed ora. Le prime due funzioni,
\funcd{asctime} e \funcd{ctime} servono per poter stampare in forma leggibile
un tempo, i loro prototipi sono:

\begin{funcproto}{
\fhead{time.h}
\fdecl{char * asctime(const struct tm *tm)}
\fdesc{Converte un \textit{broken-down time} in una stringa.} 
\fdecl{char * ctime(const time\_t *timep)}
\fdesc{Converte un \textit{calendar time} in una stringa.} 
}

{Le funzioni ritornano un puntatore al risultato in caso di successo e
  \val{NULL} per un errore, \var{errno} non viene modificata.}
\end{funcproto}

Le funzioni prendono rispettivamente come argomenti i puntatori ad una
struttura \struct{tm} contenente un \textit{broken-down time} o ad una
variabile di tipo \type{time\_t} che esprime il \textit{calendar time},
restituendo il puntatore ad una stringa che esprime la data, usando le
abbreviazioni standard di giorni e mesi in inglese, nella forma:
\begin{Example}
Sun Apr 29 19:47:44 2012\n"
\end{Example}

Nel caso di \func{ctime} la funzione tiene conto della eventuale impostazione
di una \itindex{timezone} \textit{timezone} e effettua una chiamata preventiva
a \func{tzset} (che vedremo a breve), in modo che la data espressa tenga conto
del fuso orario. In realtà \func{ctime} è banalmente definita in termini di
\func{asctime} come \code{asctime(localtime(t)}.

Dato che l'uso di una stringa statica rende le funzioni non
\index{funzioni!rientranti} rientranti POSIX.1c e SUSv2 prevedono due
sostitute \index{funzioni!rientranti} rientranti, il cui nome è al solito
ottenuto aggiungendo un \code{\_r}, che prendono un secondo argomento
\code{char *buf}, in cui l'utente deve specificare il buffer su cui la stringa
deve essere copiata (deve essere di almeno 26 caratteri).

Per la conversione fra \textit{broken-down time} e \textit{calendar time} sono
invece disponibili altre tre funzioni, \funcd{gmtime}, \funcd{localtime} e
\funcd{mktime} i cui prototipi sono:

\begin{funcproto}{
\fdecl{struct tm * gmtime(const time\_t *timep)}
\fdesc{Converte un \textit{calendar time} in un \textit{broken-down time} in
  UTC.}  
\fdecl{struct tm * localtime(const time\_t *timep)}
\fdesc{Converte un \textit{calendar time} in un \textit{broken-down time}
  nell'ora locale.} 
\fdecl{time\_t mktime(struct tm *tm)} 
\fdesc{Converte un \textit{broken-down time} in un \textit{calendar time}.} 

}

{Le funzioni ritornano un puntatore al risultato in caso di successo e
  \val{NULL} per un errore, tranne tranne che \func{mktime} che restituisce
  direttamente il valore o $-1$ in caso di errore, \var{errno} non viene
  modificata.}
\end{funcproto}

Le le prime funzioni, \func{gmtime}, \func{localtime} servono per convertire
il tempo in \textit{calendar time} specificato da un argomento di tipo
\type{time\_t} restituendo un \textit{broken-down time} con il puntatore ad
una struttura \struct{tm}. La prima effettua la conversione senza tenere conto
del fuso orario, esprimendo la data in tempo coordinato universale (UTC), cioè
l'ora di Greenwich, mentre \func{localtime} usa l'ora locale e per questo
effettua una chiamata preventiva a \func{tzset}.

Anche in questo caso le due funzioni restituiscono l'indirizzo di una
struttura allocata staticamente, per questo sono state definite anche altre
due versioni \index{funzioni!rientranti} rientranti (con la solita estensione
\code{\_r}), che prevedono un secondo argomento \code{struct tm *result},
fornito dal chiamante, che deve preallocare la struttura su cui sarà
restituita la conversione. La versione rientrante di \func{localtime} però non
effettua la chiamata preventiva a \func{tzset} che deve essere eseguita a cura
dell'utente. 

Infine \func{mktime} esegue la conversione di un \textit{broken-down time} a
partire da una struttura \struct{tm} restituendo direttamente un valore di
tipo \type{time\_t} con il \textit{calendar time}. La funzione ignora i campi
\var{tm\_wday} e \var{tm\_yday} e per gli altri campi normalizza eventuali
valori fuori degli intervalli specificati in precedenza: se cioè si indica un
12 per \var{tm\_mon} si prenderà il gennaio dell'anno successivo. Inoltre la
funzione tiene conto del valore di \var{tm\_isdst} per effettuare le
correzioni relative al fuso orario: un valore positivo indica che deve essere
tenuta in conto l'ora legale, un valore nullo che non deve essere applicata
nessuna correzione, un valore negativo che si deve far ricorso alle
informazioni relative al proprio fuso orario per determinare lo stato dell'ora
legale.  

La funzione inoltre modifica i valori della struttura \struct{tm} in forma di
\itindex{value~result~argument} \textit{value result argument}, normalizzando
i valori dei vari campi, impostando i valori risultanti per \var{tm\_wday} e
\var{tm\_yday} e assegnando a \var{tm\_isdst} il valore (positivo o nullo)
corrispondente allo stato dell'ora legale. La funzione inoltre provvede ad
impostare il valore della \index{variabili!globali} variabile globale
\var{tzname}.

\itindend{calendar~time}

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{.75\textwidth}
    \includestruct{listati/time_zone_var.c}
  \end{minipage} 
  \normalsize 
  \caption{Le \index{variabili!globali} variabili globali usate per la
    gestione delle \itindex{timezone} \textit{timezone}.}
  \label{fig:sys_tzname}
\end{figure}

Come accennato l'uso del \textit{broken-down time} permette di tenere conto
anche della differenza fra tempo universale e ora locale, compresa l'eventuale
ora legale.  Questo viene fatto dalle funzioni di conversione grazie alle
informazioni riguardo la propria \itindex{timezone} \textit{timezone}
mantenute nelle tre \index{variabili!globali} variabili globali mostrate in
fig.~\ref{fig:sys_tzname}, cui si si può accedere direttamente includendo
\headfile{time.h}. Come illustrato queste variabili vengono impostate
internamente da alcune delle delle precedenti funzioni di conversione, ma lo
si può fare esplicitamente chiamando direttamente la funzione \funcd{tzset},
il cui prototipo è:

\begin{funcproto}{
\fhead{sys/timex.h}
\fdecl{void tzset(void)} 
\fdesc{Imposta le variabili globali della \textit{timezone}.} 
}

{La funzione non ritorna niente e non dà errori.}  
\end{funcproto}

La funzione inizializza le variabili di fig.~\ref{fig:sys_tzname} a partire
dal valore della variabile di ambiente \envvar{TZ}, se quest'ultima non è
definita verrà usato il file \conffile{/etc/localtime}. La variabile
\var{tzname} contiene due stringhe, che indicano i due nomi standard della
\itindex{timezone} \textit{timezone} corrente. La prima è il nome per l'ora
solare, la seconda per l'ora legale. Anche se in fig.~\ref{fig:sys_tzname}
sono indicate come \code{char *} non è il caso di modificare queste
stringhe. La variabile \var{timezone} indica la differenza di fuso orario in
secondi, mentre \var{daylight} indica se è attiva o meno l'ora legale.

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
giorno) di un tempo si può ricorrere alla più sofisticata \funcd{strftime},
il cui prototipo è:

\begin{funcproto}{
\fhead{time.h}
\fdecl{size\_t strftime(char *s, size\_t max, const char *format, 
  const struct tm *tm)}
\fdesc{Crea una stringa con una data secondo il formato indicato.} 
}

{La funzione ritorna il numero di caratteri inseriti nella stringa \param{s}
  oppure $0$, \var{errno} non viene modificata.}  
\end{funcproto}


La funzione converte il \textit{broken-down time} indicato nella struttura
puntata dall'argomento \param{tm} in una stringa di testo da salvare
all'indirizzo puntato dall'argomento \param{s}, purché essa sia di dimensione
inferiore al massimo indicato dall'argomento \param{max}. Il numero di
caratteri generati dalla funzione viene restituito come valore di ritorno,
senza tener però conto del terminatore finale, che invece viene considerato
nel computo della dimensione. Se quest'ultima è eccessiva viene restituito 0 e
lo stato di \param{s} è indefinito.

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|c|l|p{6cm}|}
    \hline
    \textbf{Modificatore} & \textbf{Esempio} & \textbf{Significato}\\
    \hline
    \hline
    \var{\%a}&\texttt{Wed}        & Nome del giorno, abbreviato.\\ 
    \var{\%A}&\texttt{Wednesday}  & Nome del giorno, completo.\\ 
    \var{\%b}&\texttt{Apr}        & Nome del mese, abbreviato.\\ 
    \var{\%B}&\texttt{April}      & Nome del mese, completo.\\ 
    \var{\%c}&\texttt{Wed Apr 24 18:40:50 2002}& Data e ora.\\ 
    \var{\%d}&\texttt{24}         & Giorno del mese.\\ 
    \var{\%H}&\texttt{18}         & Ora del giorno, da 0 a 24.\\ 
    \var{\%I}&\texttt{06}         & Ora del giorno, da 0 a 12.\\ 
    \var{\%j}&\texttt{114}        & Giorno dell'anno.\\ 
    \var{\%m}&\texttt{04}         & Mese dell'anno.\\ 
    \var{\%M}&\texttt{40}         & Minuto.\\ 
    \var{\%p}&\texttt{PM}         & AM/PM.\\ 
    \var{\%S}&\texttt{50}         & Secondo.\\ 
    \var{\%U}&\texttt{16}         & Settimana dell'anno (partendo dalla
                                    domenica).\\ 
    \var{\%w}&\texttt{3}          & Giorno della settimana.\\ 
    \var{\%W}&\texttt{16}         & Settimana dell'anno (partendo dal
                                    lunedì).\\ 
    \var{\%x}&\texttt{04/24/02}   & La data.\\ 
    \var{\%X}&\texttt{18:40:50}   & L'ora.\\ 
    \var{\%y}&\texttt{02}         & Anno nel secolo.\\ 
    \var{\%Y}&\texttt{2002}       & Anno.\\ 
    \var{\%Z}&\texttt{CEST}       & Nome della \itindex{timezone}
                                    \textit{timezone}.\\  
    \var{\%\%}&\texttt{\%}        & Il carattere \%.\\ 
    \hline
  \end{tabular}
  \caption{Valori previsti dallo standard ANSI C per modificatore della
    stringa di formato di \func{strftime}.}  
  \label{tab:sys_strftime_format}
\end{table}

Il risultato della funzione è controllato dalla stringa di formato
\param{format}, tutti i caratteri restano invariati eccetto \texttt{\%} che
viene utilizzato come modificatore. Alcuni dei possibili valori che esso può
assumere sono riportati in tab.~\ref{tab:sys_strftime_format}.\footnote{per la
  precisione si sono riportati definiti dallo standard ANSI C, che sono anche
  quelli ripresi in POSIX.1; le \acr{glibc} forniscono anche 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.} La funzione tiene conto
anche delle eventuali impostazioni di localizzazione per stampare i vari nomi
in maniera adeguata alla lingua scelta, e con le convenzioni nazionali per i
formati di data ed ora.

Infine per effettuare l'operazione di conversione inversa, da una stringa ad
un \textit{broken-down time}, si può utilizzare la funzione \funcd{strptime},
il cui prototipo è:

\begin{funcproto}{
\fhead{time.h}
\fdecl{char *strptime(const char *s, const char *format, struct tm *tm)}
\fdesc{Converte una stringa con in un \textit{broken-down time} secondo un
  formato.} 
}

{La funzione ritorna il puntatore al primo carattere non processato della
  stringa o al terminatore finale qualora questa sia processata interamente,
  \var{errno} non viene modificata.}
\end{funcproto}

La funzione processa la stringa puntata dall'argomento \param{s} da sinistra a
destra, utilizzando il formato contenuto nella stringa puntata
dall'argomento \param{format}, avvalorando volta volta i corrispondenti campi
della struttura puntata dall'argomento \param{tm}. La scansione si interrompe
immediatamente in caso di mancata corrispondenza a quanto indicato nella
stringa di formato, che usa una sintassi analoga a quella già vista per
\func{strftime}. La funzione supporta i modificatori di
tab.~\ref{tab:sys_strftime_format} più altre estensioni, ma per i dettagli a
questo riguardo si rimanda alla lettura della pagina di manuale.

Si tenga presente comunque che anche in caso di scansione completamente
riuscita la funzione sovrascrive soltanto i campi di \param{tm} indicati dal
formato, la struttura originaria infatti non viene inizializzati e gli altri
campi restano ai valori che avevano in precedenza.


\itindend{broken-down~time}

\section{La gestione degli errori}
\label{sec:sys_errors}

In questa sezione esamineremo le caratteristiche principali della gestione
degli errori in un sistema unix-like. Infatti a parte il caso particolare di
alcuni segnali (che tratteremo in cap.~\ref{cha:signals}) in un sistema
unix-like il kernel non avvisa mai direttamente un processo dell'occorrenza di
un errore nell'esecuzione di una funzione, ma di norma questo viene riportato
semplicemente usando un opportuno valore di ritorno della funzione invocata.
Inoltre il sistema di classificazione degli errori è stato progettato
sull'architettura a processi, e presenta una serie di problemi nel caso lo si
debba usare con i \itindex{thread} \textit{thread}.


\subsection{La variabile \var{errno}}
\label{sec:sys_errno}

Quasi tutte le funzioni delle librerie del C sono in grado di individuare e
riportare condizioni di errore, ed è una norma fondamentale di buona
programmazione controllare \textsl{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, a seconda della funzione, è $-1$
o un puntatore nullo o la costante \val{EOF}; ma questo valore segnala solo
che c'è stato un errore, e non il tipo di errore.

Per riportare il tipo di errore il sistema usa \index{variabili!globali} la
variabile globale \var{errno}, definita nell'header \headfile{errno.h}.  Come
accennato l'uso di una variabile globale può comportare problemi nel caso dei
\itindex{thread} \textit{thread}, ma lo standard ISO C consente anche di
definire \var{errno} come un cosiddetto ``\textit{modifiable lvalue}'', cosa
che consente di usare anche una macro, e questo è infatti il metodo usato da
Linux per renderla locale ai singoli \itindex{thread} \textit{thread}.

La variabile è in genere definita come \direct{volatile} dato che può essere
cambiata in modo asincrono da un segnale, per un esempio si veda
sez.~\ref{sec:sig_sigchld} ricordando quanto trattato in
sez.~\ref{sec:proc_race_cond}). Dato che un gestore di segnale scritto bene si
cura di salvare e ripristinare il valore della variabile all'uscita, nella
programmazione normale, quando si può fare l'assunzione che i gestori di
segnali siano ben scritti, di questo non è necessario preoccuparsi.

I valori che può assumere \var{errno} sono riportati in app.~\ref{cha:errors},
nell'header \headfile{errno.h} sono anche definiti i nomi simbolici per le
costanti numeriche che identificano i vari errori che abbiamo citato fin
dall'inizio nelle descrizioni delle funzioni.  Essi iniziano tutti per \val{E}
e si possono considerare come nomi riservati, per questo abbiamo sempre fatto
riferimento a questi nomi, e lo faremo più avanti 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 impostato a zero all'avvio di un
programma, e la gran parte delle funzioni di libreria impostano \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 di libreria ha successo,
potrebbe averne chiamate altre al suo interno che potrebbero essere fallite
anche senza compromettere il risultato finale, modificando però \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
corretta da seguire per identificare un errore è 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:sys_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 è
\funcd{strerror}, il cui prototipo è:

\begin{funcproto}{
\fhead{string.h}
\fdecl{char *strerror(int errnum)} 
\fdesc{Restituisce una stringa con un messaggio di errore.} 
}

{La funzione ritorna il puntatore alla stringa con il messaggio di errore,
  \var{errno} non viene modificato.}
\end{funcproto}

La funzione ritorna il puntatore alla stringa contenente il messaggio di
errore corrispondente al valore di \param{errnum}, se questo non è un valore
valido verrà comunque restituita una stringa valida contenente un messaggio
che dice che l'errore è sconosciuto nella forma. La versione della \acr{glibc}
non modifica il valore di \var{errno} in caso di errore, ma questo non è detto
valga per altri sistemi in quanto lo standard POSIX.1-2001 permette che ciò
avvenga. Non si faccia affidamento su questa caratteristica se si vogliono
scrivere programmi portabili.

In generale \func{strerror} viene usata passando direttamente \var{errno} come
argomento, ed il valore di quest'ultima non verrà modificato. La funzione
inoltre tiene conto del valore della variabile di ambiente
\envvar{LC\_MESSAGES} per usare le appropriate traduzioni dei messaggi
d'errore nella localizzazione presente.

La funzione \func{strerror} utilizza una stringa statica che non deve essere
modificata dal programma; essa è utilizzabile solo fino ad una chiamata
successiva a \func{strerror} o \func{perror} e nessun'altra funzione di
libreria tocca questa stringa. In ogni caso l'uso di una stringa statica rende
la funzione non \index{funzioni!rientranti} rientrante, per cui nel caso si
usino i \itindex{thread} \textit{thread} la \acr{glibc} fornisce una apposita
versione \index{funzioni!rientranti} rientrante \funcd{strerror\_r}, il cui
prototipo è:

\begin{funcproto}{
\fhead{string.h}
\fdecl{char * strerror\_r(int errnum, char *buf, size\_t size)} 
\fdesc{Restituisce una stringa con un messaggio di errore.} 
}

{La funzione ritorna l'indirizzo del messaggio in caso di successo e
  \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] si è specificato un valore di \param{errnum} non
    valido.
  \item[\errcode{ERANGE}] la lunghezza di \param{buf} è insufficiente a
    contenere la stringa di errore.
  \end{errlist}
}  
\end{funcproto}

Si tenga presente che questa è la versione prevista normalmente nella
\acr{glibc}, ed effettivamente definita in \headfile{string.h}, ne esiste una
analoga nello standard SUSv3 (riportata anche nella pagina di manuale), che
restituisce \code{int} al posto di \code{char *}, e che tronca la stringa
restituita a \param{size}, a cui si accede definendo le opportune macro (per
le quali si rimanda alla lettura della pagina di manuale). 

La funzione è analoga a \func{strerror} ma restituisce la stringa di errore
nel buffer \param{buf} che il singolo \itindex{thread} \textit{thread} deve
allocare autonomamente per evitare i problemi connessi alla condivisione del
buffer statico. Il messaggio è copiato fino alla dimensione massima del
buffer, specificata dall'argomento \param{size}, che deve comprendere pure il
carattere di terminazione; altrimenti la stringa risulterà troncata.

Una seconda funzione usata per riportare i codici di errore in maniera
automatizzata sullo standard error è \funcd{perror}, il cui prototipo è:

\begin{funcproto}{
\fhead{stdio.h}
\fdecl{void perror(const char *message)}
\fdesc{Stampa un messaggio di errore personalizzato.} 
}

{La funzione non ritorna nulla e non modifica \var{errno}.}
\end{funcproto}


I messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati
in app.~\ref{cha:errors}), e, usando il valore corrente di \var{errno}, si
riferiscono all'ultimo errore avvenuto. La stringa specificata con
\param{message} viene stampata prima del messaggio d'errore, consentono una
personalizzazione (ad esempio l'indicazione del contesto in cui si è
verificato), seguita dai due punti e da uno spazio, il messaggio è terminato
con un a capo.  Il messaggio può essere riportato anche usando le due
\index{variabili!globali} variabili globali:
\includecodesnip{listati/errlist.c} 
dichiarate in \headfile{errno.h}. 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 una di queste stringhe è
sostanzialmente equivalente a quello di \func{strerror}.

\begin{figure}[!htbp]
  \footnotesize \centering
  \begin{minipage}[c]{\codesamplewidth}
    \includecodesample{listati/errcode_mess.c}
  \end{minipage}
  \normalsize
  \caption{Codice per la stampa del messaggio di errore standard.}
  \label{fig:sys_err_mess}
\end{figure}

In fig.~\ref{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 argomento in un intero
(\texttt{\small 1-2}), controllando con i valori di ritorno di \funcm{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 estensione consiste in due variabili, \code{char *
  program\_invocation\_name} e \code{char * program\_invocation\_short\_name}
che consentono di ricavare il nome del proprio programma.  Queste sono utili
quando si deve aggiungere il nome del programma al messaggio d'errore, cosa
comune quando si ha un programma che non viene lanciato da linea di comando e
salva gli errori in un file di log. La prima contiene il nome usato per
lanciare il programma dalla shell ed in sostanza è equivalente ad
\code{argv[0]}; la seconda mantiene solo il nome del programma eliminando
eventuali directory qualora questo sia stato lanciato con un
\textit{pathname}.

Una seconda estensione cerca di risolvere uno dei problemi che si hanno con
l'uso di \func{perror}, dovuto al fatto 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 maggiori
informazioni. 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 facilitare la
comprensione di un eventuale problema. Per questo le \acr{glibc} definiscono
la funzione \funcd{error}, il cui prototipo è:

\begin{funcproto}{
\fhead{stdio.h}
\fdecl{void error(int status, int errnum, const char *format, ...)}
\fdesc{Stampa un messaggio di errore formattato.} 
}

{La funzione non ritorna nulla e non riporta errori.}  
\end{funcproto}

La funzione fa parte delle estensioni GNU per la gestione degli errori,
l'argomento \param{format} segue la stessa sintassi di \func{printf} (vedi
sez.~\ref{sec:file_formatted_io}), ed i relativi argomenti devono essere
forniti allo stesso modo, mentre \param{errnum} indica l'errore che si vuole
segnalare (non viene quindi usato il valore corrente di \var{errno}).

La funzione stampa sullo \itindex{standard~error} \textit{standard error} il
nome del programma, come indicato dalla \index{variabili!globali} variabile
globale \var{program\_name}, seguito da due punti ed uno spazio, poi dalla
stringa generata da \param{format} e dagli argomenti seguenti, seguita da due
punti ed uno spazio infine il messaggio di errore relativo ad \param{errnum},
il tutto è terminato da un a capo.

Il comportamento della funzione può essere ulteriormente controllato se si
definisce una variabile \var{error\_print\_progname} come puntatore ad una
funzione \ctyp{void} che restituisce \ctyp{void} che si incarichi di stampare
il nome del programma. 

L'argomento \param{status} può essere usato per terminare direttamente il
programma in caso di errore, nel qual caso \func{error} dopo la stampa del
messaggio di errore chiama \func{exit} con questo stato di uscita. Se invece
il valore è nullo \func{error} ritorna normalmente ma viene incrementata
un'altra \index{variabili!globali} variabile globale,
\var{error\_message\_count}, che tiene conto di quanti errori ci sono stati.

Un'altra funzione per la stampa degli errori, ancora più sofisticata, che
prende due argomenti aggiuntivi per indicare linea e file su cui è avvenuto
l'errore è \funcd{error\_at\_line}; il suo prototipo è:

\begin{funcproto}{
\fhead{stdio.h}
\fdecl{void error\_at\_line(int status, int errnum, const char *fname, 
  unsigned int lineno, \\
\phantom{void error\_at\_line(}const char *format, ...)}
\fdesc{Stampa un messaggio di errore formattato.} 
}

{La funzione non ritorna nulla e non riporta errori.}  
\end{funcproto}

\noindent ed il suo comportamento è identico a quello di \func{error} se non
per il fatto che, separati con il solito due punti-spazio, vengono inseriti un
nome di file indicato da \param{fname} ed un numero di linea subito dopo la
stampa del nome del programma. Inoltre essa usa un'altra
\index{variabili!globali} variabile globale, \var{error\_one\_per\_line}, che
impostata ad un valore diverso da zero fa si che errori relativi alla stessa
linea non vengano ripetuti.


% LocalWords:  filesystem like kernel saved header limits sysconf sez tab float
% LocalWords:  FOPEN stdio MB LEN CHAR char UCHAR unsigned SCHAR MIN signed INT
% LocalWords:  SHRT short USHRT int UINT LONG long ULONG LLONG ULLONG POSIX ARG
% LocalWords:  Stevens exec CHILD STREAM stream TZNAME timezone NGROUPS SSIZE
% LocalWords:  ssize LISTIO JOB CONTROL job control IDS VERSION YYYYMML bits bc
% LocalWords:  dall'header posix lim nell'header glibc run unistd name errno SC
% LocalWords:  NGROUP CLK TCK clock tick process PATH pathname BUF CANON path
% LocalWords:  pathconf fpathconf descriptor fd uname sys struct utsname info
% LocalWords:  EFAULT fig SOURCE NUL LENGTH DOMAIN NMLN UTSLEN system call proc
% LocalWords:  domainname sysctl BSD nlen void oldval size oldlenp newval EPERM
% LocalWords:  newlen ENOTDIR EINVAL ENOMEM linux array oldvalue paging stack
% LocalWords:  TCP shell Documentation ostype hostname osrelease version mount
% LocalWords:  const source filesystemtype mountflags ENODEV ENOTBLK block read
% LocalWords:  device EBUSY only EACCES NODEV ENXIO major RTSIG syscall PID NSS
% LocalWords:  number EMFILE dummy ENAMETOOLONG ENOENT ELOOP virtual devfs MGC
% LocalWords:  magic MSK RDONLY NOSUID suid sgid NOEXEC SYNCHRONOUS REMOUNT MNT
% LocalWords:  MANDLOCK mandatory locking WRITE APPEND append IMMUTABLE NOATIME
% LocalWords:  access NODIRATIME BIND MOVE umount flags FORCE statfs fstatfs ut
% LocalWords:  buf ENOSYS EIO EBADF type fstab mntent home shadow username uid
% LocalWords:  passwd PAM Pluggable Authentication Method Service Switch pwd ru
% LocalWords:  getpwuid getpwnam NULL buflen result ERANGE getgrnam getgrgid AS
% LocalWords:  grp group gid SVID fgetpwent putpwent getpwent setpwent endpwent
% LocalWords:  fgetgrent putgrent getgrent setgrent endgrent accounting init HZ
% LocalWords:  runlevel Hierarchy logout setutent endutent utmpname utmp paths
% LocalWords:  WTMP getutent getutid getutline pututline LVL OLD DEAD EMPTY dev
% LocalWords:  line libc XPG utmpx getutxent getutxid getutxline pututxline who
% LocalWords:  setutxent endutxent wmtp updwtmp logwtmp wtmp host rusage utime
% LocalWords:  minflt majflt nswap fault swap timeval wait getrusage usage SELF
% LocalWords:  CHILDREN current limit soft RLIMIT address brk mremap mmap dump
% LocalWords:  SIGSEGV SIGXCPU SIGKILL sbrk FSIZE SIGXFSZ EFBIG LOCKS lock dup
% LocalWords:  MEMLOCK NOFILE NPROC fork EAGAIN SIGPENDING sigqueue kill RSS tv
% LocalWords:  resource getrlimit setrlimit rlimit rlim INFINITY capabilities
% LocalWords:  capability CAP Sun Sparc PAGESIZE getpagesize SVr SUSv get IGN
% LocalWords:  phys pages avphys NPROCESSORS CONF ONLN getloadavg stdlib double
% LocalWords:  loadavg nelem scheduler CONFIG ACCT acct filename EUSER sizeof
% LocalWords:  ENFILE EROFS PACCT AcctCtrl cap calendar UTC Jan the Epoch GMT
% LocalWords:  Greenwich Mean l'UTC timer CLOCKS SEC cron wall elapsed times tz
% LocalWords:  tms cutime cstime waitpid gettimeofday settimeofday timex NetBSD
% LocalWords:  timespec adjtime olddelta adjtimex David Mills RFC NTP ntp cmd
% LocalWords:  nell'RFC ADJ FREQUENCY frequency MAXERROR maxerror ESTERROR PLL
% LocalWords:  esterror TIMECONST constant SINGLESHOT MOD INS insert leap OOP
% LocalWords:  second delete progress has occurred BAD broken tm gmtoff asctime
% LocalWords:  ctime timep gmtime localtime mktime tzname tzset daylight format
% LocalWords:  strftime thread EOF modifiable lvalue app errcode strerror LC at
% LocalWords:  perror string errnum MESSAGES error message strtol log jiffy asm
% LocalWords:  program invocation argv printf print progname exit count fname
% LocalWords:  lineno one standardese Di page Wed Wednesday Apr April PM AM CAD
% LocalWords:  CEST utmpxname Solaris updwtmpx reboot RESTART Ctrl OFF SIGINT
% LocalWords:  HALT halted sync KEXEC kexec load bootloader POWER Power with nr
% LocalWords:  Restarting command arg entry segments segment ARCH CRASH CONTEXT
% LocalWords:  PRESERVE PPC IA ARM SH MIPS nvcsw nivcsw inblock oublock maxrss
% LocalWords:  context switch slice Resident SIG SIGCHLD cur Gb lease mlock Hz
% LocalWords:  memory mlockall MAP LOCKED shmctl MSGQUEUE attr NICE nice MADV
% LocalWords:  madvise WILLNEED RTPRIO sched setscheduler setparam scheduling
% LocalWords:  RTTIME execve kb prlimit pid new old ESRCH EUSERS refresh high
% LocalWords:  resolution HRT jiffies strptime

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "gapil"
%%% End: 
