correzioni all'allocazione dei pid, piu` una lunga serie di funzioni
authorSimone Piccardi <piccardi@gnulinux.it>
Thu, 10 Oct 2002 18:35:02 +0000 (18:35 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Thu, 10 Oct 2002 18:35:02 +0000 (18:35 +0000)
relative all'uso dei terminali

prochand.tex
session.tex

index 5432fa6bc42e28db2b3fa07798acf295c062d960..af655984f8244982e2b9817928cac9bd9ab753e7 100644 (file)
@@ -120,7 +120,7 @@ contiene tutte le informazioni rilevanti per quel processo. Tutte le strutture
 usate a questo scopo sono dichiarate nell'header file \file{linux/sched.h}, ed
 uno schema semplificato, che riporta la struttura delle principali informazioni
 contenute nella \type{task\_struct} (che in seguito incontreremo a più
-riprese), è mostrato in \nfig.
+riprese), è mostrato in \figref{fig:proc_task_struct}.
 
 \begin{figure}[htb]
   \centering
@@ -219,12 +219,14 @@ Il \acr{pid} viene assegnato in forma progressiva ogni volta che un nuovo
 processo viene creato, fino ad un limite che, essendo il \acr{pid} un numero
 positivo memorizzato in un intero a 16 bit, arriva ad un massimo di 32767.
 Oltre questo valore l'assegnazione riparte dal numero più basso disponibile a
-partire da un minimo di 300,\footnote{questi valori sono definiti dalla macro
-  \macro{PID\_MAX} in \file{threads.h} e direttamente in \file{fork.c} nei
-  sorgenti del kernel.} che serve a riservare i \acr{pid} più bassi ai processi
-eseguiti dal direttamente dal kernel.  Per questo motivo, come visto in
-\secref{sec:proc_hierarchy}, il processo di avvio (\cmd{init}) ha sempre il
-\acr{pid} uguale a uno.
+partire da un minimo di 300,\footnote{questi valori, fino al kernel 2.4.x,
+  sono definiti dalla macro \macro{PID\_MAX} in \file{threads.h} e
+  direttamente in \file{fork.c}, con il kernel 2.5.x e la nuova interfaccia
+  per i thread creata da Ingo Molnar anche il meccanismo di allocazione dei
+  \acr{pid} è stato modificato.} che serve a riservare i \acr{pid} più bassi
+ai processi eseguiti dal direttamente dal kernel.  Per questo motivo, come
+visto in \secref{sec:proc_hierarchy}, il processo di avvio (\cmd{init}) ha
+sempre il \acr{pid} uguale a uno.
 
 Tutti i processi inoltre memorizzano anche il \acr{pid} del genitore da cui
 sono stati creati, questo viene chiamato in genere \acr{ppid} (da
@@ -1883,6 +1885,7 @@ sia la sua priorit
 fintanto che esso si trova in uno qualunque degli altri stati.
 
 \begin{table}[htb]
+  \footnotesize
   \centering
   \begin{tabular}[c]{|p{2.8cm}|c|p{10cm}|}
     \hline
index 80e73394504f08e6e97d86eeccc27023465441b0..ef1c26a67d197b852bfcd3fb8bf0e1773774dc3e 100644 (file)
@@ -6,9 +6,9 @@ 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
+Nella 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
+utente di gestire le capacità multitasking 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
@@ -593,7 +593,7 @@ corrispondenza dell'uscita del leader di sessione).
 Per questo motivo un programma che deve funzionare come demone deve sempre
 prendere autonomamente i provvedimenti opportuni (come distaccarsi dal
 terminale e dalla sessione) ad impedire eventuali interferenze da parte del
-sistema del \textit{job contol}; questi sono riassunti in una lista di
+sistema del \textit{job control}; questi sono riassunti in una lista di
 prescrizioni\footnote{ad esempio sia Stevens in \cite{APUE}, che la
   \textit{Unix Programming FAQ} \cite{UnixFAQ} ne riportano di sostanzialmente
   identiche.} da seguire quando si scrive un demone.
@@ -796,7 +796,7 @@ con un OR aritmetico di una qualunque delle costanti riportate in
 \end{table}
 
 La funzione che si usa per generare un messaggio è \func{syslog}, dato che
-l'uso di \func{openlog} è ozionale, sarà quest'ultima a provvede a chiamare la
+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} è nullo). Il suo prototipo è:
 \begin{prototype}{syslog.h}
@@ -917,14 +917,8 @@ 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
+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
@@ -1107,7 +1101,7 @@ modificare i bit su cui non si interviene.
                      input. \\
     \macro{INLCR}  & Se impostato il carattere di a capo
                      (\verb|'\n'|) viene automaticamente trasformato in un
