How do I set a non-blocking socket back to blocking?

How do I set a non-blocking socket back to blocking?

Post by Peter A. Ko » Thu, 06 Jan 1994 04:00:39



I have a socket that is set non-blocking with

        fcntl(fd, F_SETFL, FNDELAY);

and would like to set it back to blocking. What do I do? Also, since this  
is the "BSD" way what is now the portable manner of setting sockets  
blocking/non-blocking?

--
        Peter A. Korp
        Assistant Scientist
        Argonne National Laboratory

 
 
 

How do I set a non-blocking socket back to blocking?

Post by John Agos » Thu, 06 Jan 1994 05:16:47



:                                                          Also, since this  
: is the "BSD" way what is now the portable manner of setting sockets  
: blocking/non-blocking?

I thought this was a pretty good question, so I looked into it a little.

On HP-UX this is done with an ioctl():

  FIOSNBIO     If the int with the address arg is non-zero, the socket
               is put into non-blocking mode.  Otherwise, the socket
               is put into blocking mode.  Blocking mode is the
               default.  The FIONBIO request is equivalent to the
               FIOSNBIO request, although using FIONBIO is not
               recommended.  See accept(2), connect(2), recv(2), and
               send(2) for an explanation of how non-blocking mode is
               used.

I looked at an HP-UX and a Solaris system to see if there were
commonalities in this area.  The answer, I found a FIONBIO ioctl() on
both systems.  As stated above, HP-UX recommends using FIOSNBIO instead
of FIONBIO.  I could not find the man page information on the Solaris
for ioctl() non/blocking socket settings, but I would guess it is
probably FIONBIO.

