\label{sec:proc_gen}
Partiremo con una introduzione generale ai concetti che stanno alla base della
-gestione dei processi in un sitema unix-like. Introdurremo in questa sezione
+gestione dei processi in un sistema unix-like. Introdurremo in questa sezione
l'architettura della gestione dei processi e le sue principali
caratteristiche, e daremo una panoramica sull'uso delle principali funzioni
per la gestione dei processi.
sono stati creati, questo viene chiamato in genere \acr{ppid} (da
\textit{parent process id}). Questi due identificativi possono essere
ottenuti da programma usando le funzioni:
-
\begin{functions}
\headdecl{sys/types.h}
\headdecl{unistd.h}
-\funcdecl{pid\_t getpid(void)} restituisce il pid del processo corrente.
-\funcdecl{pid\_t getppid(void)} restituisce il pid del padre del processo
+\funcdecl{pid\_t getpid(void)} Restituisce il pid del processo corrente.
+\funcdecl{pid\_t getppid(void)} Restituisce il pid del padre del processo
corrente.
-Entrambe le funzioni non riportano condizioni di errore.
+\bodydesc{Entrambe le funzioni non riportano condizioni di errore.}
\end{functions}
-esempi dell'uso di queste funzioni sono riportati in
+\noindent esempi dell'uso di queste funzioni sono riportati in
\figref{fig:proc_fork_code}, nel programma di esempio \file{ForkTest.c}.
Il fatto che il \acr{pid} sia un numero univoco per il sistema lo rende il
\textit{sibling}, questa è una delle relazioni usate nel \textsl{controllo di
sessione}, in cui si raggruppano i processi creati su uno stesso terminale,
o relativi allo stesso login. Torneremo su questo argomento in dettaglio in
-\secref{cap:session}, dove esamineremo gli altri identificativi associati ad
+\secref{cha:session}, dove esamineremo gli altri identificativi associati ad
un processo e le varie relazioni fra processi utilizzate per definire una
sessione.
sessione, ad ogni processo sono associati altri identificatori, usati per il
controllo di accesso, che servono per determinare se il processo può o meno
eseguire le operazioni richieste, a seconda dei privilegi e dell'identità di
-chi lo ha posto in esecuzione; su questi torneremo in dettaglii più avanti in
-\secref{sec:proc_perm}.
+chi lo ha posto in esecuzione; su questi torneremo in dettagli più avanti in
+\secref{sec:proc_perms}.
\subsection{La funzione \func{fork}}
attraverso l'uso di questa funzione, essa quindi riveste un ruolo centrale
tutte le volte che si devono scrivere programmi che usano il multitasking. Il
prototipo della funzione è:
-
\begin{functions}
\headdecl{sys/types.h}
\headdecl{unistd.h}
\funcdecl{pid\_t fork(void)}
- Restituisce zero al padre e il \acr{pid} al figlio in caso di successo,
- ritorna -1 al padre (senza creare il figlio) in caso di errore;
- \texttt{errno} può assumere i valori:
+ Crea un nuovo processo.
+
+ \bodydesc{Restituisce zero al padre e il \acr{pid} al figlio in caso di
+ successo, ritorna -1 al padre (senza creare il figlio) in caso di errore;
+ \var{errno} può assumere i valori:
\begin{errlist}
- \item \macro{EAGAIN} non ci sono risorse sufficienti per creare un'altro
+ \item[\macro{EAGAIN}] non ci sono risorse sufficienti per creare un'altro
processo (per allocare la tabella delle pagine e le strutture del task) o
si è esaurito il numero di processi disponibili.
- \item \macro{ENOMEM} non è stato possibile allocare la memoria per le
+ \item[\macro{ENOMEM}] non è stato possibile allocare la memoria per le
strutture necessarie al kernel per creare il nuovo processo.
- \end{errlist}
+ \end{errlist}}
\end{functions}
Dopo il successo dell'esecuzione di una \func{fork} sia il processo padre che
proprietà; la lista dettagliata delle proprietà che padre e figlio hanno in
comune dopo l'esecuzione di una \func{fork} è la seguente:
\begin{itemize*}
-\item i file aperti e gli eventuali flag di \textit{close-on-exec} se settati.
+\item i file aperti e gli eventuali flag di \textit{close-on-exec} (vedi
+\secref{sec:proc_exec} e \secref{sec:file_fcntl}) se settati.
\item gli identificatori per il controllo di accesso: il \textit{real user
id}, il \textit{real group id}, l'\textit{effective user id},
l'\textit{effective group id} e i \textit{supplementary group id} (vedi
\item la directory di lavoro e la directory radice (vedi
\secref{sec:file_work_dir}).
\item la maschera dei permessi di creazione (vedi \secref{sec:file_umask}).
-\item la maschera dei segnali bloccati e le azioni installate.
-\item i segmenti di memoria condivisa agganciati al processo.
-\item i limiti sulle risorse.
+\item la maschera dei segnali bloccati e le azioni installate (vedi
+\secref{sec:sig_xxx}).
+\item i segmenti di memoria condivisa agganciati al processo (vedi
+\secref{sec:ipc_xxx}).
+\item i limiti sulle risorse (vedi \secref{sec:sys_xxx}).
\item le variabili di ambiente (vedi \secref{sec:proc_environ}).
\end{itemize*}
le differenze fra padre e figlio dopo la \func{fork} invece sono:
\item il \textit{process id}.
\item il \textit{parent process id} (quello del figlio viene settato al
\acr{pid} del padre).
-\item i valori dei tempi di esecuzione (\var{tms\_utime}, \var{tms\_stime},
- \var{tms\_cutime}, \var{tms\_uetime}) che nel figlio sono posti a zero.
-\item i \textit{file lock}, che non vengono ereditati dal figlio.
-\item gli allarmi ed i segnali pendenti, che per il figlio vengono cancellati.
+\item i valori dei tempi di esecuzione (vedi \secref{sec:sys_xxx}) che
+ nel figlio sono posti a zero.
+\item i \textit{file lock} (vedi \secref{sec:file_locking}), che non
+ vengono ereditati dal figlio.
+\item gli allarmi ed i segnali pendenti (vedi \secref{sec:sig_xxx}), che per il figlio vengono cancellati.
\end{itemize*}
\item tutti i descrittori dei file sono chiusi.
\item viene memorizzato lo stato di terminazione del processo.
\item ad ogni processo figlio viene assegnato un nuovo padre.
-\item viene inviato il segnale \macro{SIGCHLD} al processo padre.
+\item viene inviato il segnale \macro{SIGCHLD} al processo padre (vedi
+ \secref{sec:sig_xxx}) .
\item se il processo è un leader di sessione viene mandato un segnale di
- \macro{SIGHUP} a tutti i processi in background e il terminale di controllo
- viene disconnesso.
-\item se la conclusione di un processo rende orfano un \textit{process group}
- ciascun membro del gruppo viene bloccato, e poi gli vengono inviati in
- successione i segnali \macro{SIGHUP} e \macro{SIGCONT}.
+ \macro{SIGHUP} a tutti i processi in background e il terminale di
+ controllo viene disconnesso (vedi \secref{sec:sess_xxx}).
+\item se la conclusione di un processo rende orfano un \textit{process
+ group} ciascun membro del gruppo viene bloccato, e poi gli vengono
+ inviati in successione i segnali \macro{SIGHUP} e \macro{SIGCONT}
+ (vedi \secref{sec:sess_xxx}).
\end{itemize*}
ma al di la di queste operazioni è necessario poter disporre di un meccanismo
ulteriore che consenta di sapere come questa terminazione è avvenuta; dato che
Questo viene fatto mantenendo attiva la voce nella tabella dei processi, e
memorizzando alcuni dati essenziali, come il \acr{pid}, i tempi di CPU usati
-dal processo (vedi \secref{sec:intro_unix_time}) e lo stato di terminazione
+dal processo (vedi \secref{sec:sys_unix_time}) e lo stato di terminazione
\footnote{NdA verificare esattamente cosa c'è!}, mentre la memoria in uso ed i
file aperti vengono rilasciati immediatamente. I processi che sono terminati,
ma il cui stato di terminazione non è stato ancora ricevuto dal padre sono
\textit{zombie} la tabella dei processi; le funzioni deputate a questo compito
sono sostanzialmente due, \func{wait} e \func{waitpid}. La prima, il cui
prototipo è:
-
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/wait.h}
\funcdecl{pid\_t wait(int * status)}
Sospende il processo corrente finché un figlio non è uscito, o finché un
-segnale termina il processo o chiama una funzione di gestione. Se un figlio è
-già uscito la funzione ritorna immediatamente. Al ritorno lo stato di
-termininazione del processo viene salvato nella variabile puntata da
-\var{status} e tutte le informazioni relative al processo (vedi
-\secref{sec:proc_termination}) vengono rilasciate.
+segnale termina il processo o chiama una funzione di gestione.
+\bodydesc{
La funzione restituisce il \acr{pid} del figlio in caso di successo e -1 in
caso di errore; \var{errno} può assumere i valori:
\begin{errlist}
- \item \macro{EINTR} la funzione è stata interrotta da un segnale.
+ \item[\macro{EINTR}] la funzione è stata interrotta da un segnale.
\end{errlist}
+}
\end{functions}
-
+\noindent
è presente fin dalle prime versioni di unix; la funzione ritorna alla
-conclusione del primo figlio (o immediatamente se un figlio è già uscito). Nel
-caso un processo abbia più figli il valore di ritorno permette di identificare
-qual'è quello che è uscito.
-
-Questa funzione però ha il difetto di essere poco flessibile, in quanto
-ritorna all'uscita di un figlio qualunque. Nelle occasioni in cui è necessario
-attendere la conclusione di un processo specifico occorre predisporre un
-meccanismo che tenga conto dei processi già terminati, e ripeta la chiamata
-alla funzione nel caso il processo cercato sia ancora attivo.
+conclusione del primo figlio (o immediatamente se un figlio è già
+uscito). Se un figlio è già uscito la funzione ritorna immediatamente.
+
+Al ritorno lo stato di termininazione del processo viene salvato nella
+variabile puntata da \var{status} e tutte le informazioni relative al
+processo (vedi \secref{sec:proc_termination}) vengono rilasciate. Nel
+caso un processo abbia più figli il valore di ritorno permette di
+identificare qual'è quello che è uscito.
+
+Questa funzione ha il difetto di essere poco flessibile, in quanto
+ritorna all'uscita di un figlio qualunque. Nelle occasioni in cui è
+necessario attendere la conclusione di un processo specifico occorre
+predisporre un meccanismo che tenga conto dei processi già terminati, e
+provveda a ripetere la chiamata alla funzione nel caso il processo
+cercato sia ancora attivo.
Per questo motivo lo standard POSIX.1 ha introdotto la funzione \func{waitpid}
che effettua lo stesso servizio, ma dispone di una serie di funzionalità più
ampie, legate anche al controllo di sessione. Dato che è possibile ottenere
lo stesso comportamento di \func{wait} si consiglia di utilizzare sempre
questa funzione; il suo prototipo è:
-
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/wait.h}
\funcdecl{pid\_t waitpid(pid\_t pid, int * status, int options)}
+Attende la conclusione di un processo figlio.
-La funzione restituisce il \acr{pid} del processo che è uscito, 0 se è stata
-specificata l'opzione \macro{WNOHANG} e il processo non è uscito e -1 per un
-errore, nel qual caso \var{errno} assumerà i valori:
+\bodydesc{La funzione restituisce il \acr{pid} del processo che è uscito, 0 se
+ è stata specificata l'opzione \macro{WNOHANG} e il processo non è uscito e
+ -1 per un errore, nel qual caso \var{errno} assumerà i valori:
\begin{errlist}
- \item \macro{EINTR} se non è stata specificata l'opzione \macro{WNOHANG} e
+ \item[\macro{EINTR}] se non è stata specificata l'opzione \macro{WNOHANG} e
la funzione è stata interrotta da un segnale.
- \item \macro{ECHILD} il processo specificato da \var{pid} non esiste o non è
+ \item[\macro{ECHILD}] il processo specificato da \var{pid} non esiste o non è
figlio del processo chiamante.
- \end{errlist}
+ \end{errlist}}
\end{functions}
Le differenze principali fra le due funzioni sono che \func{wait} si blocca
\label{tab:proc_status_macro}
\end{table}
-
Entrambe le funzioni restituiscono lo stato di terminazione del processo
tramite il puntatore \var{status} (se non interessa memorizzare lo stato si
può passare un puntatore nullo). Il valore restituito da entrambe le funzioni
kernel può restituire al processo padre ulteriori informazioni sulle risorse
usate dal processo terminato e dai vari figli. Queste funzioni, che diventano
accessibili definendo la costante \macro{\_USE\_BSD}, sono:
-
\begin{functions}
\headdecl{sys/times.h}
\headdecl{sys/types.h}
\headdecl{sys/resource.h}
\funcdecl{pid\_t wait4(pid\_t pid, int * status, int options, struct rusage
* rusage)}
- La funzione è identica a \func{waitpid} sia per comportamento che per i
+ È identica a \func{waitpid} sia per comportamento che per i
valori dei parametri, ma restituisce in \var{rusage} un sommario delle
- risorse usate dal processo (per i dettagli vedi \secref{sec:xxx_limit_res})
+ risorse usate dal processo (per i dettagli vedi \secref{sec:sys_xxx})
\funcdecl{pid\_t wait3(int *status, int options, struct rusage *rusage)}
Prima versione, equivalente a \func{wait4(-1, \&status, opt, rusage)} è
ormai deprecata in favore di \func{wait4}.
\noindent
la struttura \type{rusage} è definita in \file{sys/resource.h}, e viene
utilizzata anche dalla funzione \func{getrusage} per ottenere le risorse di
-sistema usate dal processo; in Linux è definita come:
+sistema usate dal processo; la sua definizione è riportata in \nfig.
\begin{figure}[!htb]
\footnotesize
\centering
delle risorse usate da un processo.}
\label{fig:proc_rusage_struct}
\end{figure}
-In genere includere esplicitamente \file{<sys/time.h>} non è più necessario,
-ma aumenta la portabilità, e serve in caso si debba accedere ai campi di
-\var{rusage} definiti come \type{struct timeval}. La struttura è ripresa dalla
-versione 4.3 Reno di BSD, attualmente (con il kernel 2.4.x) i soli campi che
-sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime}, \var{ru\_minflt},
-\var{ru\_majflt}, e \var{ru\_nswap}.
+
+In genere includere esplicitamente \file{<sys/time.h>} non è più
+necessario, ma aumenta la portabilità, e serve in caso si debba accedere
+ai campi di \var{rusage} definiti come \type{struct timeval}. La
+struttura è ripresa da BSD 4.3, attualmente (con il kernel 2.4.x) i soli
+campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime},
+\var{ru\_minflt}, \var{ru\_majflt}, e \var{ru\_nswap}.
\subsection{Le funzioni \func{exec}}
famiglia di funzioni) che possono essere usate per questo compito, che in
realtà (come mostrato in \figref{fig:proc_exec_relat}), costituiscono un
front-end a \func{execve}. Il prototipo di quest'ultima è:
-
\begin{prototype}{unistd.h}
{int execve(const char * filename, char * const argv [], char * const envp[])}
+ Esegue il programma contenuto nel file \param{filename}.
- La funzione esegue il file o lo script indicato da \var{filename},
- passandogli la lista di argomenti indicata da \var{argv} e come ambiente la
- lista di stringhe indicata da \var{envp}; entrambe le liste devono essere
- terminate da un puntatore nullo. I vettori degli argomenti e dell'ambiente
- possono essere acceduti dal nuovo programma quando la sua funzione
- \func{main} è dichiarata nella forma \func{main(int argc, char *argv[], char
- *envp[])}.
-
- La funzione ritorna -1 solo in caso di errore, nel qual caso caso la
- \var{errno} può assumere i valori:
+ \bodydesc{La funzione ritorna -1 solo in caso di errore, nel qual caso
+ caso la \var{errno} può assumere i valori:
\begin{errlist}
- \item \macro{EACCES} il file non è eseguibile, oppure il filesystem è
+ \item[\macro{EACCES}] il file non è eseguibile, oppure il filesystem è
montato in \cmd{noexec}, oppure non è un file normale o un interprete.
- \item \macro{EPERM} il file ha i bit \acr{suid} o \acr{sgid} ma l'utente non
+ \item[\macro{EPERM}] il file ha i bit \acr{suid} o \acr{sgid} ma l'utente non
è root o il filesystem è montato con \cmd{nosuid}, oppure
- \item \macro{ENOEXEC} il file è in un formato non eseguibile o non
+ \item[\macro{ENOEXEC}] il file è in un formato non eseguibile o non
riconosciuto come tale, o compilato per un'altra architettura.
- \item \macro{ENOENT} il file o una delle librerie dinamiche o l'interprete
+ \item[\macro{ENOENT}] il file o una delle librerie dinamiche o l'interprete
necessari per eseguirlo non esistono.
- \item \macro{ETXTBSY} L'eseguibile è aperto in scrittura da uno o più
+ \item[\macro{ETXTBSY}] L'eseguibile è aperto in scrittura da uno o più
processi.
- \item \macro{EINVAL} L'eseguibile ELF ha più di un segmento
- \macro{PF\_INTERP}, cioè chiede di essere eseguito da più di un interprete.
- \item \macro{ELIBBAD} Un interprete ELF non è in un formato riconoscibile.
+ \item[\macro{EINVAL}] L'eseguibile ELF ha più di un segmento
+ \macro{PF\_INTERP}, cioè chiede di essere eseguito da più di un
+ interprete.
+ \item[\macro{ELIBBAD}] Un interprete ELF non è in un formato
+ riconoscibile.
\end{errlist}
ed inoltre anche \macro{EFAULT}, \macro{ENOMEM}, \macro{EIO},
\macro{ENAMETOOLONG}, \macro{E2BIG}, \macro{ELOOP}, \macro{ENOTDIR},
- \macro{ENFILE}, \macro{EMFILE}.
+ \macro{ENFILE}, \macro{EMFILE}.}
\end{prototype}
+La funzione \func{exec} esegue il file o lo script indicato da
+\var{filename}, passandogli la lista di argomenti indicata da \var{argv}
+e come ambiente la lista di stringhe indicata da \var{envp}; entrambe le
+liste devono essere terminate da un puntatore nullo. I vettori degli
+argomenti e dell'ambiente possono essere acceduti dal nuovo programma
+quando la sua funzione \func{main} è dichiarata nella forma
+\func{main(int argc, char *argv[], char *envp[])}.
+
Le altre funzioni della famiglia servono per fornire all'utente una serie
possibile di diverse interfacce per la creazione di un nuovo processo. I loro
prototipi sono:
-
\begin{functions}
\headdecl{unistd.h}
\funcdecl{int execl(const char *path, const char *arg, ...)}
argomento. I parametri successivi consentono di specificare gli argomenti a
linea di comando e l'ambiente ricevuti dal nuovo processo.
-Queste funzioni ritornano solo in caso di errore, restituendo -1; nel qual
-caso \var{errno} andrà ad assumere i valori visti in precedenza per
-\func{execve}.
+\bodydesc{Queste funzioni ritornano solo in caso di errore, restituendo
+ -1; nel qual caso \var{errno} andrà ad assumere i valori visti in
+ precedenza per \func{execve}.}
\end{functions}
Per capire meglio le differenze fra le funzioni della famiglia si può fare
\begin{figure}[htb]
\centering
- \includegraphics[width=13cm]{img/exec_rel.eps}
+ \includegraphics[width=13cm]{img/exec_rel}
\caption{La interrelazione fra le sei funzioni della famiglia \func{exec}}
\label{fig:proc_exec_relat}
\end{figure}
\secref{sec:file_work_dir}).
\item la maschera di creazione dei file (\var{umask}, vedi
\secref{sec:file_umask}) ed i \textit{lock} sui file (vedi
- \secref{sec:file_xxx}).
+ \secref{sec:file_locking}).
\item i segnali sospesi (\textit{pending}) e la maschera dei segnali (si veda
\secref{sec:sig_xxx}).
-\item i limiti sulle risorse (vedi \secref{sec:limits_xxx})..
+\item i limiti sulle risorse (vedi \secref{sec:sys_limits})..
\item i valori delle variabili \var{tms\_utime}, \var{tms\_stime},
- \var{tms\_cutime}, \var{tms\_ustime} (vedi \secref{sec:xxx_xxx})..
+ \var{tms\_cutime}, \var{tms\_ustime} (vedi \secref{sec:xxx_xxx}).
\end{itemize*}
Oltre a questo i segnali che sono stati settati per essere ignorati nel
-processo chiamante mantengono lo stesso settaggio pure nuovo programma, tutti
-gli altri segnali vengono settati alla loro azione di default. Un caso
-speciale è il segnale \macro{SIGCHLD} che, quando settato a \macro{SIG\_IGN}
+processo chiamante mantengono lo stesso settaggio pure nel nuovo programma,
+tutti gli altri segnali vengono settati alla loro azione di default. Un caso
+speciale è il segnale \macro{SIGCHLD} che, quando settato a \macro{SIG\_IGN},
può anche non essere resettato a \macro{SIG\_DFL} (si veda
\secref{sec:sig_xxx}).
La gestione dei file aperti dipende dal valore del flag di
\textit{close-on-exec} per ciascun file descriptor (si veda
-\secref{sec:file_xxx}); i file per cui è settato vengono chiusi, tutti gli
+\secref{sec:file_fcntl}); i file per cui è settato vengono chiusi, tutti gli
altri file restano aperti. Questo significa che il comportamento di default è
che i file restano aperti attraverso una \func{exec}, a meno di una chiamata
esplicita a \func{fcntl} che setti il suddetto flag.
tutti gli unix prevedono che i processi abbiano almeno due gruppi di
identificatori, chiamati rispettivamente \textit{real} ed \textit{effective}.
-
\begin{table}[htb]
\footnotesize
\centering
settati (il significato di questi bit è affrontato in dettaglio in
\secref{sec:file_suid_sgid}). In questo caso essi saranno settati all'utente e
al gruppo proprietari del file; questo consente, per programmi in cui ci sia
-necessità, di dare a qualunquee utente normale privilegi o permessi di
+necessità, di dare a qualunque utente normale privilegi o permessi di
un'altro (o dell'amministratore).
Come nel caso del \acr{pid} e del \acr{ppid} tutti questi identificatori
possono essere letti dal processo attraverso delle opportune funzioni, i cui
prototipi sono i seguenti:
-
\begin{functions}
-\headdecl{unistd.h}
-\headdecl{sys/types.h}
-\funcdecl{uid\_t getuid(void)} restituisce il \textit{real user ID} del
-processo corrente.
-\funcdecl{uid\_t geteuid(void)} restituisce l'\textit{effective user ID} del
-processo corrente.
-\funcdecl{gid\_t getgid(void)} restituisce il \textit{real group ID} del
-processo corrente.
-\funcdecl{gid\_t getegid(void)} restituisce l'\textit{effective group ID} del
-processo corrente.
-
-Queste funzioni non riportano condizioni di errore.
+ \headdecl{unistd.h}
+ \headdecl{sys/types.h}
+ \funcdecl{uid\_t getuid(void)} Restituisce il \textit{real user ID} del
+ processo corrente.
+
+ \funcdecl{uid\_t geteuid(void)} Restituisce l'\textit{effective user ID} del
+ processo corrente.
+
+ \funcdecl{gid\_t getgid(void)} Restituisce il \textit{real group ID} del
+ processo corrente.
+
+ \funcdecl{gid\_t getegid(void)} Restituisce l'\textit{effective group ID} del
+ processo corrente.
+
+ \bodydesc{Queste funzioni non riportano condizioni di errore.}
\end{functions}
In generale l'uso di privilegi superiori deve essere limitato il più
\subsection{Le funzioni \func{setuid} e \func{setgid}}
\label{sec:proc_setuid}
-Le due funzioni che venfono usate per cambiare identità (cioè utente e gruppo
+Le due funzioni che vengono usate per cambiare identità (cioè utente e gruppo
di appartenenza) ad un processo sono rispettivamente \func{setuid} e
\func{setgid}; come accennato in \secref{sec:proc_user_group} in Linux esse
-seguono la sematica POSIX che prevede l'esistenza di \textit{saved user id} e
+seguono la semantica POSIX che prevede l'esistenza di \textit{saved user id} e
\textit{saved group id}; i loro prototipi sono:
-
\begin{functions}
\headdecl{unistd.h}
\headdecl{sys/types.h}
-\funcdecl{int setuid(uid\_t uid)} setta l'\textit{user ID} del processo
+\funcdecl{int setuid(uid\_t uid)} Setta l'\textit{user ID} del processo
corrente.
-\funcdecl{int setgid(gid\_t gid)} setta il \textit{group ID} del processo
+\funcdecl{int setgid(gid\_t gid)} Setta il \textit{group ID} del processo
corrente.
-Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
-l'unico errore possibile è \macro{EPERM}.
+\bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso
+ di fallimento: l'unico errore possibile è \macro{EPERM}.}
\end{functions}
Il funzionamento di queste due funzioni è analogo, per cui considereremo solo
L'effetto della chiamata è diverso a seconda dei privilegi del processo; se
l'\textit{effective user id} è zero (cioè è quello dell'amministratore di
-sistema) allora tutti gli identificatatori (\textit{real}, \textit{effective}
+sistema) allora tutti gli identificatori (\textit{real}, \textit{effective}
e \textit{saved}) vengono settati al valore specificato da \var{uid},
altrimenti viene settato solo l'\textit{effective user id}, e soltanto se il
valore specificato corrisponde o al \textit{real user id} o al \textit{saved
Come esempio per chiarire dell'uso di queste funzioni prediamo quello con cui
viene gestito l'accesso al file \file{/var/log/utmp}. In questo file viene
registrato chi sta usando il sistema al momento corrente; chiaramente non può
-essere lasciato aperto in scrittura a qualunque utente, che protrebbe
+essere lasciato aperto in scrittura a qualunque utente, che potrebbe
falsificare la registrazione. Per questo motivo questo file (e l'analogo
\file{/var/log/wtmp} su cui vengono registrati login e logout) appartengono ad
un gruppo dedicato (\acr{utmp}) ed i programmi che devono accedervi (ad
alla versione 4.3+BSD TODO, verificare e aggiornare la nota} i \textit{saved
id} le usava per poter scambiare fra di loro effective e real id. I
prototipi sono:
-
\begin{functions}
\headdecl{unistd.h}
\headdecl{sys/types.h}
-\funcdecl{int setreuid(uid\_t ruid, uid\_t euid)} setta il \textit{real user
+\funcdecl{int setreuid(uid\_t ruid, uid\_t euid)} Setta il \textit{real user
ID} e l'\textit{effective user ID} del processo corrente ai valori
specificati da \var{ruid} e \var{euid}.
-\funcdecl{int setregid(gid\_t rgid, gid\_t egid)} setta il \textit{real group
+\funcdecl{int setregid(gid\_t rgid, gid\_t egid)} Setta il \textit{real group
ID} e l'\textit{effective group ID} del processo corrente ai valori
specificati da \var{rgid} e \var{egid}.
-Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
-l'unico errore possibile è \macro{EPERM}.
+\bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso
+ di fallimento: l'unico errore possibile è \macro{EPERM}.}
\end{functions}
-I processi non privileguiati possono settare i \textit{real id} soltanto ai
+I processi non privilegiati possono settare i \textit{real id} soltanto ai
valori dei loro \textit{effective id} o \textit{real id} e gli
\textit{effective id} ai valori dei loro \textit{real id}, \textit{effective
id} o \textit{saved id}; valori diversi comportano il fallimento della
Queste due funzioni sono una estensione introdotta in Linux dal kernel 2.1.44,
e permettono un completo controllo su tutti gli identificatori (\textit{real},
\textit{effective} e \textit{saved}), i prototipi sono:
-
\begin{functions}
\headdecl{unistd.h}
\headdecl{sys/types.h}
-\funcdecl{int setresuid(uid\_t ruid, uid\_t euid, uid\_t suid)} setta il
+\funcdecl{int setresuid(uid\_t ruid, uid\_t euid, uid\_t suid)} Setta il
\textit{real user ID}, l'\textit{effective user ID} e il \textit{saved user
ID} del processo corrente ai valori specificati rispettivamente da
\var{ruid}, \var{euid} e \var{suid}.
-\funcdecl{int setresgid(gid\_t rgid, gid\_t egid, gid\_t sgid)} setta il
+\funcdecl{int setresgid(gid\_t rgid, gid\_t egid, gid\_t sgid)} Setta il
\textit{real group ID}, l'\textit{effective group ID} e il \textit{saved group
ID} del processo corrente ai valori specificati rispettivamente da
\var{rgid}, \var{egid} e \var{sgid}.
-Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
-l'unico errore possibile è \macro{EPERM}.
+\bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso
+ di fallimento: l'unico errore possibile è \macro{EPERM}.}
\end{functions}
I processi non privilegiati possono cambiare uno qualunque degli
identificatori usando uno qualunque dei valori correnti di \textit{real id},
-\textit{effective id} o \textit{saved id}, l'ammnistratore può specificare i
+\textit{effective id} o \textit{saved id}, l'amministratore può specificare i
valori che vuole; un valore di -1 per un qualunque parametro lascia inalterato
-l'dentificatore corrispondente.
+l'identificatore corrispondente.
Queste funzioni sono un'estensione allo standard POSIX.1 (ma sono comunque
supportate dalla maggior parte degli unix) e usate per cambiare gli
\textit{effective id}; i loro prototipi sono:
-
\begin{functions}
\headdecl{unistd.h}
\headdecl{sys/types.h}
-\funcdecl{int seteuid(uid\_t uid)} setta l'\textit{effective user ID} del
+\funcdecl{int seteuid(uid\_t uid)} Setta l'\textit{effective user ID} del
processo corrente a \var{uid}.
-\funcdecl{int setegid(gid\_t gid)} setta l'\textit{effective group ID} del
+\funcdecl{int setegid(gid\_t gid)} Setta l'\textit{effective group ID} del
processo corrente a \var{gid}.
-Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
-l'unico errore possibile è \macro{EPERM}.
+\bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso
+ di fallimento: l'unico errore possibile è \macro{EPERM}.}
\end{functions}
Gli utenti normali possono settare l'\textit{effective id} solo al valore del
quelli originari per quanto riguarda tutti gli altri controlli di accesso.
Le due funzioni usate per cambiare questi identificatori sono \func{setfsuid}
-e \func{setfsgid}, ovviamenete sono specifiche di Linux e non devono essere
+e \func{setfsgid}, ovviamente sono specifiche di Linux e non devono essere
usate se si intendono scrivere programmi portabili; i loro prototipi sono:
-
\begin{functions}
\headdecl{sys/fsuid.h}
-\funcdecl{int setfsuid(uid\_t fsuid)} setta il \textit{filesystem user ID} del
+\funcdecl{int setfsuid(uid\_t fsuid)} Setta il \textit{filesystem user ID} del
processo corrente a \var{fsuid}.
-\funcdecl{int setfsgid(gid\_t fsgid)} setta l'\textit{filesystem group ID} del
+\funcdecl{int setfsgid(gid\_t fsgid)} Setta l'\textit{filesystem group ID} del
processo corrente a \var{fsgid}.
-Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
-l'unico errore possibile è \macro{EPERM}.
+\bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso
+ di fallimento: l'unico errore possibile è \macro{EPERM}.}
\end{functions}
Queste funzioni hanno successo solo se il processo chiamante ha i privilegi di
che devono essere compiuti per realizzarla verranno eseguiti senza possibilità
di interruzione in una fase intermedia.
-In un ambiente multitasking il concetto è esseziale, dato che un processo può
+In un ambiente multitasking il concetto è essenziale, dato che un processo può
essere interrotto in qualunque momento dal kernel che mette in esecuzione un
altro processo o dalla ricezione di un segnale; occorre pertanto essere
accorti nei confronti delle possibili \textit{race condition} (vedi
Nel caso dell'interazione fra processi la situazione è molto più semplice, ed
occorre preoccuparsi della atomicità delle operazioni solo quando si ha a che
fare con meccanismi di intercomunicazione (che esamineremo in dettaglio in
-\capref{cha:ipc}) o nella operazioni con i file (vedremo alcuni esempi in
+\capref{cha:IPC}) o nella operazioni con i file (vedremo alcuni esempi in
\secref{sec:file_atomic}). In questi casi in genere l'uso delle appropriate
funzioni di libreria per compiere le operazioni necessarie è garanzia
sufficiente di atomicità in quanto le system call con cui esse sono realizzate
processi.
Nel caso dei segnali invece la situazione è molto più delicata, in quanto lo
-stesso processo può essere interrotto in qualunque momento, e le operazioni di
-un eventuale \textit{signal handler} saranno compiute nello stesso spazio di
-indirizzi. Per questo anche solo il solo accesso o l'assegnazione di una
-variabile possono non essere più operazioni atomiche (torneremo su questi
-aspetti in \secref{sec:sign_xxx}).
+stesso processo, e pure alcune system call, possono essere interrotti in
+qualunque momento, e le operazioni di un eventuale \textit{signal handler}
+sono compiute nello stesso spazio di indirizzi del processo. Per questo anche
+solo il solo accesso o l'assegnazione di una variabile possono non essere più
+operazioni atomiche (torneremo su questi aspetti in \secref{sec:sign_xxx}).
In questo caso il sistema provvede un tipo di dato, il \type{sig\_atomic\_t},
il cui accesso è assicurato essere atomico. In pratica comunque si può
condivise siano opportunamente protette da meccanismi di sincronizzazione
(torneremo su queste problematiche di questo tipo in \secref{sec:ipc_semaph}).
-Un caso particolare di \textit{race condition} sono poi i cosidetti
+Un caso particolare di \textit{race condition} sono poi i cosiddetti
\textit{deadlock}; l'esempio tipico è quello di un flag di ``occupazione'' che
viene rilasciato da un evento asincrono fra il controllo (in cui viene trovato
-occupato) e la successiva messa in attesa, attesa che a questo punto diventerà
+occupato) e la successiva messa in attesa, che a questo punto diventerà
perpetua (da cui il nome di \textit{deadlock}) in quanto l'evento di sblocco
-di questa è stato perso.
+del flag è stato perso fra il controllo e la messa in attesa.
\subsection{Le funzioni rientranti}
chiamante: due chiamate possono interferire se viene passato lo stesso
oggetto.
-Le glibc mettono a disposizione due macro di compilatore \macro{_REENTRANT} e
-\macro{_THREAD_SAFE} per assicurare che siano usate delle versioni rientranti
+Le glibc mettono a disposizione due macro di compilatore \macro{\_REENTRANT} e
+\macro{\_THREAD\_SAFE} per assicurare che siano usate delle versioni rientranti
delle funzioni di libreria.