This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Re: [Fwd: I/O errors - confusion]
- From: Nick Garnett <nickg at ecoscentric dot com>
- To: Gary Thomas <gary at mlbassoc dot com>
- Cc: eCos patches <ecos-patches at sources dot redhat dot com>
- Date: 18 Mar 2003 17:58:28 +0000
- Subject: Re: [Fwd: I/O errors - confusion]
- References: <1047910751.7462.49.camel@hermes.chez-thomas.org>
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