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: 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


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