xref: /illumos-gate/usr/src/test/os-tests/tests/sockfs/sockpair.c (revision 45ede40b2394db7967e59f19288fae9b62efd4aa)
1 /*
2  * Copyright 2016 Jeremy Allison
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include <sys/param.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <pthread.h>
35 
36 extern char *__progname;
37 
38 static void *
39 server(void *varg)
40 {
41 	int *sfds = (int *)varg;
42 	int ret;
43 	int sock = sfds[0];
44 	unsigned int i;
45 
46 	for (i = 0; i < 5; i++) {
47 		struct iovec iov;
48 		struct msghdr msg;
49 		uint8_t buf[4096];
50 
51 		iov = (struct iovec) {
52 			.iov_base = buf,
53 			.iov_len = sizeof (buf)
54 		};
55 
56 		msg = (struct msghdr) {
57 			.msg_iov = &iov,
58 			.msg_iovlen = 1,
59 		};
60 
61 		ret = recvmsg(sock, &msg, 0);
62 		if (ret == -1) {
63 			fprintf(stderr, "server - recvmsg fail %s\n",
64 			    strerror(errno));
65 			exit(1);
66 		}
67 		if (ret == 0) {
68 			printf("SERVER: got HUP\n");
69 			break;
70 		}
71 
72 		printf("SERVER:%s\n", (char *)msg.msg_iov->iov_base);
73 		fflush(stdout);
74 	}
75 
76 	close(sock);
77 	return (NULL);
78 }
79 
80 void
81 runtest(int sotype)
82 {
83 	int sfds[2];
84 	int sock;
85 	int ret;
86 	unsigned int i;
87 
88 	/* Create socketpair */
89 	ret = socketpair(AF_UNIX, sotype, 0, sfds);
90 	if (ret == -1) {
91 		fprintf(stderr, "%s - socketpair fail %s\n",
92 		    __progname, strerror(errno));
93 		exit(1);
94 	}
95 
96 	/* Set up the server.  It closes sfds[0] when done. */
97 	ret = pthread_create(NULL, NULL, server, sfds);
98 	if (ret == -1) {
99 		fprintf(stderr, "%s - thread create fail %s\n",
100 		    __progname, strerror(errno));
101 		exit(1);
102 	}
103 
104 	sleep(1);
105 
106 	/* "Server" is sfds[0], "client" is sfds[1] */
107 	sock = sfds[1];
108 
109 	/* Send some messages */
110 	for (i = 0; i < 3; i++) {
111 		struct iovec iov;
112 		struct msghdr msg;
113 		uint8_t buf[4096];
114 
115 		memcpy(buf, "TEST0", sizeof ("TEST0"));
116 		buf[4] = '0' + i;
117 
118 		printf("CLIENT:%s\n", buf);
119 
120 		iov = (struct iovec) {
121 			.iov_base = buf,
122 			.iov_len = sizeof (buf),
123 		};
124 
125 		msg = (struct msghdr) {
126 			.msg_iov = &iov,
127 			.msg_iovlen = 1,
128 		};
129 
130 		ret = sendmsg(sock, &msg, 0);
131 
132 		if (ret == -1) {
133 			fprintf(stderr, "%s - sendmsg fail %s\n",
134 			    __progname, strerror(errno));
135 			exit(1);
136 		}
137 
138 		fflush(stdout);
139 		sleep(1);
140 	}
141 
142 	/*
143 	 * Tell sever to terminate
144 	 */
145 	if (sotype == SOCK_STREAM) {
146 		printf("CLIENT: close\n");
147 		close(sock);
148 	} else {
149 		printf("CLIENT: send 0\n");
150 		send(sock, "", 0, 0);
151 	}
152 	sleep(1);
153 }
154 
155 int
156 main(int argc, char **argv)
157 {
158 
159 	printf("%s SOCK_STREAM test...\n", argv[0]);
160 	runtest(SOCK_STREAM);
161 
162 	printf("%s SOCK_DGRAM test...\n", argv[0]);
163 	runtest(SOCK_DGRAM);
164 
165 	return (0);
166 }
167