\chapter{Sessioni di lavoro}
\label{cha:session}

Esamineremo in questo capitolo le modalità in cui sono organizzati i processi
all'interno del sistema e le varie relazioni che intercorrono fra di essi, e
le modalità che permettono, a partire dall'avvio del sistema, di organizzare
il lavoro degli utenti in sessioni di lavoro associate ai terminali di
controllo con cui essi si sono collegati al sistema.

\section{La procedura di login}
\label{sec:sess_login}

L'organizzazione del sistema del \textit{Job Control}\footnote{viene
  usualmente chiamata così la capacità del sistema di poter gestire più
  processi (i \textit{job}) lanciati in contemporanea a partire da una shell,
  di solito associata al terminale su cui si è appunto effettuato il login, in
  modo da poter gestire la possibile presenza di più di un processo che
  necessita di accedere a quest'ultimo.} è 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 semplicemente
associato ad una connessione di rete. Per questo motivo in questa prima
sezione prenderemo in esame le modalità di come avviene tutto ciò e di come il
sistema (a partire da \cmd{init}) sia in grado di gestire il tutto.


\subsection{Il login su terminale}
\label{sec:sess_tty_log}

La modalità più classica di accesso ad un sistema Unix è quella del login su
terminale, che pertanto esamineremo per prima. 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}, vengano lanciati tutti gli altri
programmi. Adesso prenderemo in esame in maniera dettagliata le modalità con
cui si arriva a fornire ad un utente la shell che gli permette di lanciare i
suoi comandi.

Nella maggior parte delle distribuzioni di GNU/Linux\footnote{fa eccezione la
  distribuzione \textit{Slackware}, come alcune distribuzioni su dischetto, ed
  altre distribuzioni dedicate a compiti limitati e specifici.}  viene usata
la procedura di avvio di System V; questa prevede che \cmd{init} legga dal
file di configurazione \file{/etc/inittab} quali programmi devono essere
lanciati, ed in quali modalità, a seconda del cosiddetto \textit{run level},
anch'esso definito nello stesso file.

Tralasciando la descrizione del sistema dei run level, (per il quale si
rimanda alla lettura della pagina di manuale di \cmd{init} e di
\file{inittab}) quello che comunque viene sempre fatto è di lanciare almeno
una istanza di un programma che permetta l'accesso ad un terminale. Uno schema
di massima della procedura è riportato in \secref{fig:sess_term_login}.

\begin{figure}[htb]
  \centering
  \includegraphics[width=15cm]{img/tty_login}
  \caption{Schema della procedura di login su un terminale.}
  \label{fig:sess_term_login}
\end{figure}

Un terminale, che esso sia un terminale effettivo, attaccato ad una seriale o
ad un altro tipo di porta di comunicazione, o una delle console virtuali
associate allo schermo, viene sempre visto attraverso attraverso un device
driver che ne presenta un'interfaccia comune su un apposito file di
dispositivo. Storicamente i primi terminali erano appunto terminali di
telescriventi (\textit{teletype}), da cui deriva sia il nome dell'interfaccia,
\textit{tty}, che quello dei relativi file di dispositivo, che sono sempre
della forma \texttt{/dev/tty*}.

Per controllare i terminali si usa di solito il programma \cmd{getty} (od una
delle sue varianti), che permette di mettersi in ascolto sugli stessi. Alla
radice della catena che porta ad una shell per i comandi perciò c'è sempre
\cmd{init} che esegue prima una \func{fork} e poi una \func{exec} per lanciare
una istanza di questo programma su un terminale, il tutto ripetuto per
ciascuno dei terminali che si hanno a disposizione (o per un certo numero di
essi, nel caso delle console virtuali), secondo quanto indicato
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.

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
suddetta stringa ed un ambiente opportunamente costruito che contenga quanto
necessario (ad esempio di solito viene opportunamente inizializzata la
variabile di ambiente \texttt{TERM}) ad identificare il terminale su cui si
sta operando, a beneficio dei programmi che verranno lanciati in seguito.

A sua volta \cmd{login}, che mantiene i privilegi di amministratore, usa il
nome dell'utente per effettuare una ricerca nel database degli
utenti,\footnote{in genere viene chiamata \func{getpwnam}, che abbiamo visto
  in \secref{sec:sys_user_group}, per leggere la password e gli altri dati dal
  database degli utenti.} e richiede una password. Se l'utente non esiste o se
la password non corrisponde\footnote{il confronto non viene effettuato con un
  valore in chiaro; quanto immesso da terminale viene invece a sua volta
  criptato, ed è il risultato che viene confrontato con il valore che viene
  mantenuto nel database degli utenti.} la richiesta viene ripetuta un certo
numero di volte dopo di che \cmd{login} esce ed \cmd{init} provvede a
rilanciare un'altra istanza di \func{getty}.

