Iniziato a scrivere la fork.
[gapil.git] / prochand.tex
index 390b072421612d0dfc58ab281037f65ccd7f9768..f29677b4f28c887de920c0dee4197fa7e4a77a0d 100644 (file)
@@ -11,110 +11,175 @@ dei processi, della gestione dei loro attributi e privilegi, e di tutte le
 funzioni a questo connesse.
 
 
 funzioni a questo connesse.
 
 
-\section{Una panoramica sui concetti base}
+\section{Introduzione}
 \label{sec:proc_gen}
 
 \label{sec:proc_gen}
 
-Una delle caratteristiche essenziali di unix (che esamineremo in dettaglio più
-avanti) è che ogni processo può a sua volta generare altri processi figli
-(\textit{child}): questo è ad esempio quello che fa la shell quando mette in
-esecuzione il programma che gli indichiamo nella linea di comando.
-
-Una seconda caratteristica è che ogni processo viene sempre generato in tale
-modo da un processo genitore (\textit{parent}) attraverso una apposita system
-call. Questo vale per tutti i processi, tranne per un processo speciale, che
-normalmente è \texttt{/sbin/init}, che invece viene lanciato dal kernel finita
-la fase di avvio e che quindi non è figlio di nessuno.
-
-Tutto ciò significa che, come per i file su disco, i processi sono organizzati
-gerarchicamente dalla relazione fra genitori e figli; alla base dell'albero in
-questo caso c'è init che è progenitore di ogni altro processo.
-
-
-\section{Gli identificatori dei processi}
-\label{sec:proc_id}
-
-Ogni processo viene identificato dal sistema da un numero identificativo
-unico, il \textit{process id} o \textit{pid}. Questo 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 (init) ha sempre il pid uguale a uno.
-
-Ogni processo è identificato univocamente dal sistema per il suo
-pid; quest'ultimo è un apposito tipo di dato, il \texttt{pid\_t} che in
-genere è un intero con segno (nel caso di Linux e delle glibc il tipo usato è
-\texttt{int}.
-
-Tutti i processi inoltre portano traccia del pid del genitore, chiamato in
-genere \textit{ppid} (da \textit{Parente Process Id}). Questi identificativi
-possono essere ottenuti da un programma usando le funzioni:
-\begin{itemize} 
-  \item \texttt{pid\_t getpid(void)} restituisce il pid del processo corrente.
-    
-  \item \texttt{pid\_t getppid(void)} restituisce il pid del padre del processo
-    corrente.
-
-\end{itemize}
-(per l'accesso a queste funzioni e ai relativi tipi di dati occorre includere
-gli header files \texttt{unistd.h} e \texttt{sys/types.h}). 
-
-
-
-\section{Il controllo dei processi}
-\label{sec:proc_control}
-
-Esamineremo in questa sezione le varie funzioni per il controllo dei processi:
-la lore creazione, la terminazione, l'esecuzione di altri programmi. Prima di
-trattare in dettaglio le singole funzioni, faremo un'introduzione generale ai
-contetti che stanno alla base della gestione dei processi in unix.
-
-\subsection{Una panoramica}
-\label{sec:proc_control_overview}
-
-I processi vengono creati dalla funzione \texttt{fork}; in genere questa è una
-system call, ma linux però usa un'altra nomenclatura, e la funzione fork è
-basata a sua volta sulla system call \texttt{clone}, che viene usata anche per
-generare i \textit{thread}.  Il processo figlio creato dalla \textit{fork} è
-una copia identica del processo processo padre, solo che ha un suo pid
-proprio.
+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
 
 Se si vuole che il processo padre si fermi fino alla conclusione del processo
-figlio questo deve essere specificato subito dopo la fork chiamando la
-funzione \texttt{wait} o la funzione \texttt{waitpid}, che restituiscono anche
-una informazione abbastanza limitata (il codice di uscita) sulle cause della
-terminazione 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
 
 Quando un processo ha concluso il suo compito o ha incontrato un errore non
-risolvibile esso può essere terminato con la funzione \texttt{exit} (la
-questione è più complessa ma ci torneremo più avanti). La vita del processo
-però termina solo quando viene chiamata la quando la sua conclusione viene
-ricevuta dal processo padre, a quel punto tutte le risorse allocate nel
-sistema ad esso associate vengono rilasciate.
+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
 
 Avere due processi che eseguono esattamente lo stesso codice non è molto
-utile, mormalmente si genera un secondo processo per affidagli l'esecuzione di
-un compito specifico (ad esempio gestire una connessione dopo che questa è
+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
 stata stabilita), o fargli eseguire (come fa la shell) un altro programma. Per
-questo si usa la seconda funzione fondamentale per programmazione coi processi
-che è la \texttt{exec}.
+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
-(\textit{process image}), le funzioni della famiglia \textit{exec} permettono
-di caricare un'altro programma da disco sostituendo quest'ultimo alla process
-image corrente, questo fa si che la precedente immagine venga completamente
-cancellata e quando il nuovo programma esce anche il processo termina, senza
-ritornare alla precedente immagine.
+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 \texttt{fork} e la \texttt{exec} sono funzioni molto
+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).
 
 
 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).
 
 
-\subsection{La funzione \texttt{fork}}
+
+\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}
 
 \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
 
 Dopo l'esecuzione di una fork sia il processo padre che il processo figlio
 continuano ad essere eseguiti normalmente, ed il processo figlio esegue
@@ -135,21 +200,45 @@ viene eseguito dal padre o dal figlio.
 
 
 
 
 
 
+\section{Il controllo di accesso}
+\label{sec:proc_perms}
+
 
 
 
 
-\section{Il controllo di accesso}
-\label{sec:process_perms}
 
 
-Va messo qui tutta la storia su effective, real, saved uid, e pure le cose di
-linux come il filesystem uid.
 
 
+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, 
 
 
-\subsection{Le funzioni \texttt{setuid} e \texttt{setgid}}
-\label{sec:proc_setuid}
 
 
+\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{seteuid} e \texttt{setegid}}
+
+\subsection{Le funzioni \texttt{setuid} e \texttt{setgid}}
 \label{sec:proc_setuid}
 
 
 \label{sec:proc_setuid}
 
 
+\subsection{Le funzioni \texttt{seteuid} e \texttt{setegid}}
+\label{sec:proc_seteuid}