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) { |