-\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
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
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}.
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}
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.
-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.
\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},
\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
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