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:
Lennart Poettering
2019-04-18 15:18:12 +02:00
parent 528fcf8d1d
commit f3d75364fb
+15 -2
View File
@@ -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;