This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Fwd: I/O errors - confusion]


Gary Thomas <gary at mlbassoc dot com> writes:

> I saw no response to this - can someone (Nick?) please comment?
> 

Oops. I had it set aside to respond to, but then forgot it.

> 
> I was looking into a problem (dealing with abnormal exits
> from I/O functions) and I'm a bit confused.
> 
> In particular, in io/fileio/current/src/devfs.cxx, there
> is a test
>   if (-EAGAIN == err) 
> Looking at the underlying cyg_io_XX functions, I don't think
> that they will ever return a negative value.

Can't they get error codes from the drivers? In particular, I suspect
that this code is intended to interact with this piece of code in
serial.c:

#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
                if (!cbuf->blocking) {
                    *len = size;        // characters actually read
                    res = -EAGAIN;
                    break;
                }
#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING


> 
> Also, that particular piece of code seems wrong to me.  My
> experience is that if I have a device in a non-blocking mode
> and there is no data (to be read), the value of read() is
> an error = EWOULDBLOCK.  The code currently returns no error,
> but also no data.  A generic piece of "read this" code will
> thus not be able to tell the difference between actually
> reaching the end of data (like on a file) vs. not having
> any data at the moment (which it may be prepared to handle 
> in some other fashion).  I think this routine should behave
> like this patch:
> 
> Index: io/fileio/current/src/devfs.cxx
> ===================================================================
> RCS file: /misc/cvsfiles/ecos/packages/io/fileio/current/src/devfs.cxx,v
> retrieving revision 1.5
> diff -u -5 -p -r1.5 devfs.cxx
> --- io/fileio/current/src/devfs.cxx	23 May 2002 23:06:07 -0000	1.5
> +++ io/fileio/current/src/devfs.cxx	9 Mar 2003 15:52:41 -0000
> @@ -352,12 +352,18 @@ static int dev_fo_read      (struct CYG_
>                                 iov->iov_base,
>                                 &len);
>  
>          if( -EAGAIN == err ) // must be in non-blocking mode
>          {
> -            uio->uio_resid -= len;
> -            return ENOERR;
> +            if (len != iov->iov_len) {
> +                // Something was read
> +                uio->uio_resid -= len;
> +                return ENOERR;
> +            } else {
> +                // No data, and non-blocking - tell user
> +                return EWOULDBLOCK;
> +            }
>          }
>          if( err < 0 ) break;
>  
>          uio->uio_resid -= len;
>      }
> 
> although, I'm still confused about the -EAGAIN test.
> 
> Comments?
> 

I believe that should make things work a little better. However, I am
now not sure that the serial.c functionality is correct. According the
the POSIX standard:

When attempting to read a file (other than a pipe or FIFO) that
supports non-blocking reads and has no data currently available:

· If O_NONBLOCK is set, read( ) shall return -1 and set errno to [EAGAIN].

· If O_NONBLOCK is clear, read( ) shall block the calling thread until
  some data becomes available.

· The use of the O_NONBLOCK flag has no effect if there is some data
  available.

Returning some data *and* -EAGAIN doesn't make sense, it should return
either one or the other. Your change fixes it up to work properly, but
if serial.c was doing the right thing, that entire -EAGAIN test could
be eliminated.

-- 
Nick Garnett                    eCos Kernel Architect
http://www.ecoscentric.com/     The eCos and RedBoot experts


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]