linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PROBLEM: select() says closed socket readable
@ 2001-08-18  3:28 Jay Rogers
  2001-08-18 16:27 ` kuznet
  0 siblings, 1 reply; 15+ messages in thread
From: Jay Rogers @ 2001-08-18  3:28 UTC (permalink / raw)
  To: linux-kernel

For linux 2.4.2, select() indicates socket ready for read on a
socket that's never been connected.  This is inconsistent with
other versions of Unix including Linux 2.2.

The following program demonstrates:

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    
    main(int argc, char *argv[])
    {
        fd_set rfds;
        int retval;
        int sock;
        struct timeval tv;
    
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1) abort();
    
        FD_ZERO(&rfds);
        FD_SET(sock, &rfds);
        tv.tv_sec = 0;
        tv.tv_usec = 0;
    
        retval = select(sock + 1, &rfds, NULL, NULL, &tv);
        printf("retval from select(): %d\n", retval);
    
        exit(0);
    } /* end main program */

Output from "ver_linux" follows:

Linux costarica 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
 
Gnu C                  2.96
Gnu make               3.79.1
binutils               2.10.91.0.2
util-linux             2.10r
modutils               2.4.2
e2fsprogs              1.19
reiserfsprogs          3.x.0f
pcmcia-cs              3.1.22
PPP                    2.4.0
Linux C Library        2.2.2
Dynamic linker (ldd)   2.2.2
Procps                 2.0.7
Net-tools              1.57
Console-tools          0.3.3
Sh-utils               2.0
Modules Loaded         nfs lockd sunrpc nls_iso8859-1 ide-cd cdrom autofs 3c59x ipchains usb-uhci usbcore

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-18  3:28 PROBLEM: select() says closed socket readable Jay Rogers
@ 2001-08-18 16:27 ` kuznet
  2001-08-18 22:52   ` Ton Hospel
                     ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: kuznet @ 2001-08-18 16:27 UTC (permalink / raw)
  To: jay; +Cc: linux-kernel

Hello!

> For linux 2.4.2, select() indicates socket ready for read on a
> socket that's never been connected. 

Right. It does not block on read, hence it is readable.


>					 This is inconsistent

This is perfectly consistent. Reaction to bugs in applications
is undefined.

Alexey

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-18 16:27 ` kuznet
@ 2001-08-18 22:52   ` Ton Hospel
  2001-08-20 14:34   ` Jay Rogers
  2001-08-20 15:03   ` David S. Miller
  2 siblings, 0 replies; 15+ messages in thread
From: Ton Hospel @ 2001-08-18 22:52 UTC (permalink / raw)
  To: linux-kernel

In article <200108181627.UAA19351@ms2.inr.ac.ru>,
	kuznet@ms2.inr.ac.ru writes:
> Hello!
>
>> For linux 2.4.2, select() indicates socket ready for read on a
>> socket that's never been connected.
>
> Right. It does not block on read, hence it is readable.
>

mm, that's not really the rule, since e.g. you want to be able to select
on read and write on the write side of a pipe, and would expect to only
get readable on error/close:

But there's weird stuff going on here (examples need perl >= 5.6.0):

perl -wle 'use POSIX; pipe(my $rd, my $wr)||die $!; my $fd = fileno($wr); my $mask=""; vec($mask, $fd, 1)=1; select(my $r=$mask, my $w=$mask, "", undef); print "readable" if vec($r, $fd, 1); print "writable" if vec($w, $fd, 1); my $rc = POSIX::read($fd, my $buf, 4096) || die "read returns $!"; print STDERR $rc'

prints:

writable
read returns Bad file descriptor at -e line 1.

Which is in fact weird, since I still have the $rd descriptor around, so
the read should block (it does on solaris). This seems a bug.

perl -wle 'use POSIX; pipe(my $rd, my $wr)||die $!; close $rd; my $fd = fileno($wr); my $mask=""; vec($mask, $fd, 1)=1; select(my $r=$mask, my $w=$mask, "", undef); print "readable" if vec($r, $fd, 1); print "writable" if vec($w, $fd, 1); my $rc = POSIX::read($fd, my $buf, 4096) || die "read returns $!"; print STDERR $rc'

prints:

readable
writable
read returns Bad file descriptor at -e line 1.

Which is the behaviour you want (the read does not block in either case),
closing the other side causes readability. This allows you to watch a
connection for errors without being bothered by EOF (so it's good, but
contrary to your statement).
However, the reaction on read is still weird. on solaris I get in fact EOF,
not Bad file descriptor

In fact, somewhat related, i last week ran into this:

perl -wle 'use Socket; use POSIX; socketpair(my $rd, my $wr, AF_UNIX, SOCK_STREAM, PF_UNSPEC)||die $!; shutdown($rd, 1); shutdown($wr, 0); my $fd = fileno($wr); my $mask=""; vec($mask, $fd, 1)=1; select(my $r=$mask, my $w=$mask, "", undef); print "readable" if vec($r, $fd, 1); print "writable" if vec($w, $fd, 1); my $rc = POSIX::read($fd, my $buf, 4096) || die "read returns $!"; print STDERR $rc'

which prints:

readable
writable
0 but true

(so the read returns EOF). Which is very unfortunate, because it means a
pipe is not equivalent to a socketpair where you make one side only
readable and one only writable (the way it's supposedly implemented on
some OSes) Solaris and freebsd behaves the same as linux by the way.
On the other hand, you *do* want to know if the other side does a
shutdown, so in that sense the behaviour is good.

Damn, i wish this socket stuff would finally get completely standardized.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-18 16:27 ` kuznet
  2001-08-18 22:52   ` Ton Hospel
@ 2001-08-20 14:34   ` Jay Rogers
  2001-08-20 19:48     ` David Schwartz
  2001-08-20 15:03   ` David S. Miller
  2 siblings, 1 reply; 15+ messages in thread
