%% prochand.tex
%%
-%% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
\cmd{init} o da uno dei suoi figli\footnote{in realtà questo non è del tutto
vero, in Linux ci sono alcuni processi speciali che pur comparendo come
figli di \cmd{init}, o con \acr{pid} successivi, sono in realtà generati
- direttamente dal kernel, (come \cmd{keventd}, \cmd{kswapd}, etc.).} si
+ direttamente dal kernel, (come \cmd{keventd}, \cmd{kswapd}, ecc.).} si
possono classificare i processi con la relazione padre/figlio in
un'organizzazione gerarchica ad albero, in maniera analoga a come i file sono
organizzati in un albero di directory (si veda
descrizione delle opzioni); il codice completo, compresa la parte che gestisce
le opzioni a riga di comando, è disponibile nel file \file{ForkTest.c},
distribuito insieme agli altri sorgenti degli esempi su
-\href{http://gapil.firenze.linux.it/gapil_source.tgz}
-{\texttt{http://gapil.firenze.linux.it/gapil\_source.tgz}}.
+\href{http://gapil.truelite.it/gapil_source.tgz}
+{\textsf{http://gapil.truelite.it/gapil\_source.tgz}}.
Decifrato il numero di figli da creare, il ciclo principale del programma
(\texttt{\small 24--40}) esegue in successione la creazione dei processi figli
\begin{itemize*}
\item i file aperti e gli eventuali flag di
\textit{close-on-exec}\index{\textit{close-on-exec}} impostati (vedi
- sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl}).
+ sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl});
\item gli identificatori per il controllo di accesso: l'\textsl{user-ID
reale}, il \textsl{group-ID reale}, l'\textsl{user-ID effettivo}, il
\textsl{group-ID effettivo} ed i \textit{group-ID supplementari} (vedi
- sez.~\ref{sec:proc_access_id}).
+ sez.~\ref{sec:proc_access_id});
\item gli identificatori per il controllo di sessione: il \textit{process
group-ID} e il \textit{session id} ed il terminale di controllo (vedi
- sez.~\ref{sec:sess_proc_group}).
+ sez.~\ref{sec:sess_proc_group});
\item la directory di lavoro e la directory radice (vedi
- sez.~\ref{sec:file_work_dir} e sez.~\ref{sec:file_chroot}).
-\item la maschera dei permessi di creazione (vedi sez.~\ref{sec:file_umask}).
+ sez.~\ref{sec:file_work_dir} e sez.~\ref{sec:file_chroot});
+\item la maschera dei permessi di creazione (vedi sez.~\ref{sec:file_umask});
\item la maschera dei segnali bloccati (vedi sez.~\ref{sec:sig_sigmask}) e le
- azioni installate (vedi sez.~\ref{sec:sig_gen_beha}).
+ azioni installate (vedi sez.~\ref{sec:sig_gen_beha});
\item i segmenti di memoria condivisa agganciati al processo (vedi
- sez.~\ref{sec:ipc_sysv_shm}).
-\item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit}).
+ sez.~\ref{sec:ipc_sysv_shm});
+\item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
\item le variabili di ambiente (vedi sez.~\ref{sec:proc_environ}).
\end{itemize*}
-le differenze fra padre e figlio dopo la \func{fork} invece sono:
+Le differenze fra padre e figlio dopo la \func{fork} invece sono:
\begin{itemize*}
-\item il valore di ritorno di \func{fork}.
-\item il \acr{pid} (\textit{process id}).
+\item il valore di ritorno di \func{fork};
+\item il \acr{pid} (\textit{process id});
\item il \acr{ppid} (\textit{parent process id}), quello del figlio viene
- impostato al \acr{pid} del padre.
+ impostato al \acr{pid} del padre;
\item i valori dei tempi di esecuzione della struttura \struct{tms} (vedi
- sez.~\ref{sec:sys_cpu_times}) che nel figlio sono posti a zero.
+ sez.~\ref{sec:sys_cpu_times}) che nel figlio sono posti a zero;
\item i \textit{lock} sui file (vedi sez.~\ref{sec:file_locking}), che non
- vengono ereditati dal figlio.
+ vengono ereditati dal figlio;
\item gli allarmi ed i segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}), che
per il figlio vengono cancellati.
\end{itemize*}
Dato che Linux supporta il \textit{copy on
write}\index{\textit{copy~on~write}} la perdita di prestazioni è
assolutamente trascurabile, e l'uso di questa funzione (che resta un caso
-speciale della system call \func{\_\_clone}), è deprecato; per questo
-eviteremo di trattarla ulteriormente.
+speciale della system call \func{\_\_clone}) è deprecato; per questo eviteremo
+di trattarla ulteriormente.
-\subsection{La conclusione di un processo.}
+\subsection{La conclusione di un processo}
\label{sec:proc_termination}
In sez.~\ref{sec:proc_conclusion} abbiamo già affrontato le modalità con cui
memoria che stava usando, e così via; l'elenco completo delle operazioni
eseguite alla chiusura di un processo è il seguente:
\begin{itemize*}
-\item tutti i file descriptor sono chiusi.
-\item viene memorizzato lo stato di terminazione del processo.
+\item tutti i file descriptor sono chiusi;
+\item viene memorizzato lo stato di terminazione del processo;
\item ad ogni processo figlio viene assegnato un nuovo padre (in genere
- \cmd{init}).
+ \cmd{init});
\item viene inviato il segnale \const{SIGCHLD} al processo padre (vedi
- sez.~\ref{sec:sig_sigchld}).
+ sez.~\ref{sec:sig_sigchld});
\item se il processo è un leader di sessione ed il suo terminale di controllo
è quello della sessione viene mandato un segnale di \const{SIGHUP} a tutti i
processi del gruppo di foreground e il terminale di controllo viene
- disconnesso (vedi sez.~\ref{sec:sess_ctrl_term}).
+ disconnesso (vedi sez.~\ref{sec:sess_ctrl_term});
\item se la conclusione di un processo rende orfano un \textit{process
group} ciascun membro del gruppo viene bloccato, e poi gli vengono
inviati in successione i segnali \const{SIGHUP} e \const{SIGCONT}
nella variabile puntata da \param{status} e tutte le risorse del kernel
relative al processo (vedi sez.~\ref{sec:proc_termination}) vengono rilasciate.
Nel caso un processo abbia più figli il valore di ritorno (il \acr{pid} del
-figlio) permette di identificare qual'è quello che è uscito.
+figlio) permette di identificare qual è quello che è uscito.
Questa funzione ha il difetto di essere poco flessibile, in quanto ritorna
all'uscita di un qualunque processo figlio. Nelle occasioni in cui è
\hline
\hline
\macro{WIFEXITED(s)} & Condizione vera (valore non nullo) per un processo
- figlio che sia terminato normalmente. \\
+ figlio che sia terminato normalmente. \\
\macro{WEXITSTATUS(s)} & Restituisce gli otto bit meno significativi dello
- stato di uscita del processo (passato attraverso \func{\_exit}, \func{exit}
- o come valore di ritorno di \func{main}). Può essere valutata solo se
- \val{WIFEXITED} ha restituito un valore non nullo.\\
+ stato di uscita del processo (passato attraverso
+ \func{\_exit}, \func{exit} o come valore di
+ ritorno di \func{main}). Può essere valutata solo
+ se \val{WIFEXITED} ha restituito un valore non
+ nullo.\\
\macro{WIFSIGNALED(s)} & Vera se il processo figlio è terminato
- in maniera anomala a causa di un segnale che non è stato catturato (vedi
- sez.~\ref{sec:sig_notification}).\\
- \macro{WTERMSIG(s)} & restituisce il numero del segnale che ha causato
- la terminazione anomala del processo. Può essere valutata solo se
- \val{WIFSIGNALED} ha restituito un valore non nullo.\\
+ in maniera anomala a causa di un segnale che non
+ è stato catturato (vedi
+ sez.~\ref{sec:sig_notification}).\\
+ \macro{WTERMSIG(s)} & Restituisce il numero del segnale che ha causato
+ la terminazione anomala del processo. Può essere
+ valutata solo se \val{WIFSIGNALED} ha restituito
+ un valore non nullo.\\
\macro{WCOREDUMP(s)} & Vera se il processo terminato ha generato un
- file si \textit{core dump}. Può essere valutata solo se
- \val{WIFSIGNALED} ha restituito un valore non nullo.\footnotemark \\
+ file di \textit{core dump}. Può essere valutata
+ solo se \val{WIFSIGNALED} ha restituito un valore
+ non nullo.\footnotemark \\
\macro{WIFSTOPPED(s)} & Vera se il processo che ha causato il ritorno di
- \func{waitpid} è bloccato. L'uso è possibile solo avendo specificato
- l'opzione \const{WUNTRACED}. \\
- \macro{WSTOPSIG(s)} & restituisce il numero del segnale che ha bloccato
- il processo, Può essere valutata solo se \val{WIFSTOPPED} ha
- restituito un valore non nullo. \\
+ \func{waitpid} è bloccato. L'uso è possibile solo
+ avendo specificato l'opzione \const{WUNTRACED}. \\
+ \macro{WSTOPSIG(s)} & Restituisce il numero del segnale che ha bloccato
+ il processo. Può essere valutata solo se
+ \val{WIFSTOPPED} ha restituito un valore non
+ nullo. \\
\hline
\end{tabular}
\caption{Descrizione delle varie macro di preprocessore utilizzabili per
Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la
lettura dello stato di terminazione di un processo, analoghe alle precedenti
-ma che prevedono un ulteriore parametro attraverso il quale il kernel può
+ma che prevedono un ulteriore argomento attraverso il quale il kernel può
restituire al padre informazioni sulle risorse usate dal processo terminato e
dai vari figli. Le due funzioni sono \funcd{wait3} e \funcd{wait4}, che
diventano accessibili definendo la macro \macro{\_USE\_BSD}; i loro prototipi
\headdecl{sys/times.h} \headdecl{sys/types.h} \headdecl{sys/wait.h}
\headdecl{sys/resource.h}
- \funcdecl{pid\_t wait4(pid\_t pid, int * status, int options, struct rusage
- * rusage)}
- È identica a \func{waitpid} sia per comportamento che per i valori dei
- parametri, ma restituisce in \param{rusage} un sommario delle risorse usate
+ \funcdecl{pid\_t wait4(pid\_t pid, int *status, int options, struct rusage
+ *rusage)}
+ È identica a \func{waitpid} sia per comportamento che per i valori degli
+ argomenti, ma restituisce in \param{rusage} un sommario delle risorse usate
dal processo.
\funcdecl{pid\_t wait3(int *status, int options, struct rusage *rusage)}
riconosciuto come tale, o compilato per un'altra architettura.
\item[\errcode{ENOENT}] il file o una delle librerie dinamiche o l'interprete
necessari per eseguirlo non esistono.
- \item[\errcode{ETXTBSY}] L'eseguibile è aperto in scrittura da uno o più
+ \item[\errcode{ETXTBSY}] l'eseguibile è aperto in scrittura da uno o più
processi.
- \item[\errcode{EINVAL}] L'eseguibile ELF ha più di un segmento
+ \item[\errcode{EINVAL}] l'eseguibile ELF ha più di un segmento
\const{PF\_INTERP}, cioè chiede di essere eseguito da più di un
interprete.
- \item[\errcode{ELIBBAD}] Un interprete ELF non è in un formato
+ \item[\errcode{ELIBBAD}] un interprete ELF non è in un formato
riconoscibile.
- \item[\errcode{E2BIG}] La lista degli argomenti è troppo grande.
+ \item[\errcode{E2BIG}] la lista degli argomenti è troppo grande.
\end{errlist}
ed inoltre anche \errval{EFAULT}, \errval{ENOMEM}, \errval{EIO},
\errval{ENAMETOOLONG}, \errval{ELOOP}, \errval{ENOTDIR}, \errval{ENFILE},
quando la sua funzione \func{main} è dichiarata nella forma
\code{main(int argc, char *argv[], char *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
+Le altre funzioni della famiglia servono per fornire all'utente una serie di
+possibili diverse interfacce per la creazione di un nuovo processo. I loro
prototipi sono:
\begin{functions}
\headdecl{unistd.h}
\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
+argomento. Gli argomenti successivi consentono di specificare gli argomenti a
linea di comando e l'ambiente ricevuti dal nuovo processo.
\bodydesc{Queste funzioni ritornano solo in caso di errore, restituendo -1;
Per capire meglio le differenze fra le funzioni della famiglia si può fare
riferimento allo specchietto riportato in tab.~\ref{tab:proc_exec_scheme}. 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
+prima differenza riguarda le modalità di passaggio dei valori che poi andranno
+a costituire gli argomenti a linea di comando (cioè i valori di
\param{argv} e \param{argc} visti dalla funzione \func{main} del programma
chiamato).
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$ \\
+ filename completo &$\bullet$&&$\bullet$&$\bullet$&&$\bullet$\\
+ ricerca su \var{PATH} &&$\bullet$&&&$\bullet$& \\
\hline
ambiente a vettore &&&$\bullet$&&&$\bullet$ \\
uso di \var{environ} &$\bullet$&$\bullet$&&$\bullet$&$\bullet$& \\
La seconda differenza fra le funzioni riguarda le modalità con cui si
specifica il programma che si vuole eseguire. Con lo mnemonico \code{p} si
indicano le due funzioni che replicano il comportamento della shell nello
-specificare il comando da eseguire; quando il parametro \param{file} non
-contiene una ``\file{/}'' esso viene considerato come un nome di programma, e
-viene eseguita automaticamente una ricerca fra i file presenti nella lista di
-directory specificate dalla variabile di ambiente \var{PATH}. Il file che
+specificare il comando da eseguire; quando l'argomento \param{file} non
+contiene una ``\texttt{/}'' esso viene considerato come un nome di programma,
+e viene eseguita automaticamente una ricerca fra i file presenti nella lista
+di directory specificate dalla variabile di ambiente \var{PATH}. Il file che
viene posto in esecuzione è il primo che viene trovato. Se si ha un errore
relativo a permessi di accesso insufficienti (cioè l'esecuzione della
sottostante \func{execve} ritorna un \errcode{EACCES}), la ricerca viene
\end{figure}
La terza differenza è come viene passata la lista delle variabili di ambiente.
-Con lo mnemonico \code{e} vengono indicate quelle funzioni che necessitano di
-un vettore di parametri \var{envp[]} analogo a quello usato per gli argomenti
-a riga di comando (terminato quindi da un \val{NULL}), le altre usano il
-valore della variabile \var{environ} (vedi sez.~\ref{sec:proc_environ}) del
-processo di partenza per costruire l'ambiente.
+Con lo mnemonico \texttt{e} vengono indicate quelle funzioni che necessitano
+di un vettore di parametri \var{envp[]} analogo a quello usato per gli
+argomenti a riga di comando (terminato quindi da un \val{NULL}), le altre
+usano il valore della variabile \var{environ} (vedi
+sez.~\ref{sec:proc_environ}) del processo di partenza per costruire
+l'ambiente.
Oltre a mantenere lo stesso \acr{pid}, il nuovo programma fatto partire da
\func{exec} assume anche una serie di altre proprietà del processo chiamante;
la lista completa è la seguente:
\begin{itemize*}
\item il \textit{process id} (\acr{pid}) ed il \textit{parent process id}
- (\acr{ppid}).
+ (\acr{ppid});
\item l'\textsl{user-ID reale}, il \textit{group-ID reale} ed i
- \textsl{group-ID supplementari} (vedi sez.~\ref{sec:proc_access_id}).
+ \textsl{group-ID supplementari} (vedi sez.~\ref{sec:proc_access_id});
\item il \textit{session id} (\acr{sid}) ed il \textit{process group-ID}
- (\acr{pgid}), vedi sez.~\ref{sec:sess_proc_group}.
-\item il terminale di controllo (vedi sez.~\ref{sec:sess_ctrl_term}).
-\item il tempo restante ad un allarme (vedi sez.~\ref{sec:sig_alarm_abort}).
+ (\acr{pgid}), vedi sez.~\ref{sec:sess_proc_group};
+\item il terminale di controllo (vedi sez.~\ref{sec:sess_ctrl_term});
+\item il tempo restante ad un allarme (vedi sez.~\ref{sec:sig_alarm_abort});
\item la directory radice e la directory di lavoro corrente (vedi
- sez.~\ref{sec:file_work_dir}).
+ sez.~\ref{sec:file_work_dir});
\item la maschera di creazione dei file (\var{umask}, vedi
sez.~\ref{sec:file_umask}) ed i \textit{lock} sui file (vedi
- sez.~\ref{sec:file_locking}).
+ sez.~\ref{sec:file_locking});
\item i segnali sospesi (\textit{pending}) e la maschera dei segnali (si veda
- sez.~\ref{sec:sig_sigmask}).
-\item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit}).
+ sez.~\ref{sec:sig_sigmask});
+\item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
\item i valori delle variabili \var{tms\_utime}, \var{tms\_stime},
\var{tms\_cutime}, \var{tms\_ustime} (vedi sez.~\ref{sec:sys_cpu_times}).
\end{itemize*}
gruppo cui il file appartiene (per i dettagli vedi sez.~\ref{sec:proc_perms}).
Se il file da eseguire è in formato \emph{a.out} e necessita di librerie
-condivise, viene lanciato il \textit{linker} dinamico \cmd{ld.so} prima del
-programma per caricare le librerie necessarie ed effettuare il link
+condivise, viene lanciato il \textit{linker} dinamico \cmd{/lib/ld.so} prima
+del programma per caricare le librerie necessarie ed effettuare il link
dell'eseguibile. Se il programma è in formato ELF per caricare le librerie
dinamiche viene usato l'interprete indicato nel segmento \const{PT\_INTERP},
in genere questo è \file{/lib/ld-linux.so.1} per programmi linkati con le
\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi linkati con le
-\acr{glibc}. Infine nel caso il file sia uno script esso deve iniziare con
-una linea nella forma \cmd{\#!/path/to/interpreter} dove l'interprete indicato
-deve esse un programma valido (binario, non un altro script) che verrà
-chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti]
- filename}.
+\acr{glibc}. Infine nel caso il file sia uno script esso deve iniziare con una
+linea nella forma \cmd{\#!/path/to/interpreter [argomenti]} dove l'interprete
+indicato deve essere un programma valido (binario, non un altro script) che
+verrà chiamato come se si fosse eseguito il comando \cmd{interpreter
+ [argomenti] filename}.\footnote{si tenga presente che con Linux quanto viene
+ scritto come \texttt{argomenti} viene passato all'inteprete come un unico
+ argomento con una unica stringa di lunghezza massima di 127 caratteri e se
+ questa dimensione viene ecceduta la stringa viene troncata; altri Unix hanno
+ dimensioni massime diverse, e diversi comportamenti, ad esempio FreeBSD
+ esegue la scansione della riga e la divide nei vari argomenti e se è troppo
+ lunga restitituisce un errore di \const{ENAMETOOLONG}, una comparazione dei
+ vari comportamenti si trova su
+ \href{http://www.in-ulm.de/~mascheck/various/shebang/}
+ {\texttt{http://www.in-ulm.de/\~mascheck/various/shebang/}}.}
Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è
basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo
si applica alla seconda per i group-ID. I processi non privilegiati possono
cambiare uno qualunque degli user-ID solo ad un valore corrispondente o
all'user-ID reale, o a quello effettivo o a quello salvato, l'amministratore
-può specificare i valori che vuole; un valore di -1 per un qualunque parametro
+può specificare i valori che vuole; un valore di -1 per un qualunque argomento
lascia inalterato l'identificatore corrispondente.
Per queste funzioni esistono anche due controparti che permettono di leggere
Lo standard POSIX.1b prevede comunque che i due valori della massima e minima
priorità statica possano essere ottenuti, per ciascuna delle politiche di
-scheduling realtime, tramite le due funzioni \funcd{sched\_get\_priority\_max}
-e \funcd{sched\_get\_priority\_min}, i cui prototipi sono:
+scheduling \textit{real-time}, tramite le due funzioni
+\funcd{sched\_get\_priority\_max} e \funcd{sched\_get\_priority\_min}, i cui
+prototipi sono:
\begin{functions}
\headdecl{sched.h}