xref: /dragonfly/test/unix/loopdesc/loopdesc.c (revision ec21d9fb)
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