]> granicus.if.org Git - strace/blob - tests/net-yy-unix.c
tests: move /proc/ checks from scripts to executables
[strace] / tests / net-yy-unix.c
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
43 int
44 main(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 }