From: Jay Rogers @ 2001-08-20 14:34 UTC (permalink / raw)
  To: kuznet; +Cc: linux-kernel

> From: kuznet@ms2.inr.ac.ru
> > For linux 2.4.2, select() indicates socket ready for read on a
> > socket that's never been connected. 
> 
> Right. It does not block on read, hence it is readable.

No, a socket that's never been connected isn't readable, hence
select() shouldn't be returning a value of 1 on it.

> >					 This is inconsistent
> 
> This is perfectly consistent. Reaction to bugs in applications
> is undefined.

No this behavior isn't consistent with previous versions of Linux
nor is it consistent with other implementations of Unix.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-18 16:27 ` kuznet
  2001-08-18 22:52   ` Ton Hospel
  2001-08-20 14:34   ` Jay Rogers
@ 2001-08-20 15:03   ` David S. Miller
  2001-08-20 15:29     ` Udo A. Steinberg
  2001-08-21  9:02     ` Mike Jagdis
  2 siblings, 2 replies; 15+ messages in thread
From: David S. Miller @ 2001-08-20 15:03 UTC (permalink / raw)
  To: jay; +Cc: kuznet, linux-kernel

   From: Jay Rogers <jay@rgrs.com>
   Date: Mon, 20 Aug 2001 10:34:09 -0400

   > Right. It does not block on read, hence it is readable.
   
   No, a socket that's never been connected isn't readable, hence
   select() shouldn't be returning a value of 1 on it.

You may read without blocking, select() returns 1.

Please, fix your app.

Later,
David S. Miller
davem@redhat.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-20 15:03   ` David S. Miller
@ 2001-08-20 15:29     ` Udo A. Steinberg
  2001-08-21  9:02     ` Mike Jagdis
  1 sibling, 0 replies; 15+ messages in thread
From: Udo A. Steinberg @ 2001-08-20 15:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: kuznet, linux-kernel

"David S. Miller" wrote:
> 
>    No, a socket that's never been connected isn't readable, hence
>    select() shouldn't be returning a value of 1 on it.
> 
> You may read without blocking, select() returns 1.
> 
> Please, fix your app.

Hello,

While we're at it - are there any plans to fix the other
select issue which was already discussed in December 2000? The
original thread can be found at:

http://uwsg.iu.edu/hypermail/linux/net/0012.2/0008.html

I realize that the behaviour doesn't violate the standards, but
as Alexey said - it's still somewhat wrong.

-Udo.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PROBLEM: select() says closed socket readable
  2001-08-20 14:34   ` Jay Rogers
