Setting termios VMIN > 0 and VTIME > 0 on non blocking file

Corinna Vinschen corinna-cygwin@cygwin.com
Thu Mar 12 15:08:33 GMT 2020


On Mar 12 15:44, Corinna Vinschen wrote:
> On Mar 12 15:20, Åke Rehnman via Cygwin wrote:
> > I think the problem is if the number of bytes requested are more than what
> 
> To clarify: number of bytes == VMIN?
> 
> > is in the buffer it is going to overlap the read function (because of VTIME)
> > and immediately after that CancelIO is called. Contrary to what is mentioned
> > in the source code I think CancelIO is actually discarding data...
> 
> So far we didn't have that experience.  CancelIO is usually safe
> in this regard.
> 
> >   /* Use CancelIo rather than PurgeComm (PURGE_RXABORT) since
> >          PurgeComm apparently discards in-flight bytes while CancelIo
> >          only stops the overlapped IO routine. */
> > 
> > 
> > My suggestion is the following patch:
> > 
> > diff --git a/winsup/cygwin/fhandler_serial.cc
> > b/winsup/cygwin/fhandler_serial.cc
> > index 69e5768f6..afa8871bf 100644
> > --- a/winsup/cygwin/fhandler_serial.cc
> > +++ b/winsup/cygwin/fhandler_serial.cc
> > @@ -898,7 +898,11 @@ fhandler_serial::tcsetattr (int action, const struct
> > termios *t)
> >    {
> >      memset (&to, 0, sizeof (to));
> > 
> > -    if ((vmin_ > 0) && (vtime_ == 0))
> > +       if (is_nonblocking())
> > +       {
> > +               to.ReadIntervalTimeout = MAXDWORD;
> > +       }
> > +    else if ((vmin_ > 0) && (vtime_ == 0))
> 
> What if you switch to !O_NONBLOCK after calling tcsetattr?  The
> setting of ReadIntervalTimeout would be lost then.
> 
> Either we have to repeat calling SetCommTimeouts every time
> we switch mode, or we have to do the above setting temporary
> every time we call ReadFile in non blocking mode.

What about this:

diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc
--- a/winsup/cygwin/fhandler_serial.cc
+++ b/winsup/cygwin/fhandler_serial.cc
@@ -68,6 +68,16 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
 	goto err;
       else if (ev)
 	termios_printf ("error detected %x", ev);
+      else if (is_nonblocking ())
+	{
+	  if (!st.cbInQue)
+	    {
+	      tot = -1;
+	      set_errno (EAGAIN);
+	      goto out;
+	    }
+	  inq = st.cbInQue;
+	}
       else if (st.cbInQue && !vtime_)
 	inq = st.cbInQue;
       else if (!is_nonblocking () && !overlapped_armed)


Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20200312/a7e308a5/attachment.sig>


More information about the Cygwin mailing list