1 /*
2 * Check decoding of vmsplice syscall.
3 *
4 * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2016-2021 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 "scno.h"
13
14 #include <assert.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 #include <sys/uio.h>
18
19 int
20 main(void)
21 {
22 tprintf("%s", "");
23
24 int fds[2];
25 if (pipe(fds))
26 perror_msg_and_fail("pipe");
27 assert(0 == fds[0]);
28 assert(1 == fds[1]);
29
30 static const char w0_c[] = "012";
31 const char *w0_d = hexdump_strdup(w0_c);
32 void *w0 = tail_memdup(w0_c, LENGTH_OF(w0_c));
33
34 static const char w1_c[] = "34567";
35 const char *w1_d = hexdump_strdup(w1_c);
36 void *w1 = tail_memdup(w1_c, LENGTH_OF(w1_c));
37
38 static const char w2_c[] = "89abcde";
39 const char *w2_d = hexdump_strdup(w2_c);
40 void *w2 = tail_memdup(w2_c, LENGTH_OF(w2_c));
41
42 const struct iovec iov_[] = {
43 {
44 .iov_base = w0,
45 .iov_len = LENGTH_OF(w0_c)
46 }, {
47 .iov_base = w1,
48 .iov_len = LENGTH_OF(w1_c)
49 }, {
50 .iov_base = w2,
51 .iov_len = LENGTH_OF(w2_c)
52 }
53 };
54 const struct iovec *iov = tail_memdup(iov_, sizeof(iov_));
55 const unsigned int len =
56 LENGTH_OF(w0_c) + LENGTH_OF(w1_c) + LENGTH_OF(w2_c);
57
58 tprintf("vmsplice(1, [{iov_base=\"%s\", iov_len=%u}"
59 ", {iov_base=\"%s\", iov_len=%u}"
60 ", {iov_base=\"%s\", iov_len=%u}], %u, %s) = %u\n"
61 " * %u bytes in buffer 0\n"
62 " | 00000 %-49s %-16s |\n"
63 " * %u bytes in buffer 1\n"
64 " | 00000 %-49s %-16s |\n"
65 " * %u bytes in buffer 2\n"
66 " | 00000 %-49s %-16s |\n",
67 w0_c, LENGTH_OF(w0_c), w1_c, LENGTH_OF(w1_c),
68 w2_c, LENGTH_OF(w2_c), (unsigned int) ARRAY_SIZE(iov_),
69 "SPLICE_F_NONBLOCK", len,
70 LENGTH_OF(w0_c), w0_d, w0_c,
71 LENGTH_OF(w1_c), w1_d, w1_c, LENGTH_OF(w2_c), w2_d, w2_c);
72
73 const long rc = syscall(__NR_vmsplice, 1, iov, ARRAY_SIZE(iov_), 2);
74 if (rc < 0)
75 perror_msg_and_skip("vmsplice");
76 assert(rc == (int) len);
77
78 tprintf("+++ exited with 0 +++\n");
79 return 0;
80 }