[solved] [Single UNIX Spec.] select system call for sockets

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
karuon
Posts: 22
Joined: Sat Jun 29, 2013 6:16 am

[solved] [Single UNIX Spec.] select system call for sockets

Post by karuon »

Hi,

I'm currently struggling to implement a decent version of select() system call for my OS. I have read some pages from The Single UNIX Specification (http://pubs.opengroup.org/onlinepubs/00 ... elect.html and http://pubs.opengroup.org/onlinepubs/00 ... elect.html) as well the manual pages from my Linux distribution but there are still shades of grey concerning sockets. In fact, up to now, I have only implemented TCP sockets, so here, "socket" will mean "TCP socket".

Let's consider for instance the following statement:
If the readfds argument is not a null pointer, it points to an object of type fd_set that on input specifies the file descriptors to be checked for being ready to read, and on output indicates which file descriptors are ready to read.
But what does "to be ready to read" mean for a socket? At first, I thought it meant the socket had data in its receive buffer. However, after experimenting a bit, it appeared to me that it was not so simple. Indeed, after the connection is closed by the remote host, executing select() on the local host returns 1 and says the socket is ready for read, since the socket file descriptor is still set in the readfds set after select() returns. It seems quite strange to me, and I could not find any explanation neither in the Single UNIX Specification nor in the Linux manual (but maybe I didn't look at the right place).

Could you please help me if you have experienced troubles implementing select() or if you have more complete doc. ?

Thanks in advance.
Last edited by karuon on Thu Aug 22, 2013 3:55 pm, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: [Single UNIX Specification] select system call for socke

Post by Combuster »

after the connection is closed by the remote host, executing select() on the local host returns 1 and says the socket is ready for read
Closing the connection is a graceful process - the server will still send and resend data that was queued up before the close of the connection, and as such there can be enough left to read.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
karuon
Posts: 22
Joined: Sat Jun 29, 2013 6:16 am

Re: [Single UNIX Specification] select system call for socke

Post by karuon »

Combuster wrote:Closing the connection is a graceful process - the server will still send and resend data that was queued up before the close of the connection, and as such there can be enough left to read.
Yes, I know the server can send and resend unacknowledged data after closing the connection.

The problem is that, after the server closes the connection, select() from the client side always returns 1 (and doesn't clear the socket fd in readfds set) even if there is no data available in the receive buffer of the socket and even if the server didn't send any more data after closing the connection.
When the connection is opened (and not half-closed), it is different : when there's no data in the socket's receive buffer, select() on this socket (socket fd belonging to readfds) returns 0, and when data is available, select() returns 1.

It seems select() behaves differently when the connection is closed or half-closed. Why ?
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: [Single UNIX Specification] select system call for socke

Post by Owen »

Because the system needs a way to notify you that the socket is closed?

A file descriptor being "readable" doesn't necessarily indicate that it has data available - but that it has data related to the input stream associated with said file descriptor (being as sockets are an odder form of file descriptor with disjoint input and output streams)

In this case, it's saying "Call recv/read/recvmsg/recvfrom/whichever you want in order to get more information"

When you do that, you'll get an error return and errno set to tell you that the input side of the connection is now closed.

The socket will remain readable, because you haven't cleared the condition that caused it to be readable in the first place. Note that the readable flag will be asserted until there is no data available to read, and that it can be asserted spuriously.
karuon
Posts: 22
Joined: Sat Jun 29, 2013 6:16 am

Re: [Single UNIX Specification] select system call for socke

Post by karuon »

Ok, thank you. :)
JacobL
Posts: 5
Joined: Thu Aug 08, 2013 1:04 pm

Re: [Single UNIX Specification] select system call for socke

Post by JacobL »

To add to Owen's reply:
A more exact definition of the select system call is that a specific file descriptor will be set in readfds if a read operation on that file descriptor does not block. Likewise for write.
karuon
Posts: 22
Joined: Sat Jun 29, 2013 6:16 am

Re: [Single UNIX Specification] select system call for socke

Post by karuon »

Thanks for the precision, JacobL.
Post Reply