| Index: mojo/system/raw_channel_posix.cc
|
| diff --git a/mojo/system/raw_channel_posix.cc b/mojo/system/raw_channel_posix.cc
|
| index 1fd4a31ee9c9b17438d3e533128ce3e7b87bedc1..4636fe4808cb1d1157183a121441b69976e58333 100644
|
| --- a/mojo/system/raw_channel_posix.cc
|
| +++ b/mojo/system/raw_channel_posix.cc
|
| @@ -21,6 +21,8 @@
|
| #include "base/synchronization/lock.h"
|
| #include "mojo/embedder/platform_channel_utils_posix.h"
|
| #include "mojo/embedder/platform_handle.h"
|
| +#include "mojo/embedder/platform_handle_vector.h"
|
| +#include "mojo/system/transport_data.h"
|
|
|
| namespace mojo {
|
| namespace system {
|
| @@ -40,6 +42,9 @@ class RawChannelPosix : public RawChannel,
|
| // |RawChannel| protected methods:
|
| virtual IOResult Read(size_t* bytes_read) OVERRIDE;
|
| virtual IOResult ScheduleRead() OVERRIDE;
|
| + virtual scoped_ptr<embedder::PlatformHandleVector> GetReadPlatformHandles(
|
| + size_t num_platform_handles,
|
| + const void* platform_handle_table) OVERRIDE;
|
| virtual IOResult WriteNoLock(size_t* platform_handles_written,
|
| size_t* bytes_written) OVERRIDE;
|
| virtual IOResult ScheduleWriteNoLock() OVERRIDE;
|
| @@ -63,6 +68,8 @@ class RawChannelPosix : public RawChannel,
|
|
|
| bool pending_read_;
|
|
|
| + scoped_ptr<embedder::PlatformHandleVector> read_platform_handles_;
|
| +
|
| // The following members are used on multiple threads and protected by
|
| // |write_lock()|:
|
| bool pending_write_;
|
| @@ -110,28 +117,31 @@ RawChannel::IOResult RawChannelPosix::Read(size_t* bytes_read) {
|
| size_t bytes_to_read = 0;
|
| read_buffer()->GetBuffer(&buffer, &bytes_to_read);
|
|
|
| - scoped_ptr<embedder::PlatformHandleVector> handles;
|
| - ssize_t read_result = embedder::PlatformChannelRecvmsg(fd_.get(),
|
| - buffer,
|
| - bytes_to_read,
|
| - &handles);
|
| + size_t old_num_platform_handles =
|
| + read_platform_handles_ ? read_platform_handles_->size() : 0;
|
| + ssize_t read_result =
|
| + embedder::PlatformChannelRecvmsg(fd_.get(),
|
| + buffer,
|
| + bytes_to_read,
|
| + &read_platform_handles_);
|
| if (read_result > 0) {
|
| *bytes_read = static_cast<size_t>(read_result);
|
| return IO_SUCCEEDED;
|
| }
|
|
|
| - if (handles) {
|
| + if (read_platform_handles_ &&
|
| + read_platform_handles_->size() > old_num_platform_handles) {
|
| if (read_result != 1) {
|
| - LOG(WARNING) << "Invalid control message with handles";
|
| + LOG(WARNING) << "Invalid control message with platform handles";
|
| return IO_FAILED;
|
| }
|
|
|
| - // TODO(vtl): Implement this ("buffer" received handles). For now, just drop
|
| - // them on the floor. (Discard this message entirely.)
|
| - NOTIMPLEMENTED();
|
| - for (size_t i = 0; i < handles->size(); i++)
|
| - (*handles)[i].CloseIfNecessary();
|
| - return ScheduleRead();
|
| + if (read_platform_handles_->size() > TransportData::kMaxPlatformHandles) {
|
| + LOG(WARNING) << "Received too many platform handles";
|
| + embedder::CloseAllHandlesAndClear(read_platform_handles_.get());
|
| + read_platform_handles_.reset();
|
| + return IO_FAILED;
|
| + }
|
| }
|
|
|
| // |read_result == 0| means "end of file".
|
| @@ -156,6 +166,22 @@ RawChannel::IOResult RawChannelPosix::ScheduleRead() {
|
| return IO_PENDING;
|
| }
|
|
|
| +scoped_ptr<embedder::PlatformHandleVector>
|
| + RawChannelPosix::GetReadPlatformHandles(
|
| + size_t num_platform_handles,
|
| + const void* /*platform_handle_table*/) {
|
| + DCHECK_GT(num_platform_handles, 0u);
|
| +
|
| + if (!read_platform_handles_ ||
|
| + read_platform_handles_->size() != num_platform_handles) {
|
| + embedder::CloseAllHandlesAndClear(read_platform_handles_.get());
|
| + read_platform_handles_.reset();
|
| + return scoped_ptr<embedder::PlatformHandleVector>();
|
| + }
|
| +
|
| + return read_platform_handles_.Pass();
|
| +}
|
| +
|
| RawChannel::IOResult RawChannelPosix::WriteNoLock(
|
| size_t* platform_handles_written,
|
| size_t* bytes_written) {
|
|
|