\chapter{La gestione dei processi}
\label{cha:process_handling}

Come accennato nell'introduzione in un sistema unix ogni attività del sistema
viene svolta tramite i processi.  In sostanza i processi costituiscono l'unità
base per l'allocazione e l'uso delle risorse del sistema.

Nel precedente capitolo abbiamo visto come funziona un singolo processo, in
questo capitolo affronteremo i dettagli della creazione e della distruzione
dei processi, della gestione dei loro attributi e privilegi, e di tutte le
funzioni a questo connesse.


\section{Introduzione}
\label{sec:proc_gen}

Partiremo con una introduzione generale ai concetti che stanno alla base della
gestione dei processi in unix. 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.

\subsection{La gerarchia dei processi}
\label{sec:proc_hierarchy}

A differenza di quanto avviene in altri sistemi (ad esempio nel VMS la
generazione di nuovi processi è un'operazione privilegiata) una delle
caratteristiche di unix (che esamineremo in dettaglio più avanti) è che
qualunque processo può a sua volta generarne altri, detti processi figli
(\textit{child process}). Ogni processo è identificato presso il sistema da un
numero unico, il \acr{pid} (da \textit{process identifier}).

Una seconda caratteristica è che la generazione di un processo è una
operazione separata rispetto al lancio di un programma. In genere la sequenza
è sempre quella di creare un nuovo processo, il quale si eseguirà, in un passo
successivo, il programma voluto: questo è ad esempio quello che fa la shell
quando mette in esecuzione il programma che gli indichiamo nella linea di
comando.

Una terza caratteristica è che ogni processo viene sempre generato da un altro
che viene chiamato processo genitore (\textit{parent process}). Questo vale
per tutti i processi, con una eccezione (dato che ci deve essere un punto di
partenza), esiste sempre infatti un processo speciale, che normalmente è
\cmd{/sbin/init}, che viene lanciato dal kernel quando questo ha finito la
fase di avvio, esso essendo il primo processo lanciato ha sempre il \acr{pid}
uguale a 1 e non è figlio di nessuno.

Questo è ovviamente un processo speciale, che in genere si occupa di far
partire tutti gli processi altri necessari al funzionamento del sistema,
inoltre \cmd{init} è essenziale per svolgere una serie di compiti
amministrativi nelle operazioni ordinarie del sistema (torneremo si alcuni di
essi in \secref{}) e non può mai essere terminato. La struttura del sistema
comunque consente di lanciare al posto di \cmd{init} qualunque altro programma
(e in casi di emergenza, ad esempio se il file di \cmd{init} si fosse
corrotto, è possibile farlo ad esempio passando la riga \cmd{init=/bin/sh}
all'avvio).

Dato che tutti i processi successivi sono comunque generati da \cmd{init} o da
suoi figli tutto ciò comporta che, i processi sono organizzati gerarchicamente
dalla relazione fra genitori e figli, in maniera analoga a come i file sono
organizzati in un albero di directory con alla base \file{/} (si veda
\secref{sec:file_file_struct}); in questo caso alla base dell'albero c'è il
processo \cmd{init} che è progenitore di ogni altro processo\footnote{in
  realtà questo non è del tutto vero, in Linux ci sono alcuni processi che pur
  comparendo come figli di init (ad esempio in \cmd{pstree}) sono generati
  direttamente dal kernel, come \cmd{keventd}, \cmd{kswapd}, etc.}.


\subsection{Una panoramica sulle funzioni di gestione}
\label{sec:proc_handling_intro}

I processi vengono creati dalla funzione \func{fork}; in molti unix questa è
una system call, Linux però usa un'altra nomenclatura, e la funzione fork è
basata a sua volta sulla system call \func{clone}, che viene usata anche per
generare i \textit{thread}.  Il processo figlio creato dalla \func{fork} è una
copia identica del processo processo padre, ma ha nuovo \acr{pid} e viene
eseguito in maniera indipendente (le differenze fra padre e figlio sono
affrontate in dettaglio in \secref{sec:proc_fork}).

Se si vuole che il processo padre si fermi fino alla conclusione del processo
figlio questo deve essere specificato subito dopo la \func{fork} chiamando la
funzione \func{wait} o la funzione \func{waitpid}; queste funzioni
restituiscono anche una informazione abbastanza limitata (il codice di uscita)
sulle cause della terminazione del processo.

Quando un processo ha concluso il suo compito o ha incontrato un errore non
risolvibile esso può essere terminato con la funzione \func{exit} (si veda
quanto discusso in \secref{sec:proc_termination}). La vita del processo però
termina solo quando la notifica della sua conclusione viene ricevuta dal
processo padre, a quel punto tutte le risorse allocate nel sistema ad esso
associate vengono rilasciate.

Avere due processi che eseguono esattamente lo stesso codice non è molto
utile, normalmente si genera un secondo processo per affidargli l'esecuzione
di un compito specifico (ad esempio gestire una connessione dopo che questa è
stata stabilita), o fargli eseguire (come fa la shell) un altro programma. Per
quest'ultimo caso si usa la seconda funzione fondamentale per programmazione
coi processi che è la \func{exec}.

Il programma che un processo sta eseguendo si chiama immagine del processo (o
\textit{process image}), le funzioni della famiglia \func{exec} permettono di
caricare un'altro programma da disco sostituendo quest'ultimo all'immagine
corrente; questo fa si che l'immagine precedente venga completamente
cancellata. Questo significa che quando il nuovo programma esce anche il
processo termina, e non si può tornare alla precedente immagine.

Per questo motivo la \func{fork} e la \func{exec} sono funzioni molto
particolari con caratteristiche uniche rispetto a tutte le altre, infatti la
prima ritorna due volte (nel processo padre e nel figlio) mentre la seconda
non ritorna mai (in quanto con essa viene eseguito un altro programma).



\section{La gestione dei processi}
\label{sec:proc_handling}

In questa sezione tratteremo le funzioni per la gestione dei processi, a
partire dalle funzioni elementari che permettono di leggerne gli
identificatori, alle varie funzioni di manipolazione dei processi, che
riguardano la lore creazione, terminazione, e la messa in esecuzione di altri
programmi.


\subsection{Gli identificatori dei processi}
\label{sec:proc_pid}

Come accennato nell'introduzione ogni processo viene identificato dal sistema
da un numero identificativo unico, il \textit{process id} o \acr{pid};
quest'ultimo è un tipo di dato standard, il \type{pid\_t} che in genere è un
intero con segno (nel caso di Linux e delle glibc il tipo usato è \type{int}).

Il \acr{pid} viene assegnato in forma progressiva ogni volta che un nuovo
processo viene creato, fino ad un limite massimo (in genere essendo detto
numero memorizzato in un intero a 16 bit si arriva a 32767) oltre il quale si
riparte dal numero più basso disponibile (FIXME: verificare, non sono sicuro).
Per questo motivo processo il processo di avvio (\cmd{init}) ha sempre il
\acr{pid} uguale a uno.

Tutti i processi inoltre memorizzano anche il \acr{pid} del genitore da cui
sono stati creati, questo viene chiamato in genere \acr{ppid} (da
\textit{parent process id}) ed è normalmente utilizzato per il controllo di
sessione.  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
    corrente.

Entrambe le funzioni non riportano condizioni di errore. 
\end{functions}

Il fatto che il \acr{pid} sia un numero univoco per il sistema lo rende il
candidato ideale per generare ultieriori indicatori associati al processo di
cui diventa possibile garantire l'unicità: ad esempio la funzione
\func{tmpname} (si veda \secref{sec:file_temp_file}) usa il \acr{pid} per
generare un pathname univoco, che non potrà essere replicato da un'altro
processo che usi la stessa funzione.


\subsection{La funzione \func{fork}}
\label{sec:proc_fork}

La funzione \func{fork} è la funzione fondamentale della gestione dei processi
in unix; come si è detto l'unico modo di creare un nuovo processo è attraverso
l'uso di questa funzione, che è quindi la base per il multitasking; il protipo
della funzione è:

\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{unistd.h} 
  
  \funcdecl{pid\_t fork(void)} 

  Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
  caso di errore \texttt{errno} può assumere i valori:
  \begin{errlist}
  \item \macro{EAGAIN}
  \item \macro{ENOMEM}
  \end{errlist}
\end{functions}


Dopo l'esecuzione di una fork sia il processo padre che il processo figlio
continuano ad essere eseguiti normalmente, ed il processo figlio esegue
esattamente lo stesso codice del padre. La sola differenza è che nel processo
padre il valore di ritorno della funzione fork è il pid del processo figlio,
mentre nel figlio è zero; in questo modo il programma può identificare se
viene eseguito dal padre o dal figlio. 




\subsection{Le funzioni \texttt{wait} e  \texttt{waitpid}}
\label{sec:proc_wait}

\subsection{Le funzioni \texttt{exec}}
\label{sec:proc_exec}




\section{Il controllo di accesso}
\label{sec:proc_perms}





Come accennato in \secref{sec:file_perm_overview} ciascun processo porta con
se un gruppo di identificatori (riportati in \ntab) utilizzati per i controllo
degli accessi, 


\begin{table}[htb]
  \centering
  \begin{tabular}[c]{|c|l|l|}
    \hline
    Sigla & Significato & Utilizzo \\ 
    \hline
    \hline
    \acr{ruid} & \textit{real user id} & indica l'utente reale \\ 
    \acr{rgid} & \textit{real group id} & indica il gruppo reale \\ 
    \acr{euid} & \textit{effective user id} & indica l'utente reale \\ 
    \acr{egid} & \textit{effective group id} & indica il gruppo reale \\ 
               & \textit{supplementaru group id} & indica il gruppo  \\ 
    \acr{suid} & \textit{saved user id} & indica l'utente reale \\ 
    \acr{sgid} & \textit{daved group id} & indica il gruppo reale \\ 
    \acr{fsuid} & \textit{real user id} & indica l'utente reale \\ 
    \acr{fsgid} & \textit{real group id} & indica il gruppo reale \\ 
    \hline
  \end{tabular}
  \caption{Identificatori di utente e gruppo associati a ciascun processo.}
  \label{tab:proc_uid_gid}
\end{table}


\subsection{Le funzioni \texttt{setuid} e \texttt{setgid}}
\label{sec:proc_setuid}


\subsection{Le funzioni \texttt{seteuid} e \texttt{setegid}}
\label{sec:proc_seteuid}

