Skip to contentSkip to conversation

select for UNIX sockets?

DISCUSSION Petr Vandrovec 2 participants 3 messages Jun 4, 2003 – Jun 6, 2003

lore
Share & tools
lore
#0 lore raw
Quoted 24 lines · Jesse Pollard
Quoted 23 lines · Krzysztof Halasa

Hi,

Should something like this work correctly?

while(1) {
        FD_ZERO(&set);
        FD_SET(fd, &set);
        select(FD_SETSIZE, NULL, &set, NULL, NULL); <<<<<<< for writing

        if (FD_ISSET(fd, &set))
                sendto(fd, &datagram, 1, 0, ...);
}

fd is a normal local datagram socket. It looks select() returns with "fd ready for write" and sendto() then blocks as the queue is full.

I don't know if it's expected behaviour or just a not yet known bug. Of course, I have a more complete test program if needed.

2.4.21rc6, haven't tried any other version.

strace shows:

Quoted 8 lines
Quoted 3 lines

select(1024, NULL, [3], NULL, NULL) = 1 (out [3])
sendto(3, "\0", 1, 0, {sa_family=AF_UNIX, path="/tmp/tempUn"}, 13 <<< blocks

Could. There may be room for the buffer, but unless it is set to nonblock, you may have a stream open to another host that may not accept the data (busy, network congestion...) With the required acks, the return may (should?) be delayed until the ack arrives.

Besides that select() on unconnected socket is nonsense... If you'll change code to do connect(), select(), send(), then it should work, unless I missed something.
Petr Vandrovec [email protected]

#1 lore raw
Quoted 10 lines · Petr Vandrovec
Quoted 6 lines
Quoted 6 lines
        FD_ZERO(&set);
        FD_SET(fd, &set);
        select(FD_SETSIZE, NULL, &set, NULL, NULL); <<<<<<< for writing

        if (FD_ISSET(fd, &set))
                sendto(fd, &datagram, 1, 0, ...);

Besides that select() on unconnected socket is nonsense... If you'll change code to do connect(), select(), send(), then it should work, unless I missed something.

We FD_SET the bit, ignore the return value of select, and test if the bit is still set. Plenty of programming bad karma there. However, one would vaguely hope that the kernel would notice that the socket isn't connected and -ENOTCONN rather than blocking....

#2 lore raw
Quoted 9 lines · On Thu, Jun 05, 2003 at 08:28:46PM -0400, [email protected] wrote:
Quoted 6 lines · Petr Vandrovec
Quoted 6 lines
Quoted 6 lines
        FD_ZERO(&set);
        FD_SET(fd, &set);
        select(FD_SETSIZE, NULL, &set, NULL, NULL); <<<<<<< for writing

        if (FD_ISSET(fd, &set))
                sendto(fd, &datagram, 1, 0, ...);
Quoted 8 lines
Quoted 3 lines

Besides that select() on unconnected socket is nonsense... If you'll change code to do connect(), select(), send(), then it should work, unless I missed something.

We FD_SET the bit, ignore the return value of select, and test if the bit is still set. Plenty of programming bad karma there. However, one would vaguely hope that the kernel would notice that the socket isn't connected and -ENOTCONN rather than blocking....

You'll get ENOTCONN from send, just sendto blocks. select() returns that fd is ready because this end of socket is ready, and there is probably at least one UNIX socket on the system which is ready to accept data - so I think that it is correct that select() returns data ready.

I think that whole problem comes from code's author idea that UNIX datagram sockets are equivalent to UDP through localhost while they are completely different thing.
Petr Vandrovec [email protected]