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