Opened on 01/16/04 at 11:47:00
Closed on 11/29/22 at 21:47:15
#550 closed defect (wontfix)
fcntl() fails to put a non-blocking socket into blocking mode
Reported by: | Thomas Rauscher | Owned by: | Joel Sherrill |
---|---|---|---|
Priority: | normal | Milestone: | 6.1 |
Component: | network/legacy | Version: | 4.5 |
Severity: | major | Keywords: | |
Cc: | bugs@…, joel.sherrill@… | Blocked By: | |
Blocking: |
Description (last modified by Joel Sherrill)
A socket cannot be put into blocking mode using fcntl()
once it has been put into non-blocking mode.
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.
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
# endif
#endif
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.
Release:
RTEMS-4.5
Environment:
rtems-4.5.0, newlib-1.10 or newlib-1.11
Attachments (1)
Change History (9)
comment:1 Changed on 01/16/04 at 18:01:54 by Joel Sherrill
Status: | assigned → waiting |
---|
comment:2 Changed on 11/22/14 at 14:23:02 by Gedare Bloom
Description: | modified (diff) |
---|---|
Milestone: | 2 → 4.9.5 |
comment:3 Changed on 11/22/14 at 14:24:39 by Gedare Bloom
Owner: | changed from Eric Norum to Joel Sherrill |
---|
comment:4 Changed on 11/23/14 at 18:52:45 by Joel Sherrill
I am hacking together a test but I believe this does happen in the current source. It looks like so_ioctl(fd, FIONBIO, [O_NONBLOCK|~O_NONBLOCK]) needs to be called. We have the ioctl_h handler but should we make the call if networking is enabled?
comment:5 Changed on 11/23/14 at 18:56:06 by Joel Sherrill
NOTE that FIONBIO is not defined in newlib -- only in the network stack so that makes for some trouble. I suppose we could modify rtems_syscalls.c to handle F_SETFD.
comment:6 Changed on 02/12/15 at 17:46:49 by Joel Sherrill
Description: | modified (diff) |
---|---|
Milestone: | 4.9.5 → 5.0 |
This is a known issue with many RTOS'. The FACE (http://www.opengroup.org/face) standard has specifically had to add requirements so this behavior is required of RTOSes conforming to the FACE POSIX Profiles. The ioctl() interface is not in POSIX and fcntl() is the only way to set non-blocking in a pure POSIX environment.
I pushed this milestone to 5.0 because:
- this is a long-standing issue.
- it is technically beyond the POSIX standard itself.
- it will need to be addressed with the current IPV4 stack, the new IPV4/IPV6 stack and LWIP if we are to support that.
- this needs test code.
- this needs a design that can work with multiple network stacks.
comment:8 Changed on 11/29/22 at 21:47:15 by Chris Johns
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
The fd handling has evolved and now we have libbsd. If this is still a problem please reopen.
State-Changed-From-To: open->feedback
State-Changed-Why: Thomas .. does this happen in 4.6 or the currect source?