The program ed, a minimal text editor, cannot be exited by sending it an interrupt through using Ctrl–C, instead printing the error message “?” to the console. Why doesn’t ed just exit when it receives the interrupt? Surely there’s no reason why a cryptic error message is more useful here than just exiting. This behavior leads many new users into the following sort of interaction:
$ ed hello ? help ? exit ? quit ? ^C ? ^C ? ? ? ^D $ su # rm -f /bin/ed
Such a tragic waste—easily avoidable if ed simply agreed to be interrupted.
Another stubborn program exhibiting similar behavior is less which also doesn’t appear to have much reason to ignore C-c. Why don’t these programs just take a hint?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Ctrl+C sends SIGINT. The conventional action for SIGINT is to return to a program’s toplevel loop, cancelling the current command and entering a mode where the program waits for the next command. Only non-interactive programs are supposed to die from SIGINT.
So it’s natural that Ctrl+C doesn’t kill ed, but causes it to return to its toplevel loop. Ctrl+C aborts the current input line and returns to the ed prompt.
The same goes for less: Ctrl+C interrupts the current command and brings you back to its command prompt.
For historical reasons, ed ignores SIGQUIT (Ctrl+). Normal applications should not catch this signal and allow themselves to be terminated, with a core dump if enabled.
Method 2
The Unix V7 ed(1) source code is a primitive 1,762-line C program with just a few comments, one of which is this highly-enlightening header comment:
/* * Editor */
Given that the source code itself does not provide any rationale, you’re only going to get it from the program’s author.
ed was originally written by Ken Thompson in PDP-11 assembly, but you’d actually need to talk to whoever ported it to C. That might have been Dennis Ritchie, since he created C for Unix, and was one of many who used C to make Unix portable to non-PDP machines. Dr Ritchie is no longer around to answer such questions, though.
My reading of the code suggests that it was done to try and preserve the contents of the in-core copy of the edited document. You’ll notice that other text editors also do not die on Ctrl-C.
Here’s what ed does on Ctrl-C:
onintr()
{
signal(SIGINT, onintr);
putchr('n');
lastc = 'n';
error(Q);
}
(Yes, K&R C. We don’t need no steenkin’ return type specifiers or parameter declarations.)
Translated into English, ed:
-
Re-registers the signal handler.
(Unix didn’t get auto-resetting signals until 4.3BSD, in the mid-1980s.)
-
Writes out a new line, and remembers that it did so, via the global variable
lastc.(
ed.chas about sixty global variables.) -
Calls the
error()function, which famously does little more than print?, from the user’s perspective.
In other words, it’s saying, “You didn’t really mean to do that, did you?”
Method 3
ed, like other interactive programs, use Ctrl+C to interrupt tasks of the program itself.
This is very similar to the normal case, where it interrupts a task running in the shell – a command.
From the user perspective, both variants are very similar.
The handling of the signal is different: in the usual case, the signal SIGINT is sent to the foreground process, a running command, and the command handles it by exiting.
In the case of ed, the signal is sent to the foreground process, the ed instance. If there is a task running in ed, it is interrupted and the prompt is shown. If there is no task running, nothing is changed.
Note how a shell also does not exit on Ctrl+C, just like ed. And that it does exit on Ctrl+D. Again, just like ed
Method 4
There are three signals that ed cares about:
INTHUPQUIT
The POSIX specification of ed says the following about these:
SIGINTThe
edutility shall interrupt its current activity, write the string?nto standard output, and return to command mode (see the EXTENDED DESCRIPTION section).
SIGHUPIf the buffer is not empty and has changed since the last write, the
edutility shall attempt to write a copy of the buffer in a file. First, the file nameded.hupin the current directory shall be used; if that fails, the file nameded.hupin the directory named by theHOMEenvironment variable shall be used. In any case, theedutility shall exit without writing the file to the currently remembered pathname and without returning to command mode.
SIGQUITThe
edutility shall ignore this event.
So whatever implementation of ed you are using, it conforms to the POSIX specification with regards to the INT signal (which is what Ctrl+C sends).
In this regard, the editor behaves like an interactive shell, which also does not terminate upon receiving the INT signal. Other editors, such as vi and nano does the same thing.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0