socket-util: make sure flush_accept() doesn't hang on unexpected EOPNOTSUPP
So apparently there are two reasons why accept() can return EOPNOTSUPP: because the socket is not a listening stream socket (or similar), or because the incoming TCP connection for some reason wasn't acceptable to the host. THe latter should be a transient error, as suggested on accept(2). The former however should be considered fatal for flush_accept(). Let's fix this by explicitly checking whether the socket is a listening socket beforehand.
This commit is contained in:
+15
-2
@@ -1225,9 +1225,22 @@ int flush_accept(int fd) {
|
||||
.fd = fd,
|
||||
.events = POLLIN,
|
||||
};
|
||||
int r;
|
||||
int r, b;
|
||||
socklen_t l = sizeof(b);
|
||||
|
||||
/* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
|
||||
/* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately
|
||||
* closing them. */
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0)
|
||||
return -errno;
|
||||
|
||||
assert(l == sizeof(b));
|
||||
if (!b) /* Let's check if this is a socket accepting connections before calling accept(). That's
|
||||
* because accept4() can return EOPNOTSUPP in the fd we are called on is not a listening
|
||||
* socket, or in case the incoming TCP connection transiently triggered that (see accept(2)
|
||||
* man page for details). The latter case is a transient error we should continue looping
|
||||
* on. The former case however is fatal. */
|
||||
return -ENOTTY;
|
||||
|
||||
for (;;) {
|
||||
int cfd;
|
||||
|
||||
Reference in New Issue
Block a user