Controllo del terminale iniziato.
[gapil.git] / session.tex
index 10129fa70b7f24995a3b0262ce3ed71e126a2520..653ff75f175b3fe0fb0fce4ec4ff8acd510242fb 100644 (file)
@@ -891,12 +891,11 @@ disco e agli altri dispositivi.
 \subsection{L'architettura}
 \label{sec:term_design}
 
-
-I terminali sono una classe speciale di dispositivi a caratteri (si rammenti
-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 in
-grado di fare da terminale di controllo per una sessione), che comportano la
+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
@@ -924,13 +923,15 @@ connessioni di rete (ad esempio per trattare i dati inviati con \cmd{telnet} o
 % 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
+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, occorre però tenere conto delle loro
-caratteristiche specifiche, essi infatti prevedono due modalità di operazione,
+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
-prevedono dei comportamenti nettamente diversi.
+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
@@ -947,22 +948,90 @@ dati in linee n
 editor ad esempio) che necessitano di poter leggere un carattere alla volta e
 che gestiscono al loro interno i vari comandi.
 
-La struttura dell'I/O, come di solito viene gestito dal driver del terminale è
-mostrata in \secref{fig:term_struct}
+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}
+  \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
+\textit{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}
 
-L'I/O viene controllato attraverso una serie di attributi mantenuti per
-ciascun terminale in una struttura \var{termios}, i cui campi
+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}
@@ -972,16 +1041,189 @@ struct termios {
     tcflag_t c_oflag;      /* output modes */
     tcflag_t c_cflag;      /* control modes */
     tcflag_t c_lflag;      /* local modes */
-    cc_t c_cc[NCCS];       /* control chars */
+    cc_t c_cc[NCCS];       /* control characters */
 };
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \var{termios}, che identifica le proprietà di un
-    terminale.} 
+    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.
+
+Il primo flag, \var{c\_iflag}, o flag di input, controlla le modalità
+dell'ingresso dei dati 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}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Valore}& \textbf{Significato}\\
+    \hline
+    \hline
+    \macro{IGNBRK} & Ignora le condizioni di \textit{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} & Se si è impostato \macro{IGNBRK} un \textit{BREAK} viene
+                     comunque ignorato.  Altrimenti se \macro{BRKINT} è
+                     impostato il \textit{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} è
+                     impostato un \textit{BREAK} viene letto come un carattere
+                     \textit{NUL}, a meno che non sia settato \macro{PARMRK}
+                     nel qual caso viene letto come la sequenza di caratteri
+                     \texttt{0xFF 0x00 0x00}.\\
+    \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à. 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  \\ 
+    \macro{ISTRIP} & .\\
+    \macro{INLCR}  & .\\
+    \macro{IGNCR}  & .\\
+    \macro{ICRNL}  & .\\
+    \macro{IUCLC}  & .\\
+    \macro{IXON}   & .\\
+    \macro{IXANY}  & .\\
+    \macro{IXOFF}  & .\\
+    \macro{IMAXBEL}& .\\
+    \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 secondo flag, \var{c\_oflag}, o flag di output, controlla le modalità di
+output, 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}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Valore}& \textbf{Significato}\\
+    \hline
+    \hline
+    \macro{OPOST} & . \\
+    \macro{OLCUC} & .\\
+    \macro{ONLCR} & .\\
+    \macro{OCRNL} & .\\
+    \macro{ONOCR} & .\\
+    \macro{ONLRET} & .\\
+    \macro{OFILL} & . \\
+    \macro{OFDEL} & .\\
+    \macro{NLDLY} & .\\
+    \macro{CRDLY} & .\\
+    \macro{TABDLY} & .\\
+    \macro{BSDLY} & .\\
+    \macro{VTDLY} & .\\
+    \macro{FFDLY} & .\\
+    \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 terzo flag, \var{c\_cflag}, o flag di controllo è legato al funzionamento
+delle linee seriali permette di impostarne varie caratteristiche, come il
+numero di bit di stop, i settaggi della parità, il funzionamento del controllo
+di flusso; un elenco dei vari bit, del loro significato e delle costanti
+utilizzate per identificarli è riportato in \tabref{tab:sess_termios_cflag}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Valore}& \textbf{Significato}\\
+    \hline
+    \hline
+    \macro{CBAUD} & . \\
+    \macro{CBAUDEX} & .\\
+    \macro{CSIZE} & .\\
+    \macro{CSTOPB} & .\\
+    \macro{CREAD} & .\\
+    \macro{PARENB} & .\\
+    \macro{PARODD} & . \\
+    \macro{HUPCL} & .\\
+    \macro{CLOCAL} & .\\
+    \macro{LOBLK} & .\\
+    \macro{CIBAUD} & .\\
+    \macro{CRTSCTS} & .\\
+    \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 quarto flag, \var{c\_lflag}, o flag locale, serve per modificare il
+funzionamento dell'interfaccia fra il driver e l'utente, come abilitare l'eco,
+controllare l'emissione dei segnali generati dal terminale, attivare i
+caratteri per il job control; un elenco dei vari bit, del loro significato e
+delle costanti utilizzate per identificarli è riportato in
+\tabref{tab:sess_termios_lflag}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Valore}& \textbf{Significato}\\
+    \hline
+    \hline
+    \macro{ISIG} & . \\
+    \macro{ICANON} & .\\
+    \macro{XCASE} & .\\
+    \macro{ECHO} & .\\
+    \macro{ECHOE} & .\\
+    \macro{ECHOK} & .\\
+    \macro{ECHONL} & . \\
+    \macro{ECHOPRT} & .\\
+    \macro{ECHOKE} & .\\
+    \macro{DEFECHO} & .\\
+    \macro{FLUSHO} & .\\
+    \macro{NOFLSH} & .\\
+    \macro{TOSTOP} & .\\
+    \macro{PENDIN} & .\\
+    \macro{IEXTEN} & .\\
+    \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}
+
+
+
+
 
 
 \subsection{Il \textsl{modo canonico}}