@ 2001-08-20 19:48     ` David Schwartz
  0 siblings, 0 replies; 15+ messages in thread
From: David Schwartz @ 2001-08-20 19:48 UTC (permalink / raw)
  Cc: linux-kernel


> No, a socket that's never been connected isn't readable, hence
> select() shouldn't be returning a value of 1 on it.

	It is readable. A read that produces an error is still a read.

	DS


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-20 15:03   ` David S. Miller
  2001-08-20 15:29     ` Udo A. Steinberg
@ 2001-08-21  9:02     ` Mike Jagdis
  2001-08-21 17:35       ` David Schwartz
  1 sibling, 1 reply; 15+ messages in thread
From: Mike Jagdis @ 2001-08-21  9:02 UTC (permalink / raw)
  To: David S. Miller; +Cc: jay, kuznet, linux-kernel

David S. Miller wrote:
>    From: Jay Rogers <jay@rgrs.com>
>    Date: Mon, 20 Aug 2001 10:34:09 -0400
> 
>    > Right. It does not block on read, hence it is readable.
>    
>    No, a socket that's never been connected isn't readable, hence
>    select() shouldn't be returning a value of 1 on it.
> 
> You may read without blocking, select() returns 1.

By this logic a socket that is set non-blocking should always be
treated as readable. I think we can all agree that argument is
flawed :-).


The prevailing view from other systems appears to be that reading
from an unconnected (or unconnectING) socket is meaningless so
the socket is not readable.

Presumably there is a damn good reason, or a standards reference,
why that is the wrong behaviour and should be changed?

				Mike


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PROBLEM: select() says closed socket readable
  2001-08-21  9:02     ` Mike Jagdis
@ 2001-08-21 17:35       ` David Schwartz
  2001-08-21 18:38         ` Alan Cox
  2001-08-22  9:26         ` Mike Jagdis
  0 siblings, 2 replies; 15+ messages in thread
From: David Schwartz @ 2001-08-21 17:35 UTC (permalink / raw)
  To: Mike Jagdis; +Cc: linux-kernel


> David S. Miller wrote:
> >    From: Jay Rogers <jay@rgrs.com>
> >    Date: Mon, 20 Aug 2001 10:34:09 -0400
> >
> >    > Right. It does not block on read, hence it is readable.
> >
> >    No, a socket that's never been connected isn't readable, hence
> >    select() shouldn't be returning a value of 1 on it.
> >
> > You may read without blocking, select() returns 1.

> By this logic a socket that is set non-blocking should always be
> treated as readable. I think we can all agree that argument is
> flawed :-).

	No, because 'select' is defined to work the same on both blocking and
non-blocking sockets. Roughly, select should hit on read if a non-blocking
read wouldn't return 'would block'.

> The prevailing view from other systems appears to be that reading
> from an unconnected (or unconnectING) socket is meaningless so
> the socket is not readable.

	So is reading from a closed or errored socket. There is nothing to wait
for, so why should the system call wait?

> Presumably there is a damn good reason, or a standards reference,
> why that is the wrong behaviour and should be changed?

	If you think about the cases where someone might actually do this, odds are
you want the application's error handling code to launch. That won't happen
if you never break out of select. However, if you do break out of select, do
a read, and get an error, the problem will then be handled, rather than
ignored.

	DS


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-21 17:35       ` David Schwartz
@ 2001-08-21 18:38         ` Alan Cox
  2001-08-21 19:01           ` David Schwartz
  2001-08-22  9:26         ` Mike Jagdis
  1 sibling, 1 reply; 15+ messages in thread
From: Alan Cox @ 2001-08-21 18:38 UTC (permalink / raw)
  To: David Schwartz; +Cc: Mike Jagdis, linux-kernel

> 	No, because 'select' is defined to work the same on both blocking and
> non-blocking sockets. Roughly, select should hit on read if a non-blocking
> read wouldn't return 'would block'.

Select is not reliable for a blocking socket in all cases. There is always 
a risk select may return "data to read" and the read will find there is now
none. It isnt going to bite anyone on Linux with our current protocols but
it may bite portable code

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PROBLEM: select() says closed socket readable
  2001-08-21 18:38         ` Alan Cox
