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 *
server(void * varg)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
runtest(int sotype)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
main(int argc,char ** argv)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