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