2
int main(void){


    char cmdline[MAXLINE];
    while(1){
        printf("> ");
        fgets(cmdline, MAXLINE, stdin); 
        if(feof(stdin)){            
            exit(0); 
        }
        eval(cmdline); 
    }
}

This is main part of myShell program that professor gave to me.

But there is one thing I don't understand in code.

There says if(feof(stdin)) exit(0);

What is the end of the standard input?

fgets accept all characters until the enter key is input. The end of a typical "file"(e.g.txt) is intuitively understandable, but what does the end of a standard input mean?

In what practical situations does the feof(stdin) actually return true?

Even if you enter a space without entering anything, the IF statement does not pass.

  • 2
    `In what practical situations does the feof(stdin) actually return true?` When the input ends, i.e. is closed. Yes. stdin can be closed. Try pressing CTRL+D – tkausl Mar 24 '22 at 11:28
  • @tkausl: Pressing control-D does not close `stdin` or the standard input stream. To see this, compile and execute `#include ` / `int main(void) { int c; while (EOF != (c = getchar())) putchar(c); }` and type A, B, C, control-D, X, Y, Z, control-D, control-D. You will see the output “XYZ” as well as “ABC”, showing that input was read after the first control-D, so the input stream was not closed. What control-D actually means is [send pending data to the program](https://stackoverflow.com/a/21365313/298225)… – Eric Postpischil Mar 24 '22 at 12:26
  • … When there is no pending data, software inside the program may interpret it as an end-of-file, but the stream remains open. In fact, you can call `clearerr(stdin);` and continue reading characters even after the end-of-file indication. – Eric Postpischil Mar 24 '22 at 12:28

2 Answers2

2

feof tests the stream’s end-of-file indicator and returns true (non-zero) iff the end-of-file indicator is set.

For regular files, attempting to read past the end of the file sets the end-of-file indicator. For terminals, a typical behavior is that when a program attempts to read from the terminal and gets no data, the end-of-file indicator is set. In Unix systems with default settings, a way to trigger this “no data, end-of-file behavior” is to press control-D at the beginning of a line or immediately after a prior control-D.

The reason this works is because control-D is used to mean “send pending data to the program immediately.” That is described further in this answer.

Thus, if you want to end input for a program, press control-D (and, if not at the beginning of a line, press it a second time).

For input from terminals, while this does cause an end-of-file indication, it does not actually end the input or close the stream. The program can clear the end-of-file indicator and keep reading. Even for regular files, the program could clear the end-of-file indicator, reset the file context to a different position, and continue reading.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

The confusion is to assume stdin = terminal. It is not necessarily true.

What stdin is depends on how you run your program. For example, assuming your executable is named a.out, if you run it like this:

echo "foo" | ./a.out

Stdin is an output of a different process, in this example this process simply outputs the word "foo", so stdin will contain "foo" and then EOF.

Another example is:

./a.out < file.txt

In this case, stdin is "file.txt". When the file is read to the end, stdin gets EOF.

Stdin can also be a special device, for example:

./a.out < /dev/random

In this specific case it is infinite.

Last, when you simply run your program and stdin is terminal - you can generate EOF too - just press CTRL-D, this sends a special symbol meaning EOF to the terminal.

P.S. There are other ways to execute a process. Here I only gave examples of processes executed from the command line shell. But process can be executed by a different process, not necessarily from the shell. In this case the creator of the process can decide what stdin will be - terminal, pipe, socket, file or any other object.

Yuri Nudelman
  • 2,874
  • 2
  • 17
  • 24