(root)/
strace-6.5/
tests/
net-y-unix.c
       1  /*
       2   * This file is part of net-y-unix strace test.
       3   *
       4   * Copyright (c) 2013-2017 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include <assert.h>
      13  #include <fcntl.h>
      14  #include <stddef.h>
      15  #include <stdio.h>
      16  #include <stdlib.h>
      17  #include <string.h>
      18  #include <unistd.h>
      19  #include <sys/socket.h>
      20  #include <sys/un.h>
      21  
      22  #define TEST_SOCKET "net-y-unix.socket"
      23  
      24  int
      25  main(void)
      26  {
      27  	skip_if_unavailable("/proc/self/fd/");
      28  
      29  	static const struct sockaddr_un addr = {
      30  		.sun_family = AF_UNIX,
      31  		.sun_path = TEST_SOCKET
      32  	};
      33  	struct sockaddr * const listen_sa = tail_memdup(&addr, sizeof(addr));
      34  
      35  	TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len);
      36  	*len = offsetof(struct sockaddr_un, sun_path) + strlen(TEST_SOCKET) + 1;
      37  	if (*len > sizeof(addr))
      38  		*len = sizeof(addr);
      39  
      40  	int listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
      41  	if (listen_fd < 0)
      42  		perror_msg_and_skip("socket");
      43  	unsigned long listen_inode = inode_of_sockfd(listen_fd);
      44  	printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n",
      45  	       listen_fd, listen_inode);
      46  
      47  	(void) unlink(TEST_SOCKET);
      48  	if (bind(listen_fd, listen_sa, *len))
      49  		perror_msg_and_skip("bind");
      50  	printf("bind(%d<socket:[%lu]>, {sa_family=AF_UNIX, sun_path=\"%s\"}"
      51  	       ", %u) = 0\n",
      52  	       listen_fd, listen_inode, TEST_SOCKET, (unsigned) *len);
      53  
      54  	if (listen(listen_fd, 1))
      55  		perror_msg_and_skip("listen");
      56  	printf("listen(%d<socket:[%lu]>, 1) = 0\n", listen_fd, listen_inode);
      57  
      58  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, optval);
      59  	*len = sizeof(*optval);
      60  	if (getsockopt(listen_fd, SOL_SOCKET, SO_PASSCRED, optval, len))
      61  		perror_msg_and_fail("getsockopt");
      62  	printf("getsockopt(%d<socket:[%lu]>, SOL_SOCKET, SO_PASSCRED"
      63  	       ", [%u], [%u]) = 0\n",
      64  	       listen_fd, listen_inode, *optval, (unsigned) *len);
      65  
      66  	memset(listen_sa, 0, sizeof(addr));
      67  	*len = sizeof(addr);
      68  	if (getsockname(listen_fd, listen_sa, len))
      69  		perror_msg_and_fail("getsockname");
      70  	printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX"
      71  	       ", sun_path=\"%s\"}, [%d => %d]) = 0\n", listen_fd, listen_inode,
      72  	       TEST_SOCKET, (int) sizeof(addr), (int) *len);
      73  
      74  	int connect_fd = socket(AF_UNIX, SOCK_STREAM, 0);
      75  	if (connect_fd < 0)
      76  		perror_msg_and_fail("socket");
      77  	unsigned long connect_inode = inode_of_sockfd(connect_fd);
      78  	printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n",
      79  	       connect_fd, connect_inode);
      80  
      81  	if (connect(connect_fd, listen_sa, *len))
      82  		perror_msg_and_fail("connect");
      83  	printf("connect(%d<socket:[%lu]>, {sa_family=AF_UNIX"
      84  	       ", sun_path=\"%s\"}, %u) = 0\n",
      85  	       connect_fd, connect_inode, TEST_SOCKET, (unsigned) *len);
      86  
      87  	struct sockaddr * const accept_sa = tail_alloc(sizeof(addr));
      88  	memset(accept_sa, 0, sizeof(addr));
      89  	*len = sizeof(addr);
      90  	int accept_fd = accept4(listen_fd, accept_sa, len, O_CLOEXEC);
      91  	if (accept_fd < 0)
      92  		perror_msg_and_fail("accept");
      93  	unsigned long accept_inode = inode_of_sockfd(accept_fd);
      94  	printf("accept4(%d<socket:[%lu]>, {sa_family=AF_UNIX}"
      95  	       ", [%d => %d], SOCK_CLOEXEC) = %d<socket:[%lu]>\n",
      96  	       listen_fd, listen_inode,
      97  	       (int) sizeof(addr), (int) *len,
      98  	       accept_fd, accept_inode);
      99  
     100  	memset(listen_sa, 0, sizeof(addr));
     101  	*len = sizeof(addr);
     102  	if (getpeername(connect_fd, listen_sa, len))
     103  		perror_msg_and_fail("getpeername");
     104  	printf("getpeername(%d<socket:[%lu]>, {sa_family=AF_UNIX"
     105  	       ", sun_path=\"%s\"}, [%d => %d]) = 0\n",
     106  	       connect_fd, connect_inode,
     107  	       TEST_SOCKET, (int) sizeof(addr), (int) *len);
     108  
     109  	char text[] = "text";
     110  	assert(sendto(connect_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, 0)
     111  	       == sizeof(text) - 1);
     112  	printf("sendto(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT"
     113  	       ", NULL, 0) = %u\n",
     114  	       connect_fd, connect_inode, text,
     115  	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
     116  
     117  	assert(close(connect_fd) == 0);
     118  	printf("close(%d<socket:[%lu]>) = 0\n", connect_fd, connect_inode);
     119  
     120  	assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, NULL)
     121  	       == sizeof(text) - 1);
     122  	printf("recvfrom(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT"
     123  	       ", NULL, NULL) = %u\n",
     124  	       accept_fd, accept_inode, text,
     125  	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
     126  
     127  	assert(close(accept_fd) == 0);
     128  	printf("close(%d<socket:[%lu]>) = 0\n", accept_fd, accept_inode);
     129  
     130  	connect_fd = socket(AF_UNIX, SOCK_STREAM, 0);
     131  	if (connect_fd < 0)
     132  		perror_msg_and_fail("socket");
     133  	connect_inode = inode_of_sockfd(connect_fd);
     134  	printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n",
     135  	       connect_fd, connect_inode);
     136  
     137  	*optval = 1;
     138  	*len = sizeof(*optval);
     139  	if (setsockopt(connect_fd, SOL_SOCKET, SO_PASSCRED, optval, *len))
     140  		perror_msg_and_fail("setsockopt");
     141  	printf("setsockopt(%d<socket:[%lu]>, SOL_SOCKET, SO_PASSCRED"
     142  	       ", [%u], %u) = 0\n",
     143  	       connect_fd, connect_inode, *optval, (unsigned) *len);
     144  
     145  	memset(listen_sa, 0, sizeof(addr));
     146  	*len = sizeof(addr);
     147  	if (getsockname(listen_fd, listen_sa, len))
     148  		perror_msg_and_fail("getsockname");
     149  	printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX"
     150  	       ", sun_path=\"%s\"}, [%d => %d]) = 0\n",
     151  	       listen_fd, listen_inode, TEST_SOCKET,
     152  	       (int) sizeof(addr), (int) *len);
     153  
     154  	if (connect(connect_fd, listen_sa, *len))
     155  		perror_msg_and_fail("connect");
     156  	printf("connect(%d<socket:[%lu]>, {sa_family=AF_UNIX"
     157  	       ", sun_path=\"%s\"}, %u) = 0\n",
     158  	       connect_fd, connect_inode, TEST_SOCKET, (unsigned) *len);
     159  
     160  	memset(accept_sa, 0, sizeof(addr));
     161  	*len = sizeof(addr);
     162  	accept_fd = accept4(listen_fd, accept_sa, len, O_CLOEXEC);
     163  	if (accept_fd < 0)
     164  		perror_msg_and_fail("accept");
     165  	accept_inode = inode_of_sockfd(accept_fd);
     166  	const char * const sun_path1 =
     167  		((struct sockaddr_un *) accept_sa)->sun_path + 1;
     168  	printf("accept4(%d<socket:[%lu]>, {sa_family=AF_UNIX"
     169  	       ", sun_path=@\"%s\"}, [%d => %d], SOCK_CLOEXEC)"
     170  	       " = %d<socket:[%lu]>\n",
     171  	       listen_fd, listen_inode, sun_path1,
     172  	       (int) sizeof(addr), (int) *len,
     173  	       accept_fd, accept_inode);
     174  
     175  	memset(listen_sa, 0, sizeof(addr));
     176  	*len = sizeof(addr);
     177  	if (getpeername(connect_fd, listen_sa, len))
     178  		perror_msg_and_fail("getpeername");
     179  	printf("getpeername(%d<socket:[%lu]>, {sa_family=AF_UNIX"
     180  	       ", sun_path=\"%s\"}, [%d => %d]) = 0\n",
     181  	       connect_fd, connect_inode, TEST_SOCKET,
     182  	       (int) sizeof(addr), (int) *len);
     183  
     184  	memset(accept_sa, 0, sizeof(addr));
     185  	*len = sizeof(addr);
     186  	if (getsockname(connect_fd, accept_sa, len))
     187  		perror_msg_and_fail("getsockname");
     188  	printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX"
     189  	       ", sun_path=@\"%s\"}, [%d => %d]) = 0\n",
     190  	       connect_fd, connect_inode, sun_path1,
     191  	       (int) sizeof(addr), (int) *len);
     192  
     193  	assert(sendto(connect_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, 0)
     194  	       == sizeof(text) - 1);
     195  	printf("sendto(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT"
     196  	       ", NULL, 0) = %u\n",
     197  	       connect_fd, connect_inode, text,
     198  	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
     199  
     200  	assert(close(connect_fd) == 0);
     201  	printf("close(%d<socket:[%lu]>) = 0\n", connect_fd, connect_inode);
     202  
     203  	assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, NULL)
     204  	       == sizeof(text) - 1);
     205  	printf("recvfrom(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT"
     206  	       ", NULL, NULL) = %u\n",
     207  	       accept_fd, accept_inode, text,
     208  	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
     209  
     210  	assert(close(accept_fd) == 0);
     211  	printf("close(%d<socket:[%lu]>) = 0\n", accept_fd, accept_inode);
     212  
     213  	assert(unlink(TEST_SOCKET) == 0);
     214  
     215  	assert(close(listen_fd) == 0);
     216  	printf("close(%d<socket:[%lu]>) = 0\n",
     217  	       listen_fd, listen_inode);
     218  
     219  	puts("+++ exited with 0 +++");
     220  	return 0;
     221  }