1/* 2 * This file is part of net-yy-unix strace test. 3 * 4 * Copyright (c) 2013-2017 Dmitry V. Levin <ldv@altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include "tests.h" 31#include <assert.h> 32#include <stddef.h> 33#include <stdio.h> 34#include <stdlib.h> 35#include <string.h> 36#include <unistd.h> 37#include <sys/param.h> 38#include <sys/socket.h> 39#include <sys/un.h> 40 41#define TEST_SOCKET "net-yy-unix.socket" 42 43int 44main(void) 45{ 46 skip_if_unavailable("/proc/self/fd/"); 47 48 struct sockaddr_un addr = { 49 .sun_family = AF_UNIX, 50 .sun_path = TEST_SOCKET 51 }; 52 struct sockaddr * const listen_sa = tail_memdup(&addr, sizeof(addr)); 53 54 TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len); 55 *len = offsetof(struct sockaddr_un, sun_path) + strlen(TEST_SOCKET) + 1; 56 if (*len > sizeof(addr)) 57 *len = sizeof(addr); 58 59 int listen_fd = socket(AF_UNIX, SOCK_STREAM, 0); 60 if (listen_fd < 0) 61 perror_msg_and_skip("socket"); 62 unsigned long listen_inode = inode_of_sockfd(listen_fd); 63 printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<UNIX:[%lu]>\n", 64 listen_fd, listen_inode); 65 66 (void) unlink(TEST_SOCKET); 67 if (bind(listen_fd, listen_sa, *len)) 68 perror_msg_and_skip("bind"); 69 printf("bind(%d<UNIX:[%lu]>, {sa_family=AF_UNIX, sun_path=\"%s\"}" 70 ", %u) = 0\n", 71 listen_fd, listen_inode, TEST_SOCKET, (unsigned) *len); 72 73 if (listen(listen_fd, 1)) 74 perror_msg_and_skip("listen"); 75 printf("listen(%d<UNIX:[%lu,\"%s\"]>, 1) = 0\n", 76 listen_fd, listen_inode, TEST_SOCKET); 77 78 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, optval); 79 *len = sizeof(*optval); 80 if (getsockopt(listen_fd, SOL_SOCKET, SO_PASSCRED, optval, len)) 81 perror_msg_and_fail("getsockopt"); 82 printf("getsockopt(%d<UNIX:[%lu,\"%s\"]>, SOL_SOCKET, SO_PASSCRED" 83 ", [%u], [%u]) = 0\n", 84 listen_fd, listen_inode, TEST_SOCKET, *optval, (unsigned) *len); 85 86 memset(listen_sa, 0, sizeof(addr)); 87 *len = sizeof(addr); 88 if (getsockname(listen_fd, listen_sa, len)) 89 perror_msg_and_fail("getsockname"); 90 printf("getsockname(%d<UNIX:[%lu,\"%s\"]>, {sa_family=AF_UNIX" 91 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", listen_fd, listen_inode, 92 TEST_SOCKET, TEST_SOCKET, (int) sizeof(addr), (int) *len); 93 94 int connect_fd = socket(AF_UNIX, SOCK_STREAM, 0); 95 if (connect_fd < 0) 96 perror_msg_and_fail("socket"); 97 unsigned long connect_inode = inode_of_sockfd(connect_fd); 98 printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<UNIX:[%lu]>\n", 99 connect_fd, connect_inode); 100 101 if (connect(connect_fd, listen_sa, *len)) 102 perror_msg_and_fail("connect"); 103 printf("connect(%d<UNIX:[%lu]>, {sa_family=AF_UNIX" 104 ", sun_path=\"%s\"}, %u) = 0\n", 105 connect_fd, connect_inode, TEST_SOCKET, (unsigned) *len); 106 107 struct sockaddr * const accept_sa = tail_alloc(sizeof(addr)); 108 memset(accept_sa, 0, sizeof(addr)); 109 *len = sizeof(addr); 110 int accept_fd = accept(listen_fd, accept_sa, len); 111 if (accept_fd < 0) 112 perror_msg_and_fail("accept"); 113 unsigned long accept_inode = inode_of_sockfd(accept_fd); 114 printf("accept(%d<UNIX:[%lu,\"%s\"]>, {sa_family=AF_UNIX}" 115 ", [%d->%d]) = %d<UNIX:[%lu->%lu,\"%s\"]>\n", 116 listen_fd, listen_inode, TEST_SOCKET, 117 (int) sizeof(addr), (int) *len, 118 accept_fd, accept_inode, connect_inode, TEST_SOCKET); 119 120 memset(listen_sa, 0, sizeof(addr)); 121 *len = sizeof(addr); 122 if (getpeername(connect_fd, listen_sa, len)) 123 perror_msg_and_fail("getpeername"); 124 printf("getpeername(%d<UNIX:[%lu->%lu]>, {sa_family=AF_UNIX" 125 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", 126 connect_fd, connect_inode, 127 accept_inode, TEST_SOCKET, (int) sizeof(addr), (int) *len); 128 129 char text[] = "text"; 130 assert(sendto(connect_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, 0) 131 == sizeof(text) - 1); 132 printf("sendto(%d<UNIX:[%lu->%lu]>, \"%s\", %u, MSG_DONTWAIT" 133 ", NULL, 0) = %u\n", 134 connect_fd, connect_inode, accept_inode, text, 135 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 136 137 assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, NULL) 138 == sizeof(text) - 1); 139 printf("recvfrom(%d<UNIX:[%lu->%lu,\"%s\"]>, \"%s\", %u, MSG_DONTWAIT" 140 ", NULL, NULL) = %u\n", 141 accept_fd, accept_inode, connect_inode, TEST_SOCKET, text, 142 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 143 144 assert(close(connect_fd) == 0); 145 printf("close(%d<UNIX:[%lu->%lu]>) = 0\n", 146 connect_fd, connect_inode, accept_inode); 147 148 assert(close(accept_fd) == 0); 149 printf("close(%d<UNIX:[%lu->%lu,\"%s\"]>) = 0\n", 150 accept_fd, accept_inode, connect_inode, TEST_SOCKET); 151 152 connect_fd = socket(AF_UNIX, SOCK_STREAM, 0); 153 if (connect_fd < 0) 154 perror_msg_and_fail("socket"); 155 connect_inode = inode_of_sockfd(connect_fd); 156 printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<UNIX:[%lu]>\n", 157 connect_fd, connect_inode); 158 159 *optval = 1; 160 *len = sizeof(*optval); 161 if (setsockopt(connect_fd, SOL_SOCKET, SO_PASSCRED, optval, *len)) 162 perror_msg_and_fail("setsockopt"); 163 printf("setsockopt(%d<UNIX:[%lu]>, SOL_SOCKET, SO_PASSCRED" 164 ", [%u], %u) = 0\n", 165 connect_fd, connect_inode, *optval, (unsigned) *len); 166 167 memset(listen_sa, 0, sizeof(addr)); 168 *len = sizeof(addr); 169 if (getsockname(listen_fd, listen_sa, len)) 170 perror_msg_and_fail("getsockname"); 171 printf("getsockname(%d<UNIX:[%lu,\"%s\"]>, {sa_family=AF_UNIX" 172 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", listen_fd, listen_inode, 173 TEST_SOCKET, TEST_SOCKET, (int) sizeof(addr), (int) *len); 174 175 if (connect(connect_fd, listen_sa, *len)) 176 perror_msg_and_fail("connect"); 177 printf("connect(%d<UNIX:[%lu]>, {sa_family=AF_UNIX" 178 ", sun_path=\"%s\"}, %u) = 0\n", 179 connect_fd, connect_inode, TEST_SOCKET, (unsigned) *len); 180 181 memset(accept_sa, 0, sizeof(addr)); 182 *len = sizeof(addr); 183 accept_fd = accept(listen_fd, accept_sa, len); 184 if (accept_fd < 0) 185 perror_msg_and_fail("accept"); 186 accept_inode = inode_of_sockfd(accept_fd); 187 const char * const sun_path1 = 188 ((struct sockaddr_un *) accept_sa)->sun_path + 1; 189 printf("accept(%d<UNIX:[%lu,\"%s\"]>, {sa_family=AF_UNIX" 190 ", sun_path=@\"%s\"}, [%d->%d]) = %d<UNIX:[%lu->%lu,\"%s\"]>\n", 191 listen_fd, listen_inode, TEST_SOCKET, sun_path1, 192 (int) sizeof(addr), (int) *len, 193 accept_fd, accept_inode, connect_inode, TEST_SOCKET); 194 195 memset(listen_sa, 0, sizeof(addr)); 196 *len = sizeof(addr); 197 if (getpeername(connect_fd, listen_sa, len)) 198 perror_msg_and_fail("getpeername"); 199 printf("getpeername(%d<UNIX:[%lu->%lu,@\"%s\"]>, {sa_family=AF_UNIX" 200 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", connect_fd, connect_inode, 201 accept_inode, sun_path1, TEST_SOCKET, (int) sizeof(addr), (int) *len); 202 203 assert(sendto(connect_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, 0) 204 == sizeof(text) - 1); 205 printf("sendto(%d<UNIX:[%lu->%lu,@\"%s\"]>, \"%s\", %u, MSG_DONTWAIT" 206 ", NULL, 0) = %u\n", 207 connect_fd, connect_inode, accept_inode, sun_path1, text, 208 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 209 210 assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, NULL) 211 == sizeof(text) - 1); 212 printf("recvfrom(%d<UNIX:[%lu->%lu,\"%s\"]>, \"%s\", %u, MSG_DONTWAIT" 213 ", NULL, NULL) = %u\n", 214 accept_fd, accept_inode, connect_inode, TEST_SOCKET, text, 215 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 216 217 assert(close(connect_fd) == 0); 218 printf("close(%d<UNIX:[%lu->%lu,@\"%s\"]>) = 0\n", 219 connect_fd, connect_inode, accept_inode, sun_path1); 220 221 assert(close(accept_fd) == 0); 222 printf("close(%d<UNIX:[%lu->%lu,\"%s\"]>) = 0\n", 223 accept_fd, accept_inode, connect_inode, TEST_SOCKET); 224 225 assert(unlink(TEST_SOCKET) == 0); 226 227 assert(close(listen_fd) == 0); 228 printf("close(%d<UNIX:[%lu,\"%s\"]>) = 0\n", 229 listen_fd, listen_inode, TEST_SOCKET); 230 231 puts("+++ exited with 0 +++"); 232 return 0; 233} 234