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);
        }
              
}
              

Reply via email to