| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ipc/ipc_channel_nacl.h" | 5 #include "ipc/ipc_channel_nacl.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <sys/types.h> | 9 #include <sys/types.h> |
| 10 | 10 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 17 #include "base/task_runner_util.h" | 17 #include "base/task_runner_util.h" |
| 18 #include "base/threading/simple_thread.h" | 18 #include "base/threading/simple_thread.h" |
| 19 #include "ipc/file_descriptor_set_posix.h" | |
| 20 #include "ipc/ipc_listener.h" | 19 #include "ipc/ipc_listener.h" |
| 21 #include "ipc/ipc_logging.h" | 20 #include "ipc/ipc_logging.h" |
| 21 #include "ipc/ipc_message_attachment_set.h" |
| 22 #include "native_client/src/public/imc_syscalls.h" | 22 #include "native_client/src/public/imc_syscalls.h" |
| 23 #include "native_client/src/public/imc_types.h" | 23 #include "native_client/src/public/imc_types.h" |
| 24 | 24 |
| 25 namespace IPC { | 25 namespace IPC { |
| 26 | 26 |
| 27 struct MessageContents { | 27 struct MessageContents { |
| 28 std::vector<char> data; | 28 std::vector<char> data; |
| 29 std::vector<int> fds; | 29 std::vector<int> fds; |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 bool ReadDataOnReaderThread(int pipe, MessageContents* contents) { | 34 bool ReadDataOnReaderThread(int pipe, MessageContents* contents) { |
| 35 DCHECK(pipe >= 0); | 35 DCHECK(pipe >= 0); |
| 36 if (pipe < 0) | 36 if (pipe < 0) |
| 37 return false; | 37 return false; |
| 38 | 38 |
| 39 contents->data.resize(Channel::kReadBufferSize); | 39 contents->data.resize(Channel::kReadBufferSize); |
| 40 contents->fds.resize(FileDescriptorSet::kMaxDescriptorsPerMessage); | 40 contents->fds.resize(MessageAttachmentSet::kMaxDescriptorsPerMessage); |
| 41 | 41 |
| 42 NaClAbiNaClImcMsgIoVec iov = { &contents->data[0], contents->data.size() }; | 42 NaClAbiNaClImcMsgIoVec iov = { &contents->data[0], contents->data.size() }; |
| 43 NaClAbiNaClImcMsgHdr msg = { | 43 NaClAbiNaClImcMsgHdr msg = { |
| 44 &iov, 1, &contents->fds[0], contents->fds.size() | 44 &iov, 1, &contents->fds[0], contents->fds.size() |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 int bytes_read = imc_recvmsg(pipe, &msg, 0); | 47 int bytes_read = imc_recvmsg(pipe, &msg, 0); |
| 48 | 48 |
| 49 if (bytes_read <= 0) { | 49 if (bytes_read <= 0) { |
| 50 // NaClIPCAdapter::BlockingReceive returns -1 when the pipe closes (either | 50 // NaClIPCAdapter::BlockingReceive returns -1 when the pipe closes (either |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 | 268 |
| 269 if (pipe_ == -1) | 269 if (pipe_ == -1) |
| 270 return false; | 270 return false; |
| 271 | 271 |
| 272 // Write out all the messages. The trusted implementation is guaranteed to not | 272 // Write out all the messages. The trusted implementation is guaranteed to not |
| 273 // block. See NaClIPCAdapter::Send for the implementation of imc_sendmsg. | 273 // block. See NaClIPCAdapter::Send for the implementation of imc_sendmsg. |
| 274 while (!output_queue_.empty()) { | 274 while (!output_queue_.empty()) { |
| 275 linked_ptr<Message> msg = output_queue_.front(); | 275 linked_ptr<Message> msg = output_queue_.front(); |
| 276 output_queue_.pop_front(); | 276 output_queue_.pop_front(); |
| 277 | 277 |
| 278 int fds[FileDescriptorSet::kMaxDescriptorsPerMessage]; | 278 int fds[MessageAttachmentSet::kMaxDescriptorsPerMessage]; |
| 279 const size_t num_fds = msg->file_descriptor_set()->size(); | 279 const size_t num_fds = msg->attachment_set()->size(); |
| 280 DCHECK(num_fds <= FileDescriptorSet::kMaxDescriptorsPerMessage); | 280 DCHECK(num_fds <= MessageAttachmentSet::kMaxDescriptorsPerMessage); |
| 281 msg->file_descriptor_set()->PeekDescriptors(fds); | 281 msg->attachment_set()->PeekDescriptors(fds); |
| 282 | 282 |
| 283 NaClAbiNaClImcMsgIoVec iov = { | 283 NaClAbiNaClImcMsgIoVec iov = { |
| 284 const_cast<void*>(msg->data()), msg->size() | 284 const_cast<void*>(msg->data()), msg->size() |
| 285 }; | 285 }; |
| 286 NaClAbiNaClImcMsgHdr msgh = { &iov, 1, fds, num_fds }; | 286 NaClAbiNaClImcMsgHdr msgh = { &iov, 1, fds, num_fds }; |
| 287 ssize_t bytes_written = imc_sendmsg(pipe_, &msgh, 0); | 287 ssize_t bytes_written = imc_sendmsg(pipe_, &msgh, 0); |
| 288 | 288 |
| 289 DCHECK(bytes_written); // The trusted side shouldn't return 0. | 289 DCHECK(bytes_written); // The trusted side shouldn't return 0. |
| 290 if (bytes_written < 0) { | 290 if (bytes_written < 0) { |
| 291 // The trusted side should only ever give us an error of EPIPE. We | 291 // The trusted side should only ever give us an error of EPIPE. We |
| 292 // should never be interrupted, nor should we get EAGAIN. | 292 // should never be interrupted, nor should we get EAGAIN. |
| 293 DCHECK(errno == EPIPE); | 293 DCHECK(errno == EPIPE); |
| 294 Close(); | 294 Close(); |
| 295 PLOG(ERROR) << "pipe_ error on " | 295 PLOG(ERROR) << "pipe_ error on " |
| 296 << pipe_ | 296 << pipe_ |
| 297 << " Currently writing message of size: " | 297 << " Currently writing message of size: " |
| 298 << msg->size(); | 298 << msg->size(); |
| 299 return false; | 299 return false; |
| 300 } else { | 300 } else { |
| 301 msg->file_descriptor_set()->CommitAll(); | 301 msg->attachment_set()->CommitAll(); |
| 302 } | 302 } |
| 303 | 303 |
| 304 // Message sent OK! | 304 // Message sent OK! |
| 305 DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type() | 305 DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type() |
| 306 << " on fd " << pipe_; | 306 << " on fd " << pipe_; |
| 307 } | 307 } |
| 308 return true; | 308 return true; |
| 309 } | 309 } |
| 310 | 310 |
| 311 void ChannelNacl::CallOnChannelConnected() { | 311 void ChannelNacl::CallOnChannelConnected() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 | 345 |
| 346 bool ChannelNacl::WillDispatchInputMessage(Message* msg) { | 346 bool ChannelNacl::WillDispatchInputMessage(Message* msg) { |
| 347 uint16 header_fds = msg->header()->num_fds; | 347 uint16 header_fds = msg->header()->num_fds; |
| 348 CHECK(header_fds == input_fds_.size()); | 348 CHECK(header_fds == input_fds_.size()); |
| 349 if (header_fds == 0) | 349 if (header_fds == 0) |
| 350 return true; // Nothing to do. | 350 return true; // Nothing to do. |
| 351 | 351 |
| 352 // The shenaniganery below with &foo.front() requires input_fds_ to have | 352 // The shenaniganery below with &foo.front() requires input_fds_ to have |
| 353 // contiguous underlying storage (such as a simple array or a std::vector). | 353 // contiguous underlying storage (such as a simple array or a std::vector). |
| 354 // This is why the header warns not to make input_fds_ a deque<>. | 354 // This is why the header warns not to make input_fds_ a deque<>. |
| 355 msg->file_descriptor_set()->AddDescriptorsToOwn(&input_fds_.front(), | 355 msg->attachment_set()->AddDescriptorsToOwn(&input_fds_.front(), header_fds); |
| 356 header_fds); | |
| 357 input_fds_.clear(); | 356 input_fds_.clear(); |
| 358 return true; | 357 return true; |
| 359 } | 358 } |
| 360 | 359 |
| 361 bool ChannelNacl::DidEmptyInputBuffers() { | 360 bool ChannelNacl::DidEmptyInputBuffers() { |
| 362 // When the input data buffer is empty, the fds should be too. | 361 // When the input data buffer is empty, the fds should be too. |
| 363 return input_fds_.empty(); | 362 return input_fds_.empty(); |
| 364 } | 363 } |
| 365 | 364 |
| 366 void ChannelNacl::HandleInternalMessage(const Message& msg) { | 365 void ChannelNacl::HandleInternalMessage(const Message& msg) { |
| 367 // The trusted side IPC::Channel should handle the "hello" handshake; we | 366 // The trusted side IPC::Channel should handle the "hello" handshake; we |
| 368 // should not receive the "Hello" message. | 367 // should not receive the "Hello" message. |
| 369 NOTREACHED(); | 368 NOTREACHED(); |
| 370 } | 369 } |
| 371 | 370 |
| 372 // Channel's methods | 371 // Channel's methods |
| 373 | 372 |
| 374 // static | 373 // static |
| 375 scoped_ptr<Channel> Channel::Create( | 374 scoped_ptr<Channel> Channel::Create( |
| 376 const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { | 375 const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { |
| 377 return scoped_ptr<Channel>( | 376 return scoped_ptr<Channel>( |
| 378 new ChannelNacl(channel_handle, mode, listener)); | 377 new ChannelNacl(channel_handle, mode, listener)); |
| 379 } | 378 } |
| 380 | 379 |
| 381 } // namespace IPC | 380 } // namespace IPC |
| OLD | NEW |