+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 figlio non è un \textit{process group leader}, (avrà il \ids{PGID} del
+ padre, ma un \ids{PID} diverso) e si può chiamare \func{setsid} con
+ successo. Inoltre la shell considererà terminato il comando all'uscita del
+ padre.
+\item Eseguire \func{setsid} per creare una nuova sessione ed un nuovo
+ raggruppamento di cui il processo diventa automaticamente il leader, che
+ però 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 \const{O\_NOCTTY} nell'aprire i file di terminale, che
+ eseguendo una ulteriore \func{fork} uscendo nel padre e proseguendo nel
+ figlio. In questo caso, non essendo più quest'ultimo un leader di sessione
+ non potrà ottenere automaticamente un terminale di controllo.
+\item Eseguire una \func{chdir} per impostare la directory di lavoro del
+ processo (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 tutti i file aperti che non servono più (in generale tutti); in
+ particolare vanno chiusi i file standard che di norma sono ancora associati
+ al terminale (un'altra opzione è quella di redirigerli verso
+ \file{/dev/null}).
+\end{enumerate*}
+
+
+In Linux buona parte di queste azioni possono venire eseguite invocando la
+funzione \funcd{daemon} (fornita dalle \acr{glibc}), introdotta per la prima
+volta in BSD4.4; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int daemon(int nochdir, int noclose)}
+\fdesc{Rende il processo un demone.}
+}
+
+{La funzione ritorna (nel nuovo processo) $0$ in caso di successo e $-1$ per
+ un errore, nel qual caso \var{errno} assumerà uno dei valori i
+ valori impostati dalle sottostanti \func{fork} e \func{setsid}.}
+\end{funcproto}
+
+La funzione esegue una \func{fork}, per uscire subito, con \func{\_exit}, nel
+padre, mentre l'esecuzione prosegue nel figlio che esegue subito una
+\func{setsid}. In questo modo si compiono automaticamente i passi 1 e 2 della
+precedente lista. 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} (corrispondenti ai passi 4 e 6); in caso
+di valori non nulli non viene eseguita nessuna altra azione.
+
+Dato che un programma demone non può più accedere al terminale, si pone il
+problema di come fare per la notifica di eventuali errori, non potendosi più
+utilizzare lo \textit{standard error}. Per il normale I/O infatti ciascun
+demone avrà le sue modalità di interazione col sistema e gli utenti a seconda
+dei compiti e delle funzionalità che sono previste; ma gli errori devono
+normalmente essere notificati all'amministratore del sistema.
+
+\itindbeg{syslog}
+
+Una soluzione può essere quella di scrivere gli eventuali messaggi su uno
+specifico file (cosa che a volte viene fatta comunque) ma questo comporta il
+grande svantaggio che l'amministratore dovrà tenere sotto controllo un file
+diverso per ciascun demone, e che possono anche generarsi conflitti di nomi.
+Per questo in BSD4.2 venne introdotto un servizio di sistema, il
+\textit{syslog}, che oggi si trova su tutti i sistemi Unix, e che permette ai
+demoni di inviare messaggi all'amministratore in una maniera standardizzata.
+
+Il servizio prevede vari meccanismi di notifica, e, come ogni altro servizio
+in un sistema unix-like, viene gestito attraverso un apposito programma, che è
+anch'esso un \textsl{demone}. In generale i messaggi di errore vengono
+raccolti dal file speciale \file{/dev/log}, un socket locale (vedi
+sez.~\ref{sec:sock_sa_local}) dedicato a questo scopo, o via rete, con un
+socket UDP e trattati dal demone che gestisce il servizio. Il più comune di
+questi è \texttt{syslogd}, che consente un semplice smistamento dei messaggi
+sui file in base alle informazioni in esse presenti; oggi però
+\texttt{syslogd} è in sostanziale disuso, sostituito da programmi più
+sofisticati come \texttt{rsyslog} o \texttt{syslog-ng}.
+
+Il servizio del \textit{syslog} permette infatti di trattare i vari messaggi
+classificandoli attraverso due indici: il primo, chiamato \textit{facility},
+suddivide in diverse categorie i messaggi in modo di raggruppare quelli
+provenienti da operazioni che hanno attinenza fra loro, ed è organizzato in
+sottosistemi (kernel, posta elettronica, demoni di stampa, ecc.). Il secondo,
+chiamato \textit{priority}, identifica l'importanza dei vari messaggi, e
+permette di classificarli e differenziare le modalità di notifica degli
+stessi.
+
+Il sistema del \textit{syslog} attraverso il proprio demone di gestione
+provvede poi a riportare i messaggi all'amministratore attraverso una serie
+differenti meccanismi come:
+\begin{itemize*}
+\item scriverli su un file (comunemente detto \textit{log file}, o giornale),
+\item scriverli sulla console,
+\item scriverli sui terminali degli utenti connessi,
+\item inviarli via mail ad uno specifico utente,
+\item inviarli ad un altro programma,
+\item inviarli via rete ad una macchina di raccolta,
+\item ignorarli completamente;
+\end{itemize*}
+le modalità con cui queste azioni vengono realizzate dipendono ovviamente dal
+demone che si usa, per la gestione del quale si rimanda ad un testo di
+amministrazione di sistema.\footnote{l'argomento è ad esempio coperto dal
+ capitolo 3.2.3 si \cite{AGL}.}
+
+Le \acr{glibc} definiscono una serie di funzioni standard con cui un processo
+può accedere in maniera generica al servizio di \textit{syslog}, che però
+funzionano solo localmente; se si vogliono inviare i messaggi ad un altro
+sistema occorre farlo esplicitamente con un socket UDP, o utilizzare le
+capacità di reinvio del servizio.
+
+La prima funzione definita dall'interfaccia è \funcd{openlog}, che inizializza
+una connessione al servizio di \textit{syslog}. Essa in generale non è
+necessaria per l'uso del servizio, ma permette di impostare alcuni valori che
+controllano gli effetti delle chiamate successive; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{syslog.h}
+\fdecl{void openlog(const char *ident, int option, int facility)}
+\fdesc{Inizializza una connessione al sistema del \textit{syslog}.}
+}
+
+{La funzione non restituisce nulla.}
+\end{funcproto}
+
+La funzione permette di specificare, tramite \param{ident}, l'identità di chi
+ha inviato il messaggio (di norma si passa il nome del programma, come
+specificato da \code{argv[0]}), e la stringa verrà preposta all'inizio di ogni
+messaggio. Si tenga presente che il valore di \param{ident} che si passa alla
+funzione è un puntatore, se la stringa cui punta viene cambiata lo sarà pure
+nei successivi messaggi, e se viene cancellata i risultati potranno essere
+impredicibili, per questo è sempre opportuno usare una stringa costante.
+
+L'argomento \param{facility} permette invece di preimpostare per le successive
+chiamate l'omonimo indice che classifica la categoria del messaggio.
+L'argomento è interpretato come una maschera binaria, e pertanto è possibile
+inviare i messaggi su più categorie alla volta. I valori delle costanti che
+identificano ciascuna categoria sono riportati in
+tab.~\ref{tab:sess_syslog_facility}, il valore di \param{facility} deve essere
+specificato con un OR aritmetico.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{LOG\_AUTH} & Messaggi relativi ad autenticazione e sicurezza,
+ obsoleto, è sostituito da \const{LOG\_AUTHPRIV}.\\
+ \constd{LOG\_AUTHPRIV} & Sostituisce \const{LOG\_AUTH}.\\
+ \constd{LOG\_CRON} & Messaggi dei demoni di gestione dei comandi
+ programmati (\cmd{cron} e \cmd{at}).\\
+ \constd{LOG\_DAEMON} & Demoni di sistema.\\
+ \constd{LOG\_FTP} & Servizio FTP.\\
+ \constd{LOG\_KERN} & Messaggi del kernel.\\
+ \constd{LOG\_LOCAL0} & Riservato all'amministratore per uso locale.\\
+ \hspace{.5cm}$\vdots$ & \hspace{3cm}$\vdots$\\
+ \constd{LOG\_LOCAL7} & Riservato all'amministratore per uso locale.\\
+ \constd{LOG\_LPR} & Messaggi del sistema di gestione delle stampanti.\\
+ \constd{LOG\_MAIL} & Messaggi del sistema di posta elettronica.\\
+ \constd{LOG\_NEWS} & Messaggi del sistema di gestione delle news
+ (USENET).\\
+ \constd{LOG\_SYSLOG} & Messaggi generati dal demone di gestione del
+ \textit{syslog}.\\
+ \constd{LOG\_USER} & Messaggi generici a livello utente.\\
+ \constd{LOG\_UUCP} & Messaggi del sistema UUCP (\textit{Unix to Unix
+ CoPy}), ormai in disuso.\\
+\hline
+\end{tabular}
+\caption{Valori possibili per l'argomento \param{facility} di \func{openlog}.}
+\label{tab:sess_syslog_facility}
+\end{table}
+
+L'argomento \param{option} serve invece per controllare il comportamento della
+funzione \func{openlog} e delle modalità con cui le successive chiamate
+scriveranno i messaggi, esso viene specificato come maschera binaria composta
+con un OR aritmetico di una qualunque delle costanti riportate in
+tab.~\ref{tab:sess_openlog_option}.
+
+\begin{table}[htb]
+ \footnotesize
+\centering
+\begin{tabular}[c]{|l|p{8cm}|}
+\hline
+\textbf{Valore}& \textbf{Significato}\\
+\hline
+\hline
+ \constd{LOG\_CONS} & Scrive sulla console in caso di errore nell'invio del
+ messaggio al sistema del \textit{syslog}. \\
+ \constd{LOG\_NDELAY} & Apre la connessione al sistema del \textit{syslog}
+ subito invece di attendere l'invio del primo
+ messaggio.\\
+ \constd{LOG\_NOWAIT} & Non usato su Linux, su altre piattaforme non attende i
+ processi figli creati per inviare il messaggio.\\
+ \constd{LOG\_ODELAY} & Attende il primo messaggio per aprire la connessione al
+ sistema del \textit{syslog}.\\
+ \constd{LOG\_PERROR} & Stampa anche su \file{stderr} (non previsto in
+ POSIX.1-2001).\\
+ \constd{LOG\_PID} & Inserisce nei messaggi il \ids{PID} del processo
+ chiamante.\\
+\hline
+\end{tabular}
+\caption{Valori possibili per l'argomento \param{option} di \func{openlog}.}
+\label{tab:sess_openlog_option}
+\end{table}
+
+La funzione che si usa per generare un messaggio è \funcd{syslog}, dato che
+l'uso di \func{openlog} è opzionale, sarà quest'ultima a provvede a chiamare la
+prima qualora ciò non sia stato fatto (nel qual caso il valore di
+\param{ident} è \val{NULL}). Il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{syslog.h}
+\fdecl{void syslog(int priority, const char *format, ...)}
+\fdesc{Genera un messaggio per il \textit{syslog}.}
+}
+
+{La funzione non restituisce nulla.}
+\end{funcproto}
+
+La funzione genera un messaggio le cui caratteristiche sono indicate
+da \param{priority}. Per i restanti argomenti il suo comportamento è analogo a
+quello di \func{printf}, e il valore dell'argomento \param{format} è identico
+a quello descritto nella pagina di manuale di quest'ultima (per i valori
+principali si può vedere la trattazione sommaria che se ne è fatto in
+sez.~\ref{sec:file_formatted_io}). L'unica differenza è che la sequenza
+\val{\%m} viene rimpiazzata dalla stringa restituita da
+\code{strerror(errno)}. Gli argomenti seguenti i primi due devono essere
+forniti secondo quanto richiesto da \param{format}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{LOG\_EMERG} & Il sistema è inutilizzabile.\\
+ \constd{LOG\_ALERT} & C'è una emergenza che richiede intervento
+ immediato.\\
+ \constd{LOG\_CRIT} & Si è in una condizione critica.\\
+ \constd{LOG\_ERR} & Si è in una condizione di errore.\\
+ \constd{LOG\_WARNING} & Messaggio di avvertimento.\\
+ \constd{LOG\_NOTICE} & Notizia significativa relativa al comportamento.\\
+ \constd{LOG\_INFO} & Messaggio informativo.\\
+ \constd{LOG\_DEBUG} & Messaggio di debug.\\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili per l'indice di importanza del messaggio da
+ specificare nell'argomento \param{priority} di \func{syslog}.}
+ \label{tab:sess_syslog_priority}
+\end{table}
+
+L'argomento \param{priority} permette di impostare sia la \textit{facility}
+che la \textit{priority} del messaggio. In realtà viene prevalentemente usato
+per specificare solo quest'ultima in quanto la prima viene di norma
+preimpostata con \func{openlog}. La priorità è indicata con un valore numerico
+specificabile attraverso le costanti riportate in
+tab.~\ref{tab:sess_syslog_priority}.
+
+Le \acr{glibc}, seguendo POSIX.1-2001, prevedono otto diverse priorità
+ordinate da 0 a 7, in ordine di importanza decrescente; questo comporta che i
+tre bit meno significativi dell'argomento \param{priority} sono occupati da
+questo valore, mentre i restanti bit più significativi vengono usati per
+specificare la \textit{facility}. Nel caso si voglia specificare anche la
+\textit{facility} basta eseguire un OR aritmetico del valore della priorità
+con la maschera binaria delle costanti di tab.~\ref{tab:sess_syslog_facility}.
+
+Una funzione sostanzialmente identica a \func{syslog} è \funcd{vsyslog}. La
+funzione è originaria di BSD e per utilizzarla deve essere definito
+\macro{\_BSD\_SOURCE}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{syslog.h}
+\fdecl{void vsyslog(int priority, const char *format, va\_list src)}
+\fdesc{Genera un messaggio per il \textit{syslog}.}
+}
+
+{La funzione non restituisce nulla.}
+\end{funcproto}
+
+La sola differenza con \func{syslog} è quella di prendere invece di una lista
+di argomenti esplicita un unico argomento finale passato nella forma di una
+\macro{va\_list}; la funzione risulta utile qualora si ottengano gli argomenti
+dalla invocazione di un'altra funzione \textit{variadic} (si ricordi quanto
+visto in sez.~\ref{sec:proc_variadic}).
+
+Per semplificare la gestione della scelta del livello di priorità a partire
+dal quale si vogliono registrare i messaggi, le funzioni di gestione
+mantengono per ogni processo una maschera che determina quale delle chiamate
+effettuate a \func{syslog} verrà effettivamente registrata. In questo modo
+sarà possibile escludere i livelli di priorità che non interessa registrare,
+impostando opportunamente la maschera una volta per tutte.
+
+Questo significa che in genere nei programmi vengono comunque previste le
+chiamate a \func{syslog} per tutti i livelli di priorità, ma poi si imposta
+questa maschera per registrare solo quello che effettivamente interessa. La
+funzione che consente di fare questo è \funcd{setlogmask}, ed il suo prototipo
+è:
+
+\begin{funcproto}{
+\fhead{syslog.h}
+\fdecl{int setlogmask(int mask)}
+\fdesc{Imposta la maschera dei messaggi del \textit{syslog}.}
+}
+
+{La funzione ritorna il precedente valore della maschera dei messaggi e non
+ prevede errori.}
+\end{funcproto}
+
+La funzione restituisce il valore della maschera corrente, e se si passa un
+valore nullo per \param{mask} la maschera corrente non viene modificata; in
+questo modo si può leggere il valore della maschera corrente. Indicando un
+valore non nullo per \param{mask} la registrazione dei messaggi viene
+disabilitata per tutte quelle priorità che non rientrano nella maschera.
+
+In genere il valore viene impostato usando la macro
+\macrod{LOG\_MASK}\texttt{(p)} dove \code{p} è una delle costanti di
+tab.~\ref{tab:sess_syslog_priority}. É inoltre disponibile anche la macro
+\macrod{LOG\_UPTO}\texttt{(p)} che permette di specificare automaticamente
+tutte le priorità fino a quella indicata da \code{p}.
+
+Una volta che si sia certi che non si intende registrare più nessun messaggio
+si può chiudere esplicitamente la connessione al \textit{syslog} (l'uso di
+questa funzione è comunque completamente opzionale) con la funzione
+\funcd{closelog}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{syslog.h}
+\fdecl{void closelog(void)}
+\fdesc{Chiude la connessione al \textit{syslog}.}
+}
+
+{La funzione non ritorna nulla.}
+\end{funcproto}
+
+
+Come si evince anche dalla presenza della facility \const{LOG\_KERN} in
+tab.~\ref{tab:sess_syslog_facility}, uno dei possibili utenti del servizio del
+\textit{syslog} è anche il kernel, che a sua volta può avere necessità di
+inviare messaggi verso l'\textit{user space}. I messaggi del kernel sono
+mantenuti in un apposito buffer circolare e generati all'interno del kernel
+tramite la funzione \texttt{printk}, analoga alla \func{printf} usata in
+\textit{user space}.\footnote{una trattazione eccellente dell'argomento si
+ trova nel quarto capitolo di \cite{LinDevDri}.}
+
+Come per i messaggi ordinari anche i messaggi del kernel hanno una priorità ma
+in questo caso non si può contare sulla coincidenza con le costanti di
+tab.~\ref{tab:sess_syslog_priority} dato che il codice del kernel viene
+mantenuto in maniera indipendente dalle librerie del C. Per questo motivo le
+varie priorità usate dal kernel sono associate ad un valore numerico che viene
+tradotto in una stringa preposta ad ogni messaggio, secondo i valori che si
+sono riportati in fig.~\ref{fig:printk_priority}
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.80\textwidth}
+ \includestruct{listati/printk_prio.c}
+ \end{minipage}
+ \normalsize
+ \caption{Definizione delle stringhe coi relativi valori numerici che
+ indicano le priorità dei messaggi del kernel (ripresa da
+ \file{include/linux/kernel.h}).}
+ \label{fig:printk_priority}
+\end{figure}
+
+Dato che i messaggi generati da \texttt{printk} hanno un loro specifico
+formato tradizionalmente si usava un demone ausiliario, \cmd{klogd}, per
+leggerli, rimappare le loro priorità sui valori di
+tab.~\ref{tab:sess_syslog_priority} ed inviarli al sistema del \textit{syslog}
+nella facility \const{LOG\_KERN}. Oggi i nuovi demoni più avanzati che
+realizzano il servizio (come \texttt{rsyslog} o \texttt{syslog-ng}) sono in
+grado di fare tutto questo da soli leggendoli direttamente senza necessità di
+un intermediario.
+
+Ma i messaggi del kernel non sono necessariamente connessi al sistema del
+\textit{syslog}; ad esempio possono anche essere letti direttamente dal buffer
+circolare con il comando \texttt{dmesg}. Inoltre è previsto che se superano
+una certa priorità essi vengano stampati direttamente sul terminale indicato
+come \textit{console} di sistema,\footnote{quello che viene indicato con il
+ parametro di avvio \texttt{console} del kernel, si consulti al riguardo
+ sez.~5.3.1 di \cite{AGL}.} in modo che sia possibile vederli anche in caso
+di blocco totale del sistema (nell'assunzione che la console sia collegata).
+
+In particolare la stampa dei messaggi sulla console è controllata dal
+contenuto del file \sysctlfiled{kernel/printk} (o con l'equivalente parametro
+di \func{sysctl}) che prevede quattro valori numerici interi: il primo,
+\textit{console\_loglevel}, indica la priorità corrente oltre la quale vengono
+stampati i messaggi sulla console, il secondo,
+\textit{default\_message\_loglevel}, la priorità di default assegnata ai
+messaggi che non ne hanno impostata una, il terzo,
+\textit{minimum\_console\_level}, il valore minimo che si può assegnare al
+primo valore,\footnote{che può essere usato con una delle operazioni di
+ gestione che vedremo a breve per ``\textsl{silenziare}'' il kernel.} ed il
+quarto, \textit{default\_console\_loglevel}, il valore di
+default.\footnote{anch'esso viene usato nelle operazioni di controllo per
+ tornare ad un valore predefinito.}
+
+Per la lettura dei messaggi del kernel e la gestione del relativo buffer
+circolare esiste una apposita \textit{system call} chiamata anch'essa
+ \texttt{syslog}, ma dato il conflitto di nomi questa viene rimappata su
+ un'altra funzione di libreria, in particolare nelle \acr{glibc} essa viene
+ invocata tramite la funzione \funcd{klogctl},\footnote{nelle \acr{libc4} e
+ nelle \acr{libc5} la funzione invece era \code{SYS\_klog}.} il cui prototipo
+ è:
+
+\begin{funcproto}{
+\fhead{sys/klog.h}
+\fdecl{int klogctl(int op, char *buffer, int len)}
+\fdesc{Gestisce i messaggi di log del kernel.}
+}
+
+{La funzione ritorna un intero positivo o nullo dipendente dall'operazione
+ scelta in caso di successo e $-1$ per un errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] l'argomento \param{op} non ha un valore valido, o si
+ sono specificati valori non validi per gli altri argomenti quando questi
+ sono richiesti.
+ \item[\errcode{ENOSYS}] il supporto per \texttt{printk} non è stato compilato
+ nel kernel.
+ \item[\errcode{EPERM}] non si hanno i privilegi richiesti per l'operazione
+ richiesta.
+ \item[\errcode{ERESTARTSYS}] l'operazione è stata interrotta da un segnale.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione prevede che si passi come primo argomento \param{op} un codice
+numerico che indica l'operazione richiesta, il secondo argomento deve essere,
+per le operazioni che compiono una lettura di dati, l'indirizzo del buffer su
+cui copiarli, ed il terzo quanti byte leggere. L'effettivo uso di questi due
+argomenti dipende comunque dall'operazione richiesta, ma essi devono essere
+comunque specificati, anche quando non servono, nel qual caso verranno
+semplicemente ignorati.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \texttt{0} & apre il log (attualmente non fa niente), \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{1} & chiude il log (attualmente non fa niente), \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{2} & legge \param{len} byte nel buffer \param{buffer} dal log dei
+ messaggi.\\
+ \texttt{3} & legge \param{len} byte nel buffer \param{buffer} dal buffer
+ circolare dei messaggi.\\
+ \texttt{4} & legge \param{len} byte nel buffer \param{buffer} dal buffer
+ circolare dei messaggi e lo svuota.\\
+ \texttt{5} & svuota il buffer circolare dei messaggi, \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{6} & disabilita la stampa dei messaggi sulla console, \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{7} & abilita la stampa dei messaggi sulla console, \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{8} & imposta a \param{len} il livello dei messaggi stampati sulla
+ console, \param{buffer} è ignorato.\\
+ \texttt{9} & ritorna il numero di byte da leggere presenti sul buffer di
+ log, \param{buffer} e \param{len} sono ignorati (dal kernel
+ 2.4.10).\\
+ \texttt{10}& ritorna la dimensione del buffer di log, \param{buffer}
+ e \param{len} sono ignorati (dal kernel 2.6.6).\\
+\hline
+\end{tabular}
+\caption{Valori possibili per l'argomento \param{op} di \func{klogctl}.}
+\label{tab:klogctl_operation}
+\end{table}
+
+Si sono riportati in tab.~\ref{tab:klogctl_operation} i valori utilizzabili
+per \param{op}, con una breve spiegazione della relativa operazione e di come
+vengono usati gli altri due argomenti. Come si può notare la funzione è una
+sorta di interfaccia comune usata per eseguire operazioni completamente
+diverse fra loro.
+
+L'operazione corrispondente al valore 2 di \param{op} consente di leggere un
+messaggio dal cosiddetto \textit{log} del kernel. Eseguire questa operazione è
+equivalente ad eseguire una lettura dal file
+\procfile{/proc/kmsg},\footnote{in realtà è vero l'opposto, è questa funzione
+ che viene eseguita quando si legge da questo file.} se non vi sono messaggi
+la funzione si blocca in attesa di dati e ritorna soltanto quando questi
+diventano disponibili. In tal caso verranno letti ed
+estratti\footnote{estratti in quanti i dati del \textit{log} del kernel si
+ possono leggere una volta sola, se più processi eseguono l'operazione di
+ lettura soltanto uno riceverà i dati, a meno che completata la propria
+ operazione di lettura non restino altri messaggi pendenti che a questo punto
+ potrebbero essere letti da un altro processo in attesa.} dal log \param{len}
+byte che verranno scritti su \param{buffer}; in questo caso il valore di
+ritorno di \func{klogctl} corrisponderà al numero di byte ottenuti.
+
+Se invece si usa l'operazione 3 i dati vengono letti dal buffer circolare
+usato da \texttt{printk}, che mantiene tutti i messaggi stampati dal kernel
+fino al limite delle sue dimensioni, in questo caso i messaggi possono essere
+letti più volte. Usando invece l'operazione 4 si richiede di cancellare il
+buffer dopo la lettura, che così risulterà vuoto ad una lettura
+successiva. Anche con queste operazioni \param{len} indica il numero di byte
+da leggere e \param{buffer} l'indirizzo dove leggerli, e la funzione ritorna
+il numero di byte effettivamente letti. L'operazione 5 esegue soltanto la
+cancellazione del buffer circolare, \param{len} e \param{buffer} sono ignorati
+e la funzione ritorna un valore nullo.
+
+Le operazioni corrispondenti ai valori 6, 7 ed 8 consentono di modificare la
+priorità oltre la quale i messaggi vengono stampati direttamente sulla
+\textit{console} e fanno riferimento ai parametri del kernel gestiti con le
+variabili contenute in \sysctlfile{kernel/printk} di cui abbiamo
+parlato prima, ed in particolare con 6 si imposta come corrente il valore
+minimo della terza variabile (\textit{minimum\_console\_level}), ottenendo
+l'effetto di ridurre al minimo i messaggi che arrivano in console, mentre con
+7 si ripristina il valore di default.\footnote{secondo la documentazione
+ questo sarebbe quello indicato della quarta variabile,
+ \textit{default\_console\_loglevel} in genere pari a 7, ma alcune prove con
+ il programma \texttt{mydmesg} che si trova nei sorgenti allegati alla guida
+ rivelano che l'unico effetto di questa operazione è riportare il valore a
+ quello precedente se lo si è ridotto al minimo con l'operazione 6.} Per
+impostare direttamente un valore specifico infine si può usare 8, nel qual
+caso il valore numerico del livello da impostare deve essere specificato
+con \param{len}, che può assumere solo un valore fra 1 e 8.
+
+Infine le due operazioni 9 e 10 consentono di ottenere rispettivamente il
+numero di byte ancora non letti dal log del kernel, e la dimensione totale di
+questo. Per entrambe i dati sono restituiti come valore di ritorno, e gli
+argomento \param{buffer} e \param{len} sono ignorati.
+
+Si tenga presente che la modifica del livello minimo per cui i messaggi
+vengono stampati sulla console (operazioni 6, 7 e 8) e la cancellazione del
+buffer circolare di \texttt{printk} (operazioni 4 e 5) sono privilegiate; fino
+al kernel 2.6.30 era richiesta la capacità \const{CAP\_SYS\_ADMIN}, a partire
+dal 2.6.38 detto privilegio è stato assegnato ad una capacità aggiuntiva,
+\const{CAP\_SYSLOG}. Tutto questo è stato fatto per evitare che processi
+eseguiti all'interno di un sistema di virtualizzazione ``\textsl{leggera}''
+(come i \textit{Linux Container} di LXC) che necessitano di
+\const{CAP\_SYS\_ADMIN} per operare all'interno del proprio ambiente
+ristretto, potessero anche avere la capacità di influire sui log del kernel
+al di fuori di questo.
+
+\itindend{syslog}
+
+
+
+\section{L'I/O su terminale}
+\label{sec:sess_terminal_io}
+
+Benché come ogni altro dispositivo i terminali siano accessibili come file,
+essi hanno assunto storicamente, essendo stati a lungo l'unico modo di
+accedere al sistema, una loro rilevanza specifica, che abbiamo già avuto modo
+di incontrare nella precedente sezione.
+
+Esamineremo qui le peculiarità dell'I/O eseguito sui terminali, che per la
+loro particolare natura presenta delle differenze rispetto ai normali file su
+disco e agli altri dispositivi.
+
+
+
+\subsection{L'architettura dell'I/O su terminale}
+\label{sec:term_io_design}
+
+I terminali sono una classe speciale di dispositivi a caratteri (si ricordi la
+classificazione di sez.~\ref{sec:file_file_types}). Un terminale ha infatti
+una caratteristica che lo contraddistingue da un qualunque altro dispositivo,
+è infatti destinato a gestire l'interazione con un utente e deve perciò essere
+in grado di fare da terminale di controllo per una sessione; tutto questo
+comporta la presenza di una serie di capacità specifiche.
+
+L'interfaccia per i terminali è una delle più oscure e complesse, essendosi
+stratificata dagli inizi dei sistemi Unix fino ad oggi. Questo comporta una
+grande quantità di opzioni e controlli relativi ad un insieme di
+caratteristiche (come ad esempio la velocità della linea) necessarie per
+dispositivi, come i terminali seriali, che al giorno d'oggi sono praticamente
+in disuso.
+
+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{ciò vale solo in parte per i terminali virtuali,
+ essi infatti hanno due lati, un \textit{master}, che può assumere i nomi
+ \file{/dev/pty[p-za-e][0-9a-f]} ed un corrispondente \textit{slave} con nome
+ \file{/dev/tty[p-za-e][0-9a-f]}.} Oggi essi includono le porte seriali, le
+console virtuali dello schermo, i terminali virtuali che vengono creati come
+canali di comunicazione dal kernel e che di solito vengono associati alle
+connessioni di rete (ad esempio per trattare i dati inviati con \cmd{telnet} o
+\cmd{ssh}).
+
+L'I/O sui terminali si effettua con le stesse modalità dei file normali: si
+apre il relativo file di dispositivo, e si leggono e scrivono i dati con le
+usuali funzioni di lettura e scrittura. Così se apriamo una console virtuale
+avremo che \func{read} leggerà quanto immesso dalla tastiera, mentre
+\func{write} scriverà sullo schermo. In realtà questo è vero solo a grandi
+linee, perché non tiene conto delle caratteristiche specifiche dei terminali;
+una delle principali infatti è che essi prevedono due modalità di operazione,
+dette rispettivamente ``\textsl{modo canonico}'' e ``\textsl{modo non
+ canonico}'', che hanno dei comportamenti nettamente
+diversi. \index{modo~canonico}\index{modo~non~canonico}
+
+% TODO: inserire qui il comportamento di read relativo all'errore EIO sulla
+% lettura in background???
+
+La modalità preimpostata all'apertura del terminale è quella canonica, in cui
+le operazioni di lettura vengono sempre effettuate assemblando i dati in una
+linea. Questo significa che eseguendo una \func{read} su un terminale in modo
+canonico la funzione si bloccherà, anche se si sono scritti dei caratteri,
+fintanto che non si preme il tasto di ritorno a capo: a questo punto la linea
+sarà completata e la funzione ritornerà leggendola per intero.
+
+Inoltre in modalità canonica alcuni dei caratteri che si scrivono sul
+terminale vengono interpretati direttamente dal kernel per compiere operazioni
+(come la generazione dei segnali associati al \textit{job control} illustrata
+in sez.~\ref{sec:sig_job_control}), e non saranno mai letti dal
+dispositivo. Quella canonica è di norma la modalità in cui opera la shell.
+
+Un terminale in modo non canonico invece non effettua nessun accorpamento dei
+dati in linee né li interpreta; esso viene di solito usato da quei programmi,
+come ad esempio gli editor, che necessitano di poter leggere un carattere alla
+volta e che gestiscono al loro interno l'interpretazione dei caratteri
+ricevuti impiegandoli opportunamente come comandi o come dati.
+
+\begin{figure}[!htb]
+ \centering \includegraphics[width=12cm]{img/term_struct}
+ \caption{Struttura interna generica del kernel per l'accesso ai dati di un
+ terminale.}
+ \label{fig:term_struct}
+\end{figure}
+
+Per capire le caratteristiche dell'I/O sui terminali occorre esaminare le
+modalità con cui esso viene effettuato. L'accesso, come per tutti i
+dispositivi, viene gestito dal kernel, ma per tutti i terminali viene
+utilizzata una architettura generica che si è schematizzata in
+fig.~\ref{fig:term_struct}.
+
+Ad ogni terminale sono sempre associate due code
+per gestire l'input e l'output, che ne implementano una bufferizzazione
+all'interno del kernel che è completamente indipendente dalla eventuale
+ulteriore bufferizzazione fornita dall'interfaccia standard dei file.
+
+La coda di ingresso mantiene i caratteri che sono stati letti dal terminale ma
+non ancora letti da un processo, la sua dimensione è definita dal parametro di
+sistema \const{MAX\_INPUT} (si veda sez.~\ref{sec:sys_file_limits}), che ne
+specifica il limite minimo, in realtà la coda può essere più grande e cambiare
+dimensione dinamicamente.
+
+Se è stato abilitato il controllo di flusso in ingresso il kernel emette i
+caratteri di STOP e START per bloccare e sbloccare l'ingresso dei dati;
+altrimenti i caratteri immessi oltre le dimensioni massime vengono persi; in
+alcuni casi il kernel provvede ad inviare automaticamente un avviso (un
+carattere di BELL, che provoca un beep) sull'output quando si eccedono le
+dimensioni della coda.
+
+Se è abilitato la modalità canonica i caratteri in ingresso restano nella coda
+fintanto che non viene ricevuto un a capo; un altro parametro del sistema,
+\const{MAX\_CANON}, specifica la dimensione massima di una riga in modalità
+canonica.
+
+La coda di uscita è analoga a quella di ingresso e contiene i caratteri
+scritti dai processi ma non ancora inviati al terminale. Se è abilitato il
+controllo di flusso in uscita il kernel risponde ai caratteri di START e STOP
+inviati dal terminale. Le dimensioni della coda non sono specificate, ma non
+hanno molta importanza, in quanto qualora esse vengano eccedute il driver
+provvede automaticamente a bloccare la funzione chiamante.
+
+
+
+\subsection{La gestione delle caratteristiche di un terminale}
+\label{sec:term_attr}
+
+Data le loro peculiarità, fin dalla realizzazione dei primi sistemi unix-like
+si è posto il problema di come gestire le caratteristiche specifiche dei
+terminali. Storicamente i vari dialetti di Unix hanno utilizzato delle
+funzioni specifiche diverse fra loro, ma con la realizzazione dello standard
+POSIX.1-2001 è stata effettuata opportuna unificazione delle funzioni
+attinenti i terminali, sintetizzando le differenze fra BSD e System V in una
+unica interfaccia, che è quella adottata da Linux.
+
+Molte delle funzioni previste dallo standard POSIX.1-2001 prevedono come
+argomento un file descriptor, dato che in origine le relative operazioni
+venivano effettuate con delle opportune chiamate a \func{ioctl}. Ovviamente
+dette funzioni potranno essere usate correttamente soltanto con dei file
+descriptor che corrispondono ad un terminale, in caso contrario lo standard
+richiede che venga restituito un errore di \errcode{ENOTTY}.
+
+Per evitare l'errore, ed anche semplicemente per verificare se un file
+descriptor corrisponde ad un terminale, è disponibile la funzione
+\funcd{isatty}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int isatty(int fd)}
+\fdesc{Controlla se un file è un terminale.}
+}
+
+{La funzione ritorna $1$ se \param{fd} è connesso ad un terminale e $0$
+ altrimenti, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido.
+ \item[\errcode{EINVAL}] \param{fd} non è associato a un terminale (non
+ ottempera a POSIX.1-2001 che richiederebbe \errcode{ENOTTY}).
+ \end{errlist}
+}
+\end{funcproto}
+
+Un'altra funzione per avere informazioni su un terminale è \funcd{ttyname},
+che permette di ottenere il nome del file di dispositivo del terminale
+associato ad un file descriptor; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{char *ttyname(int fd)}
+\fdesc{Restituisce il nome del terminale associato ad un file descriptor.}
+}
+
+{La funzione ritorna il puntatore alla stringa contenente il nome del
+ terminale in caso di successo e \val{NULL} per un errore, nel qual caso
+ \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido.
+ \item[\errcode{ENOTTY}] \param{fd} non è associato a un terminale.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione restituisce il puntatore alla stringa contenente il nome del file
+di dispositivo del terminale associato a \param{fd}, che però è allocata
+staticamente e può essere sovrascritta da successive chiamate. Per questo
+della funzione esiste anche una versione rientrante, \funcd{ttyname\_r}, che
+non presenta il problema dell'uso di una zona di memoria statica; il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int ttyname\_r(int fd, char *buff, size\_t len)}
+\fdesc{Restituisce il nome del terminale associato ad un file descriptor.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{ERANGE}] la lunghezza del buffer \param{len} non è
+ sufficiente per contenere la stringa restituita.
+ \end{errlist}
+ ed inoltre \errval{EBADF} ed \errval{ENOTTY} con lo stesso significato di
+ \func{ttyname}.}
+\end{funcproto}
+
+La funzione prende due argomenti in più, il puntatore \param{buff} alla zona
+di memoria in cui l'utente vuole che il risultato venga scritto, che dovrà
+essere allocata in precedenza, e la relativa dimensione, \param{len}. Se la
+stringa che deve essere restituita, compreso lo zero di terminazione finale,
+eccede questa dimensione si avrà un errore.
+
+Una funzione funzione analoga alle precedenti prevista da POSIX.1, che
+restituisce il nome di un file di dispositivo, è \funcd{ctermid}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{char *ctermid(char *s)}
+\fdesc{Restituisce il nome del terminale di controllo del processo.}
+}
+
+{La funzione ritorna il puntatore alla stringa contenente il \textit{pathname}
+ del terminale o \val{NULL} se non non riesce ad eseguire l'operazione, non
+ sono previsti errori.}
+\end{funcproto}
+
+La funzione restituisce un puntatore al \textit{pathname} del file di
+dispositivo del terminale di controllo del processo chiamante. Se si passa
+come argomento \val{NULL} la funzione restituisce il puntatore ad una stringa
+statica che può essere sovrascritta da chiamate successive, e non è
+rientrante. Indicando invece un puntatore ad una zona di memoria già allocata
+la stringa sarà scritta su di essa, ma in questo caso il buffer preallocato
+deve avere una dimensione di almeno \constd{L\_ctermid}
+caratteri.\footnote{\const{L\_ctermid} è una delle varie costanti del sistema,
+ non trattata esplicitamente in sez.~\ref{sec:sys_characteristics}, che
+ indica la dimensione che deve avere una stringa per poter contenere il nome
+ di un terminale.}
+
+Si tenga presente che il \textit{pathname} restituito dalla funzione potrebbe
+non identificare univocamente il terminale (ad esempio potrebbe essere
+\file{/dev/tty}), inoltre non è detto che il processo possa effettivamente
+essere in grado di aprire il terminale.
+
+I vari attributi associati ad un terminale vengono mantenuti per ciascuno di
+essi in una struttura \struct{termios} che viene usata dalle varie funzioni
+dell'interfaccia. In fig.~\ref{fig:term_termios} si sono riportati tutti i
+campi della definizione di questa struttura usata in Linux; di questi solo i
+primi cinque sono previsti dallo standard POSIX.1, ma le varie implementazioni
+ne aggiungono degli altri per mantenere ulteriori informazioni.\footnote{la
+ definizione della struttura si trova in \file{bits/termios.h}, da non
+ includere mai direttamente; Linux, seguendo l'esempio di BSD, aggiunge i due
+ campi \var{c\_ispeed} e \var{c\_ospeed} per mantenere le velocità delle
+ linee seriali, ed un campo ulteriore, \var{c\_line} per indicare la
+ disciplina di linea.}
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.80\textwidth}
+ \includestruct{listati/termios.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{termios}, che identifica le proprietà di un
+ terminale.}
+ \label{fig:term_termios}
+\end{figure}
+
+% per le definizioni dei dati vedi anche:
+% http://www.lafn.org/~dave/linux/termios.txt
+
+I primi quattro campi sono quattro flag che controllano il comportamento del
+terminale; essi sono realizzati come maschera binaria, pertanto il tipo
+\typed{tcflag\_t} è di norma realizzato con un intero senza segno di lunghezza
+opportuna. I valori devono essere specificati bit per bit, avendo cura di non
+modificare i bit su cui non si interviene.
+
+\begin{table}[b!ht]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{IGNBRK} & Ignora le condizioni di BREAK sull'input. Una
+ \textit{condizione di BREAK} è definita nel contesto di
+ una trasmissione seriale asincrona come una sequenza di
+ bit nulli più lunga di un byte.\\
+ \constd{BRKINT} & Controlla la reazione ad un BREAK quando
+ \const{IGNBRK} non è impostato. Se \const{BRKINT} è
+ impostato il BREAK causa lo scarico delle code,
+ e se il terminale è il terminale di controllo per un
+ gruppo in foreground anche l'invio di \signal{SIGINT} ai
+ processi di quest'ultimo. Se invece \const{BRKINT} non è
+ impostato un BREAK viene letto come un carattere
+ NUL, a meno che non sia impostato \const{PARMRK}
+ nel qual caso viene letto come la sequenza di caratteri
+ \texttt{0xFF 0x00 0x00}.\\
+ \constd{IGNPAR} & Ignora gli errori di parità, il carattere viene passato
+ come ricevuto. Ha senso solo se si è impostato
+ \const{INPCK}.\\
+ \constd{PARMRK} & Controlla come vengono riportati gli errori di parità. Ha
+ senso solo se \const{INPCK} è impostato e \const{IGNPAR}
+ no. Se impostato inserisce una sequenza \texttt{0xFF
+ 0x00} prima di ogni carattere che presenta errori di
+ parità, se non impostato un carattere con errori di
+ parità viene letto come uno \texttt{0x00}. Se un
+ carattere ha il valore \texttt{0xFF} e \const{ISTRIP}
+ non è impostato, per evitare ambiguità esso viene sempre
+ riportato come \texttt{0xFF 0xFF}.\\
+ \constd{INPCK} & Abilita il controllo di parità in ingresso. Se non viene
+ impostato non viene fatto nessun controllo ed i caratteri
+ vengono passati in input direttamente.\\
+ \constd{ISTRIP} & Se impostato i caratteri in input sono tagliati a sette
+ bit mettendo a zero il bit più significativo, altrimenti
+ vengono passati tutti gli otto bit.\\
+ \constd{INLCR} & Se impostato in ingresso il carattere di a capo
+ (\verb|'\n'|) viene automaticamente trasformato in un
+ ritorno carrello (\verb|'\r'|).\\
+ \constd{IGNCR} & Se impostato il carattere di ritorno carrello
+ (\textit{carriage return}, \verb|'\r'|) viene scartato
+ dall'input. Può essere utile per i terminali che inviano
+ entrambi i caratteri di ritorno carrello e a capo
+ (\textit{newline}, \verb|'\n'|).\\
+ \constd{ICRNL} & Se impostato un carattere di ritorno carrello
+ (\verb|'\r'|) sul terminale viene automaticamente
+ trasformato in un a capo (\verb|'\n'|) sulla coda di
+ input.\\
+ \constd{IUCLC} & Se impostato trasforma i caratteri maiuscoli dal
+ terminale in minuscoli sull'ingresso (opzione non
+ POSIX).\\
+ \constd{IXON} & Se impostato attiva il controllo di flusso in uscita con i
+ caratteri di START e STOP. se si riceve
+ uno STOP l'output viene bloccato, e viene fatto
+ ripartire solo da uno START, e questi due
+ caratteri non vengono passati alla coda di input. Se non
+ impostato i due caratteri sono passati alla coda di input
+ insieme agli altri.\\
+ \constd{IXANY} & Se impostato con il controllo di flusso permette a
+ qualunque carattere di far ripartire l'output bloccato da
+ un carattere di STOP.\\
+ \constd{IXOFF} & Se impostato abilita il controllo di flusso in
+ ingresso. Il computer emette un carattere di STOP per
+ bloccare l'input dal terminale e lo sblocca con il
+ carattere START.\\
+ \constd{IMAXBEL}& Se impostato fa suonare il cicalino se si riempie la cosa
+ di ingresso; in Linux non è implementato e il kernel si
+ comporta cose se fosse sempre impostato (è una estensione
+ BSD).\\
+ \constd{IUTF8} & Indica che l'input è in UTF-8, cosa che consente di
+ utilizzare la cancellazione dei caratteri in maniera
+ corretta (dal kernel 2.6.4 e non previsto in POSIX).\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative dei vari bit del flag di controllo
+ \var{c\_iflag} delle modalità di input di un terminale.}
+ \label{tab:sess_termios_iflag}
+\end{table}
+
+Il primo flag, mantenuto nel campo \var{c\_iflag}, è detto \textsl{flag di
+ input} e controlla le modalità di funzionamento dell'input dei caratteri sul
+terminale, come il controllo di parità, il controllo di flusso, la gestione
+dei caratteri speciali; un elenco dei vari bit, del loro significato e delle
+costanti utilizzate per identificarli è riportato in
+tab.~\ref{tab:sess_termios_iflag}.
+
+Si noti come alcuni di questi flag (come quelli per la gestione del flusso)
+fanno riferimento a delle caratteristiche che ormai sono completamente
+obsolete; la maggior parte inoltre è tipica di terminali seriali, e non ha
+alcun effetto su dispositivi diversi come le console virtuali o gli
+pseudo-terminali usati nelle connessioni di rete.
+
+Il secondo flag, mantenuto nel campo \var{c\_oflag}, è detto \textsl{flag di
+ output} e controlla le modalità di funzionamento dell'output dei caratteri,
+come l'impacchettamento dei caratteri sullo schermo, la traslazione degli a
+capo, la conversione dei caratteri speciali; un elenco dei vari bit, del loro
+significato e delle costanti utilizzate per identificarli è riportato in
+tab.~\ref{tab:sess_termios_oflag}, di questi solo \const{OPOST} era previsto
+da POSIX.1, buona parte degli altri sono stati aggiunti in POSIX.1-2001,
+quelli ancora assenti sono stati indicati esplicitamente.
+
+\begin{table}[!htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{OPOST} & Se impostato i caratteri vengono convertiti opportunamente
+ (in maniera dipendente dall'implementazione) per la
+ visualizzazione sul terminale, ad esempio al
+ carattere di a capo (NL) può venire aggiunto un ritorno
+ carrello (CR).\\
+ \constd{OLCUC} & Se impostato trasforma i caratteri minuscoli in ingresso
+ in caratteri maiuscoli sull'uscita (non previsto da
+ POSIX).\\
+ \constd{ONLCR} & Se impostato converte automaticamente il carattere di a
+ capo (NL) in un carattere di ritorno carrello (CR).\\
+ \constd{OCRNL} & Se impostato converte automaticamente il carattere di a
+ capo (NL) nella coppia di caratteri ritorno carrello, a
+ capo (CR-NL).\\
+ \constd{ONOCR} & Se impostato converte il carattere di ritorno carrello
+ (CR) nella coppia di caratteri CR-NL.\\
+ \constd{ONLRET}& Se impostato rimuove dall'output il carattere di ritorno
+ carrello (CR).\\
+ \constd{OFILL} & Se impostato in caso di ritardo sulla linea invia dei
+ caratteri di riempimento invece di attendere.\\
+ \constd{OFDEL} & Se impostato il carattere di riempimento è DEL
+ (\texttt{0x3F}), invece che NUL (\texttt{0x00}), (non
+ previsto da POSIX e non implementato su Linux).\\
+ \constd{NLDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di a capo (NL), i valori possibili sono
+ \val{NL0} o \val{NL1}.\\
+ \constd{CRDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere ritorno carrello (CR), i valori possibili sono
+ \val{CR0}, \val{CR1}, \val{CR2} o \val{CR3}.\\
+ \constd{TABDLY}& Maschera per i bit che indicano il ritardo per il
+ carattere di tabulazione, i valori possibili sono
+ \val{TAB0}, \val{TAB1}, \val{TAB2} o \val{TAB3}.\\
+ \constd{BSDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di ritorno indietro (\textit{backspace}), i
+ valori possibili sono \val{BS0} o \val{BS1}.\\
+ \constd{VTDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di tabulazione verticale, i valori possibili sono
+ \val{VT0} o \val{VT1}.\\
+ \constd{FFDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di pagina nuova (\textit{form feed}), i valori
+ possibili sono \val{FF0} o \val{FF1}.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative dei vari bit del flag di controllo
+ \var{c\_oflag} delle modalità di output di un terminale.}
+ \label{tab:sess_termios_oflag}
+\end{table}
+
+Si noti come alcuni dei valori riportati in tab.~\ref{tab:sess_termios_oflag}
+fanno riferimento a delle maschere di bit; essi infatti vengono utilizzati per
+impostare alcuni valori numerici relativi ai ritardi nell'output di alcuni
+caratteri: una caratteristica originaria dei primi terminali su telescrivente,
+che avevano bisogno di tempistiche diverse per spostare il carrello in
+risposta ai caratteri speciali, e che oggi sono completamente in disuso.
+
+Si tenga presente inoltre che nel caso delle maschere il valore da inserire in
+\var{c\_oflag} deve essere fornito avendo cura di cancellare prima tutti i bit
+della maschera, i valori da immettere infatti (quelli riportati nella
+spiegazione corrispondente) sono numerici e non per bit, per cui possono
+sovrapporsi fra di loro. Occorrerà perciò utilizzare un codice del tipo:
+
+\includecodesnip{listati/oflag.c}
+
+\noindent che prima cancella i bit della maschera in questione e poi imposta
+il valore.
+
+
+\begin{table}[!htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{CBAUD} & Maschera dei bit (4+1) usati per impostare della velocità
+ della linea (il \textit{baud rate}) in ingresso; non è
+ presente in POSIX ed in Linux non è implementato in
+ quanto viene usato un apposito campo di
+ \struct{termios}.\\
+ \constd{CBAUDEX}& Bit aggiuntivo per l'impostazione della velocità della
+ linea, non è presente in POSIX e per le stesse
+ motivazioni del precedente non è implementato in Linux.\\
+ \constd{CSIZE} & Maschera per i bit usati per specificare la dimensione
+ del carattere inviato lungo la linea di trasmissione, i
+ valore ne indica la lunghezza (in bit), ed i valori
+ possibili sono \val{CS5}, \val{CS6}, \val{CS7} e \val{CS8}
+ corrispondenti ad un analogo numero di bit.\\
+ \constd{CSTOPB} & Se impostato vengono usati due bit di stop sulla linea
+ seriale, se non impostato ne viene usato soltanto uno.\\
+ \constd{CREAD} & Se è impostato si può leggere l'input del terminale,
+ altrimenti i caratteri in ingresso vengono scartati
+ quando arrivano.\\
+ \constd{PARENB} & Se impostato abilita la generazione il controllo di
+ parità. La reazione in caso di errori dipende dai
+ relativi valori per \var{c\_iflag}, riportati in
+ tab.~\ref{tab:sess_termios_iflag}. Se non è impostato i
+ bit di parità non vengono generati e i caratteri non
+ vengono controllati.\\
+ \constd{PARODD} & Ha senso solo se è attivo anche \const{PARENB}. Se
+ impostato viene usata una parità è dispari, altrimenti
+ viene usata una parità pari.\\
+ \constd{HUPCL} & Se è impostato viene distaccata la connessione del
+ modem quando l'ultimo dei processi che ha ancora un file
+ aperto sul terminale lo chiude o esce.\\
+ \constd{LOBLK} & Se impostato blocca l'output su un strato di shell non
+ corrente, non è presente in POSIX e non è implementato
+ da Linux.\\
+ \constd{CLOCAL} & Se impostato indica che il terminale è connesso in locale
+ e che le linee di controllo del modem devono essere
+ ignorate. Se non impostato effettuando una chiamata ad
+ \func{open} senza aver specificato il flag di
+ \const{O\_NONBLOCK} si bloccherà il processo finché
+ non si è stabilita una connessione con il modem; inoltre
+ se viene rilevata una disconnessione viene inviato un
+ segnale di \signal{SIGHUP} al processo di controllo del
+ terminale. La lettura su un terminale sconnesso comporta
+ una condizione di \textit{end of file} e la scrittura un
+ errore di \errcode{EIO}.\\
+ \constd{CIBAUD} & Maschera dei bit della velocità della linea in
+ ingresso; analogo a \const{CBAUD}, non è previsto da
+ POSIX e non è implementato in Linux dato che è
+ mantenuto in un apposito campo di \struct{termios}.\\
+ \constd{CMSPAR} & imposta un bit di parità costante: se \const{PARODD} è
+ impostato la parità è sempre 1 (\textit{MARK}) se non è
+ impostato la parità è sempre 0 (\textit{SPACE}), non è
+ previsto da POSIX.\\
+% vedi: http://www.lothosoft.ch/thomas/libmip/markspaceparity.php
+ \constd{CRTSCTS}& Abilita il controllo di flusso hardware sulla seriale,
+ attraverso l'utilizzo delle dei due fili di RTS e CTS.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative dei vari bit del flag di controllo
+ \var{c\_cflag} delle modalità di controllo di un terminale.}
+ \label{tab:sess_termios_cflag}
+\end{table}
+
+Il terzo flag, mantenuto nel campo \var{c\_cflag}, è detto \textsl{flag di
+ controllo} ed è legato al funzionamento delle linee seriali, permettendo di
+impostarne varie caratteristiche, come il numero di bit di stop, le
+impostazioni della parità, il funzionamento del controllo di flusso; esso ha
+senso solo per i terminali connessi a linee seriali. Un elenco dei vari bit,
+del loro significato e delle costanti utilizzate per identificarli è riportato
+in tab.~\ref{tab:sess_termios_cflag}.
+
+I valori previsti per questo flag sono molto specifici, e completamente
+attinenti al controllo delle modalità operative di un terminale che opera
+attraverso una linea seriale; essi pertanto non hanno nessuna rilevanza per i
+terminali che usano un'altra interfaccia fisica, come le console virtuali e
+gli pseudo-terminali usati dalle connessioni di rete.
+
+Inoltre alcuni valori di questi flag sono previsti solo per quelle
+implementazioni (lo standard POSIX non specifica nulla riguardo
+l'implementazione, ma solo delle funzioni di lettura e scrittura) che
+mantengono le velocità delle linee seriali all'interno dei flag; come
+accennato in Linux questo viene fatto (seguendo l'esempio di BSD) attraverso
+due campi aggiuntivi, \var{c\_ispeed} e \var{c\_ospeed}, nella struttura
+\struct{termios} (mostrati in fig.~\ref{fig:term_termios}).
+
+\begin{table}[b!ht]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{ISIG} & Se impostato abilita il riconoscimento dei caratteri
+ INTR, QUIT, e SUSP generando il relativo segnale.\\
+ \constd{ICANON} & Se impostato il terminale opera in modalità canonica,
+ altrimenti opera in modalità non canonica.\\
+ \constd{XCASE} & Se impostato il terminale funziona solo con le
+ maiuscole. L'input è convertito in minuscole tranne per i
+ caratteri preceduti da una ``\texttt{\bslash}''. In output
+ le maiuscole sono precedute da una ``\texttt{\bslash}'' e
+ le minuscole convertite in maiuscole. Non è presente in
+ POSIX.\\
+ \constd{ECHO} & Se è impostato viene attivato l'eco dei caratteri in
+ input sull'output del terminale.\\
+ \constd{ECHOE} & Se è impostato l'eco mostra la cancellazione di un
+ carattere in input (in reazione al carattere ERASE)
+ cancellando l'ultimo carattere della riga corrente dallo
+ schermo; altrimenti il carattere è rimandato in eco per
+ mostrare quanto accaduto (usato per i terminali con
+ l'uscita su una stampante).\\
+ \constd{ECHOK} & Se impostato abilita il trattamento della visualizzazione
+ del carattere KILL, andando a capo dopo aver visualizzato
+ lo stesso, altrimenti viene solo mostrato il carattere e
+ sta all'utente ricordare che l'input precedente è stato
+ cancellato.\\
+ \constd{ECHONL} & Se impostato viene effettuato l'eco di un a
+ capo (\verb|\n|) anche se non è stato impostato
+ \const{ECHO}.\\
+ \constd{ECHOCTL}& Se impostato insieme ad \const{ECHO} i caratteri di
+ controllo ASCII (tranne TAB, NL, START, e STOP) sono
+ mostrati nella forma che prepone un ``\texttt{\circonf}''
+ alla lettera ottenuta sommando \texttt{0x40} al valore del
+ carattere (di solito questi si possono ottenere anche
+ direttamente premendo il tasto \texttt{ctrl} più la
+ relativa lettera). Non è presente in POSIX.\\
+ \constd{ECHOPRT}& Se impostato abilita la visualizzazione del carattere di
+ cancellazione in una modalità adatta ai terminali con
+ l'uscita su stampante; l'invio del carattere di ERASE
+ comporta la stampa di un ``\texttt{|}'' seguito dal
+ carattere cancellato, e così via in caso di successive
+ cancellazioni, quando si riprende ad immettere carattere
+ normali prima verrà stampata una ``\texttt{/}''. Non è
+ presente in POSIX.\\
+ \constd{ECHOKE} & Se impostato abilita il trattamento della visualizzazione
+ del carattere KILL cancellando i caratteri precedenti
+ nella linea secondo le modalità specificate dai valori di
+ \const{ECHOE} e \const{ECHOPRT}. Non è presente in
+ POSIX.\\
+ \constd{DEFECHO}& Se impostato effettua l'eco solo se c'è un processo in
+ lettura. Non è presente in POSIX e non è supportato da
+ Linux.\\
+ \constd{FLUSHO} & Effettua la cancellazione della coda di uscita. Viene
+ attivato dal carattere DISCARD. Non è presente in POSIX e
+ non è supportato da Linux.\\
+ \constd{NOFLSH} & Se impostato disabilita lo scarico delle code di ingresso
+ e uscita quando vengono emessi i segnali \signal{SIGINT},
+ \signal{SIGQUIT} e \signal{SIGSUSP}.\\
+ \constd{TOSTOP} & Se abilitato, con il supporto per il job control presente,
+ genera il segnale \signal{SIGTTOU} per un processo in
+ background che cerca di scrivere sul terminale.\\
+ \constd{PENDIN} & Indica che la linea deve essere ristampata, viene
+ attivato dal carattere REPRINT e resta attivo fino alla
+ fine della ristampa. Non è presente in POSIX e
+ non è supportato in Linux.\\
+ \constd{IEXTEN} & Abilita alcune estensioni previste dalla
+ implementazione. Deve essere impostato perché caratteri
+ speciali come EOL2, LNEXT, REPRINT e WERASE possano
+ essere interpretati.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative dei vari bit del flag di controllo
+ \var{c\_lflag} delle modalità locali di un terminale.}
+ \label{tab:sess_termios_lflag}
+\end{table}
+
+Il quarto flag, mantenuto nel campo \var{c\_lflag}, è detto \textsl{flag
+ locale}, e serve per controllare il funzionamento dell'interfaccia fra il
+driver e l'utente, come abilitare l'eco, gestire i caratteri di controllo e
+l'emissione dei segnali, impostare modo canonico o non canonico. Un elenco dei
+vari bit, del loro significato e delle costanti utilizzate per identificarli è
+riportato in tab.~\ref{tab:sess_termios_lflag}. Con i terminali odierni
+l'unico flag con cui probabilmente si può avere a che fare è questo, in quanto
+è con questo che si impostano le caratteristiche generiche comuni a tutti i
+terminali.
+
+Si tenga presente che i flag che riguardano le modalità di eco dei caratteri
+(\const{ECHOE}, \const{ECHOPRT}, \const{ECHOK}, \const{ECHOKE},
+\const{ECHONL}) controllano solo il comportamento della visualizzazione, il
+riconoscimento dei vari caratteri dipende dalla modalità di operazione, ed
+avviene solo in modo canonico, pertanto questi flag non hanno significato se
+non è impostato \const{ICANON}.
+
+Oltre ai vari flag per gestire le varie caratteristiche dei terminali,
+\struct{termios} contiene pure il campo \var{c\_cc} che viene usato per
+impostare i caratteri speciali associati alle varie funzioni di controllo. Il
+numero di questi caratteri speciali è indicato dalla costante \constd{NCCS},
+POSIX ne specifica almeno 11, ma molte implementazioni ne definiscono molti
+altri.\footnote{in Linux il valore della costante è 32, anche se i caratteri
+ effettivamente definiti sono solo 17.}
+
+\begin{table}[!htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|c|c|p{9cm}|}
+ \hline
+ \textbf{Indice} & \textbf{Valore}&\textbf{Codice} & \textbf{Funzione}\\
+ \hline
+ \hline
+ \constd{VINTR} &\texttt{0x03}&(\texttt{C-c})& Carattere di interrupt,
+ provoca l'emissione di
+ \signal{SIGINT}.\\
+ \constd{VQUIT} &\texttt{0x1C}&(\texttt{C-\bslash})& Carattere di uscita,
+ provoca l'emissione di
+ \signal{SIGQUIT}.\\
+ \constd{VERASE}&\texttt{0x7f}&DEL,\texttt{C-?}& Carattere di ERASE, cancella
+ l'ultimo carattere
+ precedente nella linea.\\
+ \constd{VKILL} &\texttt{0x15}&(\texttt{C-u})& Carattere di KILL, cancella
+ l'intera riga.\\
+ \constd{VEOF} &\texttt{0x04}&(\texttt{C-d})& Carattere di
+ \textit{end-of-file}. Causa
+ l'invio del contenuto del
+ buffer di ingresso al
+ processo in lettura anche se
+ non è ancora stato ricevuto
+ un a capo. Se è il primo
+ carattere immesso comporta il
+ ritorno di \func{read} con
+ zero caratteri, cioè la
+ condizione di
+ \textit{end-of-file}.\\
+ \constd{VMIN} & --- & --- & Numero minimo di caratteri per una
+ lettura in modo non canonico.\\
+ \constd{VEOL} &\texttt{0x00}& NUL & Carattere di fine riga. Agisce come
+ un a capo, ma non viene scartato ed
+ è letto come l'ultimo carattere
+ nella riga.\\
+ \constd{VTIME} & --- & --- & Timeout, in decimi di secondo, per
+ una lettura in modo non canonico.\\
+ \constd{VEOL2} &\texttt{0x00}& NUL & Ulteriore carattere di fine
+ riga. Ha lo stesso effetto di
+ \const{VEOL} ma può essere un
+ carattere diverso. \\
+ \constd{VSWTC} &\texttt{0x00}& NUL & Carattere di switch. Non supportato
+ in Linux.\\
+ \constd{VSTART}&\texttt{0x17}&(\texttt{C-q})& Carattere di START. Riavvia un
+ output bloccato da uno STOP.\\
+ \constd{VSTOP} &\texttt{0x19}&(\texttt{C-s})& Carattere di STOP. Blocca
+ l'output fintanto che non
+ viene premuto un carattere di
+ START.\\
+ \constd{VSUSP} &\texttt{0x1A}&(\texttt{C-z})& Carattere di
+ sospensione. Invia il segnale
+ \signal{SIGTSTP}.\\
+ \constd{VDSUSP}&\texttt{0x19}&(\texttt{C-y})& Carattere di sospensione
+ ritardata. Invia il segnale
+ \signal{SIGTSTP} quando il
+ carattere viene letto dal
+ programma, (non presente in
+ POSIX e non riconosciuto in
+ Linux).\\
+ \constd{VLNEXT}&\texttt{0x16}&(\texttt{C-v})& Carattere di escape, serve a
+ quotare il carattere
+ successivo che non viene
+ interpretato ma passato
+ direttamente all'output.\\
+ \constd{VWERASE}&\texttt{0x17}&(\texttt{C-w})&Cancellazione di una
+ parola.\\
+ \constd{VREPRINT}&\texttt{0x12}&(\texttt{C-r})& Ristampa i caratteri non
+ ancora letti (non presente in
+ POSIX).\\
+ \constd{VDISCARD}&\texttt{0x0F}&(\texttt{C-o})& Non riconosciuto in Linux.\\
+ \constd{VSTATUS} &\texttt{0x13}&(\texttt{C-t})& Non riconosciuto in Linux.\\
+ \hline
+ \end{tabular}
+ \caption{Valori dei caratteri di controllo mantenuti nel campo \var{c\_cc}
+ della struttura \struct{termios}.}
+ \label{tab:sess_termios_cc}
+\end{table}
+
+
+A ciascuna di queste funzioni di controllo corrisponde un elemento del vettore
+\var{c\_cc} che specifica quale è il carattere speciale associato; per
+portabilità invece di essere indicati con la loro posizione numerica nel
+vettore, i vari elementi vengono indicizzati attraverso delle opportune
+costanti, il cui nome corrisponde all'azione ad essi associata. Un elenco
+completo dei caratteri di controllo, con le costanti e delle funzionalità
+associate è riportato in tab.~\ref{tab:sess_termios_cc}, usando quelle
+definizioni diventa possibile assegnare un nuovo carattere di controllo con un
+codice del tipo:
+\includecodesnip{listati/value_c_cc.c}
+
+La maggior parte di questi caratteri (tutti tranne \const{VTIME} e
+\const{VMIN}) hanno effetto solo quando il terminale viene utilizzato in modo
+canonico; per alcuni devono essere soddisfatte ulteriori richieste, ad esempio
+\const{VINTR}, \const{VSUSP}, e \const{VQUIT} richiedono sia impostato
+\const{ISIG}; \const{VSTART} e \const{VSTOP} richiedono sia impostato
+\const{IXON}; \const{VLNEXT}, \const{VWERASE}, \const{VREPRINT} richiedono sia
+impostato \const{IEXTEN}. In ogni caso quando vengono attivati i caratteri
+vengono interpretati e non sono passati sulla coda di ingresso.
+
+Per leggere ed scrivere tutte le varie impostazioni dei terminali viste finora
+lo standard POSIX prevede due funzioni che utilizzano come argomento un
+puntatore ad una struttura \struct{termios} che sarà quella in cui andranno
+immagazzinate le impostazioni. Le funzioni sono \funcd{tcgetattr} e
+\funcd{tcsetattr} ed il loro prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+
+\fdecl{int tcgetattr(int fd, struct termios *termios\_p)}
+\fdesc{Legge il valore delle impostazioni di un terminale.}
+\fdecl{int tcsetattr(int fd, int optional\_actions, struct termios *termios\_p)}
+\fdesc{Scrive le impostazioni di un terminale.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] la funzione è stata interrotta.
+ \end{errlist}
+ ed inoltre \errval{EBADF}, \errval{ENOTTY} ed \errval{EINVAL} nel loro
+ significato generico.}
+\end{funcproto}
+
+
+Le funzioni operano sul terminale cui fa riferimento il file descriptor
+\param{fd} utilizzando la struttura indicata dal puntatore \param{termios\_p}
+per lo scambio dei dati. Si tenga presente che le impostazioni sono associate
+al terminale e non al file descriptor; questo significa che se si è cambiata
+una impostazione un qualunque altro processo che apra lo stesso terminale, od
+un qualunque altro file descriptor che vi faccia riferimento, vedrà le nuove
+impostazioni pur non avendo nulla a che fare con il file descriptor che si è
+usato per effettuare i cambiamenti.
+
+Questo significa che non è possibile usare file descriptor diversi per
+utilizzare automaticamente il terminale in modalità diverse, se esiste una
+necessità di accesso differenziato di questo tipo occorrerà cambiare
+esplicitamente la modalità tutte le volte che si passa da un file descriptor
+ad un altro.
+
+La funzione \func{tcgetattr} legge i valori correnti delle impostazioni di un
+terminale qualunque nella struttura puntata da \param{termios\_p};
+\func{tcsetattr} invece effettua la scrittura delle impostazioni e quando
+viene invocata sul proprio terminale di controllo può essere eseguita con
+successo solo da un processo in foreground. Se invocata da un processo in
+background infatti tutto il gruppo riceverà un segnale di \signal{SIGTTOU} come
+se si fosse tentata una scrittura, a meno che il processo chiamante non abbia
+\signal{SIGTTOU} ignorato o bloccato, nel qual caso l'operazione sarà eseguita.
+
+La funzione \func{tcsetattr} prevede tre diverse modalità di funzionamento,
+specificabili attraverso l'argomento \param{optional\_actions}, che permette
+di stabilire come viene eseguito il cambiamento delle impostazioni del
+terminale, i valori possibili sono riportati in
+tab.~\ref{tab:sess_tcsetattr_option}; di norma (come fatto per le due funzioni
+di esempio) si usa sempre \const{TCSANOW}, le altre opzioni possono essere
+utili qualora si cambino i parametri di output.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{TCSANOW} & Esegue i cambiamenti in maniera immediata.\\
+ \constd{TCSADRAIN}& I cambiamenti vengono eseguiti dopo aver atteso che
+ tutto l'output presente sulle code è stato scritto.\\
+ \constd{TCSAFLUSH}& È identico a \const{TCSADRAIN}, ma in più scarta
+ tutti i dati presenti sulla coda di input.\\
+ \hline
+ \end{tabular}
+ \caption{Possibili valori per l'argomento \param{optional\_actions} della
+ funzione \func{tcsetattr}.}
+ \label{tab:sess_tcsetattr_option}
+\end{table}
+
+Occorre infine tenere presente che \func{tcsetattr} ritorna con successo anche
+se soltanto uno dei cambiamenti richiesti è stato eseguito. Pertanto se si
+effettuano più cambiamenti è buona norma controllare con una ulteriore
+chiamata a \func{tcgetattr} che essi siano stati eseguiti tutti quanti.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/SetTermAttr.c}
+ \end{minipage}
+ \normalsize
+ \caption{Codice della funzione \func{SetTermAttr} che permette di
+ impostare uno dei flag di controllo locale del terminale.}
+ \label{fig:term_set_attr}
+\end{figure}
+
+Come già accennato per i cambiamenti effettuati ai vari flag di controllo
+occorre che i valori di ciascun bit siano specificati avendo cura di mantenere
+intatti gli altri; per questo motivo in generale si deve prima leggere il
+valore corrente delle impostazioni con \func{tcgetattr} per poi modificare i
+valori impostati.
+
+In fig.~\ref{fig:term_set_attr} e fig.~\ref{fig:term_unset_attr} si è
+riportato rispettivamente il codice delle due funzioni \func{SetTermAttr} e
+\func{UnSetTermAttr}, che possono essere usate per impostare o rimuovere, con
+le dovute precauzioni, un qualunque bit di \var{c\_lflag}. Il codice completo
+di entrambe le funzioni può essere trovato nel file \file{SetTermAttr.c} dei
+sorgenti allegati alla guida.
+
+La funzione \func{SetTermAttr} provvede ad impostare il bit specificato
+dall'argomento \param{flag}; prima si leggono i valori correnti
+(\texttt{\small 8}) con \func{tcgetattr}, uscendo con un messaggio in caso di
+errore (\texttt{\small 9--10}), poi si provvede a impostare solo i bit
+richiesti (possono essere più di uno) con un OR binario (\texttt{\small 12});
+infine si scrive il nuovo valore modificato con \func{tcsetattr}
+(\texttt{\small 13}), notificando un eventuale errore (\texttt{\small 14--15})
+o uscendo normalmente.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/UnSetTermAttr.c}
+ \end{minipage}
+ \normalsize
+ \caption{Codice della funzione \func{UnSetTermAttr} che permette di
+ rimuovere uno dei flag di controllo locale del terminale.}
+ \label{fig:term_unset_attr}
+\end{figure}
+
+La seconda funzione, \func{UnSetTermAttr}, è assolutamente identica alla
+prima, solo che in questo caso (\texttt{\small 9}) si rimuovono i bit
+specificati dall'argomento \param{flag} usando un AND binario del valore
+negato.
+
+Al contrario di tutte le altre caratteristiche dei terminali, che possono
+essere impostate esplicitamente utilizzando gli opportuni campi di
+\struct{termios}, per le velocità della linea (il cosiddetto \textit{baud
+ rate}) non è prevista una implementazione standardizzata, per cui anche se
+in Linux sono mantenute in due campi dedicati nella struttura, questi non
+devono essere acceduti direttamente ma solo attraverso le apposite funzioni di
+interfaccia provviste da POSIX.1.
+
+Lo standard prevede due funzioni per scrivere la velocità delle linee seriali,
+\funcd{cfsetispeed} per la velocità della linea di ingresso e
+\funcd{cfsetospeed} per la velocità della linea di uscita; i loro prototipi
+sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{int cfsetispeed(struct termios *termios\_p, speed\_t speed)}
+\fdesc{Imposta la velocità delle linee seriali in ingresso.}
+\fdecl{int cfsetospeed(struct termios *termios\_p, speed\_t speed)}
+\fdesc{Imposta la velocità delle linee seriali in uscita.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, che
+ avviene solo quando il valore specificato non è valido.}
+\end{funcproto}
+
+Si noti che le funzioni si limitano a scrivere opportunamente il valore della
+velocità prescelta \param{speed} all'interno della struttura puntata da
+\param{termios\_p}; per effettuare l'impostazione effettiva occorrerà poi
+chiamare \func{tcsetattr}.
+
+Si tenga presente che per le linee seriali solo alcuni valori di velocità sono
+validi; questi possono essere specificati direttamente (le \acr{glibc}
+prevedono che i valori siano indicati in bit per secondo), ma in generale
+altre versioni di librerie possono utilizzare dei valori diversi. Per questo
+POSIX.1 prevede una serie di costanti che però servono solo per specificare le
+velocità tipiche delle linee seriali:
+\begin{verbatim}
+ B0 B50 B75 B110 B134 B150 B200
+ B300 B600 B1200 B1800 B2400 B4800 B9600
+ B19200 B38400 B57600 B115200 B230400 B460800
+\end{verbatim}
+
+Un terminale può utilizzare solo alcune delle velocità possibili, le funzioni
+però non controllano se il valore specificato è valido, dato che non possono
+sapere a quale terminale le velocità saranno applicate; sarà l'esecuzione di
+\func{tcsetattr} a fallire quando si cercherà di eseguire l'impostazione.
+
+Di norma il valore ha senso solo per i terminali seriali dove indica appunto
+la velocità della linea di trasmissione; se questa non corrisponde a quella
+del terminale quest'ultimo non potrà funzionare: quando il terminale non è
+seriale il valore non influisce sulla velocità di trasmissione dei dati.
+
+In generale impostare un valore nullo (\val{B0}) sulla linea di output fa si
+che il modem non asserisca più le linee di controllo, interrompendo di fatto
+la connessione, qualora invece si utilizzi questo valore per la linea di input
+l'effetto sarà quello di rendere la sua velocità identica a quella della linea
+di output.
+
+Dato che in genere si imposta sempre la stessa velocità sulle linee di uscita
+e di ingresso è supportata anche la funzione \funcd{cfsetspeed}, una
+estensione di BSD (la funzione origina da 4.4BSD e richiede sia definita la
+macro \macro{\_BSD\_SOURCE}) il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{int cfsetspeed(struct termios *termios\_p, speed\_t speed)}
+\fdesc{Imposta la velocità delle linee seriali.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, che avviene
+ solo quando il valore specificato non è valido.}
+\end{funcproto}
+
+\noindent la funzione è identica alle due precedenti ma imposta la stessa
+velocità sia per la linea di ingresso che per quella di uscita.
+
+Analogamente a quanto avviene per l'impostazione, le velocità possono essere
+lette da una struttura \struct{termios} utilizzando altre due funzioni,
+\funcd{cfgetispeed} e \funcd{cfgetospeed}, i cui prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{speed\_t cfgetispeed(struct termios *termios\_p)}
+\fdesc{Legge la velocità delle linee seriali in ingresso.}
+\fdecl{speed\_t cfgetospeed(struct termios *termios\_p)}
+\fdesc{Legge la velocità delle linee seriali in uscita.}
+}
+
+{Le funzioni ritornano la velocità della linea, non sono previste condizioni
+ di errore.}
+\end{funcproto}
+
+Anche in questo caso le due funzioni estraggono i valori della velocità della
+linea da una struttura, il cui indirizzo è specificato dall'argomento
+\param{termios\_p} che deve essere stata letta in precedenza con
+\func{tcgetattr}.
+
+Infine sempre da BSD è stata ripresa una funzione che consente di impostare il
+terminale in una modalità analoga alla cosiddetta modalità ``\textit{raw}'' di
+System V, in cui i dati in input vengono resi disponibili un carattere alla
+volta, e l'eco e tutte le interpretazioni dei caratteri in entrata e uscita
+sono disabilitate. La funzione è \funcd{cfmakeraw} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{void cfmakeraw(struct termios *termios\_p)}
+\fdesc{Imposta il terminale in modalità ``\textit{raw}''.}
+}
+
+{La funzione imposta solo i valori in \param{termios\_p}, e non
+ sono previste condizioni di errore.}
+\end{funcproto}
+
+Anche in questo caso la funzione si limita a preparare i valori che poi
+saranno impostato con una successiva chiamata a \func{tcsetattr}, in sostanza
+la funzione è equivalente a:
+\includecodesnip{listati/cfmakeraw.c}
+
+
+\subsection{La gestione della disciplina di linea.}
+\label{sec:term_line_discipline}
+
+Come illustrato dalla struttura riportata in fig.~\ref{fig:term_struct} tutti
+i terminali hanno un insieme di funzionalità comuni, che prevedono la presenza
+di code di ingresso ed uscita; in generale si fa riferimento a queste
+funzionalità con il nome di \textsl{disciplina di
+ linea}.\index{disciplina~di~linea} Lo standard POSIX prevede alcune funzioni
+che permettono di intervenire direttamente sulla gestione della disciplina di
+linea e sull'interazione fra i dati in ingresso ed uscita e le relative code.
+
+In generale tutte queste funzioni vengono considerate, dal punto di vista
+dell'accesso al terminale, come delle funzioni di scrittura, pertanto se usate
+da processi in background sul loro terminale di controllo provocano
+l'emissione di \signal{SIGTTOU}, come illustrato in
+sez.~\ref{sec:sess_ctrl_term}, con la stessa eccezione, già vista per
+\func{tcsetattr}, che quest'ultimo sia bloccato o ignorato dal processo
+chiamante.
+
+Una prima funzione, che è efficace solo in caso di terminali seriali
+asincroni, e non fa niente per tutti gli altri terminali, è
+\funcd{tcsendbreak}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{int tcsendbreak(int fd, int duration)}
+\fdesc{Genera una condizione di \textit{break}.}
+
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori \errval{EBADF} o \errval{ENOTTY}
+ nel loro significato generico.}
+\end{funcproto}
+
+La funzione invia un flusso di bit nulli, che genera una condizione di
+\textit{break}, sul terminale associato a \param{fd}. Un valore nullo
+di \param{duration} implica una durata del flusso fra 0.25 e 0.5 secondi, un
+valore diverso da zero implica una durata pari a \code{duration*T} dove
+\code{T} è un valore compreso fra 0.25 e 0.5 secondi. Lo standard POSIX
+specifica il comportamento solo nel caso si sia impostato un valore nullo
+per \param{duration}, il comportamento negli altri casi può dipendere
+dall'implementazione.
+
+Le altre funzioni previste dallo standard POSIX servono a controllare il
+comportamento dell'interazione fra le code associate al terminale e l'utente;
+la prima di queste è \funcd{tcdrain}, il cui prototipo è:
+
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{int tcdrain(int fd)}
+\fdesc{Attende lo svuotamento della coda di uscita.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà i valori \errval{EBADF} o \errval{ENOTTY}.}
+\end{funcproto}
+
+La funzione blocca il processo fino a che tutto l'output presente sulla coda
+di uscita non è stato trasmesso al terminale associato ad \param{fd}. % La
+ % funzione è un punto di cancellazione per i
+ % programmi multi-thread, in tal caso le
+ % chiamate devono essere protette con dei
+ % gestori di cancellazione.
+
+Una seconda funzione, \funcd{tcflush}, permette svuotare immediatamente le code
+di cancellando tutti i dati presenti al loro interno; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{int tcflush(int fd, int queue)}
+\fdesc{Cancella i dati presenti nelle code di ingresso o di uscita.} }
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà i valori \errval{EBADF} o \errval{ENOTTY}.}
+\end{funcproto}
+
+La funzione agisce sul terminale associato a \param{fd}, l'argomento
+\param{queue} permette di specificare su quale coda (ingresso, uscita o
+entrambe), operare. Esso può prendere i valori riportati in
+tab.~\ref{tab:sess_tcflush_queue}, nel caso si specifichi la coda di ingresso
+cancellerà i dati ricevuti ma non ancora letti, nel caso si specifichi la coda
+di uscita cancellerà i dati scritti ma non ancora trasmessi.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \constd{TCIFLUSH} & Cancella i dati sulla coda di ingresso.\\
+ \constd{TCOFLUSH} & Cancella i dati sulla coda di uscita. \\
+ \constd{TCIOFLUSH}& Cancella i dati su entrambe le code.\\
+ \hline
+ \end{tabular}
+ \caption{Possibili valori per l'argomento \param{queue} della
+ funzione \func{tcflush}.}
+ \label{tab:sess_tcflush_queue}
+\end{table}
+
+
+L'ultima funzione dell'interfaccia che interviene sulla disciplina di linea è
+\funcd{tcflow}, che viene usata per sospendere la trasmissione e la ricezione
+dei dati sul terminale; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{termios.h}
+\fdecl{int tcflow(int fd, int action)}
+\fdesc{Sospende e riavvia il flusso dei dati sul terminale.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà i valori \errval{EBADF} o \errval{ENOTTY}.}
+\end{funcproto}
+
+La funzione permette di controllare (interrompendo e facendo riprendere) il
+flusso dei dati fra il terminale ed il sistema sia in ingresso che in uscita.
+Il comportamento della funzione è regolato dall'argomento \param{action}, i
+cui possibili valori, e relativa azione eseguita dalla funzione, sono
+riportati in tab.~\ref{tab:sess_tcflow_action}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Azione}\\
+ \hline
+ \hline
+ \constd{TCOOFF}& Sospende l'output.\\
+ \constd{TCOON} & Riprende un output precedentemente sospeso.\\
+ \constd{TCIOFF}& Il sistema trasmette un carattere di STOP, che
+ fa interrompere la trasmissione dei dati dal terminale.\\
+ \constd{TCION} & Il sistema trasmette un carattere di START, che
+ fa riprendere la trasmissione dei dati dal terminale.\\
+ \hline
+ \end{tabular}
+ \caption{Possibili valori per l'argomento \param{action} della
+ funzione \func{tcflow}.}
+ \label{tab:sess_tcflow_action}
+\end{table}
+
+
+
+\subsection{Operare in \textsl{modo non canonico}}
+\label{sec:term_non_canonical}
+
+Operare con un terminale in modo canonico è relativamente semplice; basta
+eseguire una lettura e la funzione ritornerà quando il terminale avrà
+completato una linea di input. Non è detto che la linea sia letta interamente
+(si può aver richiesto un numero inferiore di byte) ma in ogni caso nessun
+dato verrà perso, e il resto della linea sarà letto alla chiamata successiva.
+
+Inoltre in modo canonico la gestione dei dati in ingresso è di norma eseguita
+direttamente dal kernel, che si incarica (a seconda di quanto impostato con le
+funzioni viste nei paragrafi precedenti) di cancellare i caratteri, bloccare e
+riavviare il flusso dei dati, terminare la linea quando viene ricevuti uno dei
+vari caratteri di terminazione (NL, EOL, EOL2, EOF).
+
+In modo non canonico è invece compito del programma gestire tutto quanto, i
+caratteri NL, EOL, EOL2, EOF, ERASE, KILL, CR, REPRINT non vengono
+interpretati automaticamente ed inoltre, non dividendo più l'input in linee,
+il sistema non ha più un limite definito su quando ritornare i dati ad un
+processo. Per questo motivo abbiamo visto che in \var{c\_cc} sono previsti due
+caratteri speciali, MIN e TIME (specificati dagli indici \const{VMIN} e
+\const{VTIME} in \var{c\_cc}) che dicono al sistema di ritornare da una
+\func{read} quando è stata letta una determinata quantità di dati o è passato
+un certo tempo.
+
+Come accennato nella relativa spiegazione in tab.~\ref{tab:sess_termios_cc},
+TIME e MIN non sono in realtà caratteri ma valori numerici. Il comportamento
+del sistema per un terminale in modalità non canonica prevede quattro casi
+distinti:
+\begin{description}
+\item[MIN$>0$, TIME$>0$] In questo caso MIN stabilisce il numero minimo di
+ caratteri desiderati e TIME un tempo di attesa, in decimi di secondo, fra un
+ carattere e l'altro. Una \func{read} ritorna se vengono ricevuti almeno MIN
+ caratteri prima della scadenza di TIME (MIN è solo un limite inferiore, se
+ la funzione ha richiesto un numero maggiore di caratteri ne possono essere
+ restituiti di più); se invece TIME scade vengono restituiti i byte ricevuti
+ fino ad allora (un carattere viene sempre letto, dato che il timer inizia a
+ scorrere solo dopo la ricezione del primo carattere).
+\item[MIN$>0$, TIME$=0$] Una \func{read} ritorna solo dopo che sono stati
+ ricevuti almeno MIN caratteri. Questo significa che una \func{read} può
+ bloccarsi indefinitamente.
+\item[MIN$=0$, TIME$>0$] In questo caso TIME indica un tempo di attesa dalla
+ chiamata di \func{read}, la funzione ritorna non appena viene ricevuto un
+ carattere o scade il tempo. Si noti che è possibile che \func{read} ritorni
+ con un valore nullo.
+\item[MIN$=0$, TIME$=0$] In questo caso una \func{read} ritorna immediatamente
+ restituendo tutti i caratteri ricevuti. Anche in questo caso può ritornare
+ con un valore nullo.
+\end{description}
+
+
+
+\section{La gestione dei terminali virtuali}
+\label{sec:sess_virtual_terminal}
+
+%
+% TODO terminali virtuali
+% Qui c'è da mettere tutta la parte sui terminali virtuali, e la gestione
+% degli stessi
+%
+
+Da fare.
+
+\subsection{I terminali virtuali}
+\label{sec:sess_pty}
+
+Qui vanno spiegati i terminali virtuali, \file{/dev/pty} e compagnia.
+% vedi man pts
+% vedi
+
+
+\subsection{Allocazione dei terminali virtuali}
+\label{sec:sess_openpty}