1 /*
2 * Copyright (c) 2014 Masatake YAMATO <yamato@redhat.com>
3 * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@strace.io>
4 * Copyright (c) 2014-2021 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include <assert.h>
12 #include <unistd.h>
13
14 #include "msghdr.h"
15
16 int
17 main(void)
18 {
19 tprintf("%s", "");
20
21 int fds[2];
22 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds))
23 perror_msg_and_skip("socketpair");
24 assert(0 == fds[0]);
25 assert(1 == fds[1]);
26
27 static const char w0_c[] = "012";
28 const char *w0_d = hexdump_strdup(w0_c);
29 void *w0 = tail_memdup(w0_c, LENGTH_OF(w0_c));
30
31 static const char w1_c[] = "34567";
32 const char *w1_d = hexdump_strdup(w1_c);
33 void *w1 = tail_memdup(w1_c, LENGTH_OF(w1_c));
34
35 static const char w2_c[] = "89abcde";
36 const char *w2_d = hexdump_strdup(w2_c);
37 void *w2 = tail_memdup(w2_c, LENGTH_OF(w2_c));
38
39 const struct iovec w0_iov_[] = {
40 {
41 .iov_base = w0,
42 .iov_len = LENGTH_OF(w0_c)
43 }, {
44 .iov_base = w1,
45 .iov_len = LENGTH_OF(w1_c)
46 }
47 };
48 struct iovec *w0_iov = tail_memdup(w0_iov_, sizeof(w0_iov_));
49
50 const struct iovec w1_iov_[] = {
51 {
52 .iov_base = w2,
53 .iov_len = LENGTH_OF(w2_c)
54 }
55 };
56 struct iovec *w1_iov = tail_memdup(w1_iov_, sizeof(w1_iov_));
57
58 const struct mmsghdr w_mmh_[] = {
59 {
60 .msg_hdr = {
61 .msg_iov = w0_iov,
62 .msg_iovlen = ARRAY_SIZE(w0_iov_),
63 }
64 }, {
65 .msg_hdr = {
66 .msg_iov = w1_iov,
67 .msg_iovlen = ARRAY_SIZE(w1_iov_),
68 }
69 }
70 };
71 void *w_mmh = tail_memdup(w_mmh_, sizeof(w_mmh_));
72 const unsigned int n_w_mmh = ARRAY_SIZE(w_mmh_);
73
74 int r = send_mmsg(1, w_mmh, n_w_mmh, MSG_DONTROUTE | MSG_NOSIGNAL);
75 if (r < 0)
76 perror_msg_and_skip("sendmmsg");
77 assert(r == (int) n_w_mmh);
78 assert(close(1) == 0);
79 tprintf("sendmmsg(1, [{msg_hdr={msg_name=NULL, msg_namelen=0"
80 ", msg_iov=[{iov_base=\"%s\", iov_len=%u}"
81 ", {iov_base=\"%s\", iov_len=%u}], msg_iovlen=%u"
82 ", msg_controllen=0, msg_flags=0}, msg_len=%u}"
83 ", {msg_hdr={msg_name=NULL, msg_namelen=0"
84 ", msg_iov=[{iov_base=\"%s\", iov_len=%u}], msg_iovlen=%u"
85 ", msg_controllen=0, msg_flags=0}, msg_len=%u}], %u"
86 ", MSG_DONTROUTE|MSG_NOSIGNAL) = %d\n"
87 " = %u buffers in vector 0\n"
88 " * %u bytes in buffer 0\n"
89 " | 00000 %-49s %-16s |\n"
90 " * %u bytes in buffer 1\n"
91 " | 00000 %-49s %-16s |\n"
92 " = %u buffers in vector 1\n"
93 " * %u bytes in buffer 0\n"
94 " | 00000 %-49s %-16s |\n",
95 w0_c, LENGTH_OF(w0_c),
96 w1_c, LENGTH_OF(w1_c),
97 (unsigned int) ARRAY_SIZE(w0_iov_),
98 LENGTH_OF(w0_c) + LENGTH_OF(w1_c),
99 w2_c, LENGTH_OF(w2_c), (unsigned int) ARRAY_SIZE(w1_iov_),
100 LENGTH_OF(w2_c),
101 n_w_mmh, r,
102 (unsigned int) ARRAY_SIZE(w0_iov_),
103 LENGTH_OF(w0_c), w0_d, w0_c,
104 LENGTH_OF(w1_c), w1_d, w1_c,
105 (unsigned int) ARRAY_SIZE(w1_iov_),
106 LENGTH_OF(w2_c), w2_d, w2_c);
107
108 const unsigned int w_len =
109 LENGTH_OF(w0_c) + LENGTH_OF(w1_c) + LENGTH_OF(w2_c);
110 const unsigned int r_len = (w_len + 1) / 2;
111 void *r0 = tail_alloc(r_len);
112 void *r1 = tail_alloc(r_len);
113 void *r2 = tail_alloc(r_len);
114 const struct iovec r0_iov_[] = {
115 {
116 .iov_base = r0,
117 .iov_len = r_len
118 }
119 };
120 struct iovec *r0_iov = tail_memdup(r0_iov_, sizeof(r0_iov_));
121 const struct iovec r1_iov_[] = {
122 {
123 .iov_base = r1,
124 .iov_len = r_len
125 },
126 {
127 .iov_base = r2,
128 .iov_len = r_len
129 }
130 };
131 struct iovec *r1_iov = tail_memdup(r1_iov_, sizeof(r1_iov_));
132
133 const struct mmsghdr r_mmh_[] = {
134 {
135 .msg_hdr = {
136 .msg_iov = r0_iov,
137 .msg_iovlen = ARRAY_SIZE(r0_iov_),
138 }
139 }, {
140 .msg_hdr = {
141 .msg_iov = r1_iov,
142 .msg_iovlen = ARRAY_SIZE(r1_iov_),
143 }
144 }
145 };
146 void *r_mmh = tail_memdup(r_mmh_, sizeof(r_mmh_));
147 const unsigned int n_r_mmh = ARRAY_SIZE(r_mmh_);
148
149 static const char r0_c[] = "01234567";
150 const char *r0_d = hexdump_strdup(r0_c);
151 static const char r1_c[] = "89abcde";
152 const char *r1_d = hexdump_strdup(r1_c);
153
154 assert(recv_mmsg(0, r_mmh, n_r_mmh, MSG_DONTWAIT, NULL) == (int) n_r_mmh);
155 assert(close(0) == 0);
156 tprintf("recvmmsg(0, [{msg_hdr={msg_name=NULL, msg_namelen=0"
157 ", msg_iov=[{iov_base=\"%s\", iov_len=%u}], msg_iovlen=%u"
158 ", msg_controllen=0, msg_flags=0}, msg_len=%u}"
159 ", {msg_hdr={msg_name=NULL, msg_namelen=0"
160 ", msg_iov=[{iov_base=\"%s\", iov_len=%u}"
161 ", {iov_base=\"\", iov_len=%u}], msg_iovlen=%u"
162 ", msg_controllen=0, msg_flags=0}, msg_len=%u}], %u"
163 ", MSG_DONTWAIT, NULL) = %d\n"
164 " = %u buffers in vector 0\n"
165 " * %u bytes in buffer 0\n"
166 " | 00000 %-49s %-16s |\n"
167 " = %u buffers in vector 1\n"
168 " * %u bytes in buffer 0\n"
169 " | 00000 %-49s %-16s |\n",
170 r0_c, r_len, (unsigned int) ARRAY_SIZE(r0_iov_),
171 LENGTH_OF(r0_c), r1_c, r_len, r_len,
172 (unsigned int) ARRAY_SIZE(r1_iov_), LENGTH_OF(r1_c),
173 n_r_mmh, r,
174 (unsigned int) ARRAY_SIZE(r0_iov_), LENGTH_OF(r0_c),
175 r0_d, r0_c,
176 (unsigned int) ARRAY_SIZE(r1_iov_), LENGTH_OF(r1_c),
177 r1_d, r1_c);
178
179 tprintf("+++ exited with 0 +++\n");
180 return 0;
181 }