ipc_platform_file.cc 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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
  3. // found in the LICENSE file.
  4. #include "build/build_config.h"
  5. #include "ipc/ipc_platform_file.h"
  6. #if BUILDFLAG(IS_WIN)
  7. #include <windows.h>
  8. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  9. #include <unistd.h>
  10. #include "base/posix/eintr_wrapper.h"
  11. #endif
  12. namespace IPC {
  13. #if BUILDFLAG(IS_WIN)
  14. PlatformFileForTransit::PlatformFileForTransit() : handle_(nullptr) {}
  15. PlatformFileForTransit::PlatformFileForTransit(HANDLE handle)
  16. : handle_(handle) {}
  17. bool PlatformFileForTransit::operator==(
  18. const PlatformFileForTransit& platform_file) const {
  19. return handle_ == platform_file.handle_;
  20. }
  21. bool PlatformFileForTransit::operator!=(
  22. const PlatformFileForTransit& platform_file) const {
  23. return !(*this == platform_file);
  24. }
  25. HANDLE PlatformFileForTransit::GetHandle() const {
  26. return handle_;
  27. }
  28. bool PlatformFileForTransit::IsValid() const {
  29. return handle_ != nullptr;
  30. }
  31. #endif // BUILDFLAG(IS_WIN)
  32. PlatformFileForTransit GetPlatformFileForTransit(base::PlatformFile handle,
  33. bool close_source_handle) {
  34. #if BUILDFLAG(IS_WIN)
  35. HANDLE raw_handle = INVALID_HANDLE_VALUE;
  36. DWORD options = DUPLICATE_SAME_ACCESS;
  37. if (close_source_handle)
  38. options |= DUPLICATE_CLOSE_SOURCE;
  39. if (handle == INVALID_HANDLE_VALUE ||
  40. !::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(),
  41. &raw_handle, 0, FALSE, options)) {
  42. return IPC::InvalidPlatformFileForTransit();
  43. }
  44. return IPC::PlatformFileForTransit(raw_handle);
  45. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  46. // If asked to close the source, we can simply re-use the source fd instead of
  47. // dup()ing and close()ing.
  48. // When we're not closing the source, we need to duplicate the handle and take
  49. // ownership of that. The reason is that this function is often used to
  50. // generate IPC messages, and the handle must remain valid until it's sent to
  51. // the other process from the I/O thread. Without the dup, calling code might
  52. // close the source handle before the message is sent, creating a race
  53. // condition.
  54. int fd = close_source_handle ? handle : HANDLE_EINTR(::dup(handle));
  55. return base::FileDescriptor(fd, true);
  56. #endif
  57. }
  58. PlatformFileForTransit TakePlatformFileForTransit(base::File file) {
  59. return GetPlatformFileForTransit(file.TakePlatformFile(), true);
  60. }
  61. } // namespace IPC