At first I thought they would be the same since both are SYSV systems,
BUT . . . these a BSD sockets, so there is no standard.  :-(

--
  John Agosta      

-------------------------------------------------------------------------

 
 
 

How do I set a non-blocking socket back to blocking?

Post by Casper H.S. D » Thu, 06 Jan 1994 05:45:15



Quote:>I have a socket that is set non-blocking with
>    fcntl(fd, F_SETFL, FNDELAY);
>and would like to set it back to blocking. What do I do? Also, since this  
>is the "BSD" way what is now the portable manner of setting sockets  
>blocking/non-blocking?

POSIX seems to suggest:

        fcntl(fd, F_SETFL, fcntl(fd, G_GETFL, 0) & ~O_NONBLOCK);

(Get the currect fd flags, unset the O_NONBLOCK flag and
 use the resulting value as the new flags).

Casper

 
 
 

How do I set a non-blocking socket back to blocking?

Post by Oliver Lauma » Thu, 06 Jan 1994 22:34:08



Quote:> > I have a socket that is set non-blocking [..] and would like to set it
> > back to blocking. What do I do? Also, since [using FNDELAY] is the "BSD"
> > way what is now the portable manner [..]?

>    fcntl(fd, F_SETFL, fcntl(fd, G_GETFL, 0) & ~O_NONBLOCK);

The portable manner probably is to write the code in such a way (using
conditional compilation) that either O_NDELAY *or* O_NONBLOCK can be
used, depending on which of these flags is available on the platform.

Note that not all UNIX versions that support sockets also have O_NONBLOCK;
4.3BSD, for instance, doesn't.

Also, there are subtle differences between O_NDELAY and O_NONBLOCK; on
some systems that support both flags (such as SunOS 5.x), using
O_NDELAY causes future read() calls to return zero if the call would
have blocked, while using O_NONBLOCK causes read() calls to fail with
EAGAIN or EWOULDBLOCK.  You have to keep this in mind when writing a
fully portable program that uses non-blocking I/O.

 
 
 

How do I set a non-blocking socket back to blocking?

Post by Casper H.S. D » Thu, 06 Jan 1994 23:14:04




>> > I have a socket that is set non-blocking [..] and would like to set it
>> > back to blocking. What do I do? Also, since [using FNDELAY] is the "BSD"
>> > way what is now the portable manner [..]?

>>        fcntl(fd, F_SETFL, fcntl(fd, G_GETFL, 0) & ~O_NONBLOCK);
>The portable manner probably is to write the code in such a way (using
>conditional compilation) that either O_NDELAY *or* O_NONBLOCK can be
>used, depending on which of these flags is available on the platform.

In that case, it O_NONBLOCK is the preferred solution, if it
is defined.  O_NONBLOCK has POSIX defined semantics.  System V
and BSD don't agree on what O_NDELAY means.  You don't want SysV
O_NDELAY: It is indistinguishable from EOF.

Quote:>Note that not all UNIX versions that support sockets also have O_NONBLOCK;
>4.3BSD, for instance, doesn't.

4.3BSD is pretty old now, I felt stuff like this sort-of goes w/o
saying:

#if <has POSIX>
 <use POSIX way>
#elif <has BSD way>
 <use BSD>
#elif <has SysV way>
 <use SysV>
#endif

Quote:>Also, there are subtle differences between O_NDELAY and O_NONBLOCK; on
>some systems that support both flags (such as SunOS 5.x), using
>O_NDELAY causes future read() calls to return zero if the call would
>have blocked, while using O_NONBLOCK causes read() calls to fail with
>EAGAIN or EWOULDBLOCK.  You have to keep this in mind when writing a
>fully portable program that uses non-blocking I/O.

This is where the people of SysV goofed: letting read return 0

Casper

 
 
 

How do I set a non-blocking socket back to blocking?

Post by Per Hedela » Fri, 07 Jan 1994 19:22:51



Quote:>In that case, it O_NONBLOCK is the preferred solution, if it
>is defined.  O_NONBLOCK has POSIX defined semantics.  System V
>and BSD don't agree on what O_NDELAY means.  You don't want SysV
>O_NDELAY: It is indistinguishable from EOF.

And of course, SunOS 5 has to give us those broken semantics for the
O_NDELAY that worked fine on SunOS 4 (I think this is a really *
gotcha when going 4 -> 5: Everything compiles fine, and blocking
conditions may not always get tested very thoroughly). Yes I know your
philosophy, SunOS 5 is SysV-based, and you must never change the
semantics of an interface while keeping the name, no matter how broken
the existing semantics are...

Quote:>#if <has POSIX>
> <use POSIX way>
>#elif <has BSD way>
> <use BSD>
>#elif <has SysV way>
> <use SysV>
>#endif

So, does SunOS 4.x[.y] fall in the POSIX clause in this particular case?
fcntl(fd, F_SETFL, O_NONBLOCK) seems to work as expected on at least
4.1.x, but O_NONBLOCK isn't documented as allowed for this purpose
anywhere I can see (e.g. fcntl(2) or fcntl(5)).

--Per Hedeland


...uunet!erix.ericsson.se!per

 
 
 

How do I set a non-blocking socket back to blocking?

Post by Casper H.S. D » Fri, 07 Jan 1994 21:02:31




>>In that case, it O_NONBLOCK is the preferred solution, if it
>>is defined.  O_NONBLOCK has POSIX defined semantics.  System V
>>and BSD don't agree on what O_NDELAY means.  You don't want SysV
>>O_NDELAY: It is indistinguishable from EOF.
>And of course, SunOS 5 has to give us those broken semantics for the
>O_NDELAY that worked fine on SunOS 4 (I think this is a really *
>gotcha when going 4 -> 5: Everything compiles fine, and blocking
>conditions may not always get tested very thoroughly). Yes I know your
>philosophy, SunOS 5 is SysV-based, and you must never change the
>semantics of an interface while keeping the name, no matter how broken
>the existing semantics are...

I must admit that I *really* like to know which idiot decided
to implement O_NDELAY is this way that *totally* breaks the
semantics of read(2).

And who had it first?  BSD 4.? Sys III ? Sys Vr?

What is *really* broken in Solaris 2.x is this:

/usr/ucb/cc fcntl.c
./a.out
O_NDELAY: read returns 0
O_NONBLOCK: read returns -1

(fcntl.c is a small program that tries O_NDELAY and O_NONBLOCK
on stdin and reads from stdin. See also the ucb include files)

Quote:>>#if <has POSIX>
>> <use POSIX way>
>>#elif <has BSD way>
>> <use BSD>
>>#elif <has SysV way>
>> <use SysV>
>>#endif
>So, does SunOS 4.x[.y] fall in the POSIX clause in this particular case?
>fcntl(fd, F_SETFL, O_NONBLOCK) seems to work as expected on at least
>4.1.x, but O_NONBLOCK isn't documented as allowed for this purpose
>anywhere I can see (e.g. fcntl(2) or fcntl(5)).

O_NONBLOCK is, I think, a POSIX invention, because O_NDELAY had
unreconcilable implementation differences and couldn't be used.
It seems that the best choice therefor is to test for O_NONBLOCK
and use that if it exists.  It has well-defined behaviour.

What to choose when O_NONBLOCK isn't defined?
There is no way to choose correctly unless you know what enviroment
you're in.  Even then, if you're out of luck it's SysV w/o O_NONBLOCK.
In that case you have to distinguish between reads returning 0 (EOF)
and reads returning 0 (Operation would block).

Casper

 
 
 

How do I set a non-blocking socket back to blocking?

Post by W. Richard Steve » Fri, 07 Jan 1994 22:40:12


For even more fun, turns out under AIX 3.2.x none of the fcntl()
operations work to set a socket nonblocking--you have to use the
the ioctl() FIONBIO ...


 
 
 

How do I set a non-blocking socket back to blocking?

Post by Per Hedela » Fri, 07 Jan 1994 23:35:57



Quote:>I must admit that I *really* like to know which idiot decided
>to implement O_NDELAY is this way that *totally* breaks the
>semantics of read(2).

>And who had it first?  BSD 4.? Sys III ? Sys Vr?

Unfortunately I don't have a 4.3BSD system running anymore, but I seem to
recall (and some lingering evidence indicates) that the way to set
non-blocking mode was with the FIONBIO *ioctl*, and that the fcntl
implementation was rather half-hearted and mostly for SysV compatibility -
it may well have included a similarly broken O_NDELAY - again, for SysV
compatibility; I'm confident BSD didn't invent such a stupid thing!:-)

