1 /*
2 * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "_main.h"
8
happy_path(const int family,const char * family_s,const int type,const char * type_s,const int proto,const char * proto_s)9 static void happy_path(
10 const int family, const char *family_s,
11 const int type, const char *type_s,
12 const int proto, const char *proto_s
13 )
14 {
15 int res;
16 int sv[2] = {-1, -1};
17
18 const char *expected_msg = "Hello, socketpair(2) world!";
19 const unsigned int expected_msg_len = strlen(expected_msg);
20 char actual_msg[32];
21 size_t actual_msg_len;
22 struct iovec iovec;
23 struct msghdr msghdr;
24
25 LOG_DBG("calling socketpair(%u, %u, %u, %p)", family, type, proto, sv);
26 res = socketpair(family, type, proto, sv);
27 zassert_true(res == -1 || res == 0,
28 "socketpair returned an unspecified value");
29 zassert_equal(res, 0, "socketpair failed");
30 LOG_DBG("sv: {%d, %d}", sv[0], sv[1]);
31
32 socklen_t len;
33
34 /* sockets are bidirectional. test functions from both ends */
35 for (int i = 0; i < 2; ++i) {
36
37 /*
38 * Test with send() / recv()
39 */
40
41 res = send(sv[i], expected_msg, expected_msg_len, 0);
42
43 zassert_not_equal(res, -1, "send() failed: %d", errno);
44 actual_msg_len = res;
45 zassert_equal(actual_msg_len, expected_msg_len,
46 "did not send entire message");
47
48 memset(actual_msg, 0, sizeof(actual_msg));
49
50 res = recv(sv[(!i) & 1], actual_msg, sizeof(actual_msg), 0);
51
52 zassert_not_equal(res, -1, "recv() failed: %d", errno);
53 actual_msg_len = res;
54 zassert_equal(actual_msg_len, expected_msg_len,
55 "wrong return value");
56
57 zassert_true(strncmp(expected_msg, actual_msg,
58 actual_msg_len) == 0,
59 "the wrong message was passed through the socketpair");
60
61 /*
62 * Test with sendto(2) / recvfrom(2)
63 */
64
65 res = sendto(sv[i], expected_msg, expected_msg_len, 0, NULL, 0);
66
67 zassert_not_equal(res, -1, "sendto() failed: %d", errno);
68 actual_msg_len = res;
69 zassert_equal(actual_msg_len, expected_msg_len,
70 "did not sendto entire message");
71
72 memset(actual_msg, 0, sizeof(actual_msg));
73
74 len = 0;
75 res = recvfrom(sv[(!i) & 1], actual_msg, sizeof(actual_msg), 0,
76 NULL, &len);
77 zassert_true(res >= 0, "recvfrom() failed: %d", errno);
78 actual_msg_len = res;
79 zassert_equal(actual_msg_len, expected_msg_len,
80 "wrong return value");
81
82 zassert_true(strncmp(expected_msg, actual_msg,
83 actual_msg_len) == 0,
84 "the wrong message was passed through the socketpair");
85
86 /*
87 * Test with sendmsg(2) / recv(2) - Zephyr lacks recvmsg atm
88 */
89
90 memset(&msghdr, 0, sizeof(msghdr));
91 msghdr.msg_iov = &iovec;
92 msghdr.msg_iovlen = 1;
93 iovec.iov_base = (void *)expected_msg;
94 iovec.iov_len = expected_msg_len;
95
96 res = sendmsg(sv[i], &msghdr, 0);
97
98 zassert_not_equal(res, -1, "sendmsg() failed: %d", errno);
99 actual_msg_len = res;
100 zassert_equal(actual_msg_len, expected_msg_len,
101 "did not sendmsg entire message");
102
103 res = recv(sv[(!i) & 1], actual_msg, sizeof(actual_msg), 0);
104
105 zassert_not_equal(res, -1, "recv() failed: %d", errno);
106 actual_msg_len = res;
107 zassert_equal(actual_msg_len, expected_msg_len,
108 "wrong return value");
109
110 zassert_true(strncmp(expected_msg, actual_msg,
111 actual_msg_len) == 0,
112 "the wrong message was passed through the socketpair");
113 }
114
115 res = close(sv[0]);
116 zassert_equal(res, 0, "close failed");
117
118 res = close(sv[1]);
119 zassert_equal(res, 0, "close failed");
120 }
121
ZTEST_USER(net_socketpair,test_AF_LOCAL_SOCK_STREAM_0)122 ZTEST_USER(net_socketpair, test_AF_LOCAL_SOCK_STREAM_0)
123 {
124 happy_path(
125 AF_LOCAL, "AF_LOCAL",
126 SOCK_STREAM, "SOCK_STREAM",
127 0, "0"
128 );
129 }
130
ZTEST_USER(net_socketpair,test_AF_UNIX_SOCK_STREAM_0)131 ZTEST_USER(net_socketpair, test_AF_UNIX_SOCK_STREAM_0)
132 {
133 happy_path(
134 AF_UNIX, "AF_UNIX",
135 SOCK_STREAM, "SOCK_STREAM",
136 0, "0"
137 );
138 }
139