Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(315)

Unified Diff: mojo/system/platform_channel_posix.cc

Issue 103113002: Mojo: (POSIX) Pass channel handle to child. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/system/platform_channel_handle.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/system/platform_channel_posix.cc
diff --git a/mojo/system/platform_channel_posix.cc b/mojo/system/platform_channel_posix.cc
index 0b64620c6bdd08b26c513c6ef4d6174c1c066ee1..4c23657fbd71682ac3aa3defb5cceffd9de48a94 100644
--- a/mojo/system/platform_channel_posix.cc
+++ b/mojo/system/platform_channel_posix.cc
@@ -9,20 +9,27 @@
#include <sys/types.h>
#include <unistd.h>
+#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/posix/global_descriptors.h"
+#include "base/strings/string_number_conversions.h"
namespace mojo {
namespace system {
namespace {
-void CloseIfNecessary(PlatformChannelHandle* handle) {
- if (!handle->is_valid())
- return;
+const char kMojoChannelDescriptorSwitch[] = "mojo-channel-descriptor";
- PCHECK(close(handle->fd) == 0);
- *handle = PlatformChannelHandle();
+bool IsTargetDescriptorUsed(
+ const base::FileHandleMappingVector& file_handle_mapping,
+ int target_fd) {
+ for (size_t i = 0; i < file_handle_mapping.size(); i++) {
+ if (file_handle_mapping[i].second == target_fd)
+ return true;
+ }
+ return false;
}
class PlatformServerChannelPosix : public PlatformServerChannel {
@@ -59,10 +66,7 @@ PlatformServerChannelPosix::PlatformServerChannelPosix(
}
PlatformServerChannelPosix::~PlatformServerChannelPosix() {
- if (is_valid())
- CloseIfNecessary(mutable_handle());
- if (client_handle_.is_valid())
- CloseIfNecessary(&client_handle_);
+ client_handle_.CloseIfNecessary();
}
scoped_ptr<PlatformClientChannel>
@@ -82,13 +86,39 @@ scoped_ptr<PlatformClientChannel>
void PlatformServerChannelPosix::GetDataNeededToPassClientChannelToChildProcess(
CommandLine* command_line,
base::FileHandleMappingVector* file_handle_mapping) const {
- // TODO(vtl)
- NOTIMPLEMENTED();
+ DCHECK(command_line);
+ DCHECK(file_handle_mapping);
+ // This is an arbitrary sanity check. (Note that this guarantees that the loop
+ // below will terminate sanely.)
+ CHECK_LT(file_handle_mapping->size(), 1000u);
+
+ DCHECK(client_handle_.is_valid());
+
+ // Find a suitable FD to map our client handle to in the child process.
+ // This has quadratic time complexity in the size of |*file_handle_mapping|,
+ // but |*file_handle_mapping| should be very small (usually/often empty).
+ int target_fd = base::GlobalDescriptors::kBaseDescriptor;
+ while (IsTargetDescriptorUsed(*file_handle_mapping, target_fd))
+ target_fd++;
+
+ file_handle_mapping->push_back(std::pair<int, int>(client_handle_.fd,
+ target_fd));
+ // Log a warning if the command line already has the switch, but "clobber" it
+ // anyway, since it's reasonably likely that all the switches were just copied
+ // from the parent.
+ LOG_IF(WARNING, command_line->HasSwitch(kMojoChannelDescriptorSwitch))
+ << "Child command line already has switch --"
+ << kMojoChannelDescriptorSwitch << "="
+ << command_line->GetSwitchValueASCII(kMojoChannelDescriptorSwitch);
+ // (Any existing switch won't actually be removed from the command line, but
+ // the last one appended takes precedence.)
+ command_line->AppendSwitchASCII(kMojoChannelDescriptorSwitch,
+ base::IntToString(target_fd));
}
void PlatformServerChannelPosix::ChildProcessLaunched() {
- // TODO(vtl)
- NOTIMPLEMENTED();
+ DCHECK(client_handle_.is_valid());
+ client_handle_.CloseIfNecessary();
}
} // namespace
@@ -110,9 +140,17 @@ scoped_ptr<PlatformServerChannel> PlatformServerChannel::Create(
scoped_ptr<PlatformClientChannel>
PlatformClientChannel::CreateFromParentProcess(
const CommandLine& command_line) {
- // TODO(vtl)
- NOTIMPLEMENTED();
- return scoped_ptr<PlatformClientChannel>();
+ std::string client_fd_string =
+ command_line.GetSwitchValueASCII(kMojoChannelDescriptorSwitch);
+ int client_fd = -1;
+ if (client_fd_string.empty() ||
+ !base::StringToInt(client_fd_string, &client_fd) ||
+ client_fd < base::GlobalDescriptors::kBaseDescriptor) {
+ LOG(ERROR) << "Missing or invalid --" << kMojoChannelDescriptorSwitch;
+ return scoped_ptr<PlatformClientChannel>();
+ }
+
+ return CreateFromHandle(PlatformChannelHandle(client_fd));
}
} // namespace system
« no previous file with comments | « mojo/system/platform_channel_handle.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698