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