[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ctrl+d (EOF) and the standard input.
beitamos@inter.net.il wrote:
|I got an exercise where I have to use ctrl+d (EOF sign, as much as I
|understand) with the standard input that is the channel to input data to
|a C program.
|
|1) Can you explain me what supose to happen ? I mean, when I use ctrl+d
|on the standard input that is passing commands to the shell, I am
|exiting the shell. What supoose to happen when I type ctrl+d when the
|standard input is passing input to a program ?
What happens is actually very simple - ^D simply tells the tty driver
(which is the part of the kernel who gives these "special characters"
their meaning) to stop waiting for the newline character and return
the program whatever there is in the input buffer right now. If this
is done at the beginning of the input line then the program gets zero
characters back and thinks that it reached the end of the file (most
simple file-reading programs have some "while (bytes_read = read
(...)) { ... }").
For instance:
|birnam| cat
Hello world
Hello world
HelloHello|birnam|
The first "Hello world" was typed by me. The second was echoed by
cat(1), the next "Hello" was type by me and the Second hello n the
third line was echoed by cat(1) when I pressed ^D. When I press ^D
again cat(1) exits since there is nothing in the input buffer.
|
|2)I tried to run the following program:
|
|#include <stdio.h>
|
|int main(void)
|{
| int input_char, num_of_EOFs = 0;
|
| do
| {
| if ((input_char = getchar()) == EOF)
| printf("%d EOF signs were detected so far\n", ++num_of_EOFs);
| } while (input_char != 'q');
| exit(0);
|}
|
|The results were that if I type ctrl+d after a return key, it
|immediately detects the EOF sign. But otherwise I had to press ctrl+d
|twice to make the program understands that I want it to detect an EOF.
|Why is that ?
|
What happens is actually very simple - ^D (or whatever is currently
defined as the EOF character) tells the tty driver (which is the part
of the kernel who gives these "special characters" their meaning) to
stop waiting for the newline character and return the program whatever
there is in the input buffer right now. If this is done at the
beginning of the input line then the program gets zero characters back
and thinks that it reached the end of the file (if you use read(2)
directly then you usually have a loop like "while (bytes_read = read
(...)) { ... }"). In getch()'s case, it return you the EOF constant.
For instance:
|birnam| cat
Hello world
Hello world
Hello^DHello^D|birnam|
The first "Hello world" was typed by me. The second was echoed by
cat(1), the next "Hello" was type by me and the second "Hello" on the
third line was echoed by cat(1) when I pressed ^D. When I press ^D
again cat(1) exits since there is nothing in the input buffer. (I
added the ^D here for clarity, you don't really see them)
In general - you might be better off using read(2) to investigate such
things, so you don't have the stdio clutter around this.
All the above is assuming the tty is in "cooked" mode, when it is in
"raw" mode all the "special characters" loos their meanning, including
^D.
In order to convince yourself that ^D isn't that special, try doing
"stty eof ^V^B" and start using ^B as an EOF character for a while.
Hope this helps,
--Amos
--Amos Shapira | "Of course Australia was marked for
133 Shlomo Ben-Yosef st. | glory, for its people had been chosen
Jerusalem 93 805 | by the finest judges in England."
ISRAEL amos@dsi.co.il | -- Anonymous
References: