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