X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=system.tex;h=657c0d645cc5bada0c1e7b00bf16aa52ef387ce4;hp=b824ddf87f381cadfff1c75923a0245b99068b4d;hb=3425ef5d361d8af2b3d61a3f43ae36f032f4524c;hpb=105bd8930572cf5885b4482966754d9af0597874;ds=sidebyside diff --git a/system.tex b/system.tex index b824ddf..657c0d6 100644 --- a/system.tex +++ b/system.tex @@ -2,10 +2,11 @@ \label{cha:system} In questo capitolo tratteremo varie interfacce che attengono agli aspetti più -generali del sistema, come quelle per la gestione di parametri e -configurazione, quelle per la lettura dei limiti e delle caratteristiche dello -stesso, quelle per il controllo dell'uso delle risorse da parte dei processi, -quelle per la gestione dei tempi e degli errori. +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. @@ -13,19 +14,19 @@ quelle per la gestione dei tempi e degli errori. \label{sec:sys_characteristics} In questa sezione tratteremo le varie modalità con cui un programma può -ottenere informazioni riguardo alle capacità del sistema. Ogni sistema infatti -è contraddistinto da un gran numero di limiti e costanti che lo -caratterizzano, e che possono dipendere da fattori molteplici, come +ottenere informazioni riguardo alle capacità del sistema. 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. La definizione di queste caratteristiche ed il tentativo di provvedere dei meccanismi generali che i programmi potessero usare per ricavarle è uno degli -aspetti più complessi e controversi coi cui i vari standard si sono dovuti -confrontare, spesso con risultati spesso tutt'altro che chiari. Proveremo -comunque a dare una descrizione dei principali metodi previsti dai vari -standard per ricavare sia le caratteristiche specifiche del sistema, che -quelle dei file. +aspetti più complessi e controversi con cui le diverse standardizzazioni si +sono dovute confrontare, spesso con risultati spesso tutt'altro che chiari. +Proveremo comunque a dare una descrizione dei principali metodi previsti dai +vari standard per ricavare sia le caratteristiche specifiche del sistema, che +quelle della gestione dei file. \subsection{Limiti e parametri di sistema} @@ -58,7 +59,7 @@ tramite la funzione \func{sysconf} (che esamineremo in \secref{sec:sys_sysconf}). Lo standard ANSI C definisce dei limiti che sono tutti fissi, pertanto questo -saranno sempre disponibili al momento della compilazione; un elenco, ripreso +saranno sempre disponibili al momento della compilazione. Un elenco, ripreso da \file{limits.h}, è riportato in \tabref{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 @@ -275,10 +276,10 @@ esplicitamente, se ne trova una menzione completa nell'header file \label{sec:sys_sysconf} Come accennato in \secref{sec:sys_limits} quando uno dei limiti o delle -caratteristiche del sistema può variare, è necessario ottenerne il valore -attraverso la funzione \func{sysconf}, per non dover essere costretti a +caratteristiche del sistema può variare, per non dover essere costretti a ricompilare un programma tutte le volte che si cambiano le opzioni con cui è -compilato il kernel, o alcuni dei parametri modificabili a run time. Il +compilato il kernel, o alcuni dei parametri modificabili a run time, è +necessario ottenerne il valore attraverso la funzione \func{sysconf}. Il prototipo di questa funzione è: \begin{prototype}{unistd.h}{long sysconf(int name)} Restituisce il valore del parametro di sistema \param{name}. @@ -366,9 +367,9 @@ get_child_max(void) } \end{lstlisting} %\normalsize -ma in realtà in Linux queste macro sono comunque definite e indicando un -limite generico, per cui è sempre meglio usare i valori restituiti da -quest'ultima. +ma in realtà in Linux queste macro sono comunque definite, indicando però un +limite generico. Per questo motivo è sempre meglio usare i valori restituiti +da \func{sysconf}. \subsection{I limiti dei file} @@ -402,11 +403,11 @@ riportate in \tabref{tab:sys_file_macro}. \label{tab:sys_file_macro} \end{table} -Come per i limiti di sistema POSIX.1 detta una serie di valori minimi per -queste caratteristiche, che ogni sistema che vuole essere conforme deve -rispettare; le relative macro sono riportate in \tabref{tab:sys_posix1_file}, -e per esse vale lo stesso discorso fatto per le analoghe di -\tabref{tab:sys_posix1_general}. +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 +\tabref{tab:sys_posix1_file}, e per esse vale lo stesso discorso fatto per le +analoghe di \tabref{tab:sys_posix1_general}. \begin{table}[htb] \centering @@ -446,10 +447,10 @@ implementazioni moderne. \label{sec:sys_pathconf} In generale i limiti per i file sono molto più soggetti ad essere variabili -rispetto ai precedenti limiti generali del sistema; ad esempio parametri come -la lunghezza del nome del file o il numero di link possono variare da -filesystem a filesystem; per questo motivo questi limiti devono essere sempre -controllati con la funzione \func{pathconf}, il cui prototipo è: +rispetto ai limiti generali del sistema; ad esempio parametri come la +lunghezza del nome del file o il numero di link possono variare da filesystem +a filesystem; per questo motivo questi limiti devono essere sempre controllati +con la funzione \func{pathconf}, il cui prototipo è: \begin{prototype}{unistd.h}{long pathconf(char *path, int name)} Restituisce il valore del parametro \param{name} per il file \param{path}. @@ -461,7 +462,7 @@ controllati con la funzione \func{pathconf}, il cui prototipo E si noti come la funzione in questo caso richieda un parametro che specifichi a quale file si fa riferimento, dato che il valore del limite cercato può variare a seconda del filesystem. Una seconda versione della funzione, -\func{fpathconf}, opera su un file descriptor invece che su un pathname, il +\func{fpathconf}, opera su un file descriptor invece che su un pathname. Il suo prototipo è: \begin{prototype}{unistd.h}{long fpathconf(int fd, int name)} Restituisce il valore del parametro \param{name} per il file \param{fd}. @@ -477,7 +478,7 @@ suo prototipo \label{sec:sys_uname} Un'altra funzione che si può utilizzare per raccogliere informazioni sia -riguardo al sistema che al computer su cui esso sta girando è \func{uname}, il +riguardo al sistema che al computer su cui esso sta girando è \func{uname}; il suo prototipo è: \begin{prototype}{sys/utsname.h}{int uname(struct utsname *info)} Restituisce informazioni sul sistema nella struttura \param{info}. @@ -529,11 +530,12 @@ In generale si tenga presente che le dimensioni delle stringe di una \macro{NULL}; il manuale delle \acr{glibc} indica due diverse dimensioni, \macro{\_UTSNAME\_LENGTH} per i campi standard e \macro{\_UTSNAME\_DOMAIN\_LENGTH} per quello specifico per il nome di dominio; -altri sistemi usano nomi diversi come \macro{SYS\_NMLN} or \macro{\_SYS\_NMLN} -or \macro{UTSLEN} che possono avere valori diversi; nel caso di Linux +altri sistemi usano nomi diversi come \macro{SYS\_NMLN} o \macro{\_SYS\_NMLN} +or \macro{UTSLEN} che possono avere valori diversi. Nel caso di Linux \func{uname} corrisponde in realtà a 3 system call diverse, le prime due usano -delle lunghezze delle stringhe di 9 e 65 byte; la terza 65, restituisce anche -l'ultimo campo con una lunghezza di 257 byte. +rispettivamente delle lunghezze delle stringhe 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. \section{Opzioni e configurazione del sistema} @@ -596,13 +598,13 @@ I parametri a cui la funzione permettere di accedere sono organizzati in maniera gerarchica all'interno un albero; per accedere ad uno di essi occorre specificare un cammino attraverso i vari nodi dell'albero, in maniera analoga a come avviene per la risoluzione di un pathname (da cui l'uso alternativo del -filesystem \file{/proc} che vedremo dopo). +filesystem \file{/proc}, che vedremo dopo). Ciascun nodo dell'albero è identificato da un valore intero, ed il cammino che arriva ad identificare un parametro specifico è passato alla funzione attraverso l'array \param{name}, di lunghezza \param{nlen}, che contiene la sequenza dei vari nodi da attraversare. Ogni parametro ha un valore in un -formato specifico chee può essere un intero, una stringa o anche una struttura +formato specifico che può essere un intero, una stringa o anche una struttura complessa, per questo motivo il valori vengono passati come puntatori \ctyp{void}. @@ -645,7 +647,7 @@ nomi dei file corrispondenti, e questo ha il grande vantaggio di rendere accessibili i vari parametri a qualunque comando di shell e di permettere la navigazione dell'albero dei valori. -Alcune delle corrispondenze dei file presentin \file{/proc/sys} con i valori +Alcune delle corrispondenze dei file presenti in \file{/proc/sys} con i valori di \func{sysctl} sono riportate nei commenti del codice che può essere trovato in \file{linux/sysctl.h},\footnote{indicando un file di definizioni si fa riferimento alla directory standard dei file di include, che in ogni @@ -721,7 +723,7 @@ loro dati sono generati al volo ad ogni lettura, e passati al kernel ad ogni scrittura. Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere -una delle stringhe riportate in \file{/proc/filesystems}, che contiene +una delle stringhe riportate nel file \file{/proc/filesystems}, che contiene l'elenco dei filesystem supportati dal kernel; nel caso si sia indicato uno dei filesystem virtuali, il contenuto di \param{source} viene ignorato. @@ -731,8 +733,8 @@ precedente contenuto di detta directory viene mascherato dal contenuto della directory radice del filesystem montato. Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un -\textit{mount point} da una directory ad un'altra, che montare in diversi -\textit{mount point} lo stesso filesystem, che montare più filesystem sullo +\textit{mount point} da una directory ad un'altra, sia montare in diversi +\textit{mount point} lo stesso filesystem, sia montare più filesystem sullo stesso \textit{mount point} (nel qual caso vale quanto appena detto, e solo il contenuto dell'ultimo filesystem montato sarà visibile). @@ -795,7 +797,6 @@ deve essere effettuato il rimontaggio del filesystem (con le opzioni specificate dagli altri bit), anche in questo caso il valore di \param{source} viene ignorato. - Una volta che non si voglia più utilizzare un certo filesystem è possibile \textsl{smontarlo} usando la funzione \func{umount}, il cui prototipo è: \begin{prototype}{sys/mount.h}{umount(const char *target)} @@ -903,7 +904,7 @@ nome del filesystem stesso. Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due file standard \file{/etc/fstab} e \file{/etc/mtab}, che convenzionalmente sono -usati in quasi tutti i sistemi unix per mantenere rispettivamente le +usati in quasi tutti i sistemi unix-like per mantenere rispettivamente le informazioni riguardo ai filesystem da montare e a quelli correntemente montati. Le funzioni servono a leggere il contenuto di questi file in opportune strutture \var{struct fstab} e \var{struct mntent}, e, per @@ -920,14 +921,18 @@ tralasceremo la trattazione, rimandando al manuale delle \acr{glibc} \subsection{La gestione di utenti e gruppi} \label{sec:sys_user_group} -L'ultimo argomento di questa sezione è quello che riguarda le funzioni -utilizzate per gestire utenti e gruppi all'interno del sistema. Tradizionalmente l'informazione per la gestione di utenti e gruppi veniva -tenuta tutta nei due file di testo \file{/etc/passwd} ed \file{/etc/group}; -oggi la maggior parte delle distribuzioni di Linux usa la libreria PAM (sigla -che sta \textit{Pluggable Authentication Method}) che permette di separare -completamente i meccanismi di gestione degli utenti (autenticazione, -riconoscimento, ecc.) dalle modalità in cui i relativi dati vengono mantenuti. +tenuta tutta nei due file di testo \file{/etc/passwd} ed \file{/etc/group}, e +tutte le funzioni facevano riferimento ad essi. Oggi la maggior parte delle +distribuzioni di Linux usa la libreria PAM (sigla che sta \textit{Pluggable + Authentication Method}) che permette di separare completamente i meccanismi +di gestione degli utenti (autenticazione, riconoscimento, ecc.) dalle modalità +in cui i relativi dati vengono mantenuti, per cui pur restando in gran parte +le stesse\footnote{in genere quello che viene cambiato è l'informazione usata + per l'autenticazione, che non è più necessariamente una password criptata da + verificare, ma può assumere le forme più diverse, come impronte digitali, + chiavi elettroniche, ecc.}, le informazioni non sono più necessariamente +mantenute in quei file. In questo paragrafo ci limiteremo comunque alle funzioni classiche per la lettura delle informazioni relative a utenti e gruppi previste dallo standard @@ -944,7 +949,7 @@ funzioni, \func{getpwuid} e \func{getpwnam}, i cui prototipi sono: \funcdecl{struct passwd *getpwnam(const char *name)} - Restituiscono le informazioni relative alll'utente specificato. + Restituiscono le informazioni relative all'utente specificato. \bodydesc{Le funzioni ritornano il puntatore alla struttura contenente le informazioni in caso di successo e \macro{NULL} nel caso non sia stato @@ -982,24 +987,26 @@ struct passwd { \end{figure} La struttura usata da entrambe le funzioni è allocata staticamente, per questo -motivo viene sovrascritta ad ogni nuova invocazione, così come le stringhe a -cui essa fa riferimento. Ovviamente queste funzioni non sono rientranti, ne -esistono quindi anche due versioni alternative (denotate dalla solita -estensione \code{\_r}), i cui prototipi sono: +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 posono +essere rientranti, per cui ne esistono anche due versioni alternative +(denotate dalla solita estensione \code{\_r}), i cui prototipi sono: \begin{functions} \headdecl{pwd.h} - \headdecl{sys/types.h} \funcdecl{struct passwd *getpwuid\_r(uid\_t uid, - struct passwd *password, char *buffer, size\_t buflen, struct passwd - **result)} + \headdecl{sys/types.h} + + \funcdecl{struct passwd *getpwuid\_r(uid\_t uid, struct passwd *password, + char *buffer, size\_t buflen, struct passwd **result)} \funcdecl{struct passwd *getpwnam\_r(const char *name, struct passwd *password, char *buffer, size\_t buflen, struct passwd **result)} - Restituiscono le informazioni relative alll'utente specificato. + Restituiscono le informazioni relative all'utente specificato. \bodydesc{Le funzioni ritornano 0 in caso di successo e un codice d'errore - altriementi, nel qual caso \var{errno} sarà settato opportunente.} + altrimenti, nel qual caso \var{errno} sarà settato opportunamente.} \end{functions} In questo caso l'uso è molto più complesso, in quanto bisogna prima allocare @@ -1007,11 +1014,12 @@ la memoria necessaria a contenere le informazioni. In particolare i valori della struttura \var{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} +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 \macro{NULL} altrimenti. Qualora i dati non possano essere -contenuti in \param{buflen} byte la funzione fallirà restituendo -\macro{ERANGE} (e \param{result} sarà comunque settato a \macro{NULL}). +contenuti nei byte specificati da \param{buflen}, la funzione fallirà +restituendo \macro{ERANGE} (e \param{result} sarà comunque settato a +\macro{NULL}). Del tutto analoghe alle precedenti sono le funzioni \func{getgrnam} e \func{getgrgid} (e le relative analoghe rientranti con la stessa estensione @@ -1034,7 +1042,7 @@ loro prototipi sono: Restituiscono le informazioni relative al gruppo specificato. \bodydesc{Le funzioni ritornano 0 in caso di successo e un codice d'errore - altriementi, nel qual caso \var{errno} sarà settato opportunente.} + altrimenti, nel qual caso \var{errno} sarà settato opportunamente.} \end{functions} Il comportamento di tutte queste funzioni è assolutamente identico alle @@ -1069,33 +1077,32 @@ al database degli utenti, derivata da SVID, che per database che sia tenuto su un file che abbia il formato classico di \file{/etc/passwd}. -Dato che ormai la gran parte delle distribuzioni di Linux utilizzano PAM, che -come minimo usa almeno le \textit{shadow password}, con quindi delle modifiche -rispetto al formato classico di \file{/etc/passwd}, ci limitiamo a citare -queste funzioni in \tabref{tab:sys_passwd_func}. - - \begin{table}[htb] \footnotesize \centering - \begin{tabular}[c]{|l|l|} + \begin{tabular}[c]{|l|p{8cm}|} \hline \textbf{Funzione} & \textbf{Significato}\\ \hline \hline - \func{fgetpwent} & \\ - \func{fgetpwent\_r}& \\ - \func{getpwent} & \\ - \func{getpwent\_r} & \\ - \func{setpwent} & \\ - \func{putpwent} & \\ - \func{endpwent} & \\ - \func{fgetgrent} & \\ - \func{fgetgrent\_r}& \\ - \func{getgrent} & \\ - \func{getgrent\_r} & \\ - \func{setgrent} & \\ - \func{endgrent} & \\ + \func{fgetpwent} & Legge una voce dal database utenti da un file + specificato aprendolo la prima volta.\\ + \func{fgetpwent\_r}& Come la precedente, ma rientrante.\\ + \func{getpwent} & Legge una voce dal database utenti (da + \file{/etc/passwd}) aprendolo la prima volta.\\ + \func{getpwent\_r} & Come la precedente, ma rientrante.\\ + \func{setpwent} & Ritorna all'inizio del database.\\ + \func{putpwent} & Immette una voce nel database utenti.\\ + \func{endpwent} & Chiude il database degli utenti.\\ + \func{fgetgrent} & Legge una voce dal database dei gruppi da un file + specificato aprendolo la prima volta.\\ + \func{fgetgrent\_r}& Come la precedente, ma rientrante.\\ + \func{getgrent} & Legge una voce dal database dei gruppi (da + \file{/etc/passwd}) aprendolo la prima volta.\\ + \func{getgrent\_r} & Come la precedente, ma rientrante.\\ + \func{setgrent} & Immette una voce nel database dei gruppi.\\ + \func{putgrent} & Immette una voce nel database dei gruppi.\\ + \func{endgrent} & Chiude il database dei gruppi.\\ \hline \end{tabular} \caption{Funzioni per la manipolazione dei campi di un file usato come @@ -1104,9 +1111,230 @@ queste funzioni in \tabref{tab:sys_passwd_func}. \label{tab:sys_passwd_func} \end{table} -Un altro insieme di funzioni utili è quello che permette di accedere ai dati -del database di +Dato che ormai la gran parte delle distribuzioni di Linux utilizzano PAM, che +come minimo usa almeno le \textit{shadow password} (quindi con delle modifiche +rispetto al formato classico di \file{/etc/passwd}), le funzioni che danno la +capacità scrivere delle voci nel database (cioè \func{putpwent} e +\func{putgrent}) non permettono di effettuarne una specificazione in maniera +completa. Per questo motivo l'uso di queste funzioni è deprecato in favore +dell'uso di PAM, ci limiteremo pertanto ad elencarle in +\tabref{tab:sys_passwd_func}, rimandando chi fosse interessato alle rispettive +man page e al manuale delle \acr{glibc} per i dettagli del loro funzionamento. + + + +\subsection{Il database di accounting} +\label{sec:sys_accounting} + +L'ultimo insieme di funzioni relative alla gestione del sistema che +esamineremo è quello che permette di accedere ai dati del database di +\textit{accounting}. 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\footnote{questa è la locazione specificata dal + \textit{Linux Filesystem Hierarchy Standard}, adottato dalla gran parte + delle distribuzioni.} memorizzati nei due file \file{/var/run/utmp} e +\file{/var/log/wtmp}. 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'\acr{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 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 (vedi +\tabref{tab:sys_passwd_func}) usate per accedere al database degli utenti, +solo che in questo caso la struttura del database di accounting è molto più +complessa, dato che contiene diversi tipi di informazione. + +Le prime tre funzioni, \func{setutent}, \func{endutent} e \func{utmpname} +servono rispettivamente a aprire e a chiudere il file che contiene il +database, e a specificare su quale file esso viene mantenuto. I loro prototipi +sono: +\begin{functions} + \headdecl{utmp.h} + + \funcdecl{void utmpname(const char *file)} Specifica il file da usare come + database di \textit{accounting}. + + \funcdecl{void setutent(void)} Apre il file del database di + \textit{accounting}, posizionandosi al suo inizio. + + \funcdecl{void endutent(void)} Chiude il file del database di + \textit{accounting}. + + \bodydesc{Le funzioni non ritornano codici di errore.} +\end{functions} + +In caso questo non venga specificato nessun file viene usato il valore +standard \macro{\_PATH\_UTMP} (che è definito in \file{paths.h}); in genere +\func{utmpname} prevede due possibili valori: +\begin{basedescript}{\desclabelwidth{2.0cm}} +\item[\macro{\_PATH\_UTMP}] Specifica il database di accounting per gli utenti + correntemente collegati. +\item[\macro{\_PATH\_WTMP}] Specifica il database di accounting per l'archivio + storico degli utenti collegati. +\end{basedescript} +corrispondenti ai file \file{/var/run/utmp} e \file{/var/log/wtmp} visti in +precedenza. + +Una volta aperto il file si può eseguire una scansione leggendo o scrivendo +una voce con le funzioni \func{getutent}, \func{getutid}, \func{getutline} e +\func{pututline}, i cui prototipi sono: +\begin{functions} + \headdecl{utmp.h} + + \funcdecl{struct utmp *getutent(void)} + Legge una voce dal dalla posizione corrente nel database. + + \funcdecl{struct utmp *getutid(struct utmp *ut)} + Ricerca una voce sul database in base al contenuto di \param{ut}. + + \funcdecl{struct utmp *getutline(struct utmp *ut)} + Ricerca nel database la prima voce corrispondente ad un processo sulla linea + di terminale specificata tramite \param{ut}. + + \funcdecl{struct utmp *pututline(struct utmp *ut)} + Scrive una voce nel database. + + \bodydesc{Le funzioni ritornano il puntatore ad una struttura \var{utmp} in + caso di successo e \macro{NULL} in caso di errore.} +\end{functions} + +Tutte queste funzioni fanno riferimento ad una struttura di tipo \var{utmp}, +la cui definizione in Linux è riportata in \secref{fig:sys_utmp_struct}. Le +prime tre funzioni servono per leggere una voce dal database; \func{getutent} +legge semplicemente la prima voce disponibile; le altre due permettono di +eseguire una ricerca. + +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} +struct utmp +{ + short int ut_type; /* Type of login. */ + pid_t ut_pid; /* Process ID of login process. */ + char ut_line[UT_LINESIZE]; /* Devicename. */ + char ut_id[4]; /* Inittab ID. */ + char ut_user[UT_NAMESIZE]; /* Username. */ + char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */ + struct exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ + long int ut_session; /* Session ID, used for windowing. */ + struct timeval ut_tv; /* Time entry was made. */ + int32_t ut_addr_v6[4]; /* Internet address of remote host. */ + char __unused[20]; /* Reserved for future use. */ +}; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{utmp} contenente le informazioni di una voce del + database di \textit{accounting}.} + \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 \tabref{tab:sys_ut_type}, quando assume i valori +\macro{RUN\_LVL}, \macro{BOOT\_TIME}, \macro{OLD\_TIME}, \macro{NEW\_TIME}, +verrà restituito la prima voce che corrisponde al tipo determinato; quando +invece assume i valori \macro{INIT\_PROCESS}, \macro{LOGIN\_PROCESS}, +\macro{USER\_PROCESS} o \macro{DEAD\_PROCESS} verrà restiuita la prima voce +corripondente al valore del campo \var{ut\_id} specificato in \param{ut}. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Funzione} & \textbf{Significato}\\ + \hline + \hline + \macro{EMPTY} & Non contiene informazioni valide. \\ + \macro{RUN\_LVL} & Identica il runlevel del sistema. \\ + \macro{BOOT\_TIME} & Identifica il tempo di avvio del sistema \\ + \macro{OLD\_TIME} & Identifica quando è stato modificato l'orologio di + sistema. \\ + \macro{NEW\_TIME} & Identifica da quanto è stato modificato il + sistema. \\ + \macro{INIT\_PROCESS} & Identifica un processo lanciato da \cmd{init}. \\ + \macro{LOGIN\_PROCESS}& Identifica un processo di login. \\ + \macro{USER\_PROCESS} & Identifica un processo utente. \\ + \macro{DEAD\_PROCESS} & Identifica un processo terminato. \\ + \macro{ACCOUNTING} & ??? \\ + \hline + \end{tabular} + \caption{Classificazione delle voci del database di accounting 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 \macro{LOGIN\_PROCESS} o \macro{USER\_PROCESS}, +restituendo la prima che corrisponde al valore di \var{ut\_line}, che +specifica il device\footnote{espresso senza il \file{/dev/} iniziale.} di +terminale che interessa. Lo stesso criterio di ricerca è usato da +\func{pututline} per trovare uno spazio dove inserire la voce specificata, +qualora non sia trovata la voce viene aggiunta in coda al database. + +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 \code{utmpx}, che +sono un sovrainsieme di \code{utmp}. + +Le \acr{glibc} utilizzano già una versione estesa di \code{utmp}, che rende +inutili queste nuove strutture; pertanto esse e le relative funzioni di +gestione (\func{getutxent}, \func{getutxid}, \func{getutxline}, +\func{pututxline}, \func{setutxent} e \func{endutxent}) sono ridefinite come +sinonimi delle funzioni appena viste. + +Come visto in \secref{sec:sys_user_group}, l'uso di strutture allocate +staticamente rende le funzioni di lettura non rientranti; per questo motivo le +\acr{glibc} forniscono anche delle versioni rientranti: \func{getutent\_r}, +\func{getutid\_r}, \func{getutline\_r}, che invece di restituire un puntatore +restituiscono un intero e prendono due argomenti aggiuntivi. Le funzioni si +comportano esattamente come le analoge non rientranti, solo che restituiscono +il risultato all'indirizzo specificato dal primo argomento aggiuntivo (di tipo +\code{struct utmp *buffer}) mentre il secondo (di tipo \code{struct utmp + **result)} viene usato per restituire il puntatore allo stesso buffer. + +Infine le \acr{glibc} forniscono come estensione per la scrittura delle voci +in \file{wmtp} altre due funzioni, \func{updwtmp} e \func{logwtmp}, i cui +prototipi sono: +\begin{functions} + \headdecl{utmp.h} + + \funcdecl{void updwtmp(const char *wtmp\_file, const struct utmp *ut)} + Aggiunge la voce \param{ut} nel database di accounting \file{wmtp}. + + \funcdecl{void logwtmp(const char *line, const char *name, const char + *host)} Aggiunge nel database di accounting una voce con i valori + specificati. + + \bodydesc{Le funzioni ritornano il puntatore ad una struttura \var{utmp} in + caso di successo e \macro{NULL} in caso di errore.} +\end{functions} +La prima funzione permette l'aggiunta di una voce a \file{wmtp} specificando +direttamente una struttura \type{utmp}, mentre la seconda utilizza gli +argomenti \param{line}, \param{name} e \param{host} per costruire la voce che +poi aggiunge chiamando \func{updwtmp}. \section{Limitazione ed uso delle risorse}