From ffde006b4b38517dd190c394b769c619d13174a5 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 15 Aug 2001 21:25:00 +0000 Subject: [PATCH] Sistemate cross-reference dei processi. --- errors.tex | 2 +- filedir.tex | 8 +-- gapil.tex | 4 +- process.tex | 6 +-- prochand.tex | 139 ++++++++++++++++++++++++++++++++++----------------- signal.tex | 2 +- 6 files changed, 104 insertions(+), 57 deletions(-) diff --git a/errors.tex b/errors.tex index e5f9439..a2aaa74 100644 --- a/errors.tex +++ b/errors.tex @@ -39,7 +39,7 @@ libreria che operano sui file. corretto, che il modulo relativo non è stato caricato nel kernel, o che il dispositico è fisicamente assente o non funzionante. \item \macro{ENOEXEC} \textit{Invalid executable file format}. Il file non ha - un formato eseguibile, è un errore riscontrato dalle funzioni \finc{exec}. + un formato eseguibile, è un errore riscontrato dalle funzioni \func{exec}. \item \macro{EBADF} \textit{Bad file descriptor}. File descriptor non valido: si è usato un file descriptor inesistente, o aperto in sola lettura per scrivere, o viceversa. diff --git a/filedir.tex b/filedir.tex index b7192d5..db127ae 100644 --- a/filedir.tex +++ b/filedir.tex @@ -147,7 +147,7 @@ l'\textit{effective group id} e gli eventuali \textit{supplementary group id} del processo. Per una spiegazione dettagliata degli identificatori associati ai processi si -veda \secref{sec:prochand_perms}; normalmente, a parte quanto vedremo in +veda \secref{sec:proc_perms}; normalmente, a parte quanto vedremo in \secref{sec:file_suid_sgid}, l'\textit{effective user id} e l'\textit{effective group id} corrispondono a uid e gid dell'utente che ha lanciato il processo, mentre i \textit{supplementary group id} sono quelli dei @@ -214,7 +214,7 @@ alcune propriet \textit{set-group-ID bit}) che sono identificati dalle constanti \macro{S\_ISUID} e \macro{S\_ISGID}. -Come spiegato in dettaglio in \secref{sec:prochand_exec}, quando si lancia un +Come spiegato in dettaglio in \secref{sec:proc_exec}, quando si lancia un programma il comportamendo normale del kernel è quello di settare l'\textit{effective user id} e l'\textit{effective group id} del nuovo processo all'uid e al gid del processo corrente, che normalmente corrispondono @@ -241,7 +241,7 @@ Chiaramente avere un processo che ha privilegi superiori a quelli che avrebbe normalmente l'utente che lo ha lanciato comporta vari rischi, e questo tipo di programmi devono essere scritti accuratamente per evitare che possano essere usati per guadagnare privilegi non consentiti (torneremo sull'argomento in -\secref{sec:prochand_perms}). +\secref{sec:proc_perms}). La presenza dei bit \acr{suid} e \acr{sgid} su un file può essere rilevata con il comando \cmd{ls -l}, in tal caso comparirà la lettera \cmd{s} @@ -352,7 +352,7 @@ un file viene fatto usando \textit{effective user id} e \textit{effective group id} del processo, ma ci sono casi in cui si può voler effettuare il controllo usando il \textit{real user id} e il \textit{real group id} (cioè l'uid dell'utente che ha lanciato il programma, che, come accennato in -\secref{sec:file_suid_sgid} e spiegato in \secref{sec:prochand_perms} non è +\secref{sec:file_suid_sgid} e spiegato in \secref{sec:proc_perms} non è detto sia uguale all'\textit{effective user id}). Per far questo si può usare la funzione \func{access}, il cui prototipo è: diff --git a/gapil.tex b/gapil.tex index 5d8c217..4ea34f6 100644 --- a/gapil.tex +++ b/gapil.tex @@ -94,12 +94,12 @@ directivestyle=\color{magenta}\ttfamily } \include{intro} +\include{process} +\include{prochand} \include{fileintro} \include{filedir} \include{fileunix} \include{filestd} -\include{process} -\include{prochand} \include{signal} \include{ipc} \include{network} diff --git a/process.tex b/process.tex index 23c61c5..dafdef8 100644 --- a/process.tex +++ b/process.tex @@ -116,7 +116,7 @@ Infine occorre distinguere fra lo stato di uscita di un programma possibile un processo possa essere terminato (da un segnale) prima che il programma in esecuzione si sia concluso. In caso di conclusione normale del programma però lo stato di uscita diventa parte dello stato di conclusione del -processo (vedi \secref{sec:prochand_xxx}). +processo (vedi \secref{sec:proc_xxx}). \subsection{Le funzioni \texttt{exit} e \texttt{\_exit}} @@ -157,7 +157,7 @@ stream), fa si che ogni figlio del processo sia ereditato da \texttt{init} (vedi \secref{cha:process_handling}), manda un segnale \texttt{SIGCHLD} al processo padre (vedi \ref{sec:sig_job_control}) ed infine ritorna lo stato di uscita specificato in \texttt{status} che può essere raccolto usando la -funzione \texttt{wait} (vedi \secref{sec:prochand_wait}). +funzione \texttt{wait} (vedi \secref{sec:proc_wait}). \subsection{Le funzioni \texttt{atexit} e \texttt{on\_exit}} @@ -220,7 +220,7 @@ Data l'importanza dell'argomento in un sistema unix l'unico modo in cui un programma può essere eseguito dal kernel è attraverso la chiamata alla system call \texttt{execve} (in genere attraverso una delle funzioni \texttt{exec} che vedremo in -\secref{sec:prochand_exec}). +\secref{sec:proc_exec}). Allo stesso modo l'unico modo in cui un programma può concludere volontariamente la sua esecuzione è attraverso una chiamata alla system call diff --git a/prochand.tex b/prochand.tex index 72fcc78..3b40d63 100644 --- a/prochand.tex +++ b/prochand.tex @@ -11,63 +11,73 @@ dei processi, della gestione dei loro attributi e privilegi, e di tutte le funzioni a questo connesse. -\section{Una panoramica sui concetti base} -\label{sec:prochand_gen} +\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. + +\subsection{La gerarchia dei processi} +\label{sec:proc_hierarchy} 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. +Una seconda caratteristica di unix è 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 è \file{/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. - +questo caso c'è \file{init} che è progenitore di ogni altro processo. -\section{Gli identificatori dei processi} -\label{sec:prochand_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. +\subsection{La gestione dei processi} +\label{sec:proc_handling_intro} -Ogni processo è identificato univocamente dal sistema per il suo pid; -quest'ultimo è un tipo di dato standard, il \texttt{pid\_t} che in genere è un -intero con segno (nel caso di Linux e delle glibc il tipo usato è -\texttt{int}. +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. -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{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. -\end{functions} +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. +Quando un processo ha concluso il suo compito o ha incontrato un errore non +risolvibile esso può essere terminato con la funzione \texttt{exit} (si veda +quanto discusso in \secref{sec:proc_termination}). 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. -\section{Il controllo dei processi} -\label{sec:prochand_control} +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 +questo si usa la seconda funzione fondamentale per programmazione coi processi +che è la \texttt{exec}. -Esamineremo in questa sezione le varie funzioni per il controllo dei processi: -la loro creazione, la terminazione, l'esecuzione di altri programmi. Prima di -trattare in dettaglio le singole funzioni, faremo un'introduzione generale ai -concetti che stanno alla base della gestione dei processi in unix. +Il programma che un processo sta eseguendo si chiama immagine del processo +(\textit{process image}), le funzioni della famiglia \func{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. -\subsection{Una panoramica} -\label{sec:prochand_control_overview} +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). 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 è @@ -109,8 +119,45 @@ 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{Il controllo dei processi} +\label{sec:proc_control} + +Esamineremo in questa sezione le varie funzioni per il controllo dei processi: +la loro creazione, la terminazione, l'esecuzione di altri programmi. Prima di +trattare in dettaglio le singole funzioni, + +\subsection{Gli identificatori dei processi} +\label{sec:proc_id} + +Ogni processo viene identificato dal sistema da un numero identificativo +unico, il \textit{process id} o \acr{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 tipo di dato standard, 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{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. +\end{functions} + + + \subsection{La funzione \func{fork}} -\label{sec:prochand_fork} +\label{sec:proc_fork} La funzione \func{fork} @@ -126,24 +173,24 @@ viene eseguito dal padre o dal figlio. \subsection{Le funzioni \texttt{wait} e \texttt{waitpid}} -\label{sec:prochand_wait} +\label{sec:proc_wait} \subsection{Le funzioni \texttt{exec}} -\label{sec:prochand_exec} +\label{sec:proc_exec} \section{Il controllo di accesso} -\label{sec:prochand_perms} +\label{sec:proc_perms} Va messo qui tutta la storia su effective, real, saved uid, e pure le cose di Linux come il filesystem uid. \subsection{Le funzioni \texttt{setuid} e \texttt{setgid}} -\label{sec:prochand_setuid} +\label{sec:proc_setuid} \subsection{Le funzioni \texttt{seteuid} e \texttt{setegid}} -\label{sec:prochand_seteuid} +\label{sec:proc_seteuid} diff --git a/signal.tex b/signal.tex index 897d506..b362ad8 100644 --- a/signal.tex +++ b/signal.tex @@ -548,7 +548,7 @@ cui si trattano gli argomenti relativi. Questi segnali sono: \begin{description} \item \macro{SIGCHLD} Questo è il segnale mandato al processo padre quando un figlio termina o viene fermato. L'azione di default è di ignorare il - segnale, la sua gestione è trattata in \secref{sec:prochand_wait}. + segnale, la sua gestione è trattata in \secref{sec:proc_wait}. \item \macro{SIGCLD} Per Linux questo è solo un segnale identico al precedente, il nome è obsoleto e andrebbe evitato. \item \macro{SIGCONT} Il nome sta per \textit{continue}. Il segnale viene -- 2.30.2