]> granicus.if.org Git - strace/blob - tests/net-y-unix.c
strace: terminate itself if interrupted by a signal
[strace] / 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@altlinux.org>
5  * Copyright (c) 2016-2018 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 <stddef.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <sys/socket.h>
19 #include <sys/un.h>
20
21 #include "accept_compat.h"
22
23 #define TEST_SOCKET "net-y-unix.socket"
24
25 int
26 main(void)
27 {
28         skip_if_unavailable("/proc/self/fd/");
29
30         static const struct sockaddr_un addr = {
31                 .sun_family = AF_UNIX,
32                 .sun_path = TEST_SOCKET
33         };
34         struct sockaddr * const listen_sa = tail_memdup(&addr, sizeof(addr));
35
36         TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len);
37         *len = offsetof(struct sockaddr_un, sun_path) + strlen(TEST_SOCKET) + 1;
38         if (*len > sizeof(addr))
39                 *len = sizeof(addr);
40
41         int listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
42         if (listen_fd < 0)
43                 perror_msg_and_skip("socket");
44         unsigned long listen_inode = inode_of_sockfd(listen_fd);
45         printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n",
46                listen_fd, listen_inode);
47
48         (void) unlink(TEST_SOCKET);
49         if (bind(listen_fd, listen_sa, *len))
50                 perror_msg_and_skip("bind");
51         printf("bind(%d<socket:[%lu]>, {sa_family=AF_UNIX, sun_path=\"%s\"}"
52                ", %u) = 0\n",
53                listen_fd, listen_inode, TEST_SOCKET, (unsigned) *len);
54
55         if (listen(listen_fd, 1))
56                 perror_msg_and_skip("listen");
57         printf("listen(%d<socket:[%lu]>, 1) = 0\n", listen_fd, listen_inode);
58
59         TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, optval);
60         *len = sizeof(*optval);
61         if (getsockopt(listen_fd, SOL_SOCKET, SO_PASSCRED, optval, len))
62                 perror_msg_and_fail("getsockopt");
63         printf("getsockopt(%d<socket:[%lu]>, SOL_SOCKET, SO_PASSCRED"
64                ", [%u], [%u]) = 0\n",
65                listen_fd, listen_inode, *optval, (unsigned) *len);
66
67         memset(listen_sa, 0, sizeof(addr));
68         *len = sizeof(addr);
69         if (getsockname(listen_fd, listen_sa, len))
70                 perror_msg_and_fail("getsockname");
71         printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX"
72                ", sun_path=\"%s\"}, [%d->%d]) = 0\n", listen_fd, listen_inode,
73                TEST_SOCKET, (int) sizeof(addr), (int) *len);
74
75         int connect_fd = socket(AF_UNIX, SOCK_STREAM, 0);
76         if (connect_fd < 0)
77                 perror_msg_and_fail("socket");
78         unsigned long connect_inode = inode_of_sockfd(connect_fd);
79         printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n",
80                connect_fd, connect_inode);
81
82         if (connect(connect_fd, listen_sa, *len))
83                 perror_msg_and_fail("connect");
84         printf("connect(%d<socket:[%lu]>, {sa_family=AF_UNIX"
85                ", sun_path=\"%s\"}, %u) = 0\n",
86                connect_fd, connect_inode, TEST_SOCKET, (unsigned) *len);
87
88         struct sockaddr * const accept_sa = tail_alloc(sizeof(addr));
89         memset(accept_sa, 0, sizeof(addr));
90         *len = sizeof(addr);
91         int accept_fd = do_accept(listen_fd, accept_sa, len);
92         if (accept_fd < 0)
93                 perror_msg_and_fail("accept");
94         unsigned long accept_inode = inode_of_sockfd(accept_fd);
95         printf("accept(%d<socket:[%lu]>, {sa_family=AF_UNIX}"
96                ", [%d->%d]) = %d<socket:[%lu]>\n",
97                listen_fd, listen_inode,
98                (int) sizeof(addr), (int) *len,
99                accept_fd, accept_inode);
100
101         memset(listen_sa, 0, sizeof(addr));
102         *len = sizeof(addr);
103         if (getpeername(connect_fd, listen_sa, len))
104                 perror_msg_and_fail("getpeername");
105         printf("getpeername(%d<socket:[%lu]>, {sa_family=AF_UNIX"
106                ", sun_path=\"%s\"}, [%d->%d]) = 0\n", 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 = do_accept(listen_fd, accept_sa, len);
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("accept(%d<socket:[%lu]>, {sa_family=AF_UNIX"
169                ", sun_path=@\"%s\"}, [%d->%d]) = %d<socket:[%lu]>\n",
170                listen_fd, listen_inode, sun_path1,
171                (int) sizeof(addr), (int) *len,
172                accept_fd, accept_inode);
173
174         memset(listen_sa, 0, sizeof(addr));
175         *len = sizeof(addr);
176         if (getpeername(connect_fd, listen_sa, len))
177                 perror_msg_and_fail("getpeername");
178         printf("getpeername(%d<socket:[%lu]>, {sa_family=AF_UNIX"
179                ", sun_path=\"%s\"}, [%d->%d]) = 0\n",
180                connect_fd, connect_inode, TEST_SOCKET,
181                (int) sizeof(addr), (int) *len);
182
183         memset(accept_sa, 0, sizeof(addr));
184         *len = sizeof(addr);
185         if (getsockname(connect_fd, accept_sa, len))
186                 perror_msg_and_fail("getsockname");
187         printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX"
188                ", sun_path=@\"%s\"}, [%d->%d]) = 0\n",
189                connect_fd, connect_inode, sun_path1,
190                (int) sizeof(addr), (int) *len);
191
192         assert(sendto(connect_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, 0)
193                == sizeof(text) - 1);
194         printf("sendto(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT"
195                ", NULL, 0) = %u\n",
196                connect_fd, connect_inode, text,
197                (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
198
199         assert(close(connect_fd) == 0);
200         printf("close(%d<socket:[%lu]>) = 0\n", connect_fd, connect_inode);
201
202         assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, NULL)
203                == sizeof(text) - 1);
204         printf("recvfrom(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT"
205                ", NULL, NULL) = %u\n",
206                accept_fd, accept_inode, text,
207                (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
208
209         assert(close(accept_fd) == 0);
210         printf("close(%d<socket:[%lu]>) = 0\n", accept_fd, accept_inode);
211
212         assert(unlink(TEST_SOCKET) == 0);
213
214         assert(close(listen_fd) == 0);
215         printf("close(%d<socket:[%lu]>) = 0\n",
216                listen_fd, listen_inode);
217
218         puts("+++ exited with 0 +++");
219         return 0;
220 }