2 * Copyright 2014 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
12 #include "native_client/src/include/nacl_assert.h"
13 #include "native_client/src/include/nacl_base.h"
14 #include "native_client/src/include/nacl_scoped_ptr.h"
15 #include "native_client/src/public/linux_syscalls/poll.h"
16 #include "native_client/src/public/linux_syscalls/sys/socket.h"
20 char kMessage[] = "foo";
21 size_t kMessageLen = sizeof(kMessage);
23 class ScopedSocketPair {
25 explicit ScopedSocketPair(int type) {
26 int rc = socketpair(AF_UNIX, type, 0, fds_);
31 int rc = close(fds_[0]);
37 int operator[](int i) const {
38 ASSERT(i == 0 || i == 1);
45 DISALLOW_COPY_AND_ASSIGN(ScopedSocketPair);
48 void SendPacket(const ScopedSocketPair &fds) {
49 struct msghdr sent_msg;
50 memset(&sent_msg, 0, sizeof(sent_msg));
51 struct iovec sent_iov = { kMessage, kMessageLen };
52 sent_msg.msg_iov = &sent_iov;
53 sent_msg.msg_iovlen = 1;
54 int rc = sendmsg(fds[1], &sent_msg, 0);
55 ASSERT_EQ(rc, kMessageLen);
58 char *RecvPacket(const ScopedSocketPair &fds) {
59 struct msghdr received_msg;
60 memset(&received_msg, 0, sizeof(received_msg));
61 nacl::scoped_array<char> buf(new char[kMessageLen]);
62 struct iovec received_iov = { buf.get(), kMessageLen };
63 received_msg.msg_iov = &received_iov;
64 received_msg.msg_iovlen = 1;
66 int rc = recvmsg(fds[0], &received_msg, 0);
67 ASSERT_EQ(rc, kMessageLen);
71 void TestDgramSocketpair(const char *type_str, int type) {
72 printf("TestDgramSocketpair (%s)", type_str);
73 ScopedSocketPair fds(type);
76 nacl::scoped_array<char> received(RecvPacket(fds));
77 ASSERT_EQ(0, strcmp(received.get(), kMessage));
80 void TestStreamSocketpair() {
81 printf("TestStreamSocketpair");
82 ScopedSocketPair fds(SOCK_STREAM);
84 size_t written_len = write(fds[1], kMessage, kMessageLen);
85 ASSERT_EQ(written_len, kMessageLen);
87 nacl::scoped_array<char> buf(new char[kMessageLen]);
88 size_t read_len = read(fds[0], buf.get(), kMessageLen);
89 ASSERT_EQ(read_len, kMessageLen);
91 ASSERT_EQ(0, strcmp(buf.get(), kMessage));
94 void PreparePollFd(const ScopedSocketPair &fds, struct pollfd pfd[2]) {
95 memset(pfd, 0, sizeof(*pfd) * 2);
97 pfd[0].events = POLLIN;
99 pfd[1].events = POLLOUT;
104 ScopedSocketPair fds(SOCK_DGRAM);
106 struct pollfd pfd[2];
107 PreparePollFd(fds, pfd);
109 int rc = poll(pfd, 2, 0);
111 ASSERT_EQ(pfd[0].revents, 0);
112 ASSERT_EQ(pfd[1].revents, POLLOUT);
116 PreparePollFd(fds, pfd);
118 rc = poll(pfd, 2, 0);
120 ASSERT_EQ(pfd[0].revents, POLLIN);
121 ASSERT_EQ(pfd[1].revents, POLLOUT);
123 nacl::scoped_array<char> buf(RecvPacket(fds));
125 rc = shutdown(fds[1], SHUT_RDWR);
128 PreparePollFd(fds, pfd);
129 rc = poll(pfd, 2, 0);
131 ASSERT_EQ(pfd[0].revents, 0);
132 ASSERT_EQ(pfd[1].revents, POLLOUT | POLLHUP);
137 int main(int argc, char *argv[]) {
138 TestDgramSocketpair("DGRAM", SOCK_DGRAM);
139 TestDgramSocketpair("SEQPACKET", SOCK_SEQPACKET);
140 TestStreamSocketpair();