On Sat, Jan 21, 2023 at 07:25:33PM +0100, S??ren Tempel wrote: > Hello, > > Section 11.1.9 of POSIX.1-2008 mandates the following behavior regarding > the handling of the special EOF character: > > EOF Special character on input, which is recognized if the > ICANON flag is set. When received, all the bytes waiting to be > read are immediately passed to the process without waiting for a > <newline>, and the EOF is discarded. [...] If ICANON is set, the > EOF character shall be discarded when processed. > > The "Special Characters" section of the OpenBSD termios(4) man page also > emphasizes that EOF is discarded if there is pending input. However, it > seems that this is not correctly implemented on -stable presently. > Consider the following C program: > > #include <unistd.h> > #include <stdio.h> > > int main(void) { > for (;;) { > char c; > > int r = read(1, &c, sizeof(c)); > if (r == 0) break; /* EOF */ > printf("c: %c\n", c); > } > } > > After compiling and executing this program (in canonical mode input > processing), enter "foo<ctrl-d>". According to the text referenced > above, this should cause the characters 'f', 'o', and 'o' to be printed. > The EOF should be discarded and hence the program should prompt for more > input. Over in Linux-land this is exactly what happens, however, on > OpenBSD 7.2 the EOF is **not** discarded and hence the program > terminates after printing the aforementioned characters. If my > understanding of the POSIX standard and the termios(4) man page is > correct, then OpenBSD's handling of the EOF character is not conforming > to the specification, and hence I would consider this a bug. > > I ran into this while using GNU ed(1) on OpenBSD where partially entered > text in input and command mode is not handled correctly on EOF because > of this bug. > > Greetings, > S??ren >
Some observations: - You are reading from stdout. - Since you are reading one char at the time, the moment the EOF is processed the buffer is empty, so no pending chars. I'll take that as a valid interpretation of Posix. - If you modify your program to read 4 chars at the time (see below), you will see your expected behaviour. -Otto #include <unistd.h> #include <stdio.h> int main(void) { for (;;) { char c[4]; ssize_t r = read(0, c, sizeof(c)); if (r == 0) break; /* EOF */ printf("read: %zd chars\n", r); } }