xref: /llvm-project/libc/test/src/sys/socket/linux/sendmsg_recvmsg_test.cpp (revision f6b4c34d4f96ca705409f76b9bb48de7d2bec9bd)
1*f6b4c34dSMichael Jones //===-- Unittests for sendmsg/recvmsg -------------------------------------===//
2*f6b4c34dSMichael Jones //
3*f6b4c34dSMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*f6b4c34dSMichael Jones // See https://llvm.org/LICENSE.txt for license information.
5*f6b4c34dSMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*f6b4c34dSMichael Jones //
7*f6b4c34dSMichael Jones //===----------------------------------------------------------------------===//
8*f6b4c34dSMichael Jones 
9*f6b4c34dSMichael Jones #include "src/sys/socket/recvmsg.h"
10*f6b4c34dSMichael Jones #include "src/sys/socket/sendmsg.h"
11*f6b4c34dSMichael Jones #include "src/sys/socket/socketpair.h"
12*f6b4c34dSMichael Jones 
13*f6b4c34dSMichael Jones #include "src/unistd/close.h"
14*f6b4c34dSMichael Jones 
15*f6b4c34dSMichael Jones #include "src/errno/libc_errno.h"
16*f6b4c34dSMichael Jones #include "test/UnitTest/Test.h"
17*f6b4c34dSMichael Jones 
18*f6b4c34dSMichael Jones #include <sys/socket.h> // For AF_UNIX and SOCK_DGRAM
19*f6b4c34dSMichael Jones 
20*f6b4c34dSMichael Jones TEST(LlvmLibcSendMsgRecvMsgTest, SucceedsWithSocketPair) {
21*f6b4c34dSMichael Jones   const char TEST_MESSAGE[] = "connection successful";
22*f6b4c34dSMichael Jones   const size_t MESSAGE_LEN = sizeof(TEST_MESSAGE);
23*f6b4c34dSMichael Jones 
24*f6b4c34dSMichael Jones   int sockpair[2] = {0, 0};
25*f6b4c34dSMichael Jones 
26*f6b4c34dSMichael Jones   int result = LIBC_NAMESPACE::socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair);
27*f6b4c34dSMichael Jones   ASSERT_EQ(result, 0);
28*f6b4c34dSMichael Jones   ASSERT_ERRNO_SUCCESS();
29*f6b4c34dSMichael Jones 
30*f6b4c34dSMichael Jones   iovec send_msg_text;
31*f6b4c34dSMichael Jones   send_msg_text.iov_base =
32*f6b4c34dSMichael Jones       reinterpret_cast<void *>(const_cast<char *>(TEST_MESSAGE));
33*f6b4c34dSMichael Jones   send_msg_text.iov_len = MESSAGE_LEN;
34*f6b4c34dSMichael Jones 
35*f6b4c34dSMichael Jones   msghdr send_message;
36*f6b4c34dSMichael Jones   send_message.msg_name = nullptr;
37*f6b4c34dSMichael Jones   send_message.msg_namelen = 0;
38*f6b4c34dSMichael Jones   send_message.msg_iov = &send_msg_text;
39*f6b4c34dSMichael Jones   send_message.msg_iovlen = 1;
40*f6b4c34dSMichael Jones   send_message.msg_control = nullptr;
41*f6b4c34dSMichael Jones   send_message.msg_controllen = 0;
42*f6b4c34dSMichael Jones   send_message.msg_flags = 0;
43*f6b4c34dSMichael Jones 
44*f6b4c34dSMichael Jones   ssize_t send_result = LIBC_NAMESPACE::sendmsg(sockpair[0], &send_message, 0);
45*f6b4c34dSMichael Jones   EXPECT_EQ(send_result, static_cast<ssize_t>(MESSAGE_LEN));
46*f6b4c34dSMichael Jones   ASSERT_ERRNO_SUCCESS();
47*f6b4c34dSMichael Jones 
48*f6b4c34dSMichael Jones   char buffer[256];
49*f6b4c34dSMichael Jones 
50*f6b4c34dSMichael Jones   iovec recv_msg_text;
51*f6b4c34dSMichael Jones   recv_msg_text.iov_base = reinterpret_cast<void *>(buffer);
52*f6b4c34dSMichael Jones   recv_msg_text.iov_len = sizeof(buffer);
53*f6b4c34dSMichael Jones 
54*f6b4c34dSMichael Jones   msghdr recv_message;
55*f6b4c34dSMichael Jones   recv_message.msg_name = nullptr;
56*f6b4c34dSMichael Jones   recv_message.msg_namelen = 0;
57*f6b4c34dSMichael Jones   recv_message.msg_iov = &recv_msg_text;
58*f6b4c34dSMichael Jones   recv_message.msg_iovlen = 1;
59*f6b4c34dSMichael Jones   recv_message.msg_control = nullptr;
60*f6b4c34dSMichael Jones   recv_message.msg_controllen = 0;
61*f6b4c34dSMichael Jones   recv_message.msg_flags = 0;
62*f6b4c34dSMichael Jones 
63*f6b4c34dSMichael Jones   ssize_t recv_result = LIBC_NAMESPACE::recvmsg(sockpair[1], &recv_message, 0);
64*f6b4c34dSMichael Jones   ASSERT_EQ(recv_result, static_cast<ssize_t>(MESSAGE_LEN));
65*f6b4c34dSMichael Jones   ASSERT_ERRNO_SUCCESS();
66*f6b4c34dSMichael Jones 
67*f6b4c34dSMichael Jones   ASSERT_STREQ(buffer, TEST_MESSAGE);
68*f6b4c34dSMichael Jones 
69*f6b4c34dSMichael Jones   // close both ends of the socket
70*f6b4c34dSMichael Jones   result = LIBC_NAMESPACE::close(sockpair[0]);
71*f6b4c34dSMichael Jones   ASSERT_EQ(result, 0);
72*f6b4c34dSMichael Jones   ASSERT_ERRNO_SUCCESS();
73*f6b4c34dSMichael Jones 
74*f6b4c34dSMichael Jones   result = LIBC_NAMESPACE::close(sockpair[1]);
75*f6b4c34dSMichael Jones   ASSERT_EQ(result, 0);
76*f6b4c34dSMichael Jones   ASSERT_ERRNO_SUCCESS();
77*f6b4c34dSMichael Jones }
78*f6b4c34dSMichael Jones 
79*f6b4c34dSMichael Jones TEST(LlvmLibcSendMsgRecvMsgTest, SendFails) {
80*f6b4c34dSMichael Jones   const char TEST_MESSAGE[] = "connection terminated";
81*f6b4c34dSMichael Jones   const size_t MESSAGE_LEN = sizeof(TEST_MESSAGE);
82*f6b4c34dSMichael Jones 
83*f6b4c34dSMichael Jones   iovec send_msg_text;
84*f6b4c34dSMichael Jones   send_msg_text.iov_base =
85*f6b4c34dSMichael Jones       reinterpret_cast<void *>(const_cast<char *>(TEST_MESSAGE));
86*f6b4c34dSMichael Jones   send_msg_text.iov_len = MESSAGE_LEN;
87*f6b4c34dSMichael Jones 
88*f6b4c34dSMichael Jones   msghdr send_message;
89*f6b4c34dSMichael Jones   send_message.msg_name = nullptr;
90*f6b4c34dSMichael Jones   send_message.msg_namelen = 0;
91*f6b4c34dSMichael Jones   send_message.msg_iov = &send_msg_text;
92*f6b4c34dSMichael Jones   send_message.msg_iovlen = 1;
93*f6b4c34dSMichael Jones   send_message.msg_control = nullptr;
94*f6b4c34dSMichael Jones   send_message.msg_controllen = 0;
95*f6b4c34dSMichael Jones   send_message.msg_flags = 0;
96*f6b4c34dSMichael Jones 
97*f6b4c34dSMichael Jones   ssize_t send_result = LIBC_NAMESPACE::sendmsg(-1, &send_message, 0);
98*f6b4c34dSMichael Jones   EXPECT_EQ(send_result, ssize_t(-1));
99*f6b4c34dSMichael Jones   ASSERT_ERRNO_FAILURE();
100*f6b4c34dSMichael Jones 
101*f6b4c34dSMichael Jones   LIBC_NAMESPACE::libc_errno = 0; // reset errno to avoid test ordering issues.
102*f6b4c34dSMichael Jones }
103*f6b4c34dSMichael Jones 
104*f6b4c34dSMichael Jones TEST(LlvmLibcSendMsgRecvMsgTest, RecvFails) {
105*f6b4c34dSMichael Jones   char buffer[256];
106*f6b4c34dSMichael Jones 
107*f6b4c34dSMichael Jones   iovec recv_msg_text;
108*f6b4c34dSMichael Jones   recv_msg_text.iov_base = reinterpret_cast<void *>(buffer);
109*f6b4c34dSMichael Jones   recv_msg_text.iov_len = sizeof(buffer);
110*f6b4c34dSMichael Jones 
111*f6b4c34dSMichael Jones   msghdr recv_message;
112*f6b4c34dSMichael Jones   recv_message.msg_name = nullptr;
113*f6b4c34dSMichael Jones   recv_message.msg_namelen = 0;
114*f6b4c34dSMichael Jones   recv_message.msg_iov = &recv_msg_text;
115*f6b4c34dSMichael Jones   recv_message.msg_iovlen = 1;
116*f6b4c34dSMichael Jones   recv_message.msg_control = nullptr;
117*f6b4c34dSMichael Jones   recv_message.msg_controllen = 0;
118*f6b4c34dSMichael Jones   recv_message.msg_flags = 0;
119*f6b4c34dSMichael Jones 
120*f6b4c34dSMichael Jones   ssize_t recv_result = LIBC_NAMESPACE::recvmsg(-1, &recv_message, 0);
121*f6b4c34dSMichael Jones   ASSERT_EQ(recv_result, ssize_t(-1));
122*f6b4c34dSMichael Jones   ASSERT_ERRNO_FAILURE();
123*f6b4c34dSMichael Jones 
124*f6b4c34dSMichael Jones   LIBC_NAMESPACE::libc_errno = 0; // reset errno to avoid test ordering issues.
125*f6b4c34dSMichael Jones }
126