Quote:>It seems that the best choice therefor is to test for O_NONBLOCK
>and use that if it exists.  It has well-defined behaviour.

Well, the problem with SunOS 4 is as I mentioned that O_NONBLOCK exists
(and appears to work with fcntl), and is documented for *some* cases
(e.g. open(2)), but not for use with fcntl - specifically, fcntl(2) says:

     F_SETFL        Set descriptor status flags (see fcntl(5) for
                    definitions).   The  following  flags are the
                    only ones whose values may change:  O_APPEND,
                    O_SYNC,  and  O_NDELAY, and the FASYNC, FNDE-
                    LAY, and FNBIO flags defined in <fcntl.h>.

- of course none of those flags are defined in <fcntl.h> but in
<sys/fcntlcom.h>, #included by fcntl.h, and none of them are the same as
O_NONBLOCK, and fcntlcom.h also claims that FAPPEND and FSYNC (which are
the same as O_APPEND and O_SYNC), and FNONBIO (!) (which is the same as
O_NONBLOCK!) work for the F_SETFL fcntl. Hmm, I guess if I didn't lose
myself somewhere in that maze, and include files can be regarded as
documentation, that the answer is that fcntl(fd, F_SETFL, O_NONBLOCK)
*is* (sort of:-) documented to work...

--Per Hedeland


...uunet!erix.ericsson.se!per

 
 
 

How do I set a non-blocking socket back to blocking?

Post by Brandon S. Allbe » Sat, 08 Jan 1994 02:07:43



+---------------

| >I must admit that I *really* like to know which idiot decided
| >to implement O_NDELAY is this way that *totally* breaks the
| >semantics of read(2).
| >
| >And who had it first?  BSD 4.? Sys III ? Sys Vr?
|
| Unfortunately I don't have a 4.3BSD system running anymore, but I seem to
| recall (and some lingering evidence indicates) that the way to set
| non-blocking mode was with the FIONBIO *ioctl*, and that the fcntl
+---------------

Try again.  BSD4.[12] called O_NDELAY FNDELAY.

++Brandon
--

