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 "ipc/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "ipc/ipc_listener.h" | 10 #include "ipc/ipc_listener.h" |
11 #include "ipc/ipc_logging.h" | 11 #include "ipc/ipc_logging.h" |
12 #include "ipc/ipc_message_attachment_set.h" | 12 #include "ipc/ipc_message_attachment_set.h" |
13 #include "ipc/ipc_message_macros.h" | 13 #include "ipc/ipc_message_macros.h" |
14 #include "ipc/mojo/client_channel.mojom.h" | 14 #include "ipc/mojo/client_channel.mojom.h" |
15 #include "ipc/mojo/ipc_mojo_bootstrap.h" | 15 #include "ipc/mojo/ipc_mojo_bootstrap.h" |
| 16 #include "ipc/mojo/ipc_mojo_handle_attachment.h" |
16 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" | 17 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" |
17 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" | 18 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" |
18 | 19 |
19 #if defined(OS_POSIX) && !defined(OS_NACL) | 20 #if defined(OS_POSIX) && !defined(OS_NACL) |
20 #include "ipc/ipc_platform_file_attachment_posix.h" | 21 #include "ipc/ipc_platform_file_attachment_posix.h" |
21 #endif | 22 #endif |
22 | 23 |
23 namespace IPC { | 24 namespace IPC { |
24 | 25 |
25 namespace { | 26 namespace { |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 } | 335 } |
335 | 336 |
336 #if defined(OS_POSIX) && !defined(OS_NACL) | 337 #if defined(OS_POSIX) && !defined(OS_NACL) |
337 int ChannelMojo::GetClientFileDescriptor() const { | 338 int ChannelMojo::GetClientFileDescriptor() const { |
338 return bootstrap_->GetClientFileDescriptor(); | 339 return bootstrap_->GetClientFileDescriptor(); |
339 } | 340 } |
340 | 341 |
341 base::ScopedFD ChannelMojo::TakeClientFileDescriptor() { | 342 base::ScopedFD ChannelMojo::TakeClientFileDescriptor() { |
342 return bootstrap_->TakeClientFileDescriptor(); | 343 return bootstrap_->TakeClientFileDescriptor(); |
343 } | 344 } |
344 | 345 #endif // defined(OS_POSIX) && !defined(OS_NACL) |
345 // static | |
346 MojoResult ChannelMojo::WriteToMessageAttachmentSet( | |
347 const std::vector<MojoHandle>& handle_buffer, | |
348 Message* message) { | |
349 for (size_t i = 0; i < handle_buffer.size(); ++i) { | |
350 mojo::embedder::ScopedPlatformHandle platform_handle; | |
351 MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle( | |
352 handle_buffer[i], &platform_handle); | |
353 if (unwrap_result != MOJO_RESULT_OK) { | |
354 DLOG(WARNING) << "Pipe failed to covert handles. Closing: " | |
355 << unwrap_result; | |
356 return unwrap_result; | |
357 } | |
358 | |
359 bool ok = message->attachment_set()->AddAttachment( | |
360 new internal::PlatformFileAttachment( | |
361 base::ScopedFD(platform_handle.release().fd))); | |
362 DCHECK(ok); | |
363 } | |
364 | |
365 return MOJO_RESULT_OK; | |
366 } | |
367 | 346 |
368 // static | 347 // static |
369 MojoResult ChannelMojo::ReadFromMessageAttachmentSet( | 348 MojoResult ChannelMojo::ReadFromMessageAttachmentSet( |
370 Message* message, | 349 Message* message, |
371 std::vector<MojoHandle>* handles) { | 350 std::vector<MojoHandle>* handles) { |
372 // We dup() the handles in IPC::Message to transmit. | 351 // We dup() the handles in IPC::Message to transmit. |
373 // IPC::MessageAttachmentSet has intricate lifecycle semantics | 352 // IPC::MessageAttachmentSet has intricate lifecycle semantics |
374 // of FDs, so just to dup()-and-own them is the safest option. | 353 // of FDs, so just to dup()-and-own them is the safest option. |
375 if (message->HasAttachments()) { | 354 if (message->HasAttachments()) { |
376 MessageAttachmentSet* fdset = message->attachment_set(); | 355 MessageAttachmentSet* set = message->attachment_set(); |
377 std::vector<base::PlatformFile> fds_to_send(fdset->size()); | 356 for (unsigned i = 0; i < set->size(); ++i) { |
378 fdset->PeekDescriptors(&fds_to_send[0]); | 357 scoped_refptr<MessageAttachment> attachment = set->GetAttachmentAt(i); |
379 for (size_t i = 0; i < fds_to_send.size(); ++i) { | 358 switch (attachment->GetType()) { |
380 int fd_to_send = dup(fds_to_send[i]); | 359 case MessageAttachment::TYPE_PLATFORM_FILE: |
381 if (-1 == fd_to_send) { | 360 #if defined(OS_POSIX) && !defined(OS_NACL) |
382 DPLOG(WARNING) << "Failed to dup FD to transmit."; | 361 { |
383 fdset->CommitAll(); | 362 base::PlatformFile file = |
384 return MOJO_RESULT_UNKNOWN; | 363 dup(static_cast<IPC::internal::PlatformFileAttachment*>( |
| 364 attachment.get())->file()); |
| 365 if (file == -1) { |
| 366 DPLOG(WARNING) << "Failed to dup FD to transmit."; |
| 367 set->CommitAll(); |
| 368 return MOJO_RESULT_UNKNOWN; |
| 369 } |
| 370 |
| 371 MojoHandle wrapped_handle; |
| 372 MojoResult wrap_result = CreatePlatformHandleWrapper( |
| 373 mojo::embedder::ScopedPlatformHandle( |
| 374 mojo::embedder::PlatformHandle(file)), |
| 375 &wrapped_handle); |
| 376 if (MOJO_RESULT_OK != wrap_result) { |
| 377 DLOG(WARNING) << "Pipe failed to wrap handles. Closing: " |
| 378 << wrap_result; |
| 379 set->CommitAll(); |
| 380 return wrap_result; |
| 381 } |
| 382 |
| 383 handles->push_back(wrapped_handle); |
| 384 } |
| 385 #else |
| 386 NOTREACHED(); |
| 387 #endif // defined(OS_POSIX) && !defined(OS_NACL) |
| 388 break; |
| 389 case MessageAttachment::TYPE_MOJO_HANDLE: { |
| 390 mojo::ScopedHandle handle = |
| 391 static_cast<IPC::internal::MojoHandleAttachment*>( |
| 392 attachment.get())->TakeHandle(); |
| 393 handles->push_back(handle.release().value()); |
| 394 } break; |
385 } | 395 } |
386 | |
387 MojoHandle wrapped_handle; | |
388 MojoResult wrap_result = CreatePlatformHandleWrapper( | |
389 mojo::embedder::ScopedPlatformHandle( | |
390 mojo::embedder::PlatformHandle(fd_to_send)), | |
391 &wrapped_handle); | |
392 if (MOJO_RESULT_OK != wrap_result) { | |
393 DLOG(WARNING) << "Pipe failed to wrap handles. Closing: " | |
394 << wrap_result; | |
395 fdset->CommitAll(); | |
396 return wrap_result; | |
397 } | |
398 | |
399 handles->push_back(wrapped_handle); | |
400 } | 396 } |
401 | 397 |
402 fdset->CommitAll(); | 398 set->CommitAll(); |
403 } | 399 } |
404 | 400 |
405 return MOJO_RESULT_OK; | 401 return MOJO_RESULT_OK; |
406 } | 402 } |
407 | 403 |
408 #endif // defined(OS_POSIX) && !defined(OS_NACL) | 404 // static |
| 405 MojoResult ChannelMojo::WriteToMessageAttachmentSet( |
| 406 const std::vector<MojoHandle>& handle_buffer, |
| 407 Message* message) { |
| 408 for (size_t i = 0; i < handle_buffer.size(); ++i) { |
| 409 bool ok = message->attachment_set()->AddAttachment( |
| 410 new IPC::internal::MojoHandleAttachment( |
| 411 mojo::MakeScopedHandle(mojo::Handle(handle_buffer[i])))); |
| 412 DCHECK(ok); |
| 413 if (!ok) { |
| 414 DLOG(ERROR) << "Failed to add new Mojo handle."; |
| 415 return MOJO_RESULT_UNKNOWN; |
| 416 } |
| 417 } |
| 418 |
| 419 return MOJO_RESULT_OK; |
| 420 } |
409 | 421 |
410 } // namespace IPC | 422 } // namespace IPC |
OLD | NEW |