[email protected] | 991bd8a | 2013-12-12 18:45:45 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors. All rights reserved. |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | // This file contains functions for launching subprocesses. |
| 6 | |
| 7 | #ifndef BASE_PROCESS_LAUNCH_H_ |
| 8 | #define BASE_PROCESS_LAUNCH_H_ |
| 9 | |
avi | beced7c | 2015-12-24 06:47:59 | [diff] [blame] | 10 | #include <stddef.h> |
| 11 | |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 12 | #include <string> |
| 13 | #include <utility> |
| 14 | #include <vector> |
| 15 | |
| 16 | #include "base/base_export.h" |
Jan Wilken Dörrie | 6bdce49 | 2019-11-05 11:36:50 | [diff] [blame] | 17 | #include "base/command_line.h" |
[email protected] | b345c48 | 2013-08-30 18:00:39 | [diff] [blame] | 18 | #include "base/environment.h" |
Lei Zhang | 1757508 | 2021-05-10 20:19:18 | [diff] [blame] | 19 | #include "base/files/file_path.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame^] | 20 | #include "base/memory/raw_ptr.h" |
rvargas | 6293e5b | 2014-12-01 22:53:09 | [diff] [blame] | 21 | #include "base/process/process.h" |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 22 | #include "base/process/process_handle.h" |
[email protected] | 7eb6bec6 | 2013-12-05 22:41:04 | [diff] [blame] | 23 | #include "base/strings/string_piece.h" |
Gabriel Charette | 6836c0d5 | 2021-01-11 17:40:26 | [diff] [blame] | 24 | #include "base/threading/thread_restrictions.h" |
avi | beced7c | 2015-12-24 06:47:59 | [diff] [blame] | 25 | #include "build/build_config.h" |
Yuta Hijikata | 000df18f | 2020-11-18 06:55:58 | [diff] [blame] | 26 | #include "build/chromeos_buildflags.h" |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 27 | |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 28 | #if defined(OS_WIN) |
Bruce Dawson | 9df510e | 2021-07-14 15:23:08 | [diff] [blame] | 29 | #include "base/win/windows_types.h" |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 30 | #elif defined(OS_FUCHSIA) |
Wez | 5c3c6f15 | 2018-06-09 18:24:02 | [diff] [blame] | 31 | #include <lib/fdio/spawn.h> |
Scott Graham | fe0e9f46 | 2017-09-18 21:25:04 | [diff] [blame] | 32 | #include <zircon/types.h> |
scottmg | e5a1d49 | 2017-05-24 23:41:43 | [diff] [blame] | 33 | #endif |
| 34 | |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 35 | #if defined(OS_POSIX) || defined(OS_FUCHSIA) |
| 36 | #include "base/posix/file_descriptor_shuffle.h" |
| 37 | #endif |
| 38 | |
Avi Drissman | 5b28637 | 2020-07-28 21:59:38 | [diff] [blame] | 39 | #if defined(OS_MAC) |
Robert Sesek | a6d5986 | 2019-03-05 16:06:47 | [diff] [blame] | 40 | #include "base/mac/mach_port_rendezvous.h" |
| 41 | #endif |
| 42 | |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 43 | namespace base { |
| 44 | |
[email protected] | 991bd8a | 2013-12-12 18:45:45 | [diff] [blame] | 45 | #if defined(OS_WIN) |
| 46 | typedef std::vector<HANDLE> HandlesToInheritVector; |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 47 | #elif defined(OS_FUCHSIA) |
Kevin Marshall | ad910ae2 | 2018-06-16 05:40:53 | [diff] [blame] | 48 | struct PathToTransfer { |
| 49 | base::FilePath path; |
| 50 | zx_handle_t handle; |
| 51 | }; |
Wez | 1603c32 | 2017-08-10 05:24:54 | [diff] [blame] | 52 | struct HandleToTransfer { |
| 53 | uint32_t id; |
Scott Graham | fe0e9f46 | 2017-09-18 21:25:04 | [diff] [blame] | 54 | zx_handle_t handle; |
Wez | 1603c32 | 2017-08-10 05:24:54 | [diff] [blame] | 55 | }; |
| 56 | typedef std::vector<HandleToTransfer> HandlesToTransferVector; |
brettw | 3c98c7d3 | 2017-07-25 01:44:20 | [diff] [blame] | 57 | typedef std::vector<std::pair<int, int>> FileHandleMappingVector; |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 58 | #elif defined(OS_POSIX) |
| 59 | typedef std::vector<std::pair<int, int>> FileHandleMappingVector; |
| 60 | #endif // defined(OS_WIN) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 61 | |
| 62 | // Options for launching a subprocess that are passed to LaunchProcess(). |
| 63 | // The default constructor constructs the object with default options. |
[email protected] | b345c48 | 2013-08-30 18:00:39 | [diff] [blame] | 64 | struct BASE_EXPORT LaunchOptions { |
Avi Drissman | 5b28637 | 2020-07-28 21:59:38 | [diff] [blame] | 65 | #if (defined(OS_POSIX) || defined(OS_FUCHSIA)) && !defined(OS_APPLE) |
rickyz | a0b860b | 2015-01-16 18:19:34 | [diff] [blame] | 66 | // Delegate to be run in between fork and exec in the subprocess (see |
| 67 | // pre_exec_delegate below) |
| 68 | class BASE_EXPORT PreExecDelegate { |
| 69 | public: |
Chris Watkins | 091d629 | 2017-12-13 04:25:58 | [diff] [blame] | 70 | PreExecDelegate() = default; |
Peter Boström | 7319bbd | 2021-09-15 22:59:38 | [diff] [blame] | 71 | |
| 72 | PreExecDelegate(const PreExecDelegate&) = delete; |
| 73 | PreExecDelegate& operator=(const PreExecDelegate&) = delete; |
| 74 | |
Chris Watkins | 091d629 | 2017-12-13 04:25:58 | [diff] [blame] | 75 | virtual ~PreExecDelegate() = default; |
rickyz | a0b860b | 2015-01-16 18:19:34 | [diff] [blame] | 76 | |
| 77 | // Since this is to be run between fork and exec, and fork may have happened |
| 78 | // while multiple threads were running, this function needs to be async |
| 79 | // safe. |
| 80 | virtual void RunAsyncSafe() = 0; |
rickyz | a0b860b | 2015-01-16 18:19:34 | [diff] [blame] | 81 | }; |
| 82 | #endif // defined(OS_POSIX) |
| 83 | |
[email protected] | b345c48 | 2013-08-30 18:00:39 | [diff] [blame] | 84 | LaunchOptions(); |
vmpstr | 7c787706 | 2016-02-18 22:12:24 | [diff] [blame] | 85 | LaunchOptions(const LaunchOptions&); |
[email protected] | b345c48 | 2013-08-30 18:00:39 | [diff] [blame] | 86 | ~LaunchOptions(); |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 87 | |
| 88 | // If true, wait for the process to complete. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 89 | bool wait = false; |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 90 | |
sergeyu | 78205516 | 2016-04-06 08:57:59 | [diff] [blame] | 91 | // If not empty, change to this directory before executing the new process. |
| 92 | base::FilePath current_directory; |
| 93 | |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 94 | #if defined(OS_WIN) |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 95 | bool start_hidden = false; |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 96 | |
S. Ganesh | c18d593 | 2018-11-05 03:45:31 | [diff] [blame] | 97 | // Sets STARTF_FORCEOFFFEEDBACK so that the feedback cursor is forced off |
| 98 | // while the process is starting. |
| 99 | bool feedback_cursor_off = false; |
| 100 | |
brettw | 3c98c7d3 | 2017-07-25 01:44:20 | [diff] [blame] | 101 | // Windows can inherit handles when it launches child processes. |
| 102 | // See https://blogs.msdn.microsoft.com/oldnewthing/20111216-00/?p=8873 |
| 103 | // for a good overview of Windows handle inheritance. |
| 104 | // |
| 105 | // Implementation note: it might be nice to implement in terms of |
Anton Bikineev | 7dd58ad | 2021-05-18 01:01:39 | [diff] [blame] | 106 | // absl::optional<>, but then the natural default state (vector not present) |
brettw | 3c98c7d3 | 2017-07-25 01:44:20 | [diff] [blame] | 107 | // would be "all inheritable handles" while we want "no inheritance." |
| 108 | enum class Inherit { |
| 109 | // Only those handles in |handles_to_inherit| vector are inherited. If the |
| 110 | // vector is empty, no handles are inherited. The handles in the vector must |
| 111 | // all be inheritable. |
| 112 | kSpecific, |
[email protected] | 991bd8a | 2013-12-12 18:45:45 | [diff] [blame] | 113 | |
brettw | 3c98c7d3 | 2017-07-25 01:44:20 | [diff] [blame] | 114 | // All handles in the current process which are inheritable are inherited. |
| 115 | // In production code this flag should be used only when running |
| 116 | // short-lived, trusted binaries, because open handles from other libraries |
| 117 | // and subsystems will leak to the child process, causing errors such as |
| 118 | // open socket hangs. There are also race conditions that can cause handle |
| 119 | // over-sharing. |
| 120 | // |
| 121 | // |handles_to_inherit| must be null. |
| 122 | // |
| 123 | // DEPRECATED. THIS SHOULD NOT BE USED. Explicitly map all handles that |
| 124 | // need to be shared in new code. |
| 125 | // TODO(brettw) bug 748258: remove this. |
| 126 | kAll |
| 127 | }; |
| 128 | Inherit inherit_mode = Inherit::kSpecific; |
| 129 | HandlesToInheritVector handles_to_inherit; |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 130 | |
[email protected] | 991bd8a | 2013-12-12 18:45:45 | [diff] [blame] | 131 | // If non-null, runs as if the user represented by the token had launched it. |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 132 | // Whether the application is visible on the interactive desktop depends on |
| 133 | // the token belonging to an interactive logon session. |
| 134 | // |
| 135 | // To avoid hard to diagnose problems, when specified this loads the |
| 136 | // environment variables associated with the user and if this operation fails |
| 137 | // the entire call fails as well. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 138 | UserTokenHandle as_user = nullptr; |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 139 | |
| 140 | // If true, use an empty string for the desktop name. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 141 | bool empty_desktop_name = false; |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 142 | |
[email protected] | 991bd8a | 2013-12-12 18:45:45 | [diff] [blame] | 143 | // If non-null, launches the application in that job object. The process will |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 144 | // be terminated immediately and LaunchProcess() will fail if assignment to |
| 145 | // the job object fails. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 146 | HANDLE job_handle = nullptr; |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 147 | |
brettw | 3c98c7d3 | 2017-07-25 01:44:20 | [diff] [blame] | 148 | // Handles for the redirection of stdin, stdout and stderr. The caller should |
| 149 | // either set all three of them or none (i.e. there is no way to redirect |
| 150 | // stderr without redirecting stdin). |
| 151 | // |
| 152 | // The handles must be inheritable. Pseudo handles are used when stdout and |
| 153 | // stderr redirect to the console. In that case, GetFileType() will return |
| 154 | // FILE_TYPE_CHAR and they're automatically inherited by child processes. See |
| 155 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682075.aspx |
| 156 | // Otherwise, the caller must ensure that the |inherit_mode| and/or |
| 157 | // |handles_to_inherit| set so that the handles are inherited. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 158 | HANDLE stdin_handle = nullptr; |
| 159 | HANDLE stdout_handle = nullptr; |
| 160 | HANDLE stderr_handle = nullptr; |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 161 | |
| 162 | // If set to true, ensures that the child process is launched with the |
| 163 | // CREATE_BREAKAWAY_FROM_JOB flag which allows it to breakout of the parent |
| 164 | // job if any. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 165 | bool force_breakaway_from_job_ = false; |
Greg Thompson | 47faf20 | 2018-05-18 20:59:03 | [diff] [blame] | 166 | |
| 167 | // If set to true, permission to bring windows to the foreground is passed to |
| 168 | // the launched process if the current process has such permission. |
| 169 | bool grant_foreground_privilege = false; |
Alex Gough | d383c77 | 2021-02-17 04:39:34 | [diff] [blame] | 170 | |
| 171 | // If set to true, sets a process mitigation flag to disable Hardware-enforced |
| 172 | // Stack Protection for the process. |
| 173 | // This overrides /cetcompat if set on the executable. See: |
| 174 | // https://docs.microsoft.com/en-us/cpp/build/reference/cetcompat?view=msvc-160 |
| 175 | // If not supported by Windows, has no effect. This flag weakens security by |
| 176 | // turning off ROP protection. |
| 177 | bool disable_cetcompat = false; |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 178 | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) |
brettw | 3c98c7d3 | 2017-07-25 01:44:20 | [diff] [blame] | 179 | // Remap file descriptors according to the mapping of src_fd->dest_fd to |
| 180 | // propagate FDs into the child process. |
| 181 | FileHandleMappingVector fds_to_remap; |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 182 | #endif // defined(OS_WIN) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 183 | |
David Benjamin | 76ee79eb | 2019-03-15 17:02:09 | [diff] [blame] | 184 | #if defined(OS_WIN) || defined(OS_POSIX) || defined(OS_FUCHSIA) |
| 185 | // Set/unset environment variables. These are applied on top of the parent |
| 186 | // process environment. Empty (the default) means to inherit the same |
| 187 | // environment. See internal::AlterEnvironment(). |
| 188 | EnvironmentMap environment; |
| 189 | |
| 190 | // Clear the environment for the new process before processing changes from |
| 191 | // |environment|. |
| 192 | bool clear_environment = false; |
| 193 | #endif // OS_WIN || OS_POSIX || OS_FUCHSIA |
| 194 | |
Sean McAllister | 39b8d34 | 2020-08-25 09:08:32 | [diff] [blame] | 195 | #if defined(OS_LINUX) || defined(OS_CHROMEOS) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 196 | // If non-zero, start the process using clone(), using flags as provided. |
rickyz | f1eb9cc | 2015-01-13 22:59:48 | [diff] [blame] | 197 | // Unlike in clone, clone_flags may not contain a custom termination signal |
| 198 | // that is sent to the parent when the child dies. The termination signal will |
| 199 | // always be set to SIGCHLD. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 200 | int clone_flags = 0; |
[email protected] | d078691 | 2014-04-09 20:06:26 | [diff] [blame] | 201 | |
| 202 | // By default, child processes will have the PR_SET_NO_NEW_PRIVS bit set. If |
| 203 | // true, then this bit will not be set in the new child process. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 204 | bool allow_new_privs = false; |
phajdan.jr | ed5ed8f4 | 2015-03-13 21:40:13 | [diff] [blame] | 205 | |
| 206 | // Sets parent process death signal to SIGKILL. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 207 | bool kill_on_parent_death = false; |
Sean McAllister | 39b8d34 | 2020-08-25 09:08:32 | [diff] [blame] | 208 | #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 209 | |
Avi Drissman | 5b28637 | 2020-07-28 21:59:38 | [diff] [blame] | 210 | #if defined(OS_MAC) |
Robert Sesek | a6d5986 | 2019-03-05 16:06:47 | [diff] [blame] | 211 | // Mach ports that will be accessible to the child process. These are not |
| 212 | // directly inherited across process creation, but they are stored by a Mach |
| 213 | // IPC server that a child process can communicate with to retrieve them. |
| 214 | // |
| 215 | // After calling LaunchProcess(), any rights that were transferred with MOVE |
| 216 | // dispositions will be consumed, even on failure. |
| 217 | // |
| 218 | // See base/mac/mach_port_rendezvous.h for details. |
| 219 | MachPortsForRendezvous mach_ports_for_rendezvous; |
Robert Sesek | 34025cb9 | 2019-08-22 00:07:53 | [diff] [blame] | 220 | |
| 221 | // When a child process is launched, the system tracks the parent process |
| 222 | // with a concept of "responsibility". The responsible process will be |
| 223 | // associated with any requests for private data stored on the system via |
| 224 | // the TCC subsystem. When launching processes that run foreign/third-party |
| 225 | // code, the responsibility for the child process should be disclaimed so |
| 226 | // that any TCC requests are not associated with the parent. |
| 227 | bool disclaim_responsibility = false; |
Mark Mentovai | dcfbb59 | 2020-11-04 00:18:58 | [diff] [blame] | 228 | |
Robert Sesek | 46e23c8 | 2021-02-26 22:19:47 | [diff] [blame] | 229 | // Apply a process scheduler policy to enable mitigations against CPU side- |
| 230 | // channel attacks. |
| 231 | bool enable_cpu_security_mitigations = false; |
Mark Mentovai | dcfbb59 | 2020-11-04 00:18:58 | [diff] [blame] | 232 | #endif // OS_MAC |
Robert Sesek | a6d5986 | 2019-03-05 16:06:47 | [diff] [blame] | 233 | |
scottmg | e5a1d49 | 2017-05-24 23:41:43 | [diff] [blame] | 234 | #if defined(OS_FUCHSIA) |
| 235 | // If valid, launches the application in that job object. |
Scott Graham | fe0e9f46 | 2017-09-18 21:25:04 | [diff] [blame] | 236 | zx_handle_t job_handle = ZX_HANDLE_INVALID; |
Wez | 1603c32 | 2017-08-10 05:24:54 | [diff] [blame] | 237 | |
| 238 | // Specifies additional handles to transfer (not duplicate) to the child |
Wez | 0629d40 | 2018-06-06 00:26:43 | [diff] [blame] | 239 | // process. Each entry is an <id,handle> pair, with an |id| created using the |
Kevin Marshall | 40dc4360 | 2018-06-16 01:33:55 | [diff] [blame] | 240 | // PA_HND() macro. The child retrieves the handle |
| 241 | // |zx_take_startup_handle(id)|. The supplied handles are consumed by |
| 242 | // LaunchProcess() even on failure. |
Wez | 35e50b5 | 2018-12-01 01:52:44 | [diff] [blame] | 243 | // Note that PA_USER1 ids are reserved for use by AddHandleToTransfer(), below |
| 244 | // and by convention PA_USER0 is reserved for use by the embedding |
| 245 | // application. |
Wez | 1603c32 | 2017-08-10 05:24:54 | [diff] [blame] | 246 | HandlesToTransferVector handles_to_transfer; |
Kevin Marshall | 65c2670 | 2017-09-25 18:21:42 | [diff] [blame] | 247 | |
Wez | 35e50b5 | 2018-12-01 01:52:44 | [diff] [blame] | 248 | // Allocates a unique id for |handle| in |handles_to_transfer|, inserts it, |
| 249 | // and returns the generated id. |
| 250 | static uint32_t AddHandleToTransfer( |
| 251 | HandlesToTransferVector* handles_to_transfer, |
| 252 | zx_handle_t handle); |
| 253 | |
Wez | 0629d40 | 2018-06-06 00:26:43 | [diff] [blame] | 254 | // Specifies which basic capabilities to grant to the child process. |
| 255 | // By default the child process will receive the caller's complete namespace, |
Fabrice de Gans-Riberi | 930bbf4b | 2021-02-04 23:18:56 | [diff] [blame] | 256 | // access to the current base::GetDefaultJob(), handles for stdio and access |
| 257 | // to the dynamic library loader. |
Wez | 0629d40 | 2018-06-06 00:26:43 | [diff] [blame] | 258 | // Note that the child is always provided access to the loader service. |
| 259 | uint32_t spawn_flags = FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_CLONE_STDIO | |
| 260 | FDIO_SPAWN_CLONE_JOB; |
Kevin Marshall | 2bd0455 | 2018-02-01 21:23:45 | [diff] [blame] | 261 | |
Wez | 0629d40 | 2018-06-06 00:26:43 | [diff] [blame] | 262 | // Specifies paths to clone from the calling process' namespace into that of |
Kevin Marshall | ad910ae2 | 2018-06-16 05:40:53 | [diff] [blame] | 263 | // the child process. If |paths_to_clone| is empty then the process will |
| 264 | // receive either a full copy of the parent's namespace, or an empty one, |
| 265 | // depending on whether FDIO_SPAWN_CLONE_NAMESPACE is set. |
| 266 | std::vector<FilePath> paths_to_clone; |
| 267 | |
| 268 | // Specifies handles which will be installed as files or directories in the |
Sergey Ulanov | f1b12ddf | 2018-11-27 02:56:58 | [diff] [blame] | 269 | // child process' namespace. Paths installed by |paths_to_clone| will be |
| 270 | // overridden by these entries. |
Kevin Marshall | ad910ae2 | 2018-06-16 05:40:53 | [diff] [blame] | 271 | std::vector<PathToTransfer> paths_to_transfer; |
Sergey Ulanov | 53ab7dd | 2019-08-27 17:53:18 | [diff] [blame] | 272 | |
| 273 | // Suffix that will be added to the process name. When specified process name |
| 274 | // will be set to "<binary_name><process_suffix>". |
| 275 | std::string process_name_suffix; |
Wez | 1603c32 | 2017-08-10 05:24:54 | [diff] [blame] | 276 | #endif // defined(OS_FUCHSIA) |
scottmg | e5a1d49 | 2017-05-24 23:41:43 | [diff] [blame] | 277 | |
Fabrice de Gans-Riberi | 65421f6 | 2018-05-22 23:16:18 | [diff] [blame] | 278 | #if defined(OS_POSIX) |
rkjnsn | 732f03d | 2016-10-03 17:59:54 | [diff] [blame] | 279 | // If not empty, launch the specified executable instead of |
| 280 | // cmdline.GetProgram(). This is useful when it is necessary to pass a custom |
| 281 | // argv[0]. |
| 282 | base::FilePath real_path; |
| 283 | |
Avi Drissman | 5b28637 | 2020-07-28 21:59:38 | [diff] [blame] | 284 | #if !defined(OS_APPLE) |
rickyz | a0b860b | 2015-01-16 18:19:34 | [diff] [blame] | 285 | // If non-null, a delegate to be run immediately prior to executing the new |
| 286 | // program in the child process. |
| 287 | // |
| 288 | // WARNING: If LaunchProcess is called in the presence of multiple threads, |
| 289 | // code running in this delegate essentially needs to be async-signal safe |
| 290 | // (see man 7 signal for a list of allowed functions). |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame^] | 291 | raw_ptr<PreExecDelegate> pre_exec_delegate = nullptr; |
Avi Drissman | 5b28637 | 2020-07-28 21:59:38 | [diff] [blame] | 292 | #endif // !defined(OS_APPLE) |
Wez | dc9eb2b12 | 2018-01-09 04:43:07 | [diff] [blame] | 293 | |
| 294 | // Each element is an RLIMIT_* constant that should be raised to its |
| 295 | // rlim_max. This pointer is owned by the caller and must live through |
| 296 | // the call to LaunchProcess(). |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame^] | 297 | raw_ptr<const std::vector<int>> maximize_rlimits = nullptr; |
Wez | dc9eb2b12 | 2018-01-09 04:43:07 | [diff] [blame] | 298 | |
| 299 | // If true, start the process in a new process group, instead of |
| 300 | // inheriting the parent's process group. The pgid of the child process |
| 301 | // will be the same as its pid. |
| 302 | bool new_process_group = false; |
Fabrice de Gans-Riberi | 65421f6 | 2018-05-22 23:16:18 | [diff] [blame] | 303 | #endif // defined(OS_POSIX) |
rickyz | a0b860b | 2015-01-16 18:19:34 | [diff] [blame] | 304 | |
Joel Hockey | 2e832720 | 2021-01-05 22:20:37 | [diff] [blame] | 305 | #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 306 | // If non-negative, the specified file descriptor will be set as the launched |
| 307 | // process' controlling terminal. |
gab | 21691da | 2016-08-02 20:19:58 | [diff] [blame] | 308 | int ctrl_terminal_fd = -1; |
Joel Hockey | 2e832720 | 2021-01-05 22:20:37 | [diff] [blame] | 309 | #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 310 | }; |
| 311 | |
| 312 | // Launch a process via the command line |cmdline|. |
| 313 | // See the documentation of LaunchOptions for details on |options|. |
| 314 | // |
rvargas | c40cfc6 | 2014-12-02 02:46:36 | [diff] [blame] | 315 | // Returns a valid Process upon success. |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 316 | // |
| 317 | // Unix-specific notes: |
| 318 | // - All file descriptors open in the parent process will be closed in the |
| 319 | // child process except for any preserved by options::fds_to_remap, and |
| 320 | // stdin, stdout, and stderr. If not remapped by options::fds_to_remap, |
| 321 | // stdin is reopened as /dev/null, and the child is allowed to inherit its |
| 322 | // parent's stdout and stderr. |
| 323 | // - If the first argument on the command line does not contain a slash, |
| 324 | // PATH will be searched. (See man execvp.) |
rvargas | c40cfc6 | 2014-12-02 02:46:36 | [diff] [blame] | 325 | BASE_EXPORT Process LaunchProcess(const CommandLine& cmdline, |
| 326 | const LaunchOptions& options); |
| 327 | |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 328 | #if defined(OS_WIN) |
| 329 | // Windows-specific LaunchProcess that takes the command line as a |
| 330 | // string. Useful for situations where you need to control the |
| 331 | // command line arguments directly, but prefer the CommandLine version |
| 332 | // if launching Chrome itself. |
| 333 | // |
| 334 | // The first command line argument should be the path to the process, |
| 335 | // and don't forget to quote it. |
| 336 | // |
| 337 | // Example (including literal quotes) |
| 338 | // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" |
Jan Wilken Dörrie | 6bdce49 | 2019-11-05 11:36:50 | [diff] [blame] | 339 | BASE_EXPORT Process LaunchProcess(const CommandLine::StringType& cmdline, |
rvargas | 6181277 | 2014-12-05 03:14:54 | [diff] [blame] | 340 | const LaunchOptions& options); |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 341 | |
[email protected] | fa01e47 | 2014-02-11 14:45:35 | [diff] [blame] | 342 | // Launches a process with elevated privileges. This does not behave exactly |
| 343 | // like LaunchProcess as it uses ShellExecuteEx instead of CreateProcess to |
| 344 | // create the process. This means the process will have elevated privileges |
rvargas | 6293e5b | 2014-12-01 22:53:09 | [diff] [blame] | 345 | // and thus some common operations like OpenProcess will fail. Currently the |
| 346 | // only supported LaunchOptions are |start_hidden| and |wait|. |
| 347 | BASE_EXPORT Process LaunchElevatedProcess(const CommandLine& cmdline, |
| 348 | const LaunchOptions& options); |
[email protected] | fa01e47 | 2014-02-11 14:45:35 | [diff] [blame] | 349 | |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 350 | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 351 | // A POSIX-specific version of LaunchProcess that takes an argv array |
| 352 | // instead of a CommandLine. Useful for situations where you need to |
| 353 | // control the command line arguments directly, but prefer the |
| 354 | // CommandLine version if launching Chrome itself. |
rvargas | 02a9986 | 2015-01-10 00:46:12 | [diff] [blame] | 355 | BASE_EXPORT Process LaunchProcess(const std::vector<std::string>& argv, |
| 356 | const LaunchOptions& options); |
| 357 | |
Avi Drissman | 5b28637 | 2020-07-28 21:59:38 | [diff] [blame] | 358 | #if !defined(OS_APPLE) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 359 | // Close all file descriptors, except those which are a destination in the |
| 360 | // given multimap. Only call this function in a child process where you know |
| 361 | // that there aren't any other threads. |
| 362 | BASE_EXPORT void CloseSuperfluousFds(const InjectiveMultimap& saved_map); |
Avi Drissman | 5b28637 | 2020-07-28 21:59:38 | [diff] [blame] | 363 | #endif // defined(OS_APPLE) |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 364 | #endif // defined(OS_WIN) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 365 | |
| 366 | #if defined(OS_WIN) |
[email protected] | 15db082 | 2013-09-13 21:24:47 | [diff] [blame] | 367 | // Set |job_object|'s JOBOBJECT_EXTENDED_LIMIT_INFORMATION |
| 368 | // BasicLimitInformation.LimitFlags to |limit_flags|. |
| 369 | BASE_EXPORT bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags); |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 370 | |
| 371 | // Output multi-process printf, cout, cerr, etc to the cmd.exe console that ran |
| 372 | // chrome. This is not thread-safe: only call from main thread. |
jam | 79dc59a | 2015-08-17 03:38:16 | [diff] [blame] | 373 | BASE_EXPORT void RouteStdioToConsole(bool create_console_if_not_found); |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 374 | #endif // defined(OS_WIN) |
| 375 | |
| 376 | // Executes the application specified by |cl| and wait for it to exit. Stores |
| 377 | // the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true |
| 378 | // on success (application launched and exited cleanly, with exit code |
| 379 | // indicating success). |
| 380 | BASE_EXPORT bool GetAppOutput(const CommandLine& cl, std::string* output); |
| 381 | |
jam | 79dc59a | 2015-08-17 03:38:16 | [diff] [blame] | 382 | // Like GetAppOutput, but also includes stderr. |
| 383 | BASE_EXPORT bool GetAppOutputAndError(const CommandLine& cl, |
| 384 | std::string* output); |
| 385 | |
Zijie He | e9d42a3 | 2017-07-17 20:37:55 | [diff] [blame] | 386 | // A version of |GetAppOutput()| which also returns the exit code of the |
| 387 | // executed command. Returns true if the application runs and exits cleanly. If |
| 388 | // this is the case the exit code of the application is available in |
| 389 | // |*exit_code|. |
| 390 | BASE_EXPORT bool GetAppOutputWithExitCode(const CommandLine& cl, |
| 391 | std::string* output, int* exit_code); |
| 392 | |
[email protected] | 7eb6bec6 | 2013-12-05 22:41:04 | [diff] [blame] | 393 | #if defined(OS_WIN) |
| 394 | // A Windows-specific version of GetAppOutput that takes a command line string |
| 395 | // instead of a CommandLine object. Useful for situations where you need to |
| 396 | // control the command line arguments directly. |
Jan Wilken Dörrie | 6bdce49 | 2019-11-05 11:36:50 | [diff] [blame] | 397 | BASE_EXPORT bool GetAppOutput(CommandLine::StringPieceType cl, |
| 398 | std::string* output); |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 399 | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 400 | // A POSIX-specific version of GetAppOutput that takes an argv array |
| 401 | // instead of a CommandLine. Useful for situations where you need to |
| 402 | // control the command line arguments directly. |
| 403 | BASE_EXPORT bool GetAppOutput(const std::vector<std::string>& argv, |
| 404 | std::string* output); |
| 405 | |
jbudorick | 86c756c | 2017-03-29 17:33:54 | [diff] [blame] | 406 | // Like the above POSIX-specific version of GetAppOutput, but also includes |
| 407 | // stderr. |
| 408 | BASE_EXPORT bool GetAppOutputAndError(const std::vector<std::string>& argv, |
| 409 | std::string* output); |
Fabrice de Gans-Riberi | 306871de | 2018-05-16 19:38:39 | [diff] [blame] | 410 | #endif // defined(OS_WIN) |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 411 | |
| 412 | // If supported on the platform, and the user has sufficent rights, increase |
| 413 | // the current process's scheduling priority to a high priority. |
| 414 | BASE_EXPORT void RaiseProcessToHighPriority(); |
| 415 | |
[email protected] | d078691 | 2014-04-09 20:06:26 | [diff] [blame] | 416 | // Creates a LaunchOptions object suitable for launching processes in a test |
| 417 | // binary. This should not be called in production/released code. |
| 418 | BASE_EXPORT LaunchOptions LaunchOptionsForTest(); |
| 419 | |
Sean McAllister | 39b8d34 | 2020-08-25 09:08:32 | [diff] [blame] | 420 | #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_NACL_NONSFI) |
rickyz | a2f6d74 | 2015-01-21 21:57:34 | [diff] [blame] | 421 | // A wrapper for clone with fork-like behavior, meaning that it returns the |
| 422 | // child's pid in the parent and 0 in the child. |flags|, |ptid|, and |ctid| are |
| 423 | // as in the clone system call (the CLONE_VM flag is not supported). |
| 424 | // |
| 425 | // This function uses the libc clone wrapper (which updates libc's pid cache) |
| 426 | // internally, so callers may expect things like getpid() to work correctly |
Mostyn Bramley-Moore | d0ecd6a | 2017-12-06 19:13:21 | [diff] [blame] | 427 | // after in both the child and parent. |
rickyz | a2f6d74 | 2015-01-21 21:57:34 | [diff] [blame] | 428 | // |
| 429 | // As with fork(), callers should be extremely careful when calling this while |
| 430 | // multiple threads are running, since at the time the fork happened, the |
| 431 | // threads could have been in any state (potentially holding locks, etc.). |
| 432 | // Callers should most likely call execve() in the child soon after calling |
| 433 | // this. |
Tom Anderson | 24df4195 | 2017-07-25 02:41:01 | [diff] [blame] | 434 | // |
| 435 | // It is unsafe to use any pthread APIs after ForkWithFlags(). |
| 436 | // However, performing an exec() will lift this restriction. |
rickyz | a2f6d74 | 2015-01-21 21:57:34 | [diff] [blame] | 437 | BASE_EXPORT pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid); |
| 438 | #endif |
| 439 | |
Gabriel Charette | 6836c0d5 | 2021-01-11 17:40:26 | [diff] [blame] | 440 | namespace internal { |
| 441 | |
| 442 | // Friend and derived class of ScopedAllowBaseSyncPrimitives which allows |
| 443 | // GetAppOutputInternal() to join a process. GetAppOutputInternal() can't itself |
| 444 | // be a friend of ScopedAllowBaseSyncPrimitives because it is in the anonymous |
| 445 | // namespace. |
| 446 | class GetAppOutputScopedAllowBaseSyncPrimitives |
| 447 | : public base::ScopedAllowBaseSyncPrimitives {}; |
| 448 | |
| 449 | } // namespace internal |
| 450 | |
[email protected] | 300c386 | 2013-07-17 18:12:40 | [diff] [blame] | 451 | } // namespace base |
| 452 | |
| 453 | #endif // BASE_PROCESS_LAUNCH_H_ |