@ 2001-08-21 19:01           ` David Schwartz
  0 siblings, 0 replies; 15+ messages in thread
From: David Schwartz @ 2001-08-21 19:01 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel


> > No, because 'select' is defined to work the same on both
> > blocking and
> > non-blocking sockets. Roughly, select should hit on read if a
> > non-blocking
> > read wouldn't return 'would block'.

> Select is not reliable for a blocking socket in all cases. There
> is always
> a risk select may return "data to read" and the read will find
> there is now
> none. It isnt going to bite anyone on Linux with our current protocols but
> it may bite portable code

	I should have continued my sentence with "if it was issued at the instant
'select' made that decision." Using 'select' on blocking sockets is usually
an error. Nevertheless, select itself is defined to work the same on both
blocking and non-blocking sockets. In general, there is no way the operating
system can make guarantees about the future state of a socket.

	DS


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-21 17:35       ` David Schwartz
  2001-08-21 18:38         ` Alan Cox
@ 2001-08-22  9:26         ` Mike Jagdis
  2001-08-22 21:40           ` David Schwartz
  1 sibling, 1 reply; 15+ messages in thread
From: Mike Jagdis @ 2001-08-22  9:26 UTC (permalink / raw)
  To: David Schwartz; +Cc: linux-kernel

David Schwartz wrote:

> 	No, because 'select' is defined to work the same on both blocking and
> non-blocking sockets. Roughly, select should hit on read if a non-blocking
> read wouldn't return 'would block'.

Which may be the root of the problem. Linux seems to consider that
select indicates "would not block", whereas Solaris et. al. use
"ready to read". (The difference seems to exist in man pages too)
Clearly an unconnected socket "would not block" but is not
"ready to read".

> 	If you think about the cases where someone might actually do this, odds are
> you want the application's error handling code to launch. That won't happen
> if you never break out of select. However, if you do break out of select, do
> a read, and get an error, the problem will then be handled, rather than
> ignored.

No. If there is a correct behaviour defined in a standard we should
do that. Otherwise we should do what other systems do _unless_ there
is a clear benefit to doing something else. In this case doing
something else appears to create porting problems and confusion over
what select(2) means without any clear benefit.

So, we're back to the beginning: justify with reference or reason :-).

				Mike


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PROBLEM: select() says closed socket readable
  2001-08-22  9:26         ` Mike Jagdis
@ 2001-08-22 21:40           ` David Schwartz
  2001-08-23 10:30             ` Mike Jagdis
  2001-08-23 10:56             ` [PATCH] " Mike Jagdis
  0 siblings, 2 replies; 15+ messages in thread
From: David Schwartz @ 2001-08-22 21:40 UTC (permalink / raw)
  To: Mike Jagdis; +Cc: linux-kernel


> No. If there is a correct behaviour defined in a standard we should
> do that. Otherwise we should do what other systems do _unless_ there
> is a clear benefit to doing something else. In this case doing
> something else appears to create porting problems and confusion over
> what select(2) means without any clear benefit.

> 				Mike

	There is a clear and significant benefit. Bugs that result in a program
calling 'select' on an unconnected socket will be easily and quickly
detected. During debugging, they can then be fixed. During release
execution, they can be worked around.

	There are a large number of possible mistakes that can result in this
behavior. A program that heavily uses sockets could sometimes forget to
remove a socket from its active poll/select set. A program might
accidentally close the wrong socket (and that socket might get reused by a
subsequent call to 'socket'). It's nice to have a way to catch these. During
debug, socket errors are routinely logged or displayed, so this would get
caught.

	Of course, this isn't so much of a benefit that it's worth violating a
standard like POSIX. But it could be considered enough of a benefit that
it's worth not being compatable outside the bounds of such a standard.

	DS


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PROBLEM: select() says closed socket readable
  2001-08-22 21:40           ` David Schwartz
@ 2001-08-23 10:30             ` Mike Jagdis
  2001-08-23 10:56             ` [PATCH] " Mike Jagdis
  1 sibling, 0 replies; 15+ messages in thread
From: Mike Jagdis @ 2001-08-23 10:30 UTC (permalink / raw)
  To: David Schwartz; +Cc: linux-kernel

David Schwartz wrote:

[assumptions deleted]

> 	Of course, this isn't so much of a benefit that it's worth violating a
> standard like POSIX. But it could be considered enough of a benefit that
> it's worth not being compatable outside the bounds of such a standard.

Let's think about the _facts_ for a second. In the case where select on
an unconnected socket succeeds (because a read would not block) a
process that does this would not sleep in select. If the select does
not succeed (because the socket is not ready to read) then the process
sleeps.

In the first case the process either eats CPU time or gets an error
when it reads the socket. But does it handle the error? Does it even
do the read - why should it read the unconnected socket at all?

In the second case the process either hangs or behaves as expected.
It may even recover gracefully if the socket is subsequently connected.

