This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Re: Fix for non-blocking serial write result code
- From: Dan Jakubiec <djakubiec at yahoo dot com>
- To: Andrew Lunn <andrew at lunn dot ch>
- Cc: eCos Patches <ecos-patches at sources dot redhat dot com>
- Date: Mon, 19 Jan 2004 10:42:19 -0800 (PST)
- Subject: Re: Fix for non-blocking serial write result code
Hi Andrew,
I don't think that's right. The -1 value that POSIX is talking about
is the value returned from the "write()" call, not the *len parameter.
The eCos system call semantics are set up a little differently, which I
think is the source of the confusion.
The POSIX write() call returns the number of bytes written via its
return value; the eCos call returns it via the *len pointer. After the
eCos I/O functions are called, their result is translated to POSIX
semantics by looking at the return code, as follows:
1) (serial_write() == ENOERR) --> write() returns *len
2) (serial_write() == -EAGAIN) --> write() returns -1, errno = EAGAIN,
implies 0 bytes written
For eCos cyg_io_write(), the *len pointer always needs to be equal to
the number of bytes written because it is used to decrement pending
write counts (see dev_fo_write() for example). A -Cyg_Errno return
value will eventually trigger the -1 return for write().
Thanks,
--
Dan Jakubiec
Systech Corp
--- Andrew Lunn <andrew@lunn.ch> wrote:
> diff -u -r1.24 serial.c
> --- packages/io/serial/current/src/common/serial.c 12 Sep 2003
> 15:32:50 -0000 1.24
> +++ packages/io/serial/current/src/common/serial.c 12 Jan 2004
> 15:07:22 -0000
> @@ -354,7 +354,7 @@
> if (!cbuf->blocking) {
> *len -= size; // number of characters
> actually sent
> cbuf->waiting = false;
> - res = size == 0 ? -EAGAIN : ENOERR;
> + res = (*len == 0) ? -EAGAIN : ENOERR;
> break;
> }
> #endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
>
> I don't think this is correct either. The relevant standard is:
> http://www.opengroup.org/onlinepubs/007904975/functions/write.html
>
> It says:
>
> When attempting to write to a file descriptor (other than a pipe or
> FIFO) that supports non-blocking writes and cannot accept the data
> immediately:
>
> * If the O_NONBLOCK flag is clear, write() shall block the
> calling
> thread until the data can be accepted.
>
> * If the O_NONBLOCK flag is set, write() shall not block the
> thread. If some data can be written without blocking the
> thread,
> write() shall write what it can and return the number of bytes
> written. Otherwise, it shall return -1 and set errno to
> [EAGAIN].
>
> I think the code should be something like this. Comments please.
>
> Andrew
>
> Index: packages/io/serial//current/ChangeLog
> ===================================================================
> RCS file: /cvs/ecos/ecos/packages/io/serial/current/ChangeLog,v
> retrieving revision 1.56
> diff -u -r1.56 ChangeLog
> --- packages/io/serial//current/ChangeLog 12 Sep 2003 15:32:49
> -0000 1.56
> +++ packages/io/serial//current/ChangeLog 17 Jan 2004 15:18:38
> -0000
> @@ -1,3 +1,9 @@
> +2004-01-17 Andrew Lunn <andrew.lunn@ascom.ch>
> +
> + * src/common/serial.c (serial_write): Correctly handle
> + none-blocking write. If we can write some bytes, return
> without
> + error. If no bytes can be written return EAGAIN.
> +
> 2003-08-18 Jay Foster <jay@systech.com>
>
> * src/common/serial.c: Fixed bug for XON/XOFF flow control
> that
> Index: packages/io/serial//current/src/common/serial.c
> ===================================================================
> RCS file:
> /cvs/ecos/ecos/packages/io/serial/current/src/common/serial.c,v
> retrieving revision 1.24
> diff -u -r1.24 serial.c
> --- packages/io/serial//current/src/common/serial.c 12 Sep 2003
> 15:32:50 -0000 1.24
> +++ packages/io/serial//current/src/common/serial.c 17 Jan 2004
> 15:18:41 -0000
> @@ -352,9 +352,14 @@
> #ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
> // Optionally return if configured for
> non-blocking mode.
> if (!cbuf->blocking) {
> - *len -= size; // number of characters
> actually sent
> cbuf->waiting = false;
> - res = size == 0 ? -EAGAIN : ENOERR;
> + if (*len == size) {
> + *len == -1; // No bytes can written
> + res = -EAGAIN;
> + } else {
> + *len -= size; // number of characters
> actually sent
> + res = ENOERR;
> + }
> break;
> }
> #endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
__________________________________
Do you Yahoo!?
Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
http://hotjobs.sweepstakes.yahoo.com/signingbonus