Non-blocking socket still blocking!

Eric Norum eric at cls.usask.ca
Fri Sep 1 21:25:47 UTC 2000


"Smith, Gene" wrote:
> 
> I noticed that my read() on a supposedly non-blocking socket still blocked
> after
> I had read all data from the socket and called read() again.  I then checked
> 
> the socket flags more closely to make sure I was really setting it
> non-blocking
> (O_NONBLOCK is 0x4000) with the following code:
> 
> /* set new_sock non-blocking */
> flags = 0;
> flags = fcntl( new_sock, F_GETFL, 0);
> DTRACE(("\nOrig flags = 0x%x", flags));
> flags = flags | O_NONBLOCK;
> DTRACE(("\nflags|O_NON_BLOCK=0x%x", flags));
> if ( fcntl( new_sock, F_SETFL, flags ) < 0)
>         RTEMS_PANIC(("\nCan't set new_sock non-blocking"));
> DTRACE(("\nflags set to 0x%x", flags));
> 
> /* verify non-blocking flag set */
> flags = 0;
> flags = fcntl( new_sock, F_GETFL, 0);
> if ( (flags & O_NONBLOCK) == 0 )
>         DTRACE(("\nBad flags = 0x%x", flags));
> else
>         DTRACE(("\nGood flags = 0x%x", flags));
> 
> The following output trace indicates that my attempt to set the socket
> non-blocking does not "stick."  (The value "new_sock" is the return value
> from
> accept().) Any ideas why the socket seems to remain blocking?
> 
> Orig flags = 0x2
> flags|O_NON_BLOCK=0x4002
> flags set to 0x4002
> Bad flags = 0x2
> 

This looks like the kind of problem that pops up when merging code from
widely different systems.  The socket-specific fcntl
handler(rtems_bsdnet_fcntl) is being passed a pointer to an
rtems_libio_t but is using the flags in this structure as fcntl flags. 
Unfortunately the flags have been mangled from fcntl to libio by
rtems_libio_fcntl_flags().  

Here's a patch for the socket-specific code.  Unfortunately it seems
that the code in libio.c which is converting the fcntl flags to and from
the libio flags still seems to be clearing the non-blocking
(O_NDELAY/O_NONBLOCK) bit somehow.  I don't have time to look into
this.  Joel??

diff -ur
rtems-ss-20000811.orig/c/src/libnetworking/rtems/rtems_syscall.c
rtems-ss-20000811/c/src/libnetworking/rtems/rtems_syscall.c
--- rtems-ss-20000811.orig/c/src/libnetworking/rtems/rtems_syscall.c   
Mon Jun 12 09:00:08 2000
+++ rtems-ss-20000811/c/src/libnetworking/rtems/rtems_syscall.c Fri Sep 
1 14:54:16 2000
@@ -730,7 +730,7 @@
                        rtems_bsdnet_semaphore_release ();
                        return EBADF;
                }
-               if (iop->flags & O_NONBLOCK)
+               if (iop->flags & LIBIO_FLAGS_NO_DELAY)
                        so->so_state |= SS_NBIO;
                else
                        so->so_state &= ~SS_NBIO;



Amazing how long a bug like this can lurk.  I guess everyone else has
been using ioctl (FIONBIO) to set the non-blocking state!

-- 
Eric Norum                                 eric at cls.usask.ca
Canadian Light Source                      Phone: (306) 966-6308
University of Saskatchewan                 FAX:   (306) 966-6058
Saskatoon, Canada.



More information about the users mailing list