Notice: We have migrated to GitLab launching 2024-05-01 see here:

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

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 */

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

#if ! defined(O_NDELAY)
# if defined(solaris2)
# elif defined(RTEMS_NEWLIB)
# define O_NDELAY _FNBIO
# 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.


rtems-4.5.0, newlib-1.10 or newlib-1.11

Attachments (1)

socketblock.c (6.7 KB) - added by Thomas Rauscher on 12/03/06 at 13:31:12.

Download all attachments as: .zip

Change History (9)

comment:1 Changed on 01/16/04 at 18:01:54 by Joel Sherrill

Status: assignedwaiting

State-Changed-From-To: open->feedback
State-Changed-Why: Thomas .. does this happen in 4.6 or the currect source?

I don't see this problem in the current code. At this
point, no further releases from the 4.5 branch are planned
so I am prone to close any bug report against it.

Changed on 12/03/06 at 13:31:12 by Thomas Rauscher

Attachment: socketblock.c added


comment:2 Changed on 11/22/14 at 14:23:02 by Gedare Bloom

Description: modified (diff)
Milestone: 24.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)

This is a known issue with many RTOS'. The 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:7 Changed on 11/09/17 at 06:26:42 by Sebastian Huber

Milestone: 5.06.1

Milestone renamed

comment:8 Changed on 11/29/22 at 21:47:15 by Chris Johns

Resolution: wontfix
Status: assignedclosed

The fd handling has evolved and now we have libbsd. If this is still a problem please reopen.

Note: See TracTickets for help on using tickets.