Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / nonsfi / socket_test.cc
1 /*
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.
5  */
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11
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"
17
18 namespace {
19
20 char kMessage[] = "foo";
21 size_t kMessageLen = sizeof(kMessage);
22
23 class ScopedSocketPair {
24  public:
25   explicit ScopedSocketPair(int type) {
26     int rc = socketpair(AF_UNIX, type, 0, fds_);
27     ASSERT_EQ(rc, 0);
28   }
29
30   ~ScopedSocketPair() {
31     int rc = close(fds_[0]);
32     ASSERT_EQ(rc, 0);
33     rc = close(fds_[1]);
34     ASSERT_EQ(rc, 0);
35   }
36
37   int operator[](int i) const {
38     ASSERT(i == 0 || i == 1);
39     return fds_[i];
40   }
41
42  private:
43   int fds_[2];
44
45   DISALLOW_COPY_AND_ASSIGN(ScopedSocketPair);
46 };
47
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);
56 }
57
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;
65
66   int rc = recvmsg(fds[0], &received_msg, 0);
67   ASSERT_EQ(rc, kMessageLen);
68   return buf.release();
69 }
70
71 void TestDgramSocketpair(const char *type_str, int type) {
72   printf("TestDgramSocketpair (%s)", type_str);
73   ScopedSocketPair fds(type);
74
75   SendPacket(fds);
76   nacl::scoped_array<char> received(RecvPacket(fds));
77   ASSERT_EQ(0, strcmp(received.get(), kMessage));
78 }
79
80 void TestStreamSocketpair() {
81   printf("TestStreamSocketpair");
82   ScopedSocketPair fds(SOCK_STREAM);
83
84   size_t written_len = write(fds[1], kMessage, kMessageLen);
85   ASSERT_EQ(written_len, kMessageLen);
86
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);
90
91   ASSERT_EQ(0, strcmp(buf.get(), kMessage));
92 }
93
94 void PreparePollFd(const ScopedSocketPair &fds, struct pollfd pfd[2]) {
95   memset(pfd, 0, sizeof(*pfd) * 2);
96   pfd[0].fd = fds[0];
97   pfd[0].events = POLLIN;
98   pfd[1].fd = fds[1];
99   pfd[1].events = POLLOUT;
100 }
101
102 void TestPoll() {
103   printf("TestPoll");
104   ScopedSocketPair fds(SOCK_DGRAM);
105
106   struct pollfd pfd[2];
107   PreparePollFd(fds, pfd);
108
109   int rc = poll(pfd, 2, 0);
110   ASSERT_EQ(rc, 1);
111   ASSERT_EQ(pfd[0].revents, 0);
112   ASSERT_EQ(pfd[1].revents, POLLOUT);
113
114   SendPacket(fds);
115
116   PreparePollFd(fds, pfd);
117
118   rc = poll(pfd, 2, 0);
119   ASSERT_EQ(rc, 2);
120   ASSERT_EQ(pfd[0].revents, POLLIN);
121   ASSERT_EQ(pfd[1].revents, POLLOUT);
122
123   nacl::scoped_array<char> buf(RecvPacket(fds));
124
125   rc = shutdown(fds[1], SHUT_RDWR);
126   ASSERT_EQ(rc, 0);
127
128   PreparePollFd(fds, pfd);
129   rc = poll(pfd, 2, 0);
130   ASSERT_EQ(rc, 1);
131   ASSERT_EQ(pfd[0].revents, 0);
132   ASSERT_EQ(pfd[1].revents, POLLOUT | POLLHUP);
133 }
134
135 }  // namespace
136
137 int main(int argc, char *argv[]) {
138   TestDgramSocketpair("DGRAM", SOCK_DGRAM);
139   TestDgramSocketpair("SEQPACKET", SOCK_SEQPACKET);
140   TestStreamSocketpair();
141   TestPoll();
142   return 0;
143 }