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 * 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 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