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 "test/UnitTest/ErrnoCheckingTest.h"
16#include "test/UnitTest/ErrnoSetterMatcher.h"
17#include "test/UnitTest/Test.h"
18
19#include <sys/socket.h> // For AF_UNIX and SOCK_DGRAM
20
21using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
22using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
23using LlvmLibcSendMsgRecvMsgTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
24
25TEST_F(LlvmLibcSendMsgRecvMsgTest, SucceedsWithSocketPair) {
26 const char TEST_MESSAGE[] = "connection successful";
27 const size_t MESSAGE_LEN = sizeof(TEST_MESSAGE);
28
29 int sockpair[2] = {0, 0};
30
31 ASSERT_THAT(LIBC_NAMESPACE::socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair),
32 Succeeds(0));
33
34 iovec send_msg_text;
35 send_msg_text.iov_base =
36 reinterpret_cast<void *>(const_cast<char *>(TEST_MESSAGE));
37 send_msg_text.iov_len = MESSAGE_LEN;
38
39 msghdr send_message;
40 send_message.msg_name = nullptr;
41 send_message.msg_namelen = 0;
42 send_message.msg_iov = &send_msg_text;
43 send_message.msg_iovlen = 1;
44 send_message.msg_control = nullptr;
45 send_message.msg_controllen = 0;
46 send_message.msg_flags = 0;
47
48 ASSERT_THAT(LIBC_NAMESPACE::sendmsg(sockpair[0], &send_message, 0),
49 Succeeds(static_cast<ssize_t>(MESSAGE_LEN)));
50
51 char buffer[256];
52
53 iovec recv_msg_text;
54 recv_msg_text.iov_base = reinterpret_cast<void *>(buffer);
55 recv_msg_text.iov_len = sizeof(buffer);
56
57 msghdr recv_message;
58 recv_message.msg_name = nullptr;
59 recv_message.msg_namelen = 0;
60 recv_message.msg_iov = &recv_msg_text;
61 recv_message.msg_iovlen = 1;
62 recv_message.msg_control = nullptr;
63 recv_message.msg_controllen = 0;
64 recv_message.msg_flags = 0;
65
66 ASSERT_THAT(LIBC_NAMESPACE::recvmsg(sockpair[1], &recv_message, 0),
67 Succeeds(static_cast<ssize_t>(MESSAGE_LEN)));
68
69 ASSERT_STREQ(buffer, TEST_MESSAGE);
70
71 // close both ends of the socket
72 ASSERT_THAT(LIBC_NAMESPACE::close(sockpair[0]), Succeeds(0));
73 ASSERT_THAT(LIBC_NAMESPACE::close(sockpair[1]), Succeeds(0));
74}
75
76TEST_F(LlvmLibcSendMsgRecvMsgTest, SendFails) {
77 const char TEST_MESSAGE[] = "connection terminated";
78 const size_t MESSAGE_LEN = sizeof(TEST_MESSAGE);
79
80 iovec send_msg_text;
81 send_msg_text.iov_base =
82 reinterpret_cast<void *>(const_cast<char *>(TEST_MESSAGE));
83 send_msg_text.iov_len = MESSAGE_LEN;
84
85 msghdr send_message;
86 send_message.msg_name = nullptr;
87 send_message.msg_namelen = 0;
88 send_message.msg_iov = &send_msg_text;
89 send_message.msg_iovlen = 1;
90 send_message.msg_control = nullptr;
91 send_message.msg_controllen = 0;
92 send_message.msg_flags = 0;
93
94 ASSERT_THAT(LIBC_NAMESPACE::sendmsg(-1, &send_message, 0), Fails(EBADF));
95}
96
97TEST_F(LlvmLibcSendMsgRecvMsgTest, RecvFails) {
98 char buffer[256];
99
100 iovec recv_msg_text;
101 recv_msg_text.iov_base = reinterpret_cast<void *>(buffer);
102 recv_msg_text.iov_len = sizeof(buffer);
103
104 msghdr recv_message;
105 recv_message.msg_name = nullptr;
106 recv_message.msg_namelen = 0;
107 recv_message.msg_iov = &recv_msg_text;
108 recv_message.msg_iovlen = 1;
109 recv_message.msg_control = nullptr;
110 recv_message.msg_controllen = 0;
111 recv_message.msg_flags = 0;
112
113 ASSERT_THAT(LIBC_NAMESPACE::recvmsg(-1, &recv_message, 0), Fails(EBADF));
114}
115

source code of libc/test/src/sys/socket/linux/sendmsg_recvmsg_test.cpp