web-dev-qa-db-fra.com

Entrée de terminal canonique vs non canonique

J'étudie pour un examen et je suis confus quant à la façon dont les entrées/sorties canoniques vs non canoniques fonctionnent sous Unix (par exemple, les malédictions). Je comprends qu'il existe un tampon auquel des "disciplines de ligne" sont appliquées pour l'entrée canonique. Cela signifie-t-il que le tampon est contourné pour une entrée non canonique, ou cela signifie-t-il simplement qu'aucune discipline de ligne n'est appliquée? En quoi ce processus diffère-t-il pour les opérations d'entrée et de sortie?

Dans les programmes curses avec lesquels j'ai travaillé et qui démontrent une entrée canonique, l'entrée saisie par un utilisateur est automatiquement entrée soit après qu'un certain nombre de caractères ont été saisis, soit après un certain temps. Est-ce que l'une de ces choses est considérée comme une "discipline de ligne" ou est-ce autre chose entièrement?

39
titaniumdecoy

Pour une entrée canonique - pensez Shell; en fait, pensez au bon Bourne Shell à l'ancienne, puisque Bash et ses proches ont l'édition en ligne de commande. Vous tapez une ligne d'entrée; si vous faites une erreur, vous utilisez le caractère d'effacement (la valeur par défaut est Backspace, d'habitude; quelquefois Delete) pour effacer le caractère précédent. Si vous vous trompez complètement, vous pouvez annuler toute la ligne avec le caractère de suppression de ligne (pas complètement standardisé, souvent Control-X). Sur certains systèmes, vous obtenez un effacement de Word avec Control-W. Tout cela est une entrée canonique. La ligne entière est rassemblée et éditée jusqu'à la fin du caractère de ligne - Return - est pressé. Ensuite, toute la ligne est mise à la disposition des programmes en attente. En fonction des appels système read() en attente, la ligne entière sera disponible pour être lue (par un ou plusieurs appels à read()).

Pour une entrée non canonique - pensez vi ou vim ou autre chose - vous appuyez sur un caractère, et il est immédiatement disponible pour le programme. Vous n'êtes pas retenu jusqu'à ce que vous appuyiez sur Retour. Le système ne modifie pas les caractères; ils sont mis à disposition du programme dès leur saisie. C'est au programme d'interpréter les choses de façon appropriée. Maintenant, vim fait un certain nombre de choses qui ressemblent un peu à une entrée canonique. Par exemple, le retour arrière recule et en mode de saisie efface ce qui était là. Mais c'est parce que vim choisit de le faire se comporter comme ça.

La sortie canonique et non canonique est une affaire beaucoup moins sérieuse. Il y a quelques différences, liées à des choses comme l'écho du retour chariot avant le saut de ligne, et s'il faut faire des retards (pas nécessaire avec l'électronique; important à l'époque où le périphérique de sortie aurait pu être un 110- télétype baud). Il peut également faire des choses comme gérer les périphériques de sortie insensibles à la casse - les télétypes, encore une fois. Les lettres minuscules sont affichées en majuscules et les lettres majuscules sous forme de barre oblique inverse et de majuscules.

Auparavant, si vous tapiez toutes les lettres majuscules dans l'invite de connexion, le programme de connexion se convertissait automatiquement dans le mode où toutes les majuscules étaient sorties avec une barre oblique inverse devant chaque capital réel. Je soupçonne que cela ne se fait plus sur les terminaux électroniques.


Dans un commentaire, TitaniumDecoy a demandé:

Donc, avec une entrée non canonique, le tampon d'entrée est-il complètement contourné? Aussi, où interviennent les disciplines de ligne?

Avec une entrée non canonique, le tampon d'entrée est toujours utilisé; s'il n'y a pas de programme avec un appel read() en attente d'entrée du terminal, les caractères sont conservés dans le tampon d'entrée. Ce qui ne se produit pas, c'est une modification du tampon d'entrée.

Les disciplines de ligne sont des choses comme l'ensemble des manipulations effectuées par l'édition d'entrée. Ainsi, un aspect de la discipline de ligne est que le caractère d'effacement efface un caractère précédent en mode d'entrée canonique. Si vous avez icase (mappage de casse d'entrée) défini, les caractères majuscules sont mappés en minuscules sauf s'ils sont précédés d'une barre oblique inverse; c'est une discipline de ligne, je crois, ou un aspect d'une discipline de ligne.


J'ai oublié de mentionner que EOF traitement (Control-D) est géré en mode canonique; cela signifie en fait "rendre l'entrée accumulée disponible pour read()"; s'il n'y a pas d'entrée accumulée (si vous tapez Control-D au début d'une ligne), la read() renverra zéro octet, ce qui est alors interprété comme EOF par les programmes. Bien sûr, vous pouvez taper gaiement plus de caractères sur le clavier après cela, et les programmes qui ignorent EOF (ou s'exécutent en mode non canonique) seront très satisfaits.

Bien sûr, en mode canonique, les caractères tapés au clavier sont normalement répercutés à l'écran; vous pouvez contrôler si cet écho se produit. Cependant, ceci est quelque peu tangentiel à l'entrée canonique; l'édition normale se produit même lorsque l'écho est désactivé.

De même, les signaux d'interruption et de sortie sont des artefacts du traitement en mode canonique. Il en va de même pour les signaux de contrôle des tâches tels que Control-Z pour suspendre le processus en cours et revenir au Shell. De même, le contrôle de flux (Control-SControl-Q pour arrêter et démarrer la sortie) est fourni par le mode canonique.

Le chapitre 4 de Rochkind's Advanced Unix Programming, 2nd Edn couvre les E/S du terminal et donne une grande partie de ces informations - et bien plus encore. D'autres livres de programmation UNIX (au moins, les bons) le couvriront également.

81
Jonathan Leffler