Add the socketpair_full test from [1], fixed by [2], slightly improved by
the addition of a timeout.

This test might perhaps be better named.

This might also serve as an example of how to add new tests.

[1] https://cygwin.com/pipermail/cygwin-developers/2023-July/012640.html
[2] dedbbd74d0a8 ("Cygwin: select: workaround FD_WRITE network event handling")

---
 winsup/testsuite/Makefile.am                  |  1 +
 winsup/testsuite/winsup.api/socketpair_full.c | 59 +++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 winsup/testsuite/winsup.api/socketpair_full.c

diff --git a/winsup/testsuite/Makefile.am b/winsup/testsuite/Makefile.am
index 228955668..28b23b758 100644
--- a/winsup/testsuite/Makefile.am
+++ b/winsup/testsuite/Makefile.am
@@ -48,6 +48,7 @@ check_PROGRAMS = \
        winsup.api/shmtest \
        winsup.api/sigchld \
        winsup.api/signal-into-win32-api \
+       winsup.api/socketpair_full \
        winsup.api/systemcall \
        winsup.api/user_malloc \
        winsup.api/waitpid \
diff --git a/winsup/testsuite/winsup.api/socketpair_full.c 
b/winsup/testsuite/winsup.api/socketpair_full.c
new file mode 100644
index 000000000..d432bc76d
--- /dev/null
+++ b/winsup/testsuite/winsup.api/socketpair_full.c
@@ -0,0 +1,59 @@
+//
+// This test verifies that a socket correctly indicates not ready to write when
+// poll()ed if a subsequent write() would block
+//
+//
+
+#include <assert.h>
+#include <poll.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+static void timeout(int signum)
+{
+  exit(1);
+}
+
+int main()
+{
+  char wbuf[100] = { 0, };
+  int out;
+
+  signal(SIGALRM, timeout);
+
+  {
+    int sv[2];
+    int s;
+
+    s = socketpair (AF_UNIX, SOCK_STREAM, 0, sv);
+    assert (s == 0);
+
+    out = sv[0];
+  }
+
+  size_t in_flight = 0;
+  while (1)
+    {
+      struct pollfd fds[1];
+      fds[0].fd = out;
+      fds[0].events = POLLOUT;
+
+      int r = poll(fds, 1, 0);
+      assert(r >= 0);
+
+      // fd is not ready to write
+      if (!(fds[0].revents & POLLOUT))
+        break;
+
+      alarm(5);
+
+      // otherwise, fd is ready to write, implies some data may be written 
without blocking
+      ssize_t s = write (out, wbuf, sizeof wbuf);
+      assert (s > 0);
+      in_flight += s;
+      printf("%zd written, total in_flight %zd\n", s, in_flight);
+
+      alarm(0);
+    }
+}
-- 
2.39.0

Reply via email to