select for UNIX sockets?
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" andsendto()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 <<< blocksCould. 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]
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 doconnect(),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....
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 doconnect(),select(),send(), then it should work, unless I missed something.We
FD_SETthe 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-ENOTCONNrather 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]