"MSDOS didn't get as bad as it is overnight -- it took over ten years

Do not taunt Happy Fun Coder.   (seen on the Net...)

 
 
 

How do I set a non-blocking socket back to blocking?

Post by Per Hedela » Tue, 18 Jan 1994 23:12:32




|> +---------------

|> | >I must admit that I *really* like to know which idiot decided
|> | >to implement O_NDELAY is this way that *totally* breaks the
|> | >semantics of read(2).
|> | >
|> | >And who had it first?  BSD 4.? Sys III ? Sys Vr?
|> |
|> | Unfortunately I don't have a 4.3BSD system running anymore, but I seem to
|> | recall (and some lingering evidence indicates) that the way to set
|> | non-blocking mode was with the FIONBIO *ioctl*, and that the fcntl
|> +---------------
|>
|> Try again.  BSD4.[12] called O_NDELAY FNDELAY.

Not sure how that particular piece of information contradicts anything I
said, however if you mean to imply that fcntl FNDELAY was the "standard"
way of setting non-blocking mode, you're probably right - at least that
was what was documented in 4.3BSD, whereas ioctl FIONBIO wasn't (I
checked my last 4.3 dump:-).

Anyway, ioctl FIONBIO certainly existed in 4.3BSD, and according to the
source did *exactly* the same thing as fcntl FNDELAY, and O_NDELAY
existed too, #defined to FNDELAY, but only documented for open(2). And
of course either of fcntl/ioctl caused read(2) to return -1 with errno
== EWOULDBLOCK, which was the question I tried to answer...

--Per Hedeland


...uunet!erix.ericsson.se!per

 
 
 

1. Non blocking socket blocks; says 'read would block' ?

Hi all,

I have three sockets in server which I am reading in a continuous loop,
so don't want to wait on any one. I have designated them as 'non blocking'
but when run the server exits on the very first read() and says 'would
block'. (Is it the same as 'EWOULDBLOCK' mentioned in R. Steven's book ?)
I don't want that I should get any error msg and exit, in fact the
whole purpose of nonblocking is that if something is available, read it
else proceed in the loop and come back to read next time.
The client (sender) is sending msgs on all three sockets. The sockets
are conn_oriented. I am using SunOS 4.1. The small code part is below:

int emer_s, env_s, sens_s;            /* socket fds */
//----------- making sockets nonblocking ******
if ((res=fcntl(emer_s,F_SETFL,FNDELAY)) < 0)
        {
          perror("fcntl res = -1");
          exit(1);
        }
if ((res=fcntl(env_s,F_SETFL,FNDELAY)) < 0)
        {
          perror("fcntl res = -1");
          exit(1);
        }
if ((res=fcntl(sens_s,F_SETFL,FNDELAY)) < 0)
        {
          perror("fcntl res = -1");
          exit(1);
        }

for(; ;)
   {

      if ((cc=read(emer_s,(char*)&gen_struct,size)) < size)
        {
        perror("read error");
          exit(1);
        }
......... do something
      if ((cc=read(env_s,(char*)&gen_struct,size)) < size)
        {
         perror("read error");
          exit(1);
        }
        ......... do something
      if ((cc=read(sens_s,(char*)&gen_struct,size)) < size)
        {
          perror("read error");
          exit(1);
        }
        ......... do something

   }

Any help is appreciated.

hashmi

--
-----
Atiqullah Hashmi                    
UTA (Univ. of Texas at Arlington)  

2. 1.0.9 Slackware 2.0 lockup with 86C801 (S3) VGA Chipset

3. Blocking and Non-Blocking socket

4. Printer Problems

5. Non-blocking socket reads block! (Bug?)

6. AIX 4.3.3 on a 580?

7. Difference between blocking and non-blocking socket ?

8. Python Imaging Library and Sketch SUCCESS!

9. What is difference of SYNC, ASYNC, BLOCKING, NON-BLOCKING sockets?

10. Non-blocking sockets on SunOS 4 are blocking

11. select() behavior for Blocking and non-blocking sockets.

12. How do I set a socket to non-blocking?

13. changing socket to blocking after non blocking connect