restano gli stessi indipendentemente dal numero di processori.
Si tenga conto poi che i processi non devono solo eseguire del codice: ad
-esempio molto spesso saranno impegnati in operazioni di I/O, o portranno
+esempio molto spesso saranno impegnati in operazioni di I/O, o potranno
venire bloccati da un comando dal terminale, o sospesi per un certo periodo di
tempo. In tutti questi casi la CPU diventa disponibile ed è compito dello
kernel provvedere a mettere in esecuzione un altro processo.
\hline
\end{tabular}
\caption{Elenco dei possibili stati di un processo in Linux, nella colonna
- \texttt{STAT} si è riportata la corripondente lettera usata dal comando
+ \texttt{STAT} si è riportata la corrispondente lettera usata dal comando
\cmd{ps} nell'omonimo campo.}
\label{tab:proc_proc_states}
\end{table}
specifiche dello standard SUSv3, e come avviene per tutti i sistemi che
derivano da SYSV, è richiesto che il real o l'effective user id del processo
chiamante corrispondano al real user id (e solo quello) del processo di cui si
-vuole cambiare la prorità; per i sistemi derivati da BSD invece (SunOS,
+vuole cambiare la priorità; per i sistemi derivati da BSD invece (SunOS,
Ultrix, *BSD) la corrispondenza può essere anche con l'effective user id.
Quando c'è un processo con priorità assoluta lo scheduler lo metterà in
esecuzione prima di ogni processo normale. In caso di più processi sarà
eseguito per primo quello con priorità assoluta più alta. Quando ci sono più
-processi con la stessa priorità assoluta questi vegono tenuti in una coda
+processi con la stessa priorità assoluta questi vengono tenuti in una coda
tocca al kernel decidere quale deve essere eseguito.
L'ultima funzione che permette di leggere le informazioni relative ai processi
real-time è \func{sched\_rr\_get\_interval}, che permette di ottenere la
lunghezza della \textit{time slice} usata dalla politica \textit{round robin};
-il suo protototipo è:
+il suo prototipo è:
\begin{prototype}{sched.h}
{int sched\_rr\_get\_interval(pid\_t pid, struct timespec *tp)} Legge in
\param{tp} la durata della \textit{time slice} per il processo \param{pid}.
coda alla lista dei processi da eseguire, e permettere l'esecuzione di un
altro processo; se però il processo è l'unico ad essere presente sulla coda
l'esecuzione non sarà interrotta. In genere usano questa funzione i processi
-in modalità \textit{fifo}, per permettere l'esecuzioni degli altri processi
+in modalità \textit{fifo}, per permettere l'esecuzione degli altri processi
con pari priorità quando la sezione più urgente è finita.
allarme avesse interrotto un altro manipolatore questo non sarebbe stato
eseguito correttamente; la cosa poteva essere prevenuta installando gli altri
manipolatori usando \var{sa\_mask} per bloccare \macro{SIGALRM} durante la
-loro esecuzione.
-Il valore di \var{sa\_flag} permette di specificare vari aspetti del
-comportamento di \func{sigaction}, e della reazione del processo ai vari
-segnali; i valori possibili ed il relativo significato sono riportati in
-\tabref{tab:sig_sa_flag}.
+loro esecuzione. Il valore di \var{sa\_flag} permette di specificare vari
+aspetti del comportamento di \func{sigaction}, e della reazione del processo
+ai vari segnali; i valori possibili ed il relativo significato sono riportati
+in \tabref{tab:sig_sa_flag}.
\begin{table}[htb]
\footnotesize
l'uso di \func{signal} a favore di \func{sigaction}.
Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata
-che abbia le stesse caratteristiche di \func{signal} a definire una funzione
-equivalente (che si trova come \code{inline} nel file \file{wrapper.h} dei
-sorgenti allegati) \code{Signal}, riportata in \figref{fig:sig_Signal_code}.
+che abbia le stesse caratteristiche di \func{signal}, a definire una funzione
+equivalente attraverso \func{sigaction}; la funzione è \code{Signal}, e si
+trova definita come \code{inline} nel file \file{wrapper.h} (nei sorgenti
+allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso
+in seguito.
\begin{figure}[!htb]
\footnotesize \centering
Resta quindi il problema di cosa succede alla maschera dei segnali quando si
esce da un manipolatore usando questa funzione. Il comportamento dipende
dall'implementazione; in particolare BSD ripristina la maschera dei segnali
-precedente l'invocazione, come per un normale ritorno, mentre SYSV no. Lo
+precedente l'invocazione, come per un normale ritorno, mentre System V no. Lo
standard POSIX.1 non specifica questo comportamento per \func{setjmp} e
\func{longjmp}, ed il comportamento delle \acr{glibc} dipende da quale delle
caratteristiche si sono abilitate con le macro viste in
-\secref{sec:intro_gcc_glibc_std}.
+\secref{sec:intro_gcc_glibc_std}.
Lo standard POSIX però prevede anche la presenza di altre due funzioni
\func{sigsetjmp} e \func{siglongjmp}, che permettono di decidere quale dei due
parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
\func{longjmp}.
+\begin{prototype}{signal.h}
+{int sigaltstack(const stack\_t *ss, stack\_t *oss)}
+
+Installa un nuovo stack per i segnali.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà i valori:
+
+ \begin{errlist}
+ \item[\macro{ENOMEM}] La dimensione specificata per il nuovo stack è minore
+ di \macro{MINSIGSTKSZ}.
+ \item[\macro{EPERM}] Uno degli indirizzi non è valido.
+ \item[\macro{EFAULT}] Si è cercato di cambiare lo stack alternativo mentre
+ questo è attivo (cioè il processo è in esecuzione su di esso).
+ \item[\macro{EINVAL}] \param{ss} non è nullo e \var{ss\_flags} contiene un
+ valore diverso da zero che non è \macro{SS\_DISABLE}.
+ \end{errlist}}
+\end{prototype}
\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}
+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
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}.
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
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)}
\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
\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
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
\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}.
-
+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 (\func{putpwent} e \func{putgrent})
+non permettono di specificarle in maniera completa. Per questo motivo l'uso di
+queste funzioni è deprecato in favore dell'uso di PAM, per cui ci limitiamo a
+elencarle in \tabref{tab:sys_passwd_func}, rimandando chi fosse interessato
+alle man page e al manuale delle \acr{glibc} per i dettagli del funzionamento.
\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
\end{table}
Un altro insieme di funzioni utili è quello che permette di accedere ai dati
-del database di
+del database di \textit{accounting} degli utenti, che mantiene la traccia di
+chi si è collegato al sistema e di che è correntemente collegato, insieme alle
+informazioni, per ciascun terminale, di chi ci è collegato, da che ora,
+dell'\acr{uid} della shell di login, ed una serie di altre informazioni
+relativa al sistema come il run-level, l'orario dell'ultimo riavvio, ed altre.
+
+Le informazioni sono tenute nei due file \file{/var/run/utmp} (per chi sta
+utilizzando il sistema al momento corrente) e \file{/var/log/wtmp} (per la
+storia dei login precedenti). 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 per il database delle password, solo che la struttura del database
+è molto più complessa, dato che contiene vari tipi di informazione.
+
+Le prime tre funzioni, \func{utmpname}, \func{setutent} e \func{endutent},
+servono a aprire e chiudere il database, e a specificare il file su cui esso è
+mantenuto (in caso questo non venga specificato viene usato il valore standard
+\macro{\_PATH\_UTMP} che è definito in \file{paths.h}. Il 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}
+
+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)}
+ Esegue una ricerca dalla posizione corrente sulla base del 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 la voce relativa ad uno specifico tipo di
+login o di runlevel, a seconda del valore del campo \var{ut\_type}
+dell'argomento \param{ut}; questo può assumere i valori riportati in
+
+
+\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'orogio di
+ sistema. \\
+ \macro{NEW_TIME} & Identifica da qaunto è stato modificato il
+ sistema. \\
+ \macro{INIT_PROCESS} & Identifica un processo lanciato ad \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}
+