-                     ritorno carello (\verb|'\r'|).\\
+                     ritorno carrello (\verb|'\r'|).\\
     \macro{IUCLC}  & Se impostato trasforma i caratteri maiuscoli dal
                      terminale in minuscoli sull'ingresso (opzione non 
                      POSIX).\\
@@ -1199,7 +1193,7 @@ pseudo-terminali usati nelle connessioni di rete.
     \hline
   \end{tabular}
   \caption{Costanti identificative dei vari bit del flag di controllo
-    \var{c\_oflag} delle modalità di outputdi un terminale.}
+    \var{c\_oflag} delle modalità di output di un terminale.}
   \label{tab:sess_termios_oflag}
 \end{table}
 
@@ -1273,7 +1267,7 @@ valore.
                      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.\\
+                     corrispondenti 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 
@@ -1395,7 +1389,10 @@ Il quarto flag, mantenuto nel campo \var{c\_lflag}, 
 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}. 
+riportato in \tabref{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
 (\macro{ECHOE}, \macro{ECHOPRT}, \macro{ECHOK}, \macro{ECHOKE},
@@ -1404,14 +1401,111 @@ riconoscimento dei vari caratteri dipende dalla modalit
 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.
+Oltre ai vari flag per gestire le varie caratteristiche dei terminali,
+\var{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 \macro{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.}
 
-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{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|c|c|p{9cm}|}
+    \hline
+    \textbf{Indice} & \textbf{Valore}&\textbf{Codice} & \textbf{Funzione}\\
+    \hline
+    \hline
+    \macro{VINTR}   &\texttt{0x03}&(\verb|C-c|)& Carattere di interrupt, 
+                                                 provoca l'emissione di 
+                                                 \macro{SIGINT}. \\
+    \macro{VQUIT}   &\texttt{0x1C}&(\verb|C-\|)& Carattere di uscita provoca 
+                                                 l'emissione di 
+                                                 \macro{SIGQUIT}.\\
+    \macro{VERASE}  &\texttt{0x7f}& DEL &  Carattere di ERASE, cancella
+                                           l'ultimo carattere precedente 
+                                           nella linea.\\
+    \macro{VKILL}   &\texttt{0x15}&(\verb|C-u|)& Carattere di KILL, cancella
+                                                 l'intera riga.\\
+    \macro{VEOF}    &\texttt{0x04}&(\verb|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}.\\
+    \macro{VTIME}   &   ---       & --- & Timeout, in decimi di secondo, per
+                                          una lettura in modo non canonico. \\
+    \macro{VMIN}    &   ---       & --- & Numero minimo di caratteri per una 
+                                          lettura in modo non canonico.\\
+    \macro{VSWTC}   &\texttt{0x00}& NUL & Carattere di switch. Non supportato
+                                          in Linux.\\
+    \macro{VSTART}  &\texttt{0x21}&(\verb|C-q|)& Carattere di START. Riavvia un
+                                                 output bloccato da uno STOP.\\
+    \macro{VSTOP}   &\texttt{0x23}&(\verb|C-s|)& Carattere di STOP. Blocca
+                                                 l'output fintanto che non
+                                                 viene premuto un carattere di
+                                                 START.\\
+    \macro{VSUSP}   &\texttt{0x1A}&(\verb|C-z|)& Carattere di
+                                                 sospensione. Invia il segnale
+                                                 \macro{SIGTSTP}.\\
+    \macro{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.  \\
+    \macro{VREPRINT}&\texttt{0x12}&(\verb|C-r|)& Ristampa i caratteri non
+                                                 ancora letti.  \\
+    \macro{VDISCARD}&\texttt{0x07}&(\verb|C-o|)& Non riconosciuto in Linux. \\
+    \macro{VWERASE} &\texttt{0x17}&(\verb|C-w|)& Cancellazione di una parola.\\
+    \macro{VLNEXT}  &\texttt{0x16}&(\verb|C-v|)& Carattere di escape, serve a
+                                                 quotare il carattere
+                                                 successivo che non viene
+                                                 interpretato ma passato
+                                                 direttamente all'output. \\
+    \macro{VEOL2}   &\texttt{0x00}& NUL & Ulteriore carattere di fine
+                                          riga. Ha lo stesso effetto di
+                                          \macro{VEOL} ma può essere un
+                                          carattere diverso. \\
+    \hline
+  \end{tabular}
+  \caption{Valori dei caratteri di controllo mantenuti nel campo \var{c\_cc}
+    della struttura \var{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 \tabref{tab:sess_termios_cc}, usando quelle
+definizioni diventa possibile assegnare un nuovo carattere di controllo con un
+codice del tipo:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}%
+    value.c_cc[VEOL2] = '\n';
+\end{lstlisting}
+
+La maggior parte di questi caratteri (tutti tranne \macro{VTIME} e
+\macro{VMIN}) hanno effetto solo quando il terminale viene utilizzato in modo
+canonico; per alcuni devono essere essere soddisfatte ulteriori richieste, ad
+esempio \macro{VINTR}, \macro{VSUSP}, e \macro{VQUIT} richiedono sia settato
+\macro{ISIG}; \macro{VSTART} e \macro{VSTOP} richiedono sia settato
+\macro{IXON}; \macro{VLNEXT}, \macro{VWERASE}, \macro{VREPRINT} richiedono sia
+settato \macro{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 impostazioni dei terminali lo standard POSIX
+prevede due funzioni, \func{tcgetattr} e \func{tcsetattr}; entrambe utilizzano
+come argomento un puntatore ad struttura \var{termios} che sarà quella in cui
+andranno immagazzinate le impostazioni, il loro prototipo è:
 \begin{functions}
   \headdecl{unistd.h} 
   \headdecl{termios.h}  
@@ -1431,20 +1525,64 @@ inizializzata, il loro prototipo 
   }
 \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. 
+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 \macro{SIGTTOU} come
+se si fosse tentata una scrittura, a meno che il processo chiamante non abbia
+\macro{SIGTTOU} ignorato o bloccato, nel qual caso l'operazione sarà eseguita.
 
-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.
+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
+\tabref{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{figure}[!htb]
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \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}
+
+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}[!bht]
   \footnotesize 
   \begin{lstlisting}{}%
 #include <unistd.h>
@@ -1455,7 +1593,6 @@ int SetTermAttr(int fd, tcflag_t flag)
 {
     struct termios values;
     int res;
-
     res = tcgetattr (desc, &values);
     if (res) {
         perror("Cannot get attributes");
@@ -1469,11 +1606,41 @@ int SetTermAttr(int fd, tcflag_t flag)
     }
     return 0;
 }
+  \end{lstlisting}
+  \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 \figref{fig:term_set_attr} e \figref{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 di
+entrambe le funzioni può essere trovato nel file \file{SetTermAttr.c} dei
+sorgenti allegati.
+
+La funzione \func{SetTermAttr} 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.
+
+\begin{figure}[!htb]
+  \footnotesize 
+  \begin{lstlisting}{}%
 int UnSetTermAttr(int fd, tcflag_t flag) 
 {
     struct termios values;
     int res;
-
     res = tcgetattr (desc, &values);
     if (res) {
         perror("Cannot get attributes");
@@ -1488,30 +1655,178 @@ int UnSetTermAttr(int fd, tcflag_t flag)
     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}
+  \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 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, \func{UnSetTermAttr}, è assolutamente identica alla
+prima, solo che in questo caso (in \texttt{\small 15}) si rimuovono i bit
+specificati dall'argomento \param{flag} usando un AND binario del valore
+negato.
 
-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.
+Al contrario di tutte le altre caratteristiche dei terminali, che possono
+essere impostate esplicitamente utilizzando gli opportuni campi di
+\var{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,
+\func{cfsetispeed} per la velocità della linea di ingresso e
+\func{cfsetospeed} per la velocità della linea di uscita; i loro prototipi
+sono:
+\begin{functions}
+  \headdecl{unistd.h} 
+  \headdecl{termios.h}  
+  \funcdecl{int cfsetispeed(struct termios *termios\_p, speed\_t speed)} 
+  Imposta la velocità delle linee seriali in ingresso.
+  
+  \funcdecl{int cfsetospeed(struct termios *termios\_p, speed\_t speed)} 
+  Imposta la velocità delle linee seriali in uscita.
+  
+  \bodydesc{Entrambe le funzioni restituiscono 0 in caso di successo e -1 in
+    caso di errore, che avviene solo quando il valore specificato non è
+    valido.}
+\end{functions}
+
+Si noti che le funzioni si limitano a scrivere opportunamente il valore della
+velocità prescelta \var{speed} all'interno della struttura puntata da
+\var{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
+\finc{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 (\macro{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.
+
+Analogamente a quanto avviene per l'impostazione, le velocità possono essere
+lette da una struttura \var{termios} utilizzando altre due funzioni,
+\func{cfgetispeed} e \func{cfgetospeed}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{unistd.h} 
+  \headdecl{termios.h}  
+  \funcdecl{speed\_t cfgetispeed(struct termios *termios\_p)} 
+  Legge la velocità delle linee seriali in ingresso.
+  
+  \funcdecl{speed\_t cfgetospeed(struct termios *termios\_p)} 
+  Legge la velocità delle linee seriali in uscita.
+  
+  \bodydesc{Entrambe le funzioni restituiscono la velocità della linea, non
+  sono previste condizioni di errore.}
+\end{functions}
+
+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{tcgetaddr}.
+
+
+
+\subsection{La gestione della disciplina di linea.}
+\label{sec:term_line_discipline}
+
+Come illustrato dalla struttura riportata in \figref{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 ad esse con il
+nome di \textsl{discipline di linea}. 
+
+
+Lo standard POSIX prevede alcune funzioni che permettono di intervenire
+direttamente sulla gestione di quest'ultime 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 \macro{SIGTTOU} come
+illustrato in \secref{sec:sess_ctrl_term}.\footnote{con la stessa eccezione,
+  già vista per \func{tcsetaddr}, che quest'ultimo sia bloccato o ignorato dal
+  processo chiamante.}
+
+Una prima funzione, che è efficace solo in caso di terminali seriali asincroni
+(non fa niente per tutti gli altri terminali), è \func{tcsendbreak}; il suo
+prototipo è:
+\begin{functions}
+  \headdecl{unistd.h} 
+  \headdecl{termios.h}  
+  
+  \funcdecl{int tcsendbreak(int fd, int duration)} Genera una condizione di
+  break inviando un flusso di bit nulli.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà i valori \macro{EBADF} o
+    \macro{ENOTTY}.}
+\end{functions}
+
+La funzione invia un flusso di bit nulli (che genera una condizione di 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.
+
+Le altre funzioni previste da POSIX servono a controllare il comportamento
+dell'interazione fra le code associate al terminale e l'utente; la prima è
+\func{tcdrain}, il cui prototipo è:
+\begin{functions}
+  \headdecl{unistd.h} 
+  \headdecl{termios.h}  
+  
+  \funcdecl{int tcdrain(int fd)} Attende lo svuotamento della coda di output.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà i valori \macro{EBADF} o
+    \macro{ENOTTY}.}
+\end{functions}
+
+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, \func{tcflush}, permette svuotare immediatamente le code
+di cancellando tutti i dati presenti; il suo prototipo è:
+\begin{functions}
+  \headdecl{unistd.h} \headdecl{termios.h}
+  
+  \funcdecl{int tcflush(int fd, int queue)} Cancella i dati presenti
+  nelle code di ingresso o di uscita.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà i valori \macro{EBADF} o
+    \macro{ENOTTY}.}
+\end{functions}
+
+La funzione agisce sul terminale associato a \param{fd}, cancellando tutti i
+dati presenti sulla coda specificata dall'argomento \param{queue},
+quest'ultimo può prendere i valori riportati in
+\tabref{tab:sess_tcflush_queue}.
 
 \begin{table}[htb]
   \footnotesize
@@ -1521,123 +1836,51 @@ qualora si cambino i parametri di output.
     \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.\\
+    \macro{TCIFLUSH} & Cancella i dati ricevuti ma non ancora letti. \\
+    \macro{TCOFLUSH} & Cancella i dati scritti ma non ancora trasmessi. \\
+    \macro{TCIOFLUSH}& Cancella tutte e due le code.\\
     \hline
   \end{tabular}
-  \caption{Possibili valori per l'argomento \param{optional\_actions} della
-    funzione \func{tcsetattr}.} 
-  \label{tab:sess_tcsetattr_option}
+  \caption{Possibili valori per l'argomento \param{queue} della
+    funzione \func{tcflush}.} 
+  \label{tab:sess_tcflush_queue}
 \end{table}
 
-Infine occorre 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.
 
-Oltre ai vari flag per gestire le varie caratteristiche dei terminali,
-\var{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 \macro{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.}
+Infine è possibile è possibile sospendere la trasmissione e la ricezione dei
+dati sul terminale usando \func{tcflow}; il suo prototipo è:
+\begin{functions}
+  \headdecl{unistd.h} 
+  \headdecl{termios.h}  
+  
+  \funcdecl{int tcflow(int fd, int action)} .
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà i valori \macro{EBADF} o
+    \macro{ENOTTY}.}
+\end{functions}
+
 
 \begin{table}[htb]
   \footnotesize
   \centering
-  \begin{tabular}[c]{|l|c|c|p{9cm}|}
+  \begin{tabular}[c]{|l|p{8cm}|}
     \hline
-    \textbf{Indice} & \textbf{Valore}&\textbf{Codice} & \textbf{Funzione}\\
+    \textbf{Valore}& \textbf{Significato}\\
     \hline
     \hline
-    \macro{VINTR}   &\texttt{0x03}&(\verb|C-c|)& Carattere di interrupt, 
-                                                 provoca l'emissione di 
-                                                 \macro{SIGINT}. \\
-    \macro{VQUIT}   &\texttt{0x1C}&(\verb|C-\|)& Carattere di uscita provoca 
-                                                 l'emissione di 
-                                                 \macro{SIGQUIT}.\\
-    \macro{VERASE}  &\texttt{0x7f}& DEL &  Carattere di ERASE, cancella
-                                           l'ultimo carattere precedente 
-                                           nella linea.\\
-    \macro{VKILL}   &\texttt{0x15}&(\verb|C-u|)& Carattere di KILL, cancella
-                                                 l'intera riga.\\
-    \macro{VEOF}    &\texttt{0x04}&(\verb|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}.\\
-    \macro{VTIME}   &   ---       & --- & Timeout, in decimi di secondo, per
-                                          una lettura in modo non canonico. \\
-    \macro{VMIN}    &   ---       & --- & Numero minimo di caratteri per una 
-                                          lettura in modo non canonico.\\
-    \macro{VSWTC}   &\texttt{0x00}& NUL & Carattere di switch. Non supportato
-                                          in Linux.\\
-    \macro{VSTART}  &\texttt{0x21}&(\verb|C-q|)& Carattere di START. Riavvia un
-                                                 output bloccato da uno STOP.\\
-    \macro{VSTOP}   &\texttt{0x23}&(\verb|C-s|)& Carattere di STOP. Blocca
-                                                 l'output fintanto che non
-                                                 viene premuto un carattere di
-                                                 START.\\
-    \macro{VSUSP}   &\texttt{0x1A}&(\verb|C-z|)& Carattere di
-                                                 sospensione. Invia il segnale
-                                                 \macro{SIGTSTP}.\\
-    \macro{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.  \\
-    \macro{VREPRINT}&\texttt{0x12}&(\verb|C-r|)& Ristampa i caratteri non
-                                                 ancora letti.  \\
-    \macro{VDISCARD}&\texttt{0x07}&(\verb|C-o|)& Non riconosciuto in Linux. \\
-    \macro{VWERASE} &\texttt{0x17}&(\verb|C-w|)& Cancellazione di una parola.\\
-    \macro{VLNEXT}  &\texttt{0x16}&(\verb|C-v|)& Carattere di escape, serve a
-                                                 quotare il carattere
-                                                 successivo che non viene
-                                                 interpretato ma passato
-                                                 direttamente all'output. \\
-    \macro{VEOL2}   &\texttt{0x00}& NUL & Ulteriore carattere di fine
-                                          riga. Ha lo stesso effetto di
-                                          \macro{VEOL} ma può essere un
-                                          carattere diverso. \\
+    \macro{TCOOFF} & Cancella i dati ricevuti ma non ancora letti. \\
+    \macro{TCOON} & Cancella i dati scritti ma non ancora trasmessi. \\
+    \macro{TCIOFF}& Cancella tutte e due le code.\\
+    \macro{TCION}& Cancella tutte e due le code.\\
     \hline
   \end{tabular}
-  \caption{Valori dei caratteri di controllo mantenuti nel campo \var{c\_cc}
-    della struttura \var{termios}.} 
-  \label{tab:sess_termios_cc}
+  \caption{Possibili valori per l'argomento \param{queue} della
+    funzione \func{tcflush}.} 
+  \label{tab:sess_tcflush_queue}
 \end{table}
 
 
-A ciascuna di queste funzioni di controllo corriponde 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, 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
-\tabref{tab:sess_termios_cc}, usando quelle definizioni diventa possibile
-assegnare un nuovo carattere di controllo con un codice del tipo:
-
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}%
-    value.c_cc[VEOL2] = '\n';
-\end{lstlisting}
-
-\noindent e si potrà poi ricorrere a \func{tcsetattr} per rendere effettiva la
-nuova impostazione.
-
-Come già accennato POSIX.1 prevede due funzioni da utilizzare esplicitamente
-per settare la velocità delle linee seriali, \func{cfsetispeed} e
-\func{cfsetospeed}
-
-
 \subsection{Il \textsl{modo canonico}}
 \label{sec:term_canonic_mode}