poll: deal with invalid file descriptors more like specified
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 17 Aug 2014 13:28:36 +0000 (16:28 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Sun, 17 Aug 2014 13:29:41 +0000 (16:29 +0300)
compat/poll.c

index 8c37609..21e6d59 100644 (file)
@@ -114,7 +114,32 @@ int (poll) (struct pollfd *fds, unsigned nfds, int timeout)
     val = select (val + 1, rdset, wrset, exset,
                   (timeout >= 0) ? &tv : NULL);
     if (val == -1)
-        return -1;
+    {
+#ifndef _WIN32
+        if (errno != EBADF)
+#else
+        if (WSAGetLastError () != WSAENOTSOCK)
+#endif
+            return -1;
+
+        val = 0;
+
+        for (unsigned i = 0; i < nfds; i++)
+#ifndef _WIN32
+            if (fcntl (fds[i].fd, F_GETFD) == -1)
+#else
+            if (getsockopt (fds[i].fd, SOL_SOCKET, SO_REUSEADDR,
+                            &(DWORD){ 0 }, &(int){ sizeof (DWORD) }) != 0)
+#endif
+            {
+                fds[i].revents = POLLNVAL;
+                val++;
+            }
+            else
+                fds[i].revents = 0;
+
+        return val ? val : -1;
+    }
 
     for (unsigned i = 0; i < nfds; i++)
     {