web-dev-qa-db-fra.com

Pourquoi ne peut-il pas être sorti avec C-C?

Le programme ed, un éditeur de texte minimal, ne peut pas être sorti en l'envoyant une interruption à l'aide de Ctrl-C, à la place, imprimez le message d'erreur "?" à la console. Pourquoi ne fonctionne pas ed juste sortir quand il reçoit l'interruption? Il n'y a sûrement aucune raison pour laquelle un message d'erreur cryptique est plus utile ici que de simplement sortir. Ce problème mène de nombreux nouveaux utilisateurs dans le type d'interaction suivant:

$ ed
hello
?
help
?
exit
?
quit
?
^C
?
^C
?
?
?
^D
$ su
# rm -f /bin/ed

Un tel déchet tragique - facilement évitable si ed a simplement accepté d'être interrompu.

Un autre programme obstiné présentant un comportement similaire est less qui ne semble pas non plus avoir beaucoup de raison d'ignorer C-c. Pourquoi ces programmes ne font-ils que prendre un indice?

20
Lily Chung

Ctrl+C envoie SIGINT . L'action conventionnelle pour SIGINT est de revenir à la boucle de toplevel d'un programme, d'annuler la commande actuelle et d'entrer dans un mode où le programme attend la commande suivante. Seuls les programmes non interactifs sont censés mourir de Sigint.

Donc c'est naturel que Ctrl+C Ne tue pas Ed, mais le fait revenir à sa boucle de toplevel. Ctrl+C abrite la ligne d'entrée actuelle et retourne à l'invite ED.

Il en va de même pour moins: Ctrl+C interrompt la commande actuelle et vous ramène à son invite de commande.

Pour des raisons historiques, ed ignore SIGQUIT (Ctrl+\). Les applications normales ne doivent pas attraper ce signal et se permettre de se terminer, avec un vidage de base si activé.

Le NIX V7 ed(1) Code source est un programme primitif 1 762-Line C avec quelques commentaires, dont l'un est un commentaire d'en-tête très éclairé:

/*
 * Editor
 */

Étant donné que le code source lui-même ne fournit aucune justification, vous ne ferez que l'obtenir de l'auteur du programme.

ed a été écrit à l'origine par Ken Thompson dans l'Assemblée PDP-11 , mais vous devez réellement parler à celui qui l'a porté à C. Cela aurait pu être Dennis Ritchie , puisque il crée C pour UNIX, et était l'un des nombreux ceux qui ont utilisé C pour rendre UNIX portable à des machines non-PDP. Le Dr Ritchie n'est plus là pour répondre à de telles questions.

Ma lecture du code suggère qu'il a été fait pour essayer de préserver le contenu de la copie in-noya du document modifié. Vous remarquerez que d'autres éditeurs de texte ne meurent pas non plus Ctrl-C.

Voici ce que ed fait sur Ctrl-C:

onintr()
{
    signal(SIGINT, onintr);
    putchr('\n');
    lastc = '\n';
    error(Q);
}

(Oui, K & R C . Nous n'avons pas besoin de spécificateurs de type retour de Steenkin 'ou de déclarations de paramètres.)

Traduit en anglais, ed:

  1. Réinscrit le gestionnaire de signal.

    (Unix n'a pas reçu de signaux de réinitialisation automatique jusqu'au 4,3BSD , au milieu des années 1980.)

  2. Écrit une nouvelle ligne et se souvient qu'il l'a fait, via la variable globale lastc.

    (ed.c A environ soixante variables globales.)

  3. Appelle la fonction error(), qui célibataire fait un peu plus que d'imprimer ?, Du point de vue de l'utilisateur.

En d'autres termes, ça dit: "Tu ne voulais vraiment pas faire ça, n'est-ce pas?"

18
Warren Young

ed, comme d'autres programmes interactifs, utilisez Ctrl+C interrompre les tâches du programme lui-même.
[.____] Cela ressemble beaucoup au cas normal, où il interrompt une tâche exécutée dans la coquille - une commande.

Du point de vue de l'utilisateur, les deux variantes sont très similaires. La manipulation du signal est différente: dans le cas habituel, le signal SIGINT est envoyé au processus de premier plan, une commande d'exécution et la commande le gère en sortant.
[.____] Dans le cas de ed, le signal est envoyé au processus de premier plan, l'instance ed. S'il y a une tâche exécutée dans ed, il est interrompu et l'invite est affichée. S'il n'y a pas de tâche en cours d'exécution, rien n'est changé.

Notez comment une coquille ne quitte pas non plus sur Ctrl+C, comme ed. Et que cela sort sur Ctrl+D. Encore une fois, comme ed

7
Volker Siegel

Il y a trois signaux que ed se soucie de:

  1. INT
  2. HUP
  3. QUIT

la spécification POSIX de ed dit ce qui suit à propos de ceux-ci:

SIGINT

L'utilitaire ed doit interrompre son activité actuelle, écrivez la chaîne ?\n à la sortie standard et retourner en mode de commande (voir la section Description étendue).

SIGHUP

Si le tampon n'est pas vide et a changé depuis la dernière écriture, l'utilitaire ed doit essayer d'écrire une copie du tampon dans un fichier. Tout d'abord, le fichier nommé ed.hup Dans le répertoire actuel est utilisé; Si cela échoue, le fichier nommé ed.hup Dans le répertoire nommé par la variable d'environnement HOME doit être utilisé. Dans tous les cas, l'utilitaire ed doit quitter sans écrire le fichier sur le chemin de chemin actuellement mémorisé et sans retourner en mode de commande.

SIGQUIT

L'utilitaire ed doit ignorer cet événement.

Donc quelle que soit la mise en œuvre de ed que vous utilisez, il est conforme à la spécification POSIX en ce qui concerne le signal INT (qui est ce que Ctrl+C envoie).

À cet égard, l'éditeur se comporte comme une coque interactive, qui ne se termine pas non plus lors de la réception du signal INT. D'autres éditeurs, tels que vi et nano font la même chose.

3
Kusalananda