1 //===-- Unittests for sendmsg/recvmsg -------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/sys/socket/recvmsg.h"
10 #include "src/sys/socket/sendmsg.h"
11 #include "src/sys/socket/socketpair.h"
13 #include "src/unistd/close.h"
15 #include "src/errno/libc_errno.h"
16 #include "test/UnitTest/Test.h"
18 #include <sys/socket.h> // For AF_UNIX and SOCK_DGRAM
20 TEST(LlvmLibcSendMsgRecvMsgTest
, SucceedsWithSocketPair
) {
21 const char TEST_MESSAGE
[] = "connection successful";
22 const size_t MESSAGE_LEN
= sizeof(TEST_MESSAGE
);
24 int sockpair
[2] = {0, 0};
26 int result
= LIBC_NAMESPACE::socketpair(AF_UNIX
, SOCK_STREAM
, 0, sockpair
);
28 ASSERT_ERRNO_SUCCESS();
31 send_msg_text
.iov_base
=
32 reinterpret_cast<void *>(const_cast<char *>(TEST_MESSAGE
));
33 send_msg_text
.iov_len
= MESSAGE_LEN
;
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;
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();
51 recv_msg_text
.iov_base
= reinterpret_cast<void *>(buffer
);
52 recv_msg_text
.iov_len
= sizeof(buffer
);
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;
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();
67 ASSERT_STREQ(buffer
, TEST_MESSAGE
);
69 // close both ends of the socket
70 result
= LIBC_NAMESPACE::close(sockpair
[0]);
72 ASSERT_ERRNO_SUCCESS();
74 result
= LIBC_NAMESPACE::close(sockpair
[1]);
76 ASSERT_ERRNO_SUCCESS();
79 TEST(LlvmLibcSendMsgRecvMsgTest
, SendFails
) {
80 const char TEST_MESSAGE
[] = "connection terminated";
81 const size_t MESSAGE_LEN
= sizeof(TEST_MESSAGE
);
84 send_msg_text
.iov_base
=
85 reinterpret_cast<void *>(const_cast<char *>(TEST_MESSAGE
));
86 send_msg_text
.iov_len
= MESSAGE_LEN
;
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;
97 ssize_t send_result
= LIBC_NAMESPACE::sendmsg(-1, &send_message
, 0);
98 EXPECT_EQ(send_result
, ssize_t(-1));
99 ASSERT_ERRNO_FAILURE();
101 LIBC_NAMESPACE::libc_errno
= 0; // reset errno to avoid test ordering issues.
104 TEST(LlvmLibcSendMsgRecvMsgTest
, RecvFails
) {
108 recv_msg_text
.iov_base
= reinterpret_cast<void *>(buffer
);
109 recv_msg_text
.iov_len
= sizeof(buffer
);
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;
120 ssize_t recv_result
= LIBC_NAMESPACE::recvmsg(-1, &recv_message
, 0);
121 ASSERT_EQ(recv_result
, ssize_t(-1));
122 ASSERT_ERRNO_FAILURE();
124 LIBC_NAMESPACE::libc_errno
= 0; // reset errno to avoid test ordering issues.