http://bugs.winehq.org/show_bug.cgi?id=10056
Wolfgang Walter wolfgang.walter@studentenwerk.mhn.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |wolfgang.walter@studentenwer | |k.mhn.de
--- Comment #3 from Wolfgang Walter wolfgang.walter@studentenwerk.mhn.de 2008-01-07 13:35:19 --- Posix does not define whether VMIN/VTIME mechanism or O_NONBLOCK has preference in "Non-canonical Mode Input Processing":
See
http://www.opengroup.org/onlinepubs/007908799/xbd/termios.html
"In non-canonical mode input processing, input bytes are not assembled into lines, and erase and kill processing does not occur. The values of the MIN and TIME members of the c_cc array are used to determine how to process the bytes received. The ISO POSIX-1 standard does not specify whether the setting of O_NONBLOCK takes precedence over MIN or TIME settings. Therefor, if O_NONBLOCK is set, read() may return immediately, regardless of the setting of MIN or TIME. Also, if no data is available, read() may either return 0, or return -1 with errno set to [EAGAIN]."
I think that i.e. Linux returns with 0 instead of -1, errno=EAGAIN in this case whereas Solarix always returns with -1, errno=EAGAIN.
Setting VMIN=1 probably does not solve the problem as then read may block on some OS even for non-blocking handles. (Though for linux it should work).
The last patch of Adrian Cox isn't a perfect solution, either. With VMIN=0 EOF is not detected any more for serial devices. This is a regression for systems where O_NONBLOCK has priority over VMIN/VTIME (On the other hand this patch makes serial devices work at all on those systems where VMIN,VTIME semantics win).
Another workaround is to check for serial fds if there is actually something to read:
for (;;) { int n = 0; if (type != FD_TYPE_SERIAL || (ioctl(unix_handle, FIONREAD, &n) != -1 && n>0)) { if ((result = read( unix_handle, (char *)buffer + total, length - total )) >= 0) { total += result; ..... } else { ..... } } if (!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))) ..... ..... }