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/shell/runner/host/child_process.h" | 5 #include "mojo/shell/runner/host/child_process.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 scoped_ptr<mojo::shell::LinuxSandbox> sandbox( | 293 scoped_ptr<mojo::shell::LinuxSandbox> sandbox( |
294 new mojo::shell::LinuxSandbox(permissions)); | 294 new mojo::shell::LinuxSandbox(permissions)); |
295 sandbox->Warmup(); | 295 sandbox->Warmup(); |
296 sandbox->EngageNamespaceSandbox(); | 296 sandbox->EngageNamespaceSandbox(); |
297 sandbox->EngageSeccompSandbox(); | 297 sandbox->EngageSeccompSandbox(); |
298 sandbox->Seal(); | 298 sandbox->Seal(); |
299 return sandbox; | 299 return sandbox; |
300 } | 300 } |
301 #endif | 301 #endif |
302 | 302 |
303 ScopedMessagePipeHandle InitializeHostMessagePipe( | 303 void InitializeHostMessagePipe( |
304 embedder::ScopedPlatformHandle platform_channel, | 304 embedder::ScopedPlatformHandle platform_channel, |
305 scoped_refptr<base::TaskRunner> io_task_runner) { | 305 scoped_refptr<base::TaskRunner> io_task_runner, |
306 ScopedMessagePipeHandle host_message_pipe( | 306 const base::Callback<void(ScopedMessagePipeHandle)>& callback) { |
307 embedder::CreateChannel(std::move(platform_channel), | 307 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) { |
308 base::Bind(&DidCreateChannel), io_task_runner)); | 308 embedder::SetParentPipeHandle(std::move(platform_channel)); |
| 309 std::string primordial_pipe_token = |
| 310 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 311 switches::kPrimordialPipeToken); |
| 312 edk::CreateChildMessagePipe(primordial_pipe_token, callback); |
| 313 } else { |
| 314 ScopedMessagePipeHandle host_message_pipe; |
| 315 host_message_pipe = |
| 316 embedder::CreateChannel(std::move(platform_channel), |
| 317 base::Bind(&DidCreateChannel), io_task_runner); |
| 318 callback.Run(std::move(host_message_pipe)); |
| 319 } |
| 320 } |
309 | 321 |
310 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) { | 322 void OnHostMessagePipeCreated(AppContext* app_context, |
311 // When using the new Mojo EDK, each message pipe is backed by a platform | 323 base::NativeLibrary app_library, |
312 // handle. The one platform handle that comes on the command line is used | 324 const Blocker::Unblocker& unblocker, |
313 // to bind to the ChildController interface. However we also want a | 325 ScopedMessagePipeHandle pipe) { |
314 // platform handle to setup the communication channel by which we exchange | 326 app_context->controller_runner()->PostTask( |
315 // handles to/from tokens, which is needed for sandboxed Windows | 327 FROM_HERE, |
316 // processes. | 328 base::Bind(&ChildControllerImpl::Init, base::Unretained(app_context), |
317 char broker_handle[10]; | 329 base::Unretained(app_library), base::Passed(&pipe), |
318 MojoHandleSignalsState state; | 330 unblocker)); |
319 MojoResult rv = | |
320 MojoWait(host_message_pipe.get().value(), MOJO_HANDLE_SIGNAL_READABLE, | |
321 MOJO_DEADLINE_INDEFINITE, &state); | |
322 CHECK_EQ(MOJO_RESULT_OK, rv); | |
323 uint32_t num_bytes = arraysize(broker_handle); | |
324 rv = MojoReadMessage(host_message_pipe.get().value(), | |
325 broker_handle, &num_bytes, nullptr, 0, | |
326 MOJO_READ_MESSAGE_FLAG_NONE); | |
327 CHECK_EQ(MOJO_RESULT_OK, rv); | |
328 | |
329 edk::ScopedPlatformHandle broker_channel = | |
330 edk::PlatformChannelPair::PassClientHandleFromParentProcessFromString( | |
331 std::string(broker_handle, num_bytes)); | |
332 CHECK(broker_channel.is_valid()); | |
333 embedder::SetParentPipeHandle( | |
334 mojo::embedder::ScopedPlatformHandle(mojo::embedder::PlatformHandle( | |
335 broker_channel.release().handle))); | |
336 } | |
337 | |
338 return host_message_pipe; | |
339 } | 331 } |
340 | 332 |
341 } // namespace | 333 } // namespace |
342 | 334 |
343 int ChildProcessMain() { | 335 int ChildProcessMain() { |
344 DVLOG(2) << "ChildProcessMain()"; | 336 DVLOG(2) << "ChildProcessMain()"; |
345 const base::CommandLine& command_line = | 337 const base::CommandLine& command_line = |
346 *base::CommandLine::ForCurrentProcess(); | 338 *base::CommandLine::ForCurrentProcess(); |
347 | 339 |
348 #if defined(OS_LINUX) && !defined(OS_ANDROID) | 340 #if defined(OS_LINUX) && !defined(OS_ANDROID) |
349 scoped_ptr<mojo::shell::LinuxSandbox> sandbox; | 341 scoped_ptr<mojo::shell::LinuxSandbox> sandbox; |
350 #endif | 342 #endif |
351 base::NativeLibrary app_library = 0; | 343 base::NativeLibrary app_library = 0; |
352 // Load the application library before we engage the sandbox. | 344 // Load the application library before we engage the sandbox. |
353 app_library = mojo::shell::LoadNativeApplication( | 345 base::FilePath app_library_path = |
354 command_line.GetSwitchValuePath(switches::kChildProcess)); | 346 command_line.GetSwitchValuePath(switches::kChildProcess); |
| 347 if (!app_library_path.empty()) |
| 348 app_library = mojo::shell::LoadNativeApplication(app_library_path); |
355 base::i18n::InitializeICU(); | 349 base::i18n::InitializeICU(); |
356 if (app_library) | 350 if (app_library) |
357 CallLibraryEarlyInitialization(app_library); | 351 CallLibraryEarlyInitialization(app_library); |
| 352 |
358 #if !defined(OFFICIAL_BUILD) | 353 #if !defined(OFFICIAL_BUILD) |
359 // Initialize stack dumping just before initializing sandbox to make | 354 // Initialize stack dumping just before initializing sandbox to make |
360 // sure symbol names in all loaded libraries will be cached. | 355 // sure symbol names in all loaded libraries will be cached. |
361 base::debug::EnableInProcessStackDumping(); | 356 base::debug::EnableInProcessStackDumping(); |
362 #endif | 357 #endif |
363 #if defined(OS_LINUX) && !defined(OS_ANDROID) | 358 #if defined(OS_LINUX) && !defined(OS_ANDROID) |
364 if (command_line.HasSwitch(switches::kEnableSandbox)) | 359 if (command_line.HasSwitch(switches::kEnableSandbox)) |
365 sandbox = InitializeSandbox(); | 360 sandbox = InitializeSandbox(); |
366 #endif | 361 #endif |
367 | 362 |
368 embedder::ScopedPlatformHandle platform_channel = | 363 embedder::ScopedPlatformHandle platform_channel = |
369 embedder::PlatformChannelPair::PassClientHandleFromParentProcess( | 364 embedder::PlatformChannelPair::PassClientHandleFromParentProcess( |
370 command_line); | 365 command_line); |
371 CHECK(platform_channel.is_valid()); | 366 CHECK(platform_channel.is_valid()); |
372 | 367 |
373 DCHECK(!base::MessageLoop::current()); | 368 DCHECK(!base::MessageLoop::current()); |
374 | 369 |
| 370 Blocker blocker; |
375 AppContext app_context; | 371 AppContext app_context; |
376 app_context.Init(); | 372 app_context.Init(); |
377 ScopedMessagePipeHandle host_message_pipe = InitializeHostMessagePipe( | |
378 std::move(platform_channel), app_context.io_runner()); | |
379 app_context.StartControllerThread(); | 373 app_context.StartControllerThread(); |
380 Blocker blocker; | 374 |
381 app_context.controller_runner()->PostTask( | 375 app_context.controller_runner()->PostTask( |
382 FROM_HERE, | 376 FROM_HERE, |
383 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), | 377 base::Bind( |
384 base::Unretained(app_library), | 378 &InitializeHostMessagePipe, base::Passed(&platform_channel), |
385 base::Passed(&host_message_pipe), blocker.GetUnblocker())); | 379 make_scoped_refptr(app_context.io_runner()), |
| 380 base::Bind(&OnHostMessagePipeCreated, base::Unretained(&app_context), |
| 381 base::Unretained(app_library), blocker.GetUnblocker()))); |
| 382 |
386 // This will block, then run whatever the controller wants. | 383 // This will block, then run whatever the controller wants. |
387 blocker.Block(); | 384 blocker.Block(); |
388 | 385 |
389 app_context.Shutdown(); | 386 app_context.Shutdown(); |
390 | 387 |
391 return 0; | 388 return 0; |
392 } | 389 } |
393 | 390 |
394 } // namespace shell | 391 } // namespace shell |
395 } // namespace mojo | 392 } // namespace mojo |
OLD | NEW |