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 static void *
server(void * varg)37 server(void *varg)
38 {
39 struct sockaddr_un *addr = varg;
40 int ret;
41 int sock;
42 unsigned int i;
43
44 /* Child. */
45 sock = socket(AF_UNIX, SOCK_DGRAM, 0);
46 if (sock == -1) {
47 fprintf(stderr, "server - socket fail %s\n", strerror(errno));
48 exit(1);
49 }
50
51 ret = bind(sock, (struct sockaddr *)addr, sizeof (*addr));
52
53 if (ret == -1) {
54 fprintf(stderr, "server - bind fail %s\n", strerror(errno));
55 exit(1);
56 }
57
58 for (i = 0; i < 5; i++) {
59 struct iovec iov;
60 struct msghdr msg;
61 uint8_t buf[4096];
62
63 iov = (struct iovec) {
64 .iov_base = buf,
65 .iov_len = sizeof (buf)
66 };
67
68 msg = (struct msghdr) {
69 .msg_iov = &iov,
70 .msg_iovlen = 1,
71 };
72
73 ret = recvmsg(sock, &msg, 0);
74 if (ret == -1) {
75 fprintf(stderr, "server - recvmsg fail %s\n",
76 strerror(errno));
77 exit(1);
78 }
79
80 printf("SERVER:%s\n", (char *)msg.msg_iov->iov_base);
81 fflush(stdout);
82 }
83
84 exit(0);
85 }
86
87 /*
88 * This should be a place only root is allowed to write.
89 * The test will create and destroy this directory.
90 */
91 char testdir[100] = "/var/run/os-tests-sockfs";
92 struct sockaddr_un addr;
93 int test_uid = UID_NOBODY;
94
95 int
main(int argc,char ** argv)96 main(int argc, char **argv)
97 {
98 int ret;
99 int sock;
100 unsigned int i;
101
102 if (argc > 1) {
103 ret = strlcpy(testdir, argv[1], sizeof (testdir));
104 if (ret >= sizeof (testdir)) {
105 fprintf(stderr, "%s: too long\n", argv[1]);
106 exit(1);
107 }
108 }
109
110 addr.sun_family = AF_UNIX;
111 (void) sprintf(addr.sun_path, "%s/s", testdir);
112
113 if (mkdir(testdir, 0700) != 0) {
114 switch (errno) {
115 case EEXIST:
116 case EISDIR:
117 break;
118 default:
119 perror(testdir);
120 exit(1);
121 }
122 }
123 (void) unlink(addr.sun_path);
124
125 /* Set up the server. */
126 ret = pthread_create(NULL, NULL, server, &addr);
127 if (ret == -1) {
128 fprintf(stderr, "%s - thread create fail %s\n",
129 argv[0], strerror(errno));
130 exit(1);
131 }
132
133 sleep(1);
134
135 /* Create and connect the socket endpoint. */
136
137 sock = socket(AF_UNIX, SOCK_DGRAM, 0);
138 if (sock == -1) {
139 fprintf(stderr, "%s - socket fail %s\n",
140 argv[0], strerror(errno));
141 exit(1);
142 }
143
144 /* Send some messages */
145 for (i = 0; i < 5; i++) {
146 struct iovec iov;
147 struct msghdr msg;
148 uint8_t buf[4096];
149
150 memcpy(buf, "TEST0", sizeof ("TEST0"));
151 buf[4] = '0' + i;
152
153 printf("CLIENT:%s\n", buf);
154
155 iov = (struct iovec) {
156 .iov_base = buf,
157 .iov_len = sizeof (buf),
158 };
159
160 msg = (struct msghdr) {
161 /* sendto */
162 .msg_name = &addr,
163 .msg_namelen = sizeof (addr),
164 .msg_iov = &iov,
165 .msg_iovlen = 1,
166 };
167
168 ret = sendmsg(sock, &msg, 0);
169
170 if (ret == -1) {
171 fprintf(stderr, "%s - sendmsg fail %s\n",
172 argv[0], strerror(errno));
173 exit(1);
174 }
175
176 fflush(stdout);
177 sleep(1);
178 }
179
180 close(sock);
181 return (0);
182 }
183