Matthias Drochner M.Drochner@fz-juelich.de writes:
Only a few lines later: If the data is in the buffer at the time of the read(), the result will be as if the data has been received immediately after the read().
Ok. My mental model of how this should works is this: The tty driver is one component, which operates the serial line, implements the various termios flags (including VMIN and VTIME), and makes characters available for reading via some kernel buffer. Then the read system call gets characters from that buffer, and the only difference between blocking and non-blocking read is what read does when the buffer is empty.
I guess the kernels that behave differently don't think of VMIN and VTIME as an internal feature of the tty driver, but somehow lets read and poll system calls see that the tty driver have an internal buffer of up to VMIN characters.
The only way around this I can imagine is to have VMIN==1 most of the time; to get characters coalesced for efficiency, VMAX could be set to 4 for the time of the read() (and the O_NONBLOCK cleared). What a mess...
I can see two ways to deal with this:
1. Write a configure test, and use VMIN > 1 only on systems that behave the way I think they should.
2. Spawn a separate process that reads stdin in blocking mode, and use a pipe to get the data to lsh.
You can actually try (2) already, use the somewhat obscure option --cvs-workaround or --cvs-workaround=ei to lsh. This hack exists because it's generally not very friendly to set one's stdio fds into non-blocking mode, and it is enable by default for stderr, which is the fd most commonly shared with other processes.
I've also created a bugzilla ticket for this, http://bugzilla.lysator.liu.se/show_bug.cgi?id=1175.
Regards, /Niels