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