15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_platform_file.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFileForTransit GetFileHandleForProcess(base::PlatformFile handle,
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               base::ProcessHandle process,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bool close_source_handle) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::PlatformFileForTransit out_handle;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD options = DUPLICATE_SAME_ACCESS;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (close_source_handle)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    options |= DUPLICATE_CLOSE_SOURCE;
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (handle == INVALID_HANDLE_VALUE ||
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      !::DuplicateHandle(::GetCurrentProcess(),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         handle,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         process,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &out_handle,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         0,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         FALSE,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         options)) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out_handle = IPC::InvalidPlatformFileForTransit();
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If asked to close the source, we can simply re-use the source fd instead of
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dup()ing and close()ing.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When we're not closing the source, we need to duplicate the handle and take
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ownership of that. The reason is that this function is often used to
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // generate IPC messages, and the handle must remain valid until it's sent to
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the other process from the I/O thread. Without the dup, calling code might
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // close the source handle before the message is sent, creating a race
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // condition.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fd = close_source_handle ? handle : ::dup(handle);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out_handle = base::FileDescriptor(fd, true);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #error Not implemented.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return out_handle;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PlatformFileForTransit TakeFileHandleForProcess(base::File file,
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                base::ProcessHandle process) {
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetFileHandleForProcess(file.TakePlatformFile(), process, true);
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace IPC
54