MEDIUM: listener: provide a fallback for accept4() when not supported
authorWilly Tarreau <w@1wt.eu>
Mon, 22 Oct 2012 17:32:55 +0000 (19:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 22 Oct 2012 17:32:55 +0000 (19:32 +0200)
It happens that on some systems, the libc is recent enough to permit
building with accept4() but the kernel does not support it. The result
is then a disaster since no connection is accepted. We now detect this
and automatically fall back to accept() and fcntl() when this happens.

src/listener.c

index c4259bc..6781e58 100644 (file)
@@ -311,6 +311,11 @@ void listener_accept(int fd)
 
 #ifdef USE_ACCEPT4
                cfd = accept4(fd, (struct sockaddr *)&addr, &laddr, SOCK_NONBLOCK);
+               if (unlikely(cfd == -1 && errno == EINVAL)) {
+                       /* unsupported syscall, fallback to normal accept()+fcntl() */
+                       if ((cfd = accept(fd, (struct sockaddr *)&addr, &laddr)) != -1)
+                               fcntl(cfd, F_SETFL, O_NONBLOCK);
+               }
 #else
                cfd = accept(fd, (struct sockaddr *)&addr, &laddr);
 #endif