blob: 64d1e2da925140a90cab6dc0fe84808aff89599b [file] [log] [blame]
scottmge5a1d492017-05-24 23:41:431// Copyright 2017 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 "base/process/launch.h"
6
7#include <launchpad/launchpad.h>
8#include <magenta/process.h>
9
10#include "base/command_line.h"
11
12namespace base {
13
14Process LaunchProcess(const CommandLine& cmdline,
15 const LaunchOptions& options) {
16 return LaunchProcess(cmdline.argv(), options);
17}
18
19Process LaunchProcess(const std::vector<std::string>& argv,
20 const LaunchOptions& options) {
21 std::vector<const char*> argv_cstr;
22 argv_cstr.reserve(argv.size() + 1);
23 for (size_t i = 0; i < argv.size(); i++) {
24 argv_cstr.push_back(argv[i].c_str());
25 }
26 argv_cstr.push_back(nullptr);
27
28 // Note that per launchpad.h, the intention is that launchpad_ functions are
29 // used in a "builder" style. From launchpad_create() to launchpad_go() the
30 // status is tracked in the launchpad_t object, and launchpad_go() reports on
31 // the final status, and cleans up |lp| (assuming it was even created).
32 launchpad_t* lp;
33 launchpad_create(options.job_handle, argv_cstr[0], &lp);
34 launchpad_load_from_file(lp, argv_cstr[0]);
35 launchpad_set_args(lp, argv.size(), argv_cstr.data());
36
37 uint32_t to_clone =
38 LP_CLONE_MXIO_ROOT | LP_CLONE_MXIO_CWD | LP_CLONE_DEFAULT_JOB;
39
40 std::unique_ptr<char* []> new_environ;
41 char* const empty_environ = nullptr;
42 char* const* old_environ = environ;
43 if (options.clear_environ)
44 old_environ = &empty_environ;
45 if (!options.environ.empty())
46 new_environ = AlterEnvironment(old_environ, options.environ);
47 if (!options.environ.empty() || options.clear_environ)
48 launchpad_set_environ(lp, new_environ.get());
49 else
50 to_clone |= LP_CLONE_ENVIRON;
51
52 if (!options.fds_to_remap)
53 to_clone |= LP_CLONE_MXIO_STDIO;
54 launchpad_clone(lp, to_clone);
55
56 if (options.fds_to_remap) {
57 for (const auto& src_target : *options.fds_to_remap) {
58 launchpad_clone_fd(lp, src_target.first, src_target.second);
59 }
60 }
61
62 mx_handle_t proc;
63 const char* errmsg;
64 mx_status_t status = launchpad_go(lp, &proc, &errmsg);
65 if (status != NO_ERROR) {
66 LOG(ERROR) << "launchpad_go failed: " << errmsg << ", status=" << status;
67 return Process();
68 }
69
70 return Process(proc);
71}
72
73} // namespace base