Avanti ad exec...
[gapil.git] / prochand.tex
index f7ac31f56ae127fc5484fabc42fd6a30aa98b55b..c9e4e156feda9fe814caf0bd04beb171ef61b093 100644 (file)
@@ -728,10 +728,10 @@ dei figli in stato di zombie: alla sua terminazione infatti tutti i suoi figli
 vengono ereditati (compresi gli zombie) verranno adottati da \cmd{init}, il
 quale provvederà a completarne la terminazione.
 
-Si tenga presente infine che siccome gli zombie sono processi già terminati,
-non c'è modo di eliminarli con il comando \cmd{kill}; l'unica possibilità è
-quella di terminare il processo che li ha generati, in modo che \cmd{init}
-possa adottarli e provvedere a concludere la terminazione.
+Si tenga presente infine che siccome gli zombie sono processi già usciti, non
+c'è modo di eliminarli con il comando \cmd{kill}; l'unica possibilità è quella
+di terminare il processo che li ha generati, in modo che \cmd{init} possa
+adottarli e provvedere a concludere la terminazione.
 
 
 \subsection{Le funzioni \texttt{wait} e  \texttt{waitpid}}
@@ -970,19 +970,148 @@ 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}.
 
-\subsection{Le \textit{race condition}}
-\label{sec:proc_race_cond}
-
-Si definisce una \textit{race condition} il caso in cui diversi processi
-stanno cercando di fare qualcosa con una risorsa comune e e il risultato
-finale viene a dipendere 
-
 \subsection{Le funzioni \texttt{exec}}
 \label{sec:proc_exec}
 
+Abbiamo già detto che una delle modalità principali con cui si utilizzano i
+processi in unix è quella di usarli per lanciare nuovi programmi: questo viene
+fatto attraverso una delle funzioni della famiglia \func{exec}. Quando un
+processo chiama una di queste funzioni esso viene completamente sostituito dal
+nuovo programma; il \acr{pid} del processo non cambia, dato che non viene
+creato un nuovo processo, la funzione semplicemente rimpiazza lo stack, o
+heap, i dati ed il testo del processo corrente con un nuovo programma letto da
+disco. 
+
+Ci sono sei diverse versioni di \func{exec} (per questo la si è chiamata
+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[])}
+  
+  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
+  variabile \texttt{errno} è settata come:
+  \begin{errlist}
+  \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
+    è root o il filesystem è montato con \cmd{nosuid}, oppure
+  \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'inteprete
+    necessari per eseguirlo non esistono.
+  \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.
+  \end{errlist}
+  ed inoltre anche \macro{EFAULT}, \macro{ENOMEM}, \macro{EIO},
+  \macro{ENAMETOOLONG}, \macro{E2BIG}, \macro{ELOOP}, \macro{ENOTDIR},
+  \macro{ENFILE}, \macro{EMFILE}.
+\end{prototype}
+
+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, ...)} 
+\funcdecl{int execv(const char *path, char *const argv[])} 
+\funcdecl{int execle(const char *path, const char *arg, ..., char 
+* const envp[])} 
+\funcdecl{int execlp(const char *file, const char *arg, ...)} 
+\funcdecl{int execvp(const char *file, char *const argv[])} 
+
+Sostituiscono l'immagine corrente del processo con quella indicata nel primo
+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}.
+\end{functions}
+
+Per capire meglio le differenze fra le funzioni della famiglia si può fare
+riferimento allo specchietto riportato in \ntab. La prima differenza riguarda
+le modalità di passaggio dei parametri che poi andranno a costituire gli
+argomenti a linea di comando (cioè i valori di \var{argv} e \var{argc} visti
+dalla funzione \func{main} del programma chiamato). 
+
+Queste modalità sono due e sono riassunte dagli mnenonici \func{v} e \func{l}
+che stanno rispettivamente per \textit{vector} e \textit{list}. Nel primo caso
+gli argomenti sono passati tramite il vettore di puntatori \var{argv[]} a
+stringhe terminate con zero che costituiranno gli argomenti a riga di comando,
+questo vettore \emph{deve} essere terminato da un puntatore nullo.
+
+Nel secondo caso le stringhe degli argomenti sono passate alla funzione come
+lista di puntatori, nella forma:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+  char * arg0, char * arg1,  ..., char * argn, NULL
+\end{lstlisting}
+che deve essere terminata da un puntatore nullo.  In entrambi i casi vale la
+convenzione che il primo argomento (\var{arg0} o \var{argv[0]}) viene usato
+per indicare il nome del file che contiene il programma che verrà eseguito.
+
+
+\begin{table}[!htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|c|c|c||c|c|c|}
+    \hline
+    \multicolumn{1}{|c|}{\textbf{Caratteristiche}} & 
+    \multicolumn{6}{|c|}{\textbf{Funzioni}} \\
+    \hline
+    &\func{execl\ }&\func{execlp}&\func{execle}
+    &\func{execv\ }& \func{execvp}& \func{execve} \\
+    \hline
+    \hline
+    argomenti a lista    &$\bullet$&$\bullet$&$\bullet$&&& \\
+    argomenti a vettore  &&&&$\bullet$&$\bullet$&$\bullet$\\
+    \hline
+    filename completo    &&$\bullet$&&&$\bullet$& \\ 
+    ricerca su \var{PATH}&$\bullet$&&$\bullet$&$\bullet$&&$\bullet$ \\
+    \hline
+    ambiente a vettore   &&&$\bullet$&&&$\bullet$ \\
+    uso di \var{environ} &$\bullet$&$\bullet$&&$\bullet$&$\bullet$& \\
+    \hline
+  \end{tabular}
+  \caption{Confronto delle caratteristiche delle varie funzioni della 
+    famiglia \func{exec}.}
+  \label{tab:proc_exec_scheme}
+\end{table}
+
+La seconda differenza fra le funzioni riguarda le modalità con cui si
+specifica il programma che si vuole eseguire. Con lo mnemonico \func{p} si
+indicano le due funzioni che necessitano del \textit{pathname} assoluto del
+programma come valore del parametro \var{path}. Le altre quattro funzioni
+invece usano come parametro \var{file} un nome che viene cercato
+automaticamente fra i file presenti nella lista di directory specificate dalla
+variabile di ambiente \var{PATH}.
+
+
+La terza differenza è .
 
 
 
+Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è
+basato il controllo dei processi in unix: con \func{fork} si crea un nuovo
+processo, con \func{exec} si avvia un nuovo programma, con \func{exit} e
+\func{wait} si effettua e si gestisce la conclusione dei programmi. Tutte le
+altre funzioni sono ausiliarie e servono la lettura e il settaggio dei vari
+parametri connessi ai processi.
+
+
 \section{Il controllo di accesso}
 \label{sec:proc_perms}
 
@@ -1007,6 +1136,7 @@ dall'utente che ha lanciato il processo (attraverso i valori di \acr{uid} e
 \acr{gid}), e vengono usati sia per il controllo di accesso ai file che per la
 gestione dei privilegi associati ai processi stessi.
 \begin{table}[htb]
+  \footnotesize
   \centering
   \begin{tabular}[c]{|c|l|p{8cm}|}
     \hline
@@ -1067,3 +1197,16 @@ per tener conto di eventuali \acr{suid} o \acr{sgid}.
 \subsection{Le funzioni \texttt{seteuid} e \texttt{setegid}}
 \label{sec:proc_seteuid}
 
+
+\subsection{Le \textit{race condition}}
+\label{sec:proc_race_cond}
+
+Si definisce una \textit{race condition} il caso in cui diversi processi
+stanno cercando di fare qualcosa con una risorsa comune ed il risultato finale
+viene a dipendere dall'ordine di esecuzione dei medesimi. Ovviamente dato che
+l'ordine di esecuzione di un processo, senza appositi meccanismi di
+sincronizzazione, non è assolutamente prevedibile, queste situazioni sono
+fonti di errori molto subdoli, che possono verificarsi solo in condizioni
+particolari e quindi difficilmente riproducibili.
+
+