(Non)-Blocking sockets using fcntl()
trauscher at loytec.com
Mon Dec 15 16:02:21 UTC 2003
I've found a problem with putting sockets into blocking/non-blocking
mode using fcntl() in rtems-4.5.0 and probably also rtems-4.6.0pre5.
ioctl() is working fine, so the problem is not in the IP stack.
The problem occurs in real life with the GoAhead webserver on
high-latency connections as its non-blocking write socket remains
non-blocking and a web page can be truncated when websDone() is called.
There have been several threads on this topic, so I hope this
is really a new issue.
In newlib (1.10, 1.11) there are several non-blocking flags.
The following is defined in sys/fcntl.h
#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */
#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */
#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style)
/* O_NDELAY _FNDELAY set in include/fcntl.h */
/* O_NDELAY _FNBIO set in 5include/fcntl.h */
#define O_NONBLOCK _FNONBLOCK
So O_NDELAY is never defined. sys/fcntl.h is not
patched by the rtems-newlib patch.
In RTEMS, libio.c and libio_.h both contain the following code
#if ! defined(O_NDELAY)
# if defined(solaris2)
# define O_NDELAY O_NONBLOCK
# elif defined(RTEMS_NEWLIB)
# define O_NDELAY _FNBIO
As O_NDELAY is undefined and RTEMS_NEWLIB is defined,
O_NDELAY is defined to 0x1000.
Thus, using O_NONBLOCK in fcntl() (this was suggested
in the mailing list some time ago) doesn't seem to work.
There are several workarounds/solutions:
- Define O_NDELAY to O_NONBLOCK in libio (like the newlib would
do if one of the line were not commented out).
Probably this is the cleanest solution but maybe has side-effects
when BSD/SYSV/POSIX code is mixed.
- Don't use fcntl() with O_NONBLOCK on sockets in RTEMS.
This means to fix the call to fcntl() in the web server and
probably other applications I'm not aware of.
In the web server it would be sufficient to let RTEMS use
the ECOS variant in socketSetBlock(). I've tested this.
- Add some logic to the libio/fcntl flags mapping. This could
be problematic if flags are set inconsistently, e.g.
O_NONBLOCK set, _FNBIO not set.
Maybe somebody can confirm this and/or comment my proposed fixes.
If somebody has other patches for this issue, I can test them
(as long as they can be applied to RTEMS 4.5).
LOYTEC electronics GmbH
trauscher at loytec.com
More information about the users