#include #include #include #include #include #include #include #include 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); }