| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/embedder/platform_channel_pair.h" | 5 #include "mojo/embedder/platform_channel_pair.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <poll.h> | 8 #include <poll.h> |
| 9 #include <signal.h> | 9 #include <signal.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| 11 #include <sys/socket.h> | 11 #include <sys/socket.h> |
| 12 #include <sys/types.h> | 12 #include <sys/types.h> |
| 13 #include <sys/uio.h> | 13 #include <sys/uio.h> |
| 14 #include <unistd.h> | 14 #include <unistd.h> |
| 15 | 15 |
| 16 #include <vector> | 16 #include <deque> |
| 17 | 17 |
| 18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
| 19 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
| 20 #include "base/files/scoped_file.h" | 20 #include "base/files/scoped_file.h" |
| 21 #include "base/logging.h" | 21 #include "base/logging.h" |
| 22 #include "base/macros.h" | 22 #include "base/macros.h" |
| 23 #include "mojo/common/test/test_utils.h" | 23 #include "mojo/common/test/test_utils.h" |
| 24 #include "mojo/embedder/platform_channel_utils_posix.h" | 24 #include "mojo/embedder/platform_channel_utils_posix.h" |
| 25 #include "mojo/embedder/platform_handle.h" |
| 26 #include "mojo/embedder/platform_handle_vector.h" |
| 25 #include "mojo/embedder/scoped_platform_handle.h" | 27 #include "mojo/embedder/scoped_platform_handle.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 29 |
| 28 namespace mojo { | 30 namespace mojo { |
| 29 namespace embedder { | 31 namespace embedder { |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 void WaitReadable(PlatformHandle h) { | 34 void WaitReadable(PlatformHandle h) { |
| 33 struct pollfd pfds = {}; | 35 struct pollfd pfds = {}; |
| 34 pfds.fd = h.fd; | 36 pfds.fd = h.fd; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 for (size_t i = 0; i < 10; i++) { | 112 for (size_t i = 0; i < 10; i++) { |
| 111 std::string send_string(1 << i, 'A' + i); | 113 std::string send_string(1 << i, 'A' + i); |
| 112 | 114 |
| 113 EXPECT_EQ(static_cast<ssize_t>(send_string.size()), | 115 EXPECT_EQ(static_cast<ssize_t>(send_string.size()), |
| 114 PlatformChannelWrite(server_handle.get(), send_string.data(), | 116 PlatformChannelWrite(server_handle.get(), send_string.data(), |
| 115 send_string.size())); | 117 send_string.size())); |
| 116 | 118 |
| 117 WaitReadable(client_handle.get()); | 119 WaitReadable(client_handle.get()); |
| 118 | 120 |
| 119 char buf[10000] = {}; | 121 char buf[10000] = {}; |
| 120 ScopedPlatformHandleVectorPtr received_handles; | 122 std::deque<PlatformHandle> received_handles; |
| 121 ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf, | 123 ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf, |
| 122 sizeof(buf), &received_handles); | 124 sizeof(buf), &received_handles); |
| 123 EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result); | 125 EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result); |
| 124 EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result))); | 126 EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result))); |
| 125 EXPECT_FALSE(received_handles); | 127 EXPECT_TRUE(received_handles.empty()); |
| 126 } | 128 } |
| 127 } | 129 } |
| 128 | 130 |
| 129 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { | 131 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { |
| 130 PlatformChannelPair channel_pair; | 132 PlatformChannelPair channel_pair; |
| 131 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); | 133 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); |
| 132 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); | 134 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); |
| 133 | 135 |
| 134 for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) { | 136 for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) { |
| 135 // Make |i| files, with the j-th file consisting of j copies of the digit i. | 137 // Make |i| files, with the j-th file consisting of j copies of the digit i. |
| 136 PlatformHandleVector platform_handles; | 138 PlatformHandleVector platform_handles; |
| 137 for (size_t j = 1; j <= i; j++) { | 139 for (size_t j = 1; j <= i; j++) { |
| 138 base::FilePath ignored; | 140 base::FilePath ignored; |
| 139 base::ScopedFILE fp(base::CreateAndOpenTemporaryFile(&ignored)); | 141 base::ScopedFILE fp(base::CreateAndOpenTemporaryFile(&ignored)); |
| 140 ASSERT_TRUE(fp); | 142 ASSERT_TRUE(fp); |
| 141 fwrite(std::string(j, '0' + i).data(), 1, j, fp.get()); | 143 fwrite(std::string(j, '0' + i).data(), 1, j, fp.get()); |
| 142 platform_handles.push_back( | 144 platform_handles.push_back( |
| 143 test::PlatformHandleFromFILE(fp.Pass()).release()); | 145 test::PlatformHandleFromFILE(fp.Pass()).release()); |
| 144 ASSERT_TRUE(platform_handles.back().is_valid()); | 146 ASSERT_TRUE(platform_handles.back().is_valid()); |
| 145 } | 147 } |
| 146 | 148 |
| 147 // Send the FDs. | 149 // Send the FDs. |
| 148 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), | 150 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), |
| 149 &platform_handles[0], | 151 &platform_handles[0], |
| 150 platform_handles.size())); | 152 platform_handles.size())); |
| 151 | 153 |
| 152 WaitReadable(client_handle.get()); | 154 WaitReadable(client_handle.get()); |
| 153 | 155 |
| 154 char buf[100] = { 'a' }; | 156 char buf[100] = { 'a' }; |
| 155 ScopedPlatformHandleVectorPtr received_handles; | 157 std::deque<PlatformHandle> received_handles; |
| 156 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), | 158 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), |
| 157 &received_handles)); | 159 &received_handles)); |
| 158 EXPECT_EQ('\0', buf[0]); | 160 EXPECT_EQ('\0', buf[0]); |
| 159 ASSERT_TRUE(received_handles); | 161 ASSERT_FALSE(received_handles.empty()); |
| 160 EXPECT_EQ(i, received_handles->size()); | 162 EXPECT_EQ(i, received_handles.size()); |
| 161 | 163 |
| 162 for (size_t j = 0; j < received_handles->size(); j++) { | 164 for (size_t j = 0; !received_handles.empty(); j++) { |
| 163 base::ScopedFILE fp(test::FILEFromPlatformHandle( | 165 base::ScopedFILE fp(test::FILEFromPlatformHandle( |
| 164 ScopedPlatformHandle((*received_handles)[j]), "rb")); | 166 ScopedPlatformHandle(received_handles.front()), "rb")); |
| 165 (*received_handles)[j] = PlatformHandle(); | 167 received_handles.pop_front(); |
| 166 ASSERT_TRUE(fp); | 168 ASSERT_TRUE(fp); |
| 167 rewind(fp.get()); | 169 rewind(fp.get()); |
| 168 char read_buf[100]; | 170 char read_buf[100]; |
| 169 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); | 171 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); |
| 170 EXPECT_EQ(j + 1, bytes_read); | 172 EXPECT_EQ(j + 1, bytes_read); |
| 171 EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read)); | 173 EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read)); |
| 172 } | 174 } |
| 173 } | 175 } |
| 174 } | 176 } |
| 175 | 177 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 191 ASSERT_TRUE(platform_handles.back().is_valid()); | 193 ASSERT_TRUE(platform_handles.back().is_valid()); |
| 192 | 194 |
| 193 // Send the FD. | 195 // Send the FD. |
| 194 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), | 196 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), |
| 195 &platform_handles[0], | 197 &platform_handles[0], |
| 196 platform_handles.size())); | 198 platform_handles.size())); |
| 197 } | 199 } |
| 198 | 200 |
| 199 WaitReadable(client_handle.get()); | 201 WaitReadable(client_handle.get()); |
| 200 | 202 |
| 201 // Start with an invalid handle in the vector. | 203 // Start with an invalid handle in the deque. |
| 202 ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector()); | 204 std::deque<PlatformHandle> received_handles; |
| 203 handles->push_back(PlatformHandle()); | 205 received_handles.push_back(PlatformHandle()); |
| 204 | 206 |
| 205 char buf[100] = { 'a' }; | 207 char buf[100] = { 'a' }; |
| 206 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), | 208 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), |
| 207 &handles)); | 209 &received_handles)); |
| 208 EXPECT_EQ('\0', buf[0]); | 210 EXPECT_EQ('\0', buf[0]); |
| 209 ASSERT_TRUE(handles); | 211 ASSERT_EQ(2u, received_handles.size()); |
| 210 ASSERT_EQ(2u, handles->size()); | 212 EXPECT_FALSE(received_handles[0].is_valid()); |
| 211 EXPECT_FALSE((*handles)[0].is_valid()); | 213 EXPECT_TRUE(received_handles[1].is_valid()); |
| 212 EXPECT_TRUE((*handles)[1].is_valid()); | |
| 213 | 214 |
| 214 { | 215 { |
| 215 base::ScopedFILE fp(test::FILEFromPlatformHandle( | 216 base::ScopedFILE fp(test::FILEFromPlatformHandle( |
| 216 ScopedPlatformHandle((*handles)[1]), "rb")); | 217 ScopedPlatformHandle(received_handles[1]), "rb")); |
| 217 (*handles)[1] = PlatformHandle(); | 218 received_handles[1] = PlatformHandle(); |
| 218 ASSERT_TRUE(fp); | 219 ASSERT_TRUE(fp); |
| 219 rewind(fp.get()); | 220 rewind(fp.get()); |
| 220 char read_buf[100]; | 221 char read_buf[100]; |
| 221 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); | 222 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); |
| 222 EXPECT_EQ(file_contents.size(), bytes_read); | 223 EXPECT_EQ(file_contents.size(), bytes_read); |
| 223 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read)); | 224 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read)); |
| 224 } | 225 } |
| 225 } | 226 } |
| 226 | 227 |
| 227 } // namespace | 228 } // namespace |
| 228 } // namespace embedder | 229 } // namespace embedder |
| 229 } // namespace mojo | 230 } // namespace mojo |
| OLD | NEW |