Home | History | Annotate | Download | only in ipc
      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 
      5 #include "ipc/ipc_platform_file.h"
      6 
      7 #if defined(OS_POSIX)
      8 #include <unistd.h>
      9 #endif
     10 
     11 namespace IPC {
     12 
     13 PlatformFileForTransit GetFileHandleForProcess(base::PlatformFile handle,
     14                                                base::ProcessHandle process,
     15                                                bool close_source_handle) {
     16   IPC::PlatformFileForTransit out_handle;
     17 #if defined(OS_WIN)
     18   DWORD options = DUPLICATE_SAME_ACCESS;
     19   if (close_source_handle)
     20     options |= DUPLICATE_CLOSE_SOURCE;
     21   if (handle == INVALID_HANDLE_VALUE ||
     22       !::DuplicateHandle(::GetCurrentProcess(),
     23                          handle,
     24                          process,
     25                          &out_handle,
     26                          0,
     27                          FALSE,
     28                          options)) {
     29     out_handle = IPC::InvalidPlatformFileForTransit();
     30   }
     31 #elif defined(OS_POSIX)
     32   // If asked to close the source, we can simply re-use the source fd instead of
     33   // dup()ing and close()ing.
     34   // When we're not closing the source, we need to duplicate the handle and take
     35   // ownership of that. The reason is that this function is often used to
     36   // generate IPC messages, and the handle must remain valid until it's sent to
     37   // the other process from the I/O thread. Without the dup, calling code might
     38   // close the source handle before the message is sent, creating a race
     39   // condition.
     40   int fd = close_source_handle ? handle : ::dup(handle);
     41   out_handle = base::FileDescriptor(fd, true);
     42 #else
     43   #error Not implemented.
     44 #endif
     45   return out_handle;
     46 }
     47 
     48 PlatformFileForTransit TakeFileHandleForProcess(base::File file,
     49                                                 base::ProcessHandle process) {
     50   return GetFileHandleForProcess(file.TakePlatformFile(), process, true);
     51 }
     52 
     53 }  // namespace IPC
     54