1 #include <sys/types.h> 2 #include <sys/socket.h> 3 #include <sys/un.h> 4 5 #include <err.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 11 static void 12 test_sendto_self(int to_s, int s) 13 { 14 struct msghdr msg; 15 struct iovec iov; 16 union { 17 struct cmsghdr cm; 18 uint8_t data[CMSG_SPACE(sizeof(int))]; 19 } ctrl; 20 struct cmsghdr *cm; 21 int n, buf; 22 23 iov.iov_base = &buf; 24 iov.iov_len = sizeof(buf); 25 26 memset(&msg, 0, sizeof(msg)); 27 msg.msg_iov = &iov; 28 msg.msg_iovlen = 1; 29 msg.msg_control = ctrl.data; 30 msg.msg_controllen = sizeof(ctrl.data); 31 32 memset(&ctrl, 0, sizeof(ctrl)); 33 cm = CMSG_FIRSTHDR(&msg); 34 cm->cmsg_len = CMSG_LEN(sizeof(int)); 35 cm->cmsg_level = SOL_SOCKET; 36 cm->cmsg_type = SCM_RIGHTS; 37 *((int *)CMSG_DATA(cm)) = s; 38 39 n = sendmsg(to_s, &msg, 0); 40 if (n < 0) 41 err(1, "sendmsg failed"); 42 else if (n != sizeof(buf)) 43 errx(1, "sendmsg sent %d", n); 44 } 45 46 static void 47 usage(const char *cmd) 48 { 49 fprintf(stderr, "%s [-x]\n", cmd); 50 exit(1); 51 } 52 53 int 54 main(int argc, char *argv[]) 55 { 56 int s[2], opt, xref; 57 58 xref = 0; 59 while ((opt = getopt(argc, argv, "x")) != -1) { 60 switch (opt) { 61 case 'x': 62 xref = 1; 63 break; 64 65 default: 66 usage(argv[0]); 67 } 68 } 69 70 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, s) < 0) 71 err(1, "socketpair(LOCAL, STREAM) failed"); 72 73 if (xref) { 74 fprintf(stderr, "cross reference\n"); 75 /* Send s[0] to s[1].rcvbuf */ 76 test_sendto_self(s[0], s[0]); 77 /* Send s[1] to s[0].rcvbuf */ 78 test_sendto_self(s[1], s[1]); 79 } else { 80 fprintf(stderr, "self reference\n"); 81 /* Send s[0] to s[0].rcvbuf */ 82 test_sendto_self(s[1], s[0]); 83 /* Send s[1] to s[1].rcvbuf */ 84 test_sendto_self(s[0], s[1]); 85 } 86 exit(0); 87 } 88