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 "mojo/edk/embedder/platform_channel_pair.h" | 5 #include "mojo/edk/embedder/platform_channel_pair.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
(...skipping 17 matching lines...) Expand all Loading... |
28 | 28 |
29 #if !defined(SO_PEEK_OFF) | 29 #if !defined(SO_PEEK_OFF) |
30 #define SO_PEEK_OFF 42 | 30 #define SO_PEEK_OFF 42 |
31 #endif | 31 #endif |
32 | 32 |
33 namespace mojo { | 33 namespace mojo { |
34 namespace edk { | 34 namespace edk { |
35 | 35 |
36 namespace { | 36 namespace { |
37 | 37 |
| 38 #if !defined(OS_ANDROID) |
38 bool IsTargetDescriptorUsed( | 39 bool IsTargetDescriptorUsed( |
39 const base::FileHandleMappingVector& file_handle_mapping, | 40 const base::FileHandleMappingVector& file_handle_mapping, |
40 int target_fd) { | 41 int target_fd) { |
41 for (size_t i = 0; i < file_handle_mapping.size(); i++) { | 42 for (size_t i = 0; i < file_handle_mapping.size(); i++) { |
42 if (file_handle_mapping[i].second == target_fd) | 43 if (file_handle_mapping[i].second == target_fd) |
43 return true; | 44 return true; |
44 } | 45 } |
45 return false; | 46 return false; |
46 } | 47 } |
| 48 #endif |
47 | 49 |
48 } // namespace | 50 } // namespace |
49 | 51 |
50 PlatformChannelPair::PlatformChannelPair(bool client_is_blocking) { | 52 PlatformChannelPair::PlatformChannelPair(bool client_is_blocking) { |
51 // Create the Unix domain socket. | 53 // Create the Unix domain socket. |
52 int fds[2]; | 54 int fds[2]; |
53 // TODO(vtl): Maybe fail gracefully if |socketpair()| fails. | 55 // TODO(vtl): Maybe fail gracefully if |socketpair()| fails. |
54 | 56 |
55 #if defined(OS_NACL_SFI) | 57 #if defined(OS_NACL_SFI) |
56 PCHECK(imc_socketpair(fds) == 0); | 58 PCHECK(imc_socketpair(fds) == 0); |
(...skipping 24 matching lines...) Expand all Loading... |
81 } | 83 } |
82 | 84 |
83 // static | 85 // static |
84 ScopedPlatformHandle PlatformChannelPair::PassClientHandleFromParentProcess( | 86 ScopedPlatformHandle PlatformChannelPair::PassClientHandleFromParentProcess( |
85 const base::CommandLine& command_line) { | 87 const base::CommandLine& command_line) { |
86 std::string client_fd_string = | 88 std::string client_fd_string = |
87 command_line.GetSwitchValueASCII(kMojoPlatformChannelHandleSwitch); | 89 command_line.GetSwitchValueASCII(kMojoPlatformChannelHandleSwitch); |
88 return PassClientHandleFromParentProcessFromString(client_fd_string); | 90 return PassClientHandleFromParentProcessFromString(client_fd_string); |
89 } | 91 } |
90 | 92 |
| 93 #if !defined(OS_ANDROID) |
91 ScopedPlatformHandle | 94 ScopedPlatformHandle |
92 PlatformChannelPair::PassClientHandleFromParentProcessFromString( | 95 PlatformChannelPair::PassClientHandleFromParentProcessFromString( |
93 const std::string& value) { | 96 const std::string& value) { |
94 int client_fd = -1; | 97 int client_fd = -1; |
95 if (value.empty() || | 98 if (value.empty() || |
96 !base::StringToInt(value, &client_fd) || | 99 !base::StringToInt(value, &client_fd) || |
97 client_fd < base::GlobalDescriptors::kBaseDescriptor) { | 100 client_fd < base::GlobalDescriptors::kBaseDescriptor) { |
98 LOG(ERROR) << "Missing or invalid --" << kMojoPlatformChannelHandleSwitch; | 101 LOG(ERROR) << "Missing or invalid --" << kMojoPlatformChannelHandleSwitch; |
99 return ScopedPlatformHandle(); | 102 return ScopedPlatformHandle(); |
100 } | 103 } |
101 | 104 |
102 return ScopedPlatformHandle(PlatformHandle(client_fd)); | 105 return ScopedPlatformHandle(PlatformHandle(client_fd)); |
103 } | 106 } |
| 107 #endif |
104 | 108 |
105 void PlatformChannelPair::PrepareToPassClientHandleToChildProcess( | 109 void PlatformChannelPair::PrepareToPassClientHandleToChildProcess( |
106 base::CommandLine* command_line, | 110 base::CommandLine* command_line, |
107 base::FileHandleMappingVector* handle_passing_info) const { | 111 base::FileHandleMappingVector* handle_passing_info) const { |
108 DCHECK(command_line); | 112 DCHECK(command_line); |
109 | 113 |
110 // Log a warning if the command line already has the switch, but "clobber" it | 114 // Log a warning if the command line already has the switch, but "clobber" it |
111 // anyway, since it's reasonably likely that all the switches were just copied | 115 // anyway, since it's reasonably likely that all the switches were just copied |
112 // from the parent. | 116 // from the parent. |
113 LOG_IF(WARNING, command_line->HasSwitch(kMojoPlatformChannelHandleSwitch)) | 117 LOG_IF(WARNING, command_line->HasSwitch(kMojoPlatformChannelHandleSwitch)) |
114 << "Child command line already has switch --" | 118 << "Child command line already has switch --" |
115 << kMojoPlatformChannelHandleSwitch << "=" | 119 << kMojoPlatformChannelHandleSwitch << "=" |
116 << command_line->GetSwitchValueASCII(kMojoPlatformChannelHandleSwitch); | 120 << command_line->GetSwitchValueASCII(kMojoPlatformChannelHandleSwitch); |
117 // (Any existing switch won't actually be removed from the command line, but | 121 // (Any existing switch won't actually be removed from the command line, but |
118 // the last one appended takes precedence.) | 122 // the last one appended takes precedence.) |
119 command_line->AppendSwitchASCII( | 123 command_line->AppendSwitchASCII( |
120 kMojoPlatformChannelHandleSwitch, | 124 kMojoPlatformChannelHandleSwitch, |
121 PrepareToPassClientHandleToChildProcessAsString(handle_passing_info)); | 125 PrepareToPassClientHandleToChildProcessAsString(handle_passing_info)); |
122 } | 126 } |
123 | 127 |
| 128 #if !defined(OS_ANDROID) |
124 std::string | 129 std::string |
125 PlatformChannelPair::PrepareToPassClientHandleToChildProcessAsString( | 130 PlatformChannelPair::PrepareToPassClientHandleToChildProcessAsString( |
126 HandlePassingInformation* handle_passing_info) const { | 131 HandlePassingInformation* handle_passing_info) const { |
127 DCHECK(handle_passing_info); | 132 DCHECK(handle_passing_info); |
128 // This is an arbitrary sanity check. (Note that this guarantees that the loop | 133 // This is an arbitrary sanity check. (Note that this guarantees that the loop |
129 // below will terminate sanely.) | 134 // below will terminate sanely.) |
130 CHECK_LT(handle_passing_info->size(), 1000u); | 135 CHECK_LT(handle_passing_info->size(), 1000u); |
131 | 136 |
132 DCHECK(client_handle_.is_valid()); | 137 DCHECK(client_handle_.is_valid()); |
133 | 138 |
134 // Find a suitable FD to map our client handle to in the child process. | 139 // Find a suitable FD to map our client handle to in the child process. |
135 // This has quadratic time complexity in the size of |*handle_passing_info|, | 140 // This has quadratic time complexity in the size of |*handle_passing_info|, |
136 // but |*handle_passing_info| should be very small (usually/often empty). | 141 // but |*handle_passing_info| should be very small (usually/often empty). |
137 int target_fd = base::GlobalDescriptors::kBaseDescriptor; | 142 int target_fd = base::GlobalDescriptors::kBaseDescriptor; |
138 while (IsTargetDescriptorUsed(*handle_passing_info, target_fd)) | 143 while (IsTargetDescriptorUsed(*handle_passing_info, target_fd)) |
139 target_fd++; | 144 target_fd++; |
140 | 145 |
141 handle_passing_info->push_back( | 146 handle_passing_info->push_back( |
142 std::pair<int, int>(client_handle_.get().handle, target_fd)); | 147 std::pair<int, int>(client_handle_.get().handle, target_fd)); |
143 return base::IntToString(target_fd); | 148 return base::IntToString(target_fd); |
144 } | 149 } |
| 150 #endif |
145 | 151 |
146 } // namespace edk | 152 } // namespace edk |
147 } // namespace mojo | 153 } // namespace mojo |
OLD | NEW |