While reading K&R, I encountered an issue to escape from this simple program:
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != EOF)
{
putchar(c);
}
return 0;
}
I have no idea how to input the EOF
, and have to force stop the program with ctrl+c.
From Wikipedia: End-of-file, I found a tiny note:
In UNIX the translation of the keystroke to EOF is performed by the terminal driver, so a program does not need to distinguish terminals from other input files. By default, the driver converts a Control-D character at the start of a line into an end-of-file indicator.
So, I thought ctrl+d must be the solution. However, I still can’t quit the program after press ctrl+d following the remaining inputs in the terminal.
Further search for solutions, and find someone on stack overflow answered: “it could work with press ctrl+d twice”. This is really working for me, but it didn’t sound like a precious solution.
Digg it further, I found that I have ignored the statement “at the start of a line” in Wikipedia’s explanation. And the reason why double press ctrl+d is working was explained by Eric Postpischil:
In detail, the actual operation is that, when Ctrl-D is pressed, all bytes in the terminal’s input buffer are sent to the running process using the terminal. At the start of a line, no bytes are in the buffer, so the process is told there are zero bytes available, and this acts as an EOF
indicator.
This procedure doubles as a method of delivering input to the process before the end of a line: The user may type some characters and press Ctrl-D, and the characters will be sent to the process immediately, without the usual wait for enter/return to be pressed. After this “send all buffered bytes immediately” operation is performed, no bytes are left in the buffer. So, when Ctrl-D is pressed a second time, it is the same as the beginning of a line (no bytes are sent, and the process is given zero bytes), and it acts like an EOF
.
Yeah, this solved my issue and explained clearly to me. 🍻
What’s more, if you type the following command in Mac OSX’s terminal:
You can get the current settings for the terminal driver. Here’s an example result from my MacBook:
speed 9600 baud; 24 rows; 80 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
-extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
-ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
discard dsusp eof eol eol2 erase intr kill lnext
^O ^Y ^D <undef> <undef> ^? ^C ^U ^V
min quit reprint start status stop susp time werase
1 ^\ ^R ^Q ^T ^S ^Z 0 ^W
EOF
is right there that paired wht ^D
~