- \chapter{Sessioni di lavoro e terminali}
+\chapter{Terminali e sessioni di lavoro}
\label{cha:session}
-Esamineremo in questo capitolo i concetti base del sistema delle sessioni di
-lavoro, vale a dire il metodo con cui il kernel gestisce l'accesso concorrente
-al sistema da parte di più utenti, permettendo loro di eseguire più programmi
-in contemporanea. Nella seconda parte del capitolo tratteremo poi il
-funzionamento dell'I/O su terminale, e delle varie peculiarità che esso viene
-ad assumere a causa del suo stretto legame con le modalità di accesso al
-sistema da parte degli utenti.
+I terminali per lungo tempo tempo sono stati l'unico modo per accedere al
+sistema, per questo anche oggi che esistono molte altre interfacce, essi
+continuano a coprire un ruolo particolare, restando strettamente legati al
+funzionamento dell'interfaccia a linea di comando.
+
+Mella prima parte del capitolo esamineremo i concetti base del sistema delle
+sessioni di lavoro, vale a dire il metodo con cui il kernel permette ad un
+utente di gestire le capacità multitiasking del sistema, permettendo di
+eseguire più programmi in contemporanea. Nella seconda parte del capitolo
+tratteremo poi il funzionamento dell'I/O su terminale, e delle varie
+peculiarità che esso viene ad assumere a causa del suo stretto legame con il
+suo uso come interfaccia di accesso al sistema da parte degli utenti.
\section{Il \textit{job control}}
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}.}
+dispositivo.
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
si trova in \cite{LinDevDri}, nel quarto capitolo.}
Il servizio permette poi di trattare i vari messaggi classificandoli
-attraverso due indici; il primo, chiamato \textit{facility}, indica quale
-categoria di demone ha emesso il messaggio, ed è organizzato in sottosistemi
-(kernel, posta elettronica, demoni di stampa, ecc.), il secondo, chiamato
-\textit{priority}, identifica l'importanza del messaggio. Il sistema di
-\textit{syslog} provvede poi a riportare i messaggi all'amministratore
-attraverso differenti meccanismi come:
+attraverso due indici; il primo, chiamato \textit{facility}, suddivide in
+diverse categorie i vari demoni in modo di raggruppare i messaggi 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 di \textit{syslog} attraverso \cmd{syslogd} provvede poi a
+riportare i messaggi all'amministratore attraverso una serie differenti
+meccanismi come:
\begin{itemize*}
\item scrivere sulla console.
\item inviare via mail ad uno specifico utente.
\cmd{syslogd}).
Le \acr{glibc} definiscono una serie di funzioni standard con cui un processo
-può accedere in maniera generica al servizio di 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.
+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 è \func{openlog}, che apre una
connessione al servizio di \textit{syslog}; essa in generale non è necessaria
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.
+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.
specificato con un OR aritmetico.
\begin{table}[htb]
-\centering
-\begin{tabular}[c]{|l|p{8cm}|}
-\hline
-\textbf{Valore}& \textbf{Significato}\\
-\hline
-\hline
-\macro{LOG\_AUTH} & Messaggi relativi ad autenticazione e sicurezza,
- obsoleto, è sostituito da \macro{LOG\_AUTHPRIV}. \\
-\macro{LOG\_AUTHPRIV} & Sostituisce \macro{LOG\_AUTH}.\\
-\macro{LOG\_CRON} & Messaggi dei demoni di gestione dei comandi
- programmati (\cmd{cron} e \cmd{at}).\\
-\macro{LOG\_DAEMON} & Demoni di sistema.\\
-\macro{LOG\_FTP} & Server FTP.\\
-\macro{LOG\_KERN} & Messaggi del kernel\\
-\macro{LOG\_LOCAL0} & Riservato all'amministratore per uso locale\\
---- & \\
-\macro{LOG\_LOCAL7} & Riservato all'amministratore per uso locale\\
-\macro{LOG\_LPR} & Messaggi del sistema di gestione delle stampanti \\
-\macro{LOG\_MAIL} & Messaggi del sistema di posta elettronica\\
-\macro{LOG\_NEWS} & Messaggi del sistema di gestione delle news (USENET) \\
-\macro{LOG\_SYSLOG} & Messaggi generati dallo stesso \cmd{syslogd}\\
-\macro{LOG\_USER} & Messaggi generici a livello utente\\
-\macro{LOG\_UUCP} & Messaggi del sistema UUCP\\
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{LOG\_AUTH} & Messaggi relativi ad autenticazione e sicurezza,
+ obsoleto, è sostituito da \macro{LOG\_AUTHPRIV}. \\
+ \macro{LOG\_AUTHPRIV} & Sostituisce \macro{LOG\_AUTH}.\\
+ \macro{LOG\_CRON} & Messaggi dei demoni di gestione dei comandi
+ programmati (\cmd{cron} e \cmd{at}).\\
+ \macro{LOG\_DAEMON} & Demoni di sistema.\\
+ \macro{LOG\_FTP} & Server FTP.\\
+ \macro{LOG\_KERN} & Messaggi del kernel\\
+ \macro{LOG\_LOCAL0} & Riservato all'amministratore per uso locale\\
+ --- & \\
+ \macro{LOG\_LOCAL7} & Riservato all'amministratore per uso locale\\
+ \macro{LOG\_LPR} & Messaggi del sistema di gestione delle stampanti \\
+ \macro{LOG\_MAIL} & Messaggi del sistema di posta elettronica\\
+ \macro{LOG\_NEWS} & Messaggi del sistema di gestione delle news
+ (USENET) \\
+ \macro{LOG\_SYSLOG} & Messaggi generati dallo stesso \cmd{syslogd}\\
+ \macro{LOG\_USER} & Messaggi generici a livello utente\\
+ \macro{LOG\_UUCP} & Messaggi del sistema UUCP\\
\hline
\end{tabular}
\caption{Valori possibili per l'argomento \param{facility} di \func{openlog}.}
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, anch'esso viene specificato come maschera binaria
-composta con un OR aritmetico di una qualunque delle costanti riportate in
+scriveranno i messaggi, esso viene specificato come maschera binaria composta
+con un OR aritmetico di una qualunque delle costanti riportate in
\tabref{tab:sess_openlog_option}.
\begin{table}[htb]
+ \footnotesize
\centering
\begin{tabular}[c]{|l|p{8cm}|}
\hline
con la maschera binaria delle costanti di \tabref{tab:sess_syslog_facility}.
\begin{table}[htb]
-\centering
-\begin{tabular}[c]{|l|p{8cm}|}
-\hline
-\textbf{Valore}& \textbf{Significato}\\
-\hline
-\hline
-\macro{LOG\_EMERG} & Il sistema è inutilizzabile. \\
-\macro{LOG\_ALERT} & C'è una emergenza che richiede intervento immediato.\\
-\macro{LOG\_CRIT} & Si è in una condizione critica.\\
-\macro{LOG\_ERR} & Si è in una condizione di errore.\\
-\macro{LOG\_WARNING} & Messaggio di avvertimento.\\
-\macro{LOG\_NOTICE} & Notizia significativa relativa al comportamento.\\
-\macro{LOG\_INFO} & Messaggio informativo. \\
-\macro{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}
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{LOG\_EMERG} & Il sistema è inutilizzabile. \\
+ \macro{LOG\_ALERT} & C'è una emergenza che richiede intervento
+ immediato.\\
+ \macro{LOG\_CRIT} & Si è in una condizione critica.\\
+ \macro{LOG\_ERR} & Si è in una condizione di errore.\\
+ \macro{LOG\_WARNING} & Messaggio di avvertimento.\\
+ \macro{LOG\_NOTICE} & Notizia significativa relativa al comportamento.\\
+ \macro{LOG\_INFO} & Messaggio informativo. \\
+ \macro{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}
Una ulteriore funzione, \func{setlogmask}, permette di filtrare
preliminarmente i messaggi in base alla loro priorità; il suo prototipo è:
\begin{prototype}{syslog.h}
- {int setlogmask(int mask)}
+{int setlogmask(int mask)}
Imposta la maschera dei log al valore specificato.
\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.
+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}
+\label{sec:term_design}
+
+I terminali sono una classe speciale di dispositivi a caratteri (si ricordi la
+classificazione di \secref{sec:file_file_types}); un terminale ha infatti una
+caratteristica che lo contraddistingue da un qualunque altro dispositivo, e
+cioè che è destinato a gestire l'interazione con un utente (deve essere cioè
+in grado di fare da terminale di controllo per una sessione), che comporta la
+presenza di ulteriori capacità.
+
+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}).
+
+% In generale tutti i terminali hanno un insieme di funzionalità comuni, che
+% vengono chiamate \textsl{discipline di linea}; esse contraddistinguono le
+% modalità con cui il kernel manipola (ad esempio la reazione ad un carattere di
+% cancellazione per la tastiera, o la gestione della linea tramite PPP o SLIP) i
+% dati grezzi che vengono immessi sul dispositivo;
+
+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 scriveno 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
+comportano dei comportamenti nettamente diversi.
+
+La modalità preimpostata all'apertura del terminale è quella canonica, in cui
+le operazioni di lettura vengono sempre effettuate assemblando i dati in una
+linea;\footnote{per cui 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à completa e la funzione ritornerà.} ed in cui alcuni caratteri
+vengono interpretati per compiere operazioni (come la generazione dei segnali
+illustrati in \secref{sec:sig_job_control}), questa di norma è la modalità in
+cui funziona 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 dai programmi (gli
+editor ad esempio) che necessitano di poter leggere un carattere alla volta e
+che gestiscono al loro interno i vari comandi.
+
+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 da un driver apposito, la cui struttura generica è
+mostrata in \secref{fig:term_struct}. Ad un terminale sono sempre associate
+due code per gestire l'input e l'output, che ne implementano una
+bufferizzazione\footnote{completamente indipendente dalla eventuale ulteriore
+ bufferizzazione fornita dall'interfaccia standard dei file.} all'interno del
+kernel.
+
+\begin{figure}[htb]
+ \centering \includegraphics[width=13cm]{img/term_struct}
+ \caption{Struttura interna generica di un driver per un terminale.}
+ \label{fig:term_struct}
+\end{figure}
+
+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 \macro{MAX\_INPUT}, 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 driver 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
+driver 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 il modo canonico i caratteri in ingresso restano nella coda
+fintanto che non viene ricevuto un a capo; un'altra costante,
+\macro{MAX\_CANON}, specifica la dimensione massima di una riga in modo
+canonico.
+
+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 driver 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 dall'inizio si è posto il problema di come
+gestire le caratteristiche specifiche dei terminali; storicamente i vari
+dialetti di Unix hanno utilizzato diverse funzioni, alla fine con POSIX.1, è
+stata effettuata una standardizzazione, unificando le differenze fra BSD e
+System V in una unica interfaccia, che è quella usata dal Linux.
+
+Alcune di queste funzioni prendono come argomento un file descriptor (in
+origine molte operazioni venivano effettuate con \func{ioctl}), ma ovviamente
+possono essere usate solo con file che corrispondano effettivamente ad un
+terminale; questo che può essere verificato utilizzando la funzione
+\func{isatty}, il cui prototipo è:
+\begin{prototype}{unistd.h}{int isatty(int desc)}
+
+ Controlla se il file descriptor \param{desc} è un terminale.
+
+\bodydesc{La funzione restituisce 1 se \param{desc} è connesso ad un
+ terminale, 0 altrimenti.}
+\end{prototype}
+
+Un'altra funzione che fornisce informazioni su un terminale è \func{ttyname},
+che permette anche di ottenere il nome del terminale associato ad un file
+descriptor; il suo prototipo è:
+\begin{prototype}{unistd.h}{char *ttyname(int desc)}
+
+ Restituisce il nome di un terminale.
+
+ \bodydesc{La funzione restituisce il puntatore alla stringa contenente il
+ nome del terminale associato \param{desc} e \macro{NULL} in caso di
+ errore.}
+\end{prototype}
+
+Si tenga presente che la funzione restituisce un indirizzo di dati statici,
+che pertanto possono essere sovrascritti da successive chiamate. La funzione è
+prevista da POSIX.1, che non definisce \func{isatty}.
+
+I vari attributi vengono mantenuti per ciascun terminale in una struttura
+\var{termios}, (la cui definizione è in \figref{fig:term_termios}), usata
+dalle varie funzioni dell'interfaccia. In \figref{fig:term_termios} si sono
+riportati solo i campi previsti dallo standard POSIX.1, in genere le varie
+implementazioni ne aggiungono degli altri (in Linux e BSD ci sono quelli che
+specificano le velocità della linea) per mantenere ulteriori informazioni.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}[labelstep=0]{}
+struct termios {
+ tcflag_t c_iflag; /* input modes */
+ tcflag_t c_oflag; /* output modes */
+ tcflag_t c_cflag; /* control modes */
+ tcflag_t c_lflag; /* local modes */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \var{termios}, che identifica le proprietà di un
+ terminale.}
+ \label{fig:term_termios}
+\end{figure}
+
+I primi quattro campi sono quattro flag che controllano il comportamento del
+terminale; essi sono realizzati come maschera binaria, pertanto il tipo
+\type{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{13cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{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.\\
+ \macro{IGNPAR} & Ignora gli errori di parità, il carattere viene passato
+ come ricevuto. Ha senso solo se si è impostato
+ \macro{INPCK}.\\
+ \macro{PARMRK} & Controlla come vengono riportati gli errori di parità. Ha
+ senso solo se \macro{INPCK} è impostato e \macro{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 \macro{ISTRIP}
+ non è settato, per evitare ambiguità esso viene sempre
+ riportato come \texttt{0xFF 0xFF}.\\
+ \macro{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.\\
+ \macro{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. \\
+ \macro{BRKINT} & Controlla la reazione ad un BREAK quando
+ \macro{IGNBRK} non è impostato. Se \macro{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 \macro{SIGINT} ai
+ processi di quest'ultimo. Se invece \macro{BRKINT} non è
+ impostato un BREAK viene letto come un carattere
+ NUL, a meno che non sia settato \macro{PARMRK}
+ nel qual caso viene letto come la sequenza di caratteri
+ \texttt{0xFF 0x00 0x00}.\\
+ \macro{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'|). \\
+ \macro{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. \\
+ \macro{INLCR} & Se impostato il carattere di a capo
+ (\verb|'\n'|) viene automaticamente trasformato in un
+ ritorno carello (\verb|'\r'|).\\
+ \macro{IUCLC} & Se impostato trasforma i caratteri maiuscoli dal
+ terminale in minuscoli sull'ingresso (opzione non
+ POSIX).\\
+ \macro{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.\\
+ \macro{IXANY} & Se impostato con il controllo di flusso permette a
+ qualunque carattere di far ripartire l'output bloccato da
+ un carattere di STOP.\\
+ \macro{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. \\
+ \macro{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 settato (è una estensione
+ BSD). \\
+ \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
+\tabref{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.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{13cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{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).\\
+ \macro{OCRNL} & Se impostato converte automaticamente il carattere di a
+ capo (NL) nella coppia di caratteri ritorno carrello, a
+ capo (CR-NL).\\
+ \macro{OLCUC} & Se impostato trasforma i caratteri minuscoli in ingresso
+ in caratteri maiuscoli sull'uscita (non previsto da
+ POSIX.1).\\
+ \macro{ONLCR} & Se impostato converte automaticamente il carattere di a
+ capo (NL) in un carattere di ritorno carrello (CR).\\
+ \macro{ONOCR} & Se impostato converte il carattere di ritorno carrello
+ (CR) nella coppia di caratteri CR-NL.\\
+ \macro{ONLRET}& Se impostato rimuove dall'output il carattere di ritorno
+ carrello (CR).\\
+ \macro{OFILL} & Se impostato in caso di ritardo sulla linea invia dei
+ caratteri di riempimento invece di attendere.\\
+ \macro{OFDEL} & Se impostato il carattere di riempimento è DEL
+ (\texttt{0x3F}), invece che NUL (\texttt{0x00}).\\
+ \macro{NLDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di a capo (NL), i valori possibili sono
+ \macro{NL0} o \macro{NL1}.\\
+ \macro{CRDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere ritorno carrello (CR), i valori possibili sono
+ \macro{CR0}, \macro{CR1}, \macro{CR2} o \macro{CR3}.\\
+ \macro{TABDLY}& Maschera per i bit che indicano il ritardo per il
+ carattere di tabulazione, i valori possibili sono
+ \macro{TAB0}, \macro{TAB1}, \macro{TAB2} o \macro{TAB3}.\\
+ \macro{BSDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di ritorno indietro (\textit{backspace}), i
+ valori possibili sono \macro{BS0} o \macro{BS1}.\\
+ \macro{VTDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di tabulazione verticale, i valori possibili sono
+ \macro{VT0} o \macro{VT1}.\\
+ \macro{FFDLY} & Maschera per i bit che indicano il ritardo per il
+ carattere di pagina nuova (\textit{form feed}), i valori
+ possibili sono \macro{FF0} o \macro{FF1}.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative dei vari bit del flag di controllo
+ \var{c\_oflag} delle modalità di outputdi un terminale.}
+ \label{tab:sess_termios_oflag}
+\end{table}
+
+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
+\tabref{tab:sess_termios_oflag}.
+
+Si noti come alcuni dei valori riportati in \tabref{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:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+ c_oflag &= (~CRDLY);
+ c_oflag |= CR1;
+\end{lstlisting}
+che prima cancella i bit della maschera in questione e poi setta il valore.
+
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{13cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{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
+ \macro{O\_NOBLOCK} si bloccherà il processo finché
+ non si è stabilita una connessione con il modem; inoltre
+ se viene rilevata una disconessione viene inviato un
+ \macro{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
+ \macro{EIO}. \\
+ \macro{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.\\
+ \macro{CREAD} & Se è impostato si può leggere l'input del terminale,
+ altrimenti i caratteri in ingresso vengono scartati
+ quando arrivano.\\
+ \macro{CSTOPB} & Se impostato vengono usati due bit di stop sulla linea
+ seriale, se non impostato ne viene usato soltanto uno.\\
+ \macro{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
+ \tabref{tab:sess_termios_iflag}. Se non è impostato i bit
+ di parità non vengono
+ generati e i caratteri non vengono controllati.\\
+ \macro{PARODD} & Ha senso solo se è attivo anche \macro{PARENB}. Se
+ impostato viene usata una parità è dispari, altrimenti
+ viene usata una parità pari.\\
+ \macro{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 \macro{CS5}, \macro{CS6},
+ \macro{CS7} e \macro{CS8}
+ corripondenti ad un analogo numero di bit.\\
+ \macro{CBAUD} & Maschera dei bit (4+1) usati per impostare della velocità
+ della linea (il \textit{baud rate}) in ingresso.
+ In Linux non è implementato in quanto viene
+ usato un apposito campo di \var{termios}.\\
+ \macro{CBAUDEX}& Bit aggiuntivo per l'impostazione della velocità della
+ linea, per le stesse motivazioni del precedente non è
+ implementato in Linux.\\
+ \macro{CIBAUD} & Maschera dei bit della velocità della linea in
+ ingresso. Analogo a \macro{CBAUD}, anch'esso in Linux è
+ mantenuto in un apposito campo di \var{termios}. \\
+ \macro{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, i settaggi
+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
+\tabref{tab:sess_termios_cflag}.
+
+I valori di questo flag sono molto specifici, e completamente indirizzati al
+controllo di un terminale mantenuto su una linea seriale; essi pertanto non
+hanno nessuna rilevanza per i terminali che usano un'altra interfaccia, come
+le console virtuali e gli pseudo-terminali usati dalle connessioni di rete.
+
+Inoltre alcuni valori 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 \var{termios} (non mostrati in
+\secref{fig:term_termios}).
+
+\begin{table}[b!ht]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{13cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{ICANON} & Se impostato il terminale opera in modo canonico,
+ altrimenti opera in modo non canonico.\\
+ \macro{ECHO} & Se è impostato viene attivato l'eco dei caratteri in
+ input sull'output del terminale.\\
+ \macro{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). \\
+ \macro{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 \verb|\| seguito dal carattere
+ cancellato, e così via in caso di successive
+ cancellazioni, quando si riprende ad immettere carattere
+ normali prima verrà stampata una \texttt{/}.\\
+ \macro{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. \\
+ \macro{ECHOKE} & Se impostato abilita il trattamento della visualizzazione
+ del carattere KILL cancellando i caratteri precedenti
+ nella linea secondo le modalità specificate dai valori di
+ \macro{ECHOE} e \macro{ECHOPRT}.\\
+ \macro{ECHONL} & Se impostato viene effettuato l'eco di un a
+ capo (\verb|\n|) anche se non è stato impostato
+ \macro{ECHO}. \\
+ \macro{ECHOCTL}& Se impostato insieme ad \macro{ECHO} i caratteri di
+ controllo ASCII (tranne TAB, NL, START, e STOP) sono
+ mostrati nella forma che prepende un \verb|^| 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).\\
+ \macro{ISIG} & Se impostato abilita il riconoscimento dei caratteri
+ INTR, QUIT, e SUSP generando il relativo segnale.\\
+ \macro{IEXTEN} & Abilita alcune estensioni previste dalla
+ implementazione. Deve essere impostato perché caratteri
+ speciali come EOL2, LNEXT, REPRINT e WERASE possano
+ essere interpretati. \\
+ \macro{NOFLSH} & Se impostato disabilita lo scarico delle code di ingresso
+ e uscita quando vengono emessi i segnali \macro{SIGINT},
+ \macro{SIGQUIT} and \macro{SIGSUSP}.\\
+ \macro{TOSTOP} & Se abilitato, con il supporto per il job control presente,
+ genera il segnale \macro{SIGTTOU} per un processo in
+ background che cerca di scrivere sul terminale.\\
+ \macro{XCASE} & Se settato il terminale funziona solo con le
+ maiuscole. L'input è convertito in minuscole tranne per i
+ caratteri preceduti da una \verb|\|. In output le
+ maiuscole sono precedute da una \verb|\| e le minuscole
+ convertite in maiuscole.\\
+ \macro{DEFECHO}& Se impostate effettua l'eco solo se c'è un processo in
+ lettura.\\
+ \macro{FLUSHO} & Effettua la cancellazione della coda di uscita. Viene
+ attivato dal carattere DISCARD. Non è supportato in
+ Linux.\\
+ \macro{PENDIN} & Indica che la linea deve essere ristampata, viene
+ attivato dal carattere REPRINT e resta attivo fino alla
+ fine della ristampa. Non è supportato in Linux.\\
+ \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 \tabref{tab:sess_termios_lflag}.
+
+Si tenga presente che i flag che riguardano le modalità di eco dei caratteri
+(\macro{ECHOE}, \macro{ECHOPRT}, \macro{ECHOK}, \macro{ECHOKE},
+\macro{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 \macro{ICANON}.
+
+Con i terminali odierni l'unico flag con cui probabilmente si può avere a che
+fare è questo, che è l'unico che concerne le caratteristiche generiche comuni
+a tutti i terminali.
+
+Per impostare tutti questi flag lo standard POSIX prevede due funzioni:
+\func{tcgetattr} e \func{tcsetattr}; entrambe prendono come parametro un
+puntatore ad struttura \var{termios} che deve essere oportunamente
+inizializzata, il loro prototipo è:
+\begin{functions}
+ \headdecl{unistd.h}
+ \headdecl{termios.h}
+ \funcdecl{int tcgetattr(int fd, struct termios *termios\_p)}
+ Legge il valore delle impostazioni di un terminale.
+
+ \funcdecl{int tcsetattr(int fd, int optional\_actions, struct termios
+ *termios\_p)}
+ Scrive le impostazioni di un terminale.
+
+ \bodydesc{Entrambe le funzioni restituiscono 0 in caso di successo e -1 in
+ caso di errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\macro{EINTR}] La funzione è stata interrotta.
+ \end{errlist}
+ ed inoltre \macro{EBADF}, \macro{ENOTTY} ed \macro{EINVAL}.
+ }
+\end{functions}
+
+Le funzioni operano sul terminale identificato dal file descriptor \param{fd}
+utilizzando la struttura specificata dal puntatore \param{termios\_p} per lo
+scambio dei dati. Come già accennato i valori di ciascun bit devono essere
+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 \figref{fig:term_set_attr} si è riportato il codice delle due funzioni
+\func{SetTermAttr} e \func{UnSetTermAttr} che possono essere usate
+rispettivamente per impostare o rimuovere un qualunque bit di \var{c\_lflag},
+con le dovute precauzioni. Il codice di entrambe le funzioni può essere
+trovato nel file \file{SetTermAttr.c} dei sorgenti allegati.
+
+\begin{figure}[!htb]
+ \footnotesize
+ \begin{lstlisting}{}
+#include <unistd.h>
+#include <termios.h>
+#include <errno.h>
+
+int SetTermAttr(int fd, tcflag_t flag)
+{
+ struct termios values;
+ int res;
+
+ res = tcgetattr (desc, &values);
+ if (res) {
+ perror("Cannot get attributes");
+ return res;
+ }
+ values.c_lflag |= flag;
+ res = tcsetattr (desc, TCSANOW, &values);
+ if (res) {
+ perror("Cannot set attributes");
+ return res;
+ }
+ return 0;
+}
+int UnSetTermAttr(int fd, tcflag_t flag)
+{
+ struct termios values;
+ int res;
+
+ res = tcgetattr (desc, &values);
+ if (res) {
+ perror("Cannot get attributes");
+ return res;
+ }
+ values.c_lflag &= (~flag);
+ res = tcsetattr (desc, TCSANOW, &values);
+ if (res) {
+ perror("Cannot set attributes");
+ return res;
+ }
+ return 0;
+}
+ \end{lstlisting}
+ \caption{Codice delle funzioni \func{SetTermAttr} e \func{UnSetTermAttr} per
+ impostare o rimuovere uno dei flag di controllo locale del terminale.}
+ \label{fig:term_set_attr}
+\end{figure}
+
+La prima funzione provvede ad impostare il bit specificato dall'argomento
+\param{flag}; prima si leggono i valori correnti (\texttt{\small 10}) con
+\func{tcgetattr}, uscendo con un messaggio in caso di errore (\texttt{\small
+ 11--14}), poi si provvede a impostare solo i bit richiesti (possono essere
+più di uno) con un OR binario (\texttt{\small 15}); infine si scrive il nuovo
+valore modificato con \func{tcsetattr} (\texttt{\small 16}), notificando un
+eventuale errore (\texttt{\small 11--14}) o uscendo normalmente.
+
+La seconda funzione è identica alla prima, solo che in questo caso
+(\texttt{\small 33}) si rimuovono i bit specificati dall'argomento
+\param{flag} usando un AND binario del valore negato.
+
+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
+\ref{tab:sess_tcsetattr_option}; di norma (come fatto per le due funzioni di
+esempio) si usa sempre \macro{TCSANOW}, le altre opzioni possono essere utili
+qualora si cambino i parametri di output.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{13cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{TCSANOW} & Esegue i cambiamenti in maniera immediata. \\
+ \macro{TCSADRAIN}& I cambiamenti vengono eseguiti dopo aver atteso che
+ tutto l'output presente sulle code è stato scritto. \\
+ \macro{TCSAFLUSH}& È identico a \macro{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}
+
+Infine occorre tenere presente che \func{tcsetattr} ritorna con successo anche
+se uno qualunque 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
+
+\subsection{Il \textsl{modo canonico}}
+\label{sec:term_canonic_mode}
+
+Il modo canonico
+
+
+\subsection{Il \textsl{modo non canonico}}
+\label{sec:term_noncanonic_mode}
+
+Il modo non canonico