\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}
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}
\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}
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}
\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}
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[])}
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, ...)}
\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.
+
+ \noindent 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}
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}
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}
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}
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}
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.