From: Simone Piccardi Date: Thu, 12 Sep 2002 23:07:16 +0000 (+0000) Subject: Iniziati terminali di controllo X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=0b590bfee0819bda5f875e4b53fa0e44715d2b92;hp=4d9f9d2efab74ce8580fddb05dbdbe754014cdea Iniziati terminali di controllo --- diff --git a/session.tex b/session.tex index 7b7b738..13bc2c5 100644 --- a/session.tex +++ b/session.tex @@ -1,4 +1,4 @@ -\chapter{Sessioni di lavoro e terminali} + \chapter{Sessioni di lavoro e terminali} \label{cha:session} Esamineremo in questo capitolo i concetti base del sistema delle sessioni di @@ -103,7 +103,9 @@ per far questo vengono utilizzati due ulteriori identificatori (oltre quelli visti in \secref{sec:proc_pid}) che il kernel associa a ciascun processo: l'identificatore del \textit{process group} e l'identificatore della \textsl{sessione}, che vengono indicati rispettivamente con le sigle -\acr{pgid} e \acr{sid}, e sono mantenuti in variabili di tipo \type{pid\_t}. +\acr{pgid} e \acr{sid}, e sono mantenuti in variabili di tipo \type{pid\_t}. I +valori di questi identificatori possono essere visualizzati dal comando +\cmd{ps} usando l'opzione \cmd{-j}. Un \textit{process group} è pertanto definito da tutti i processi che hanno lo stesso \acr{pgid}; è possibile leggere il valore di questo identificatore con @@ -132,9 +134,10 @@ equivalente a \code{getpgid(0)}. In maniera analoga l'identificatore della sessione può essere letto dalla funzione \func{getsid}, che però nelle \acr{glibc}\footnote{la system call è stata introdotta in Linux a partire dalla versione 1.3.44, il supporto nelle - librerie del C è iniziato dalla versione 5.2.19.} è accessibile solo -definendo \macro{\_XOPEN\_SOURCE} e \macro{\_XOPEN\_SOURCE\_EXTENDED}; il suo -prototipo è: + librerie del C è iniziato dalla versione 5.2.19. La funzione non è prevista + da POSIX.1, che parla solo di processi leader di sessione, e non di + \textit{session id}.} è accessibile solo definendo \macro{\_XOPEN\_SOURCE} e +\macro{\_XOPEN\_SOURCE\_EXTENDED}; il suo prototipo è: \begin{prototype}{unistd.h}{pid\_t getsid(pid\_t pid)} Legge l'identificatore di sessione del processo \param{pid}. @@ -143,8 +146,9 @@ prototipo i valori: \begin{errlist} \item[\macro{ESRCH}] Il processo selezionato non esiste. - \item[\macro{EPERM}] Il processo selezionato non fa parte della stessa - sessione del processo corrente. + \item[\macro{EPERM}] In alcune implementazioni viene restituito quando il + processo selezionato non fa parte della stessa sessione del processo + corrente. \end{errlist} } \end{prototype} @@ -152,17 +156,20 @@ prototipo Entrambi gli identificatori vengono inizializzati alla creazione di ciascun processo con lo stesso valore che hanno nel processo padre, per cui un processo appena creato appartiene sempre allo stesso raggruppamento e alla -stessa sessione del padre. +stessa sessione del padre. Vedremo poi come sia possibile creare più +\textit{process group} all'interno della stessa sessione, e spostare i +processi dall'uno all'altro, ma sempre all'interno di una stessa sessione. Ciascun gruppo di processi ha sempre un processo principale, il cosiddetto -\textit{process leader}, che è identificato dall'avere un \acr{pgid} uguale al -suo \acr{pid}, in genere questo è il primo processo del gruppo, che si -incarica di lanciare tutti gli altri. Un nuovo gruppo si crea con la funzione -\func{setpgrp},\footnote{questa è la definizione di POSIX.1, BSD definisce una - funzione con lo stesso nome, che però è identica a \func{setpgid}; nelle - \acr{glibc} viene sempre usata sempre questa definizione, a meno di non - richiedere esplicitamente la compatibilità all'indietro con BSD, definendo - la macro \macro{\_BSD\_SOURCE}.} il cui prototipo è: +\textit{process group leader}, che è identificato dall'avere un \acr{pgid} +uguale al suo \acr{pid}, in genere questo è il primo processo del gruppo, che +si incarica di lanciare tutti gli altri. Un nuovo gruppo si crea con la +funzione \func{setpgrp},\footnote{questa è la definizione di POSIX.1, BSD + definisce una funzione con lo stesso nome, che però è identica a + \func{setpgid}; nelle \acr{glibc} viene sempre usata sempre questa + definizione, a meno di non richiedere esplicitamente la compatibilità + all'indietro con BSD, definendo la macro \macro{\_BSD\_SOURCE}.} il cui +prototipo è: \begin{prototype}{unistd.h}{int setpgrp(void)} Modifica il \acr{pgid} al valore del \acr{pid} del processo corrente. @@ -182,23 +189,58 @@ da un gruppo ad un altro con la funzione \func{setpgid}, il cui prototipo -1 in caso di errore, nel qual caso \var{errno} assumerà i valori: \begin{errlist} \item[\macro{ESRCH}] Il processo selezionato non esiste. - \item[\macro{EPERM}] Il processo selezionato non fa parte della stessa - sessione del processo corrente. + \item[\macro{EPERM}] Il cambiamento non è consentito. + \item[\macro{EINVAL}] Il valore di \param{pgid} è negativo. \end{errlist} } \end{prototype} +La funzione permette di cambiare il \acr{pgid} del processo \param{pid}, ma il +cambiamento può essere effettuato solo se \param{pgid} indica un +\textit{process group} che è nella stessa sessione del processo chiamante. +Inoltre la funzione può essere usata soltanto sul processo corrente o su uno +dei suoi figli, ed in quest'ultimo caso ha successo soltanto se questo non ha +ancora eseguito una \func{exec}. Specificando un valore nullo per \param{pid} +si indica il processo corrente, mentre specificando un valore nullo per +\param{pgid} si imposta il \textit{process group} al valore del \acr{pid} del +processo selezionato; pertanto \func{setpgrp} è equivalente a \code{setpgid(0, + 0)}. + +Di norma questa funzione viene usata dalla shell quando si usano delle +pipeline, per mettere nello stesso process group tutti i programmi lanciati su +ogni linea di comando; essa viene chiamata dopo una \func{fork} sia dal +processo padre, per impostare il valore nel figlio, che da quest'ultimo, per +sé stesso, in modo che il cambiamento di \textit{process group} sia immediato +per entrambi; una delle due chiamate sarà ridondante, ma non potendo +determinare quale dei due processi viene eseguito per primo, occorre eseguirle +comunque entrambe per evitare di esporsi ad una race condition. + +Si noti come nessuna delle funzioni esaminate finora permetta di spostare un +processo da una sessione ad un altra; infatti l'unico modo di far cambiare +sessione ad un processo è quello di crearne una nuova con l'uso di +\func{setsid}; il suo prototipo è: +\begin{prototype}{unistd.h}{pid\_t setsid(void)} + Crea una nuova sessione sul processo corrente settandone \acr{sid} e + \acr{pgid}. + + \bodydesc{La funzione ritorna il valore del nuovo \acr{sid}, e -1 in caso di + errore, il solo errore possibile è \macro{EPERM}, che si ha quando il + \acr{pgid} e \acr{pid} del processo concidono.} +\end{prototype} +La funzione imposta il \acr{pgid} ed il \acr{sid} del processo corrente al +valore del suo \acr{pid}, creando così una nuova sessione ed un nuovo +\textit{process group} di cui esso diventa leader (come per i \textit{process + group} un processo si dice leader di sessione se il suo \acr{sid} è uguale +al suo \acr{pid}). Infine il processo viene distaccato dal terminale di +controllo. - - -La differenza fra i due identificatori è che un processo -può cambiare \acr{pgid} soltanto ad un valore che corrisponda al -\textit{process group} di un altro processo della stessa sessione, oppure al -suo stesso \acr{pid} (creando così un nuovo \textit{process group}). Se invece -si modifica il \acr{sid} il processo viene automaticamente messo anche in un -nuovo \textit{process group}, corrispondente al suo \acr{pid}. - +La funzione ha successo soltanto se il processo non è già leader per un +\textit{process group}, per cui di norma si esegue una \func{fork} e si esce, +per poi chiamare \func{setsid} nel processo figlio, in modo che, avendo questo +lo stesso \acr{pgid} del padre ma un \acr{pid} diverso, non ci siano +possibilità di errore. Questa funzione viene usata di solito dal processo di +login quando si lancia una nuova shell per un utente. @@ -207,23 +249,23 @@ nuovo \textit{process group}, corrispondente al suo \acr{pid}. \label{sec:sess_ctrl_term} Come accennato in \secref{sec:sess_job_control_overview} ad ogni sessione di -lavoro è associato un terminale di controllo. +lavoro è associato un terminale di controllo. -\subsection{La procedura di login} +\subsection{Dal login alla shell} \label{sec:sess_login} L'organizzazione del sistema del job control è strettamente connessa alle -modalità con cui un utente accede al sistema, collegandosi ad esso con un -terminale, che sia questo realmente tale, come un VT100 collegato ad una -seriale o virtuale, come quelli associati a schermo e tastiera o ad una +modalità con cui un utente accede al sistema per dare comandi, collegandosi ad +esso con un terminale, che sia questo realmente tale, come un VT100 collegato +ad una seriale o virtuale, come quelli associati a schermo e tastiera o ad una connessione di rete. Dato che i concetti base sono gli stessi, e dato che alla fine le differenze sono\footnote{in generale nel caso di login via rete o di terminali lanciati dall'interfaccia grafica cambia anche il processo da cui ha origine l'esecuzione della shell.} nel device cui il kernel associa i -file standard di \secref{sec:file_std_descr}, tratteremo solo il caso in -questo è il classico terminale. +file standard (vedi \secref{sec:file_std_descr}) per l'I/O, tratteremo solo il +caso classico del terminale. Abbiamo già brevemente illustrato in \secref{sec:intro_kern_and_sys} le modalità con cui il sistema si avvia, e di come, a partire da \cmd{init}, @@ -273,15 +315,17 @@ dall'amministratore nel file di configurazione del programma, \file{/etc/inittab}. Quando viene lanciato da \cmd{init} il programma parte con i privilegi di -amministratore e con un ambiente vuoto; \cmd{getty} si cura di aprire il -terminale in lettura sullo standard input ed in scrittura sullo standard -output e sullo standard error, e di effettuare, qualora servano, ulteriori -settaggi,\footnote{ad esempio, come qualcuno si sarà accorto scrivendo un nome - di login in maiuscolo, può effettuare la conversione automatica dell'input - in minuscolo, ponendosi in una modalità speciale che non distingue fra i due - tipi di caratteri (a beneficio di alcuni vecchi terminali che non - supportavano le minuscole).} ed infine il programma stamperà un messaggio di -benvenuto per poi porsi in attesa dell'immissione del nome di un utente. +amministratore e con un ambiente vuoto; \cmd{getty} si cura di chiamare +\func{setsid} per creare una nuova sessione ed un nuovo process group, e di +aprire il terminale in lettura sullo standard input ed in scrittura sullo +standard output e sullo standard error, e di effettuare, qualora servano, +ulteriori settaggi,\footnote{ad esempio, come qualcuno si sarà accorto + scrivendo un nome di login in maiuscolo, può effettuare la conversione + automatica dell'input in minuscolo, ponendosi in una modalità speciale che + non distingue fra i due tipi di caratteri (a beneficio di alcuni vecchi + terminali che non supportavano le minuscole).} ed infine il programma +stamperà un messaggio di benvenuto per poi porsi in attesa dell'immissione del +nome di un utente. Una volta che si sia immesso il nome di login \cmd{getty} esegue direttamente il programma \cmd{login} con una \func{exevle}, passando come argomento la @@ -323,12 +367,7 @@ che il processo genitore resta sempre \cmd{init} quest'ultimo provveder ricevendo un \macro{SIGCHLD} all'uscita della shell, a rilanciare \cmd{getty} per ripetere da capo tutto il procedimento. - - - -Lo stato del sistema può essere verificato con il comando \cmd{ps -je f} - - +Una volta arrivati alla