Se invece la password corrisponde a questo punto \cmd{login} esegue
\func{chdir} per settare la \textit{home directory} dell'utente, cambia i
diritti di accesso al terminale (con \func{chown} e \func{chmod}) per
assegnarne la titolarità all'utente ed al suo gruppo principale, assegnandogli
al contempo i diritti di lettura e scrittura. Inoltre il programma provvede
a costruire gli opportuni valori per le variabili di ambiente, come
\texttt{HOME}, \texttt{SHELL}, ecc. Infine attraverso l'uso di \func{setuid},
\func{setpid} e \func{initgroups} verrà cambiata l'identità del proprietario
del processo, infatti, come spiegato in \secref{sec:proc_setuid}, avendo
invocato tali funzioni con i privilegi di amministratore, tutti gli userid ed
i groupid (reali, effettivi e salvati) saranno settati a quelli dell'utente.

A questo punto \cmd{login} provvederà (fatte salve eventuali altre azioni
iniziali, come la stampa di messaggi di benvenuto o il controllo della posta)
ad eseguire con un'altra \func{exec} la shell di login, che si troverà con un
ambiente già pronto e con file standard di \secref{sec:file_std_descr}
impostati sul terminale, pronta ad eseguire i comandi fino all'uscita. Dato
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.


\subsection{Il login via rete}
\label{sec:sess_net_log}

Nel caso di un login via rete la cosa si fa leggermente diversa, in tal caso
infatti non esiste un terminale fisico che \cmd{init} può tenere sotto
controllo diretto, in quanto il collegamento deve avvenire tramite la rete.
Quello che succede in questo caso è che nel procedimento di avvio del sistema
si occupa di eseguire tutti i programmi che attivano la connesione di rete,
per poi avviare tutti i programmi di servizio. 

Questo viene in genere fatto attraverso una serie di script di shell, che
vengono eseguiti in un preciso ordine (di nuovo la struttura del procedimento
di avvio di System V va al di là di quanto ci interessa trattare) che
eseguiranno i programmi richiesti, fra i quali sarà compreso (se
l'amministratore lo avrà previsto) pure il server per le connessioni di rete. 

Quest'ultimo sarà posto in esecuzione e si metterà in ascolto di eventuali
connessioni sulla rete, una volta che la procedura di avvio sarà completata
gli script termineranno ed il server si troverà ad avere \cmd{init} come
processo padre.  


\subsection{Il login attraverso X}
\label{sec:sess_X_log}

Quanto scritto finora riguardo i terminali è piuttosto diverso quando si ha a
che fare con X. In tal caso infatti la procedura grafica per il login è
gestira da un apposito programma (il cosiddetto \textit{Display Manager}, come
\cmd{xdm}, che fa parte della distribuzione base di X o uno dei suoi molti
cloni) che viene lanciato all'avvio insieme agli altri demoni, e che si cura
di gestire la procedura di login, lanciare eventuali programmi che si vogliono
attivare all'avvio (sia fondamentali, come il gestore delle fineste, che
effimeri, come un notificatore di posta in arrivo).

In questo caso 



\section{Il \textit{Job control}}
\label{sec:sess_job_control}

Lo scopo del \textit{Job control} è quello di permettere ad un utente di poter
sfruttare le capacità multitasking di un sistema Unix per eseguire in
contemporanea più processi, pur potendo accedere, di solito, ad un solo
terminale,\footnote{con X e con i terminali vituali tutto questo non è più
  vero, dato che si può accedere a molti terminali in contemporanea, ma il
  sistema è nato prima dell'esistenza di tutto ciò.} avendo cioè un solo punto
in cui si può avere accesso all'input ed all'output degli stessi.



\subsection{La struttura di base}
\label{sec:sess_relation}

Una volta che si è completata la procedura di login illustrata in
\ref{sec:sess_login} si avrà a disposizione una shell dalla quale eseguire i
comandi. Come illustrato in \secref{sec:intro_kern_and_sys} in un sistema Unix
questi non sono altro che programmi come gli altri, inoltre essendo il sistema
multitasking, non è neanche detto che un programma venga eseguito da un solo
processo, infatti, oltre all'uso delle pipe, che permette di concatenare più
con un solo comando, ed i sigoli programmi possono anche creare ulteriori
sottoprocessi per eseguire alcuni compiti.

Tutti questi processi, che originano da un solo comando iniziale, vengono
raggruppati in quello che viene chiamato un \textit{process group}; quando
viene creato ogni
processo viene infatti mantenuto, 


\subsection{I \textit{process group}}
\label{sec:sess_proc_group}



\subsection{Le sessioni}
\label{sec:sess_sessions}



\subsection{Il terminale di controllo}
\label{sec:sess_ctrl_term}



\subsection{La shell e i programmi}
\label{sec:sess_shell}


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "gapil"
%%% End: 
