+Come accennato in \secref{sec:sess_job_control_overview}, nel sistema del
+\textit{job control} i processi all'interno di una sessione fanno riferimento
+ad un terminale di controllo (ad esempio quello su cui si è effettuato il
+login), sul quale effettuano le operazioni di lettura e
+scrittura,\footnote{nel caso di login grafico la cosa può essere più
+ complessa, e di norma l'I/O è effettuato tramite il server X, ma ad esempio
+ per i programmi, anche grafici, lanciati da un qualunque emulatore di
+ terminale, sarà quest'ultimo a fare da terminale (virtuale) di controllo.} e
+dal quale ricevono gli eventuali segnali da tastiera.
+
+A tale scopo lo standard POSIX.1 prevede che ad ogni sessione possa essere
+associato un terminale di controllo; in Linux questo viene realizzato
+mantenendo fra gli attributi di ciascun processo anche qual'è il suo terminale
+di controllo. \footnote{Lo standard POSIX.1 non specifica nulla riguardo
+ l'implementazione; in Linux anch'esso viene mantenuto nella solita struttura
+ \var{task\_struct}, nel campo \var{tty}.} In generale ogni processo eredita
+dal padre, insieme al \acr{pgid} e al \acr{sid} anche il terminale di
+controllo (vedi \secref{sec:proc_fork}). In questo modo tutti processi
+originati dallo stesso leader di sessione mantengono lo stesso terminale di
+controllo.
+
+Alla creazione di una nuova sessione con \func{setsid} ogni associazione con
+il precedente terminale di controllo viene cancellata, ed il processo che è
+divenuto un nuovo leader di sessione dovrà riottenere\footnote{solo quando ciò
+ è necessario, cosa che, come vedremo in \secref{sec:sess_daemon}, non è
+ sempre vera.}, un terminale di controllo. In generale questo viene fatto
+automaticamente dal sistema\footnote{a meno di non avere richiesto
+ esplicitamente che questo non diventi un terminale di controllo con il flag
+ \macro{O\_NOCTTY} (vedi \secref{sec:file_open}). In questo Linux segue la
+ semantica di SVr4; BSD invece richiede che il terminale venga allocato
+ esplicitamente con una \func{ioctl} con il comando \macro{TIOCSCTTY}.}
+quando viene aperto il primo terminale (cioè uno dei vari file di dispositivo
+\file{/dev/tty*}) che diventa automaticamente il terminale di controllo,
+mentre il processo diventa il \textsl{processo di controllo} di quella
+sessione.
+
+In genere (a meno di redirezioni) nelle sessioni di lavoro questo terminale è
+associato ai file standard (di input, output ed error) dei processi nella
+sessione, ma solo quelli che fanno parte del cosiddetto raggruppamento di
+\textit{foreground}, possono leggere e scrivere in certo istante. Per
+impostare il raggruppamento di \textit{foreground} di un terminale si usa la
+funzione \func{tcsetpgrp}, il cui prototipo è:
+\begin{functions}
+ \headdecl{unistd.h}
+ \headdecl{termios.h}
+
+ \funcdecl{int tcsetpgrp(int fd, pid\_t pgrpid)} Imposta a \param{pgrpid} il
+ \textit{process group} di \textit{foreground} del terminale associato al
+ file descriptor \param{fd}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
+ errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\macro{ENOTTY}] Il file \param{fd} non corrisponde al terminale di
+ controllo del processo chiamante.
+ \item[\macro{ENOSYS}] Il sistema non supporta il job control.
+ \item[\macro{EPERM}] Il \textit{process group} specificato non è nella
+ stessa sessione del processo chiamante.
+ \end{errlist}
+ ed inoltre \macro{EBADF} ed \macro{EINVAL}.
+ }
+\end{functions}
+\noindent la funzione può essere eseguita con successo solo da
+un processo nella stessa sessione e con lo stesso terminale di controllo.
+
+Come accennato in \secref{sec:sess_job_control_overview}, tutti i processi (e
+relativi raggruppamenti) che non fanno parte del gruppo di \textit{foreground}
+sono detti in \textit{background}; se uno si essi cerca di accedere al
+terminale di controllo provocherà l'invio da parte del kernel di uno dei due
+segnali \macro{SIGTTIN} o \macro{SIGTTOU} (a seconda che l'accesso sia stato
+in lettura o scrittura) a tutto il suo \textit{process group}; dato che il
+comportamento di default di questi segnali (si riveda quanto esposto in
+\secref{sec:sig_job_control}) è di fermare il processo, di norma questo
+comporta che tutti i membri del gruppo verranno fermati, ma non si avranno
+condizioni di errore.\footnote{la shell in genere notifica comunque un
+ avvertimento, avvertendo la presenza di processi bloccati grazie all'uso di
+ \func{waitpid}.} Se però si bloccano o ignorano i due segnali citati, le
+funzioni di lettura e scrittura falliranno con un errore di \macro{EIO}.
+
+Un processo può controllare qual'è il gruppo di \textit{foreground} associato
+ad un terminale con la funzione \func{tcgetpgrp}, il cui prototipo è:
+\begin{functions}
+ \headdecl{unistd.h} \headdecl{termios.h}
+
+ \funcdecl{pid\_t tcgetpgrp(int fd)} Legge il \textit{process group} di
+ \textit{foreground} del terminale associato al file descriptor \param{fd}.
+ \bodydesc{La funzione restituisce in caso di successo il \acr{pgid} del
+ gruppo di \textit{foreground}, e -1 in caso di errore, nel qual caso
+ \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\macro{ENOTTY}] Non c'è un terminale di controllo o \param{fd} non
+ corrisponde al terminale di controllo del processo chiamante.
+ \end{errlist}
+ ed inoltre \macro{EBADF} ed \macro{ENOSYS}.
+ }
+\end{functions}
+
+Si noti come entrambe le funzioni usino come argomento il valore di un file
+descriptor, il risultato comunque non dipende dal file descriptor che si usa
+ma solo dal terminale cui fa riferimento; il kernel inoltre permette a ciascun
+processo di accedere direttamente al suo terminale di controllo attraverso il
+file speciale \file{/dev/tty}, che per ogni processo è un sinonimo per il
+proprio terminale di controllo. Questo consente anche a processi che possono
+aver rediretto l'output di accedere al terminale di controllo, pur non
+disponendo più del file descriptor originario; un caso tipico è il programma
+\cmd{crypt} che accetta la redirezione sullo standard input di un file da
+decifrare, ma deve poi leggere la password dal terminale.
+
+Un'altra caratteristica del terminale di controllo usata nel job control è che
+utilizzando su di esso le combinazioni di tasti speciali (\cmd{C-z},
+\cmd{C-c}, \cmd{C-y} e \verb|C-\|) si farà sì che il kernel invii i
+corrispondenti segnali (rispettivamente \macro{SIGTSTP}, \macro{SIGINT},
+\macro{SIGQUIT} e \macro{SIGTERM}, trattati in \secref{sec:sig_job_control}) a
+tutti i processi del raggruppamento di \textit{foreground}; in questo modo la
+shell può gestire il blocco e l'interruzione dei vari comandi.
+
+Per completare la trattazione delle caratteristiche del job control legate al
+terminale di controllo, occorre prendere in considerazione i vari casi legati
+alla terminazione anomala dei processi, che sono di norma gestite attraverso
+il segnale \macro{SIGHUP}. Il nome del segnale deriva da \textit{hungup},
+termine che viene usato per indicare la condizione in cui il terminale diventa
+inutilizzabile, (letteralmente sarebbe \textsl{impiccagione}).
+
+Quando si verifica questa condizione, ad esempio se si interrompe la linea, o
+va giù la rete o più semplicemente si chiude forzatamente la finestra di
+terminale su cui si stava lavorando, il kernel provvederà ad inviare il
+segnale di \macro{SIGHUP} al processo di controllo. L'azione preimpostata in
+questo caso è la terminazione del processo, il problema che si pone è cosa
+accade agli altri processi nella sessione, che non han più un processo di
+controllo che possa gestire l'accesso al terminale, che potrebbe essere
+riutilizzato per qualche altra sessione.
+
+Lo standard POSIX.1 prevede che quando il processo di controllo termina, che
+ciò avvenga o meno per un \textit{hungup} del terminale (ad esempio si
+potrebbe terminare direttamente la shell con \cmd{kill}) venga inviato un
+segnale di \macro{SIGHUP} ai processi del raggruppamento di foreground. In
+questo modo essi potranno essere avvisati che non esiste più un processo in
+grado di gestire il terminale (di norma tutto ciò comporta la terminazione
+anche di questi ultimi).
+
+Restano però gli eventuali processi in background, che non ricevono il
+segnale; in effetti se il terminale non dovesse più servire essi potrebbero
+proseguire fino al completamento della loro esecuzione; ma si pone il problema
+di come gestire quelli che sono bloccati, o che si bloccano nell'accesso al
+terminale, in assenza di un processo che sia in grado di effettuare il
+controllo dello stesso.
+
+Questa è la situazione in cui si ha quello che viene chiamato un
+\textit{orphaned process group}. Lo standard POSIX.1 lo definisce come un
+\textit{process group} i cui processi hanno come padri esclusivamente o altri
+processi nel raggruppamento, o processi fuori della sessione. Lo standard
+prevede inoltre che se la terminazione di un processo fa sì che un
+raggruppamento di processi diventi orfano e se i suoi membri sono bloccati, ad
+essi vengano inviati in sequenza i segnali di \macro{SIGHUP} e
+\macro{SIGCONT}.
+
+La definizione può sembrare complicata, e a prima vista non è chiaro cosa
+tutto ciò abbia a che fare con il problema della terminazione del processo di
+controllo. Consideriamo allora cosa avviene di norma nel \textit{job
+ control}: una sessione viene creata con \func{setsid} che crea anche un
+nuovo process group: per definizione quest'ultimo è sempre \textsl{orfano},
+dato che il padre del leader di sessione è fuori dalla stessa e il nuovo
+process group contiene solo il leader di sessione. Questo è un caso limite, e
+non viene emesso nessun segnale perché quanto previsto dallo standard riguarda
+solo i raggruppamenti che diventano orfani in seguito alla terminazione di un
+processo.\footnote{l'emissione dei segnali infatti avviene solo nella fase di
+ uscita del processo, come una delle operazioni legate all'esecuzione di
+ \func{\_exit}, secondo quanto illustrato in \secref{sec:proc_termination}.}
+
+Il leader di sessione provvederà a creare nuovi raggruppamenti che a questo
+punto non sono orfani in quanto esso resta padre per almeno uno dei processi
+del gruppo (gli altri possono derivare dal primo). Alla terminazione del
+leader di sessione però avremo che, come visto in
+\secref{sec:proc_termination}, tutti i suoi figli vengono adottati da
+\cmd{init}, che è fuori dalla sessione. Questo renderà orfani tutti i process
+group creati direttamente dal leader di sessione (a meno di non aver spostato
+con \func{setpgid} un processo da un gruppo ad un altro, cosa che di norma non
+viene fatta) i quali riceveranno, nel caso siano bloccati, i due segnali;
+\macro{SIGCONT} ne farà proseguire l'esecuzione, ed essendo stato nel
+frattempo inviato anche \macro{SIGHUP}, se non c'è un gestore per
+quest'ultimo, i processi bloccati verranno automaticamente terminati.
+
+
+
+\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 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 dispositivo cui il kernel associa i
+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},
+vengano lanciati tutti gli altri processi. Adesso vedremo in maniera più
+dettagliata le modalità con cui il sistema arriva a fornire ad un utente la
+shell che gli permette di lanciare i suoi comandi su un terminale.
+
+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 delle pagine di manuale di \cmd{init} e di
+\file{inittab}) quello che comunque viene sempre fatto è di eseguire almeno
+una istanza di un programma che permetta l'accesso ad un terminale. Uno schema
+di massima della procedura è riportato in \figref{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*}.\footnote{questo vale anche per i terminali
+ virtuali associati alle connessioni di rete con \cmd{telnet} o \cmd{ssh}.}
+
+Per controllare un terminale si usa di solito il programma \cmd{getty} (od una
+delle sue varianti), che permette di mettersi in ascolto su uno di questi
+dispositivi. 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 chiamare
+\func{setsid} per creare una nuova sessione ed un nuovo process group, e di
+aprire il terminale (che così diventa il terminale di controllo della
+sessione) in lettura sullo standard input ed in scrittura sullo standard
+output e sullo standard error; inoltre effettuerà, 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).} Alla fine 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
+stringa con il nome, 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 \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, che si troverà con un ambiente
+già pronto con i file standard di \secref{sec:file_std_descr} impostati sul
+terminale, e pronta, nel ruolo di leader di sessione e di processo di
+controllo per il terminale, a gestire l'esecuzione dei comandi come illustrato
+in \secref{sec:sess_job_control_overview}.
+
+Dato che il processo padre resta sempre \cmd{init} quest'ultimo potrà
+provvedere, ricevendo un \macro{SIGCHLD} all'uscita della shell quando la
+sessione di lavoro è terminata, a rilanciare \cmd{getty} sul terminale per
+ripetere da capo tutto il procedimento.
+
+
+
+\subsection{Prescrizioni per un programma \textit{daemon}}
+\label{sec:sess_daemon}
+
+Come sottolineato fin da \secref{sec:intro_base_concept}, in un sistema
+unix-like tutte le operazioni sono eseguite tramite processi, comprese quelle
+operazioni di sistema (come l'esecuzione dei comandi periodici, o la consegna
+della posta, ed in generale tutti i programmi di servizio) che non hanno
+niente a che fare con la gestione diretta dei comandi dell'utente.
+
+Questi programmi, che devono essere eseguiti in modalità non interattiva e
+senza nessun intervento dell'utente, sono normalmente chiamati
+\textsl{demoni}, (o \textit{daemons}), nome ispirato dagli omonimi spiritelli
+che svolgevano compiti vari, di cui parlava Socrate (che sosteneva di averne
+uno al suo servizio).\footnote{NdT. ricontrollare, i miei ricordi di filosofia
+ sono piuttosto datati.}
+
+Se però si lancia un programma demone dalla riga di comando in un sistema che
+supporta, come Linux, il \textit{job control} esso verrà comunque associato ad
+un terminale di controllo e mantenuto all'interno di una sessione, e anche se
+può essere mandato in background e non eseguire più nessun I/O su terminale,
+si avranno comunque tutte le conseguenze che abbiamo appena visto in
+\secref{sec:sess_ctrl_term} (in particolare l'invio dei segnali in
+corrispondenza dell'uscita del leader di sessione).
+
+Per questo motivo un programma che deve funzionare come demone deve sempre
+prendere autonomamente i provvedimenti opportuni (come distaccarsi dal
+terminale e dalla sessione) ad impedire eventuali interferenze da parte del
+sistema del \textit{job contol}; questi sono riassunti in una lista di
+prescrizioni\footnote{ad esempio sia Stevens in \cite{APUE}, che la
+ \textit{Unix Programming FAQ} \cite{UnixFAQ} ne riportano di sostanzialmente
+ identiche.} da seguire quando si scrive un demone.
+
+Pertanto, quando si lancia un programma che deve essere eseguito come demone
+occorrerà predisporlo in modo che esso compia le seguenti azioni:
+\begin{enumerate}
+\item Eseguire una \func{fork} e terminare immediatamente il processo padre
+ proseguendo l'esecuzione nel figlio. In questo modo si ha la certezza che
+ il processo non è un \textit{process group leader}, e si può chiamare
+ \func{setsid} con successo.
+\item Eseguire \func{setsid} per creare una nuova sessione ed un nuovo
+ raggruppamento di cui il processo è leader, che non ha associato nessun
+ terminale di controllo.
+\item Assicurarsi che al processo non venga associato in seguito nessun nuovo
+ terminale di controllo; questo può essere fatto sia avendo cura di usare
+ sempre l'opzione \macro{O\_NOCTTY} nell'aprire i file di terminale, che
+ eseguendo una ulteriore \func{fork} proseguendo nel figlio, che a questo
+ punto non essendo più leader di sessione non può più ottenere un terminale
+ di controllo.
+\item Eseguire una \func{chdir} per impostare la directory di lavoro (su
+ \file{/} o su una directory che contenga dei file necessari per il
+ programma), per evitare che la directory da cui si è lanciato il processo
+ resti in uso e non sia possibile rimuoverla o smontare il filesystem che la
+ contiene.
+\item Impostare la maschera dei permessi (di solito con \code{umask(0)}) in
+ modo da non essere dipendenti dal valore ereditato da chi ha lanciato
+ originariamente il processo.
+\item Chiudere i file standard (o redirigerli verso \file{/dev/null}).
+\end{enumerate}
+
+
+In Linux buona parte di queste azioni possono venire eseguite invocando la
+funzione \func{daemon}, introdotta per la prima volta in BSD4.4; il suo
+prototipo è:
+\begin{prototype}{unistd.h}{int daemon(int nochdir, int noclose)}
+ Esegue le operazioni che distaccano il processo dal terminale di controllo e
+ lo fanno girare come demone.
+
+ \bodydesc{La funzione restituisce (nel nuovo processo) 0 in caso di
+ successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i
+ valori impostati dalle sottostanti \func{fork} e \func{setsid}.}
+\end{prototype}
+
+La funzione esegue una \func{fork}, per uscire subito, con \func{\_exit} nel
+padre, mentre l'esecuzione prosegue nel figlio che esegue \func{setsid}. Se
+\param{nochdir} è nullo la funzione imposta anche la directory di lavoro su
+\file{/}, se \param{noclose} è nullo i file standard vengono rediretti su
+\file{dev/null}; in caso di valori non nulli non viene eseguita nessuna altra
+azione.
+
+
+
+
+\section{L'I/O su terminale}
+\label{sec:sess_terminal_io}
+
+Esamineremo in questa sezione le peculiarità dell'I/O eseguito sui terminali,
+tenendo conto delle differenze che quest'ultimi presentano rispetto ai normali
+file su disco.
+
+