If VTIME == 0 and VMIN == 0, nonblocking read in noncanonical mode returns 0 instead of EAGAIN. If VTIME == 0 and VMIN == 0, then timeout == time == 0 (see n_tty_read in n_tty.c). ===== tst1.c ===== #define _GNU_SOURCE #include <err.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ioctl.h> #include <termios.h> #include <unistd.h> int fd = -1; void doerror(char *Text) { warn("%s", Text); if (fd != -1) close(fd); exit(0); } int main() { int i; char c; struct termios te; fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd == -1) doerror("open"); if (tcgetattr(fd, &te) == -1) doerror("tcgetattr"); cfmakeraw(&te); te.c_iflag &= ~(IGNPAR | INPCK | IXANY | IXOFF); te.c_cflag &= ~(CSTOPB | PARENB | PARODD | CRTSCTS); te.c_cflag |= CREAD | HUPCL | CLOCAL; te.c_cc[VTIME] = 0; te.c_cc[VMIN] = 0; cfsetispeed(&te, B115200); cfsetospeed(&te, B115200); if (tcsetattr(fd, TCSANOW, &te) == -1) doerror("tcsetattr"); i = read(fd, &c, 1); if (i == 0) fprintf(stderr, "read 0 bytes\n"); else if (i < 0) doerror("read"); else fprintf(stderr, "read 0x%.2X\r\n", (unsigned char)c); close(fd); return 0; } ================== When input is not available, input_available_p(tty, 0) returns 0 and the function also returns 0 instead of EAGAIN: if (!timeout) break; if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; break; } Another bug (blocking read in noncanonical mode): When TIME == 0, MIN == e.g. 5, and read is called with count == 3 (see tst2.c), then read blocks until 5 (not 3) chars received. But if there are already 3 chars in the buffer, then read returns immediately. Is it correct? ===== tst2.c ===== #define _GNU_SOURCE #include <err.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ioctl.h> #include <termios.h> #include <unistd.h> int fd = -1; void doerror(char *Text) { warn("%s", Text); if (fd != -1) close(fd); exit(0); } int main() { int i, j; char buf[256]; struct termios te; fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd == -1) doerror("open"); int Result = fcntl(fd, F_GETFL); if (Result != -1) Result = fcntl(fd, F_SETFL, Result & ~O_NONBLOCK); if (tcgetattr(fd, &te) == -1) doerror("tcgetattr"); cfmakeraw(&te); te.c_iflag &= ~(IGNPAR | INPCK | IXANY | IXOFF); te.c_cflag &= ~(CSTOPB | PARENB | PARODD | CRTSCTS); te.c_cflag |= CREAD | HUPCL | CLOCAL; te.c_cc[VTIME] = 0; te.c_cc[VMIN] = 5; cfsetispeed(&te, B115200); cfsetospeed(&te, B115200); if (tcsetattr(fd, TCSANOW, &te) == -1) doerror("tcsetattr"); printf("--- You can send chars. Press Enter ---\n"); getchar(); i = read(fd, buf, 3); if (i == 0) fprintf(stderr, "read 0 bytes\n"); else if (i < 0) doerror("read"); else { fprintf(stderr, "Result = %d\n", i); for (j = 0; j < i; j++) fprintf(stderr, "read 0x%.2x\n", (unsigned char)buf[j]); } close(fd); return 0; } ================== If TIME == 0, MIN > 0 then tty->minimum_to_wake = minimum and n_tty_receive_buf wakes after 5 chars (see n_tty.c).
(In reply to Ivan from comment #0) > If VTIME == 0 and VMIN == 0, nonblocking read in noncanonical mode returns 0 > instead of EAGAIN. Not a bug. POSIX does not specify if O_NONBLOCK takes precedence over the MIN/TIME settings. The Linux interpretation is that it does not. > Another bug (blocking read in noncanonical mode): > When TIME == 0, MIN == e.g. 5, and read is called with count == 3 (see > tst2.c), then read blocks until 5 (not 3) chars received. But if there are > already 3 chars in the buffer, then read returns immediately. Is it correct? There is no specification or guidance in this situation. However, I believe that read() in non-canonical mode should always complete successfully if the number of bytes requested are available. IOW, minimum_to_wake = min(minimum, nr); Please let us know if you intend to send a patch.
VMIN/VTIME behaviour is basically defined by "What does Systen 5.x do". In which case we are correct already. On the former VMIN/VTIME behaviour returning 0 matches other OS behaviour. I don't think we should change behaviour here Alan
(In reply to Alan from comment #2) > I don't think we should change behaviour here I guess maybe I wasn't clear enough in my comment (which is made worse by the initial report containing 2 separate bug reports). 1st report (TIME==0, MIN==0, O_NONBLOCK in non-canonical mode): Not a bug, nothing to do here. 2nd report (TIME==0, MIN==5, read(fd, &buf, 3)): I think it makes sense to wake up and complete the read() if 3 chars are received (since if there are already 3 chars in the input buffer we will complete the read() regardless of the MIN setting).
You can argue it either way. In fact MacOS X explicitly does one and Solaris explicitly does the other. We follow the SYS5 behaviour. We shouldn't change that behaviour between two differently random responses to an arguably bogus request. Changing it is more damaging than consistency of existing behaviour Alan
> We follow the SYS5 behaviour. Ok.
I think that you know better, as it should be but 1. "man termios" says nothing about TIME/MIN behaviour with O_NONBLOCK in non-canonical mode. I think that it should be added to man that read can return 0, not EAGAIN with TIME==0, MIN==0. The user should not forget to set MIN=1! 2. "man termios" says "MIN > 0; TIME == 0: read(2) blocks until the lesser of MIN bytes or the number of bytes requested are available, and returns the lesser of these two values" Deside for yourself...
1. Addition. Independently of POSIX standard I must be sure in read-function behaviour. E. g. select(ComPort, ...); ... Wait until data received ... read(...); ... Process read data ... read(...); If read returned 0, it means that there is no data or the connection was hung up?
(In reply to Ivan from comment #6) > I think that you know better, as it should be but > > 1. "man termios" says nothing about TIME/MIN behaviour with O_NONBLOCK in > non-canonical mode. I think that it should be added to man that read can > return 0, not EAGAIN with TIME==0, MIN==0. The user should not forget to set > MIN=1! > > 2. "man termios" says "MIN > 0; TIME == 0: read(2) blocks until the lesser > of MIN bytes or the number of bytes requested are available, and returns the > lesser of these two values" Deside for yourself... I will clarify both of these points with Michael Kerrisk. I had already noticed #2 is wrong anyway: read() will return up to the number of bytes requested regardless of the MIN value, as long as that is >= min(MIN,nr). For example, if MIN==5 and nr==300, and input available is 1000, read() will return 300, not 5. Even if input available *at the time* was only just 5, by the time the read() is woken, if more input has become available, it will be returned, provided the total amount is not larger than nr.
(In reply to Ivan from comment #7) > 1. Addition. > > Independently of POSIX standard I must be sure in read-function behaviour. > > E. g. > > select(ComPort, ...); > > ... Wait until data received ... > > read(...); > > ... Process read data ... > > read(...); > > If read returned 0, it means that there is no data or the connection was > hung up? Only blocking reads (canonical mode or MIN>0, TIME=0 in non-canonical mode) return 0 to indicate EOF (tty was hungup). All ioctl()'s on the tty will return EIO if the tty was hungup. Specifically, err = ioctl(fd, FIONREAD, &bytes_avail); is the most common way to determine the status of the tty after select() or poll(). [NB: this advice does not apply if this is about large numbers of file descriptors. Use either epoll or signal-driven i/o in these cases.]
(In reply to Alan from comment #2) > VMIN/VTIME behaviour is basically defined by "What does Systen 5.x do". In > which case we are correct already. Actually, that may not quite be true. Take a look at POSIX.1-2008 XBD 11.1.7, and then see this text I just drafted for the termios(3) man page: MIN > 0; TIME > 0: TIME specifies the limit for a timer in tenths of a sec‐ ond. Once an initial byte of input becomes available, the timer is restarted after each further byte is received. read(2) returns when any of the following conditions is met: * MIN bytes have been received. * The interbyte timer expires. * The number of bytes requested by read(2) has been received. (POSIX does not specify this termination condition, and on some other implementations read() does not return in this case.) Solaris, for example, doesn't terminate the read() in the final case. Presumably, Solaris is truly following System V (and Linux is not). On the other hand, it would not surprise me to find that the Linux behavior has been present since near the beginning, and no one seems to have minded enough to do anything about it (after all, having MIN be > number of bytes requested in read() is kind of odd).