Bug 446206 - select() on listening socket returns prematurely
Summary: select() on listening socket returns prematurely
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel
Version: 8
Hardware: All
OS: Linux
low
medium
Target Milestone: ---
Assignee: Neil Horman
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2008-05-13 14:41 UTC by Ed Man
Modified: 2008-05-13 15:44 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2008-05-13 15:44:28 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
test case to show functionality of select (2.87 KB, text/plain)
2008-05-13 15:43 UTC, Neil Horman
no flags Details

Description Ed Man 2008-05-13 14:41:38 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14

Description of problem:
I run Fedora 8 64bit and also tested on RH-ES-R3 with kernel 2.4.21-15.ELsmp on an i386. A select() call would return indicating a file descriptor is ready for reading if I had only one file descriptor and it is for a listening socket.

Create a server socket (socket())
Bind to localhost and port (bind())
Do select() for reading on socket (instead of listen())
select() returns immediately even when no process tries to connect to it.
listen() would wait until a connection request comes in. The error fd set does not indicate an error.

If using poll() instead of select(), poll() also returns immediately but revents indicate POLLHUP is set.

Solaris works properly on the select().

Version-Release number of selected component (if applicable):


How reproducible:
Always


Steps to Reproduce:
1. sin.sin_family = AF_INET;
   sin.sin_addr.s_addr = inet_addr("127.0.0.1");
   sin.sin_port = htons(22222);
   tv.tv_sec = 60;
   tv.tv_usec = 0;

2. s = socket( AF_INET, SOCK_STREAM, 0 )
3. FD_ZERO( &rdset );
   FD_ZERO( &errset );
   FD_SET( s, &rdset );
   FD_SET( s, &errset );
4. bind( s, (struct sockaddr*) &sin, sizeof(sin))
5. n = select( nfds, &rdset, NULL, &errset, &tv ))
6. FD_ISSET( s, &rdset )
7. listen( s, 6 )

select() returns 1 immediately with FD_ISSET(s, &rdset)being true even when no process tries to connect to it. A listen(s,6) would wait until a connect comes in.



Actual Results:
Select() returns immediately indicating socket reading for reading and error fd set does not indicate an error.

Poll() returns immediately indicating POLLHUP in revents.

Expected Results:
With listening sockets, select() should only return when there is an inbound connection request (when listen() would return with connection indication).

Poll() should return when there is an inbound connection request. Why did it return with POLLHUP anyway?

Additional info:

Comment 1 Neil Horman 2008-05-13 15:43:23 UTC
Created attachment 305244 [details]
test case to show functionality of select

I think you're misunderstanding how select works.  You're assumption that
listening sockets should block on select until a connection attempt is made is
correct, but in your test steps you don't set the socket to listen until
_after_ you preform the select operation.  Select simply indicates when the
corresponding read or write action would not block, not until data is
available..  As such, since you haven't set the socket to listen, when you call
select on a connection oriented socket (SOCK_STREAM), it returns right away
indicating your socket is readable, because a subsequent read of the socket
will return ENOTCONN right away.  I've included a program above to illustrate
this.

This is working as it is intended


Note You need to log in before you can comment on or make changes to this bug.