Case 1 leads to spin-or-die and case 2 leads to block-and-work.

Case 1 assumes that selecting for read on an unconnected socket is
an error. Case 2 doesn't - an unconnected socket is simply never
"ready to read".

Other systems use the "ready to read" interpretation. The Single
UNIX Spec states "ready to read". The Linux man page uses "ready
to read" but adds a parenthetical "read will not block" to allow
EOF. Linux itself implements "will not block".

I can find nothing that even suggests that selecting on an unconnected
socket is an error.

Linux is wrong. Patch follows.

				Mike


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH] select() says closed socket readable
  2001-08-22 21:40           ` David Schwartz
  2001-08-23 10:30             ` Mike Jagdis
@ 2001-08-23 10:56             ` Mike Jagdis
  1 sibling, 0 replies; 15+ messages in thread
From: Mike Jagdis @ 2001-08-23 10:56 UTC (permalink / raw)
  To: David Schwartz, Linus Torvalds, Alan Cox; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 822 bytes --]

Whoa! It isn't that select/poll is saying that a read wouldn't
block. It's saying that the socket has been hung up (POLLHUP
not POLLIN)! This is even worse - POLLHUP is always tested
for even of the user didn't ask for it. So if an unconnected
socket appears _anywhere_ in a select or poll we are heading
for spin city, regardless of whether we asked for read, write,
errors or even nothing (in the case of poll)!

Older Linux kernels (2.2.18 at least) blocked on unconnected
TCP sockets but returned POLLHUP on unix sockets. Current
kernels return POLLHUP in both cases. It looks like TCP was
fixed to match unix instead of vice-versa.

A quick poll (<grin>) of available machines here show that
both Sun and FreeBSD block for both TCP and unix unconnected
sockets.

The attached patch _should_ be applied :-).

				Mike

[-- Attachment #2: poll.diff --]
[-- Type: text/plain, Size: 1113 bytes --]

--- linux.old/net/ipv4/tcp.c	Fri Jul  6 13:50:00 2001
+++ linux/net/ipv4/tcp.c	Thu Aug 23 11:29:15 2001
@@ -415,11 +415,8 @@
 	 * then we could set it on SND_SHUTDOWN. BTW examples given
 	 * in Stevens' books assume exactly this behaviour, it explains
 	 * why PULLHUP is incompatible with POLLOUT.	--ANK
-	 *
-	 * NOTE. Check for TCP_CLOSE is added. The goal is to prevent
-	 * blocking on fresh not-connected or disconnected socket. --ANK
 	 */
-	if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE)
+	if (sk->shutdown == SHUTDOWN_MASK)
 		mask |= POLLHUP;
 	if (sk->shutdown & RCV_SHUTDOWN)
 		mask |= POLLIN | POLLRDNORM;
--- linux.old/net/unix/af_unix.c	Tue Jul 24 21:32:01 2001
+++ linux/net/unix/af_unix.c	Thu Aug 23 11:31:58 2001
@@ -1711,8 +1711,8 @@
 	if (!skb_queue_empty(&sk->receive_queue) || (sk->shutdown&RCV_SHUTDOWN))
 		mask |= POLLIN | POLLRDNORM;
 
-	/* Connection-based need to check for termination and startup */
-	if (sk->type == SOCK_STREAM && sk->state==TCP_CLOSE)
+	/* Connection-based need to check for termination */
+	if (sk->type == SOCK_STREAM)
 		mask |= POLLHUP;
 
 	/*

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2001-08-23 10:56 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-18  3:28 PROBLEM: select() says closed socket readable Jay Rogers
2001-08-18 16:27 ` kuznet
2001-08-18 22:52   ` Ton Hospel
2001-08-20 14:34   ` Jay Rogers
2001-08-20 19:48     ` David Schwartz
2001-08-20 15:03   ` David S. Miller
2001-08-20 15:29     ` Udo A. Steinberg
2001-08-21  9:02     ` Mike Jagdis
2001-08-21 17:35       ` David Schwartz
2001-08-21 18:38         ` Alan Cox
2001-08-21 19:01           ` David Schwartz
2001-08-22  9:26         ` Mike Jagdis
2001-08-22 21:40           ` David Schwartz
2001-08-23 10:30             ` Mike Jagdis
2001-08-23 10:56             ` [PATCH] " Mike Jagdis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).