test: Add test for unix socket cross/self reference
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 6 Nov 2015 15:58:28 +0000 (23:58 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 9 Nov 2015 14:03:49 +0000 (22:03 +0800)
cross ref: s1 on s2 rcvbuf, while s2 on s1 rcvbuf.
self ref: s1 on s1 rcvbuf, while s2 on s2 rcvbuf.

test/unix/loopdesc/Makefile [new file with mode: 0644]
test/unix/loopdesc/loopdesc.c [new file with mode: 0644]

diff --git a/test/unix/loopdesc/Makefile b/test/unix/loopdesc/Makefile
new file mode 100644 (file)
index 0000000..9d64565
--- /dev/null
@@ -0,0 +1,6 @@
+PROG = loopdesc
+WARNS = 6
+NOMAN = YES
+BINDIR=        /usr/local/bin
+
+.include <bsd.prog.mk>
diff --git a/test/unix/loopdesc/loopdesc.c b/test/unix/loopdesc/loopdesc.c
new file mode 100644 (file)
index 0000000..34fc9e5
--- /dev/null
@@ -0,0 +1,87 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void
+test_sendto_self(int to_s, int s)
+{
+       struct msghdr msg;
+       struct iovec iov;
+       union {
+               struct cmsghdr cm;
+               uint8_t data[CMSG_SPACE(sizeof(int))];
+       } ctrl;
+       struct cmsghdr *cm;
+       int n, buf;
+
+       iov.iov_base = &buf;
+       iov.iov_len = sizeof(buf);
+
+       memset(&msg, 0, sizeof(msg));
+       msg.msg_iov = &iov;
+       msg.msg_iovlen = 1;
+       msg.msg_control = ctrl.data;
+       msg.msg_controllen = sizeof(ctrl.data);
+
+       memset(&ctrl, 0, sizeof(ctrl));
+       cm = CMSG_FIRSTHDR(&msg);
+       cm->cmsg_len = CMSG_LEN(sizeof(int));
+       cm->cmsg_level = SOL_SOCKET;
+       cm->cmsg_type = SCM_RIGHTS;
+       *((int *)CMSG_DATA(cm)) = s;
+
+       n = sendmsg(to_s, &msg, 0);
+       if (n < 0)
+               err(1, "sendmsg failed");
+       else if (n != sizeof(buf))
+               errx(1, "sendmsg sent %d", n);
+}
+
+static void
+usage(const char *cmd)
+{
+       fprintf(stderr, "%s [-x]\n", cmd);
+       exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+       int s[2], opt, xref;
+
+       xref = 0;
+       while ((opt = getopt(argc, argv, "x")) != -1) {
+               switch (opt) {
+               case 'x':
+                       xref = 1;
+                       break;
+
+               default:
+                       usage(argv[0]);
+               }
+       }
+
+       if (socketpair(AF_LOCAL, SOCK_STREAM, 0, s) < 0)
+               err(1, "socketpair(LOCAL, STREAM) failed");
+
+       if (xref) {
+               fprintf(stderr, "cross reference\n");
+               /* Send s[0] to s[1].rcvbuf */
+               test_sendto_self(s[0], s[0]);
+               /* Send s[1] to s[0].rcvbuf */
+               test_sendto_self(s[1], s[1]);
+       } else {
+               fprintf(stderr, "self reference\n");
+               /* Send s[0] to s[0].rcvbuf */
+               test_sendto_self(s[1], s[0]);
+               /* Send s[1] to s[1].rcvbuf */
+               test_sendto_self(s[0], s[1]);
+       }
+       exit(0);
+}