1 // Copyright 2013 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 // This file contains functions for launching subprocesses. 6 7 #ifndef BASE_PROCESS_LAUNCH_H_ 8 #define BASE_PROCESS_LAUNCH_H_ 9 10 #include <string> 11 #include <utility> 12 #include <vector> 13 14 #include "base/base_export.h" 15 #include "base/basictypes.h" 16 #include "base/environment.h" 17 #include "base/process/process_handle.h" 18 #include "base/strings/string_piece.h" 19 20 #if defined(OS_POSIX) 21 #include "base/posix/file_descriptor_shuffle.h" 22 #elif defined(OS_WIN) 23 #include <windows.h> 24 #include "base/win/scoped_handle.h" 25 #endif 26 27 namespace base { 28 29 class CommandLine; 30 31 #if defined(OS_WIN) 32 typedef std::vector<HANDLE> HandlesToInheritVector; 33 #endif 34 // TODO(viettrungluu): Only define this on POSIX? 35 typedef std::vector<std::pair<int, int> > FileHandleMappingVector; 36 37 // Options for launching a subprocess that are passed to LaunchProcess(). 38 // The default constructor constructs the object with default options. 39 struct BASE_EXPORT LaunchOptions { 40 LaunchOptions(); 41 ~LaunchOptions(); 42 43 // If true, wait for the process to complete. 44 bool wait; 45 46 #if defined(OS_WIN) 47 bool start_hidden; 48 49 // If non-null, inherit exactly the list of handles in this vector (these 50 // handles must be inheritable). This is only supported on Vista and higher. 51 HandlesToInheritVector* handles_to_inherit; 52 53 // If true, the new process inherits handles from the parent. In production 54 // code this flag should be used only when running short-lived, trusted 55 // binaries, because open handles from other libraries and subsystems will 56 // leak to the child process, causing errors such as open socket hangs. 57 // Note: If |handles_to_inherit| is non-null, this flag is ignored and only 58 // those handles will be inherited (on Vista and higher). 59 bool inherit_handles; 60 61 // If non-null, runs as if the user represented by the token had launched it. 62 // Whether the application is visible on the interactive desktop depends on 63 // the token belonging to an interactive logon session. 64 // 65 // To avoid hard to diagnose problems, when specified this loads the 66 // environment variables associated with the user and if this operation fails 67 // the entire call fails as well. 68 UserTokenHandle as_user; 69 70 // If true, use an empty string for the desktop name. 71 bool empty_desktop_name; 72 73 // If non-null, launches the application in that job object. The process will 74 // be terminated immediately and LaunchProcess() will fail if assignment to 75 // the job object fails. 76 HANDLE job_handle; 77 78 // Handles for the redirection of stdin, stdout and stderr. The handles must 79 // be inheritable. Caller should either set all three of them or none (i.e. 80 // there is no way to redirect stderr without redirecting stdin). The 81 // |inherit_handles| flag must be set to true when redirecting stdio stream. 82 HANDLE stdin_handle; 83 HANDLE stdout_handle; 84 HANDLE stderr_handle; 85 86 // If set to true, ensures that the child process is launched with the 87 // CREATE_BREAKAWAY_FROM_JOB flag which allows it to breakout of the parent 88 // job if any. 89 bool force_breakaway_from_job_; 90 #else 91 // Set/unset environment variables. These are applied on top of the parent 92 // process environment. Empty (the default) means to inherit the same 93 // environment. See AlterEnvironment(). 94 EnvironmentMap environ; 95 96 // Clear the environment for the new process before processing changes from 97 // |environ|. 98 bool clear_environ; 99 100 // If non-null, remap file descriptors according to the mapping of 101 // src fd->dest fd to propagate FDs into the child process. 102 // This pointer is owned by the caller and must live through the 103 // call to LaunchProcess(). 104 const FileHandleMappingVector* fds_to_remap; 105 106 // Each element is an RLIMIT_* constant that should be raised to its 107 // rlim_max. This pointer is owned by the caller and must live through 108 // the call to LaunchProcess(). 109 const std::vector<int>* maximize_rlimits; 110 111 // If true, start the process in a new process group, instead of 112 // inheriting the parent's process group. The pgid of the child process 113 // will be the same as its pid. 114 bool new_process_group; 115 116 #if defined(OS_LINUX) 117 // If non-zero, start the process using clone(), using flags as provided. 118 int clone_flags; 119 120 // By default, child processes will have the PR_SET_NO_NEW_PRIVS bit set. If 121 // true, then this bit will not be set in the new child process. 122 bool allow_new_privs; 123 #endif // defined(OS_LINUX) 124 125 #if defined(OS_CHROMEOS) 126 // If non-negative, the specified file descriptor will be set as the launched 127 // process' controlling terminal. 128 int ctrl_terminal_fd; 129 #endif // defined(OS_CHROMEOS) 130 131 #if defined(OS_MACOSX) 132 // If this name is non-empty, the new child, after fork() but before exec(), 133 // will look up this server name in the bootstrap namespace. The resulting 134 // service port will be replaced as the bootstrap port in the child. Because 135 // the process's IPC space is cleared on exec(), any rights to the old 136 // bootstrap port will not be transferred to the new process. 137 std::string replacement_bootstrap_name; 138 #endif 139 140 #endif // !defined(OS_WIN) 141 }; 142 143 // Launch a process via the command line |cmdline|. 144 // See the documentation of LaunchOptions for details on |options|. 145 // 146 // Returns true upon success. 147 // 148 // Upon success, if |process_handle| is non-null, it will be filled in with the 149 // handle of the launched process. NOTE: In this case, the caller is 150 // responsible for closing the handle so that it doesn't leak! 151 // Otherwise, the process handle will be implicitly closed. 152 // 153 // Unix-specific notes: 154 // - All file descriptors open in the parent process will be closed in the 155 // child process except for any preserved by options::fds_to_remap, and 156 // stdin, stdout, and stderr. If not remapped by options::fds_to_remap, 157 // stdin is reopened as /dev/null, and the child is allowed to inherit its 158 // parent's stdout and stderr. 159 // - If the first argument on the command line does not contain a slash, 160 // PATH will be searched. (See man execvp.) 161 BASE_EXPORT bool LaunchProcess(const CommandLine& cmdline, 162 const LaunchOptions& options, 163 ProcessHandle* process_handle); 164 165 #if defined(OS_WIN) 166 // Windows-specific LaunchProcess that takes the command line as a 167 // string. Useful for situations where you need to control the 168 // command line arguments directly, but prefer the CommandLine version 169 // if launching Chrome itself. 170 // 171 // The first command line argument should be the path to the process, 172 // and don't forget to quote it. 173 // 174 // Example (including literal quotes) 175 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" 176 BASE_EXPORT bool LaunchProcess(const string16& cmdline, 177 const LaunchOptions& options, 178 win::ScopedHandle* process_handle); 179 180 // Launches a process with elevated privileges. This does not behave exactly 181 // like LaunchProcess as it uses ShellExecuteEx instead of CreateProcess to 182 // create the process. This means the process will have elevated privileges 183 // and thus some common operations like OpenProcess will fail. The process will 184 // be available through the |process_handle| argument. Currently the only 185 // supported LaunchOptions are |start_hidden| and |wait|. 186 BASE_EXPORT bool LaunchElevatedProcess(const CommandLine& cmdline, 187 const LaunchOptions& options, 188 ProcessHandle* process_handle); 189 190 #elif defined(OS_POSIX) 191 // A POSIX-specific version of LaunchProcess that takes an argv array 192 // instead of a CommandLine. Useful for situations where you need to 193 // control the command line arguments directly, but prefer the 194 // CommandLine version if launching Chrome itself. 195 BASE_EXPORT bool LaunchProcess(const std::vector<std::string>& argv, 196 const LaunchOptions& options, 197 ProcessHandle* process_handle); 198 199 // Close all file descriptors, except those which are a destination in the 200 // given multimap. Only call this function in a child process where you know 201 // that there aren't any other threads. 202 BASE_EXPORT void CloseSuperfluousFds(const InjectiveMultimap& saved_map); 203 #endif // defined(OS_POSIX) 204 205 #if defined(OS_WIN) 206 // Set |job_object|'s JOBOBJECT_EXTENDED_LIMIT_INFORMATION 207 // BasicLimitInformation.LimitFlags to |limit_flags|. 208 BASE_EXPORT bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags); 209 210 // Output multi-process printf, cout, cerr, etc to the cmd.exe console that ran 211 // chrome. This is not thread-safe: only call from main thread. 212 BASE_EXPORT void RouteStdioToConsole(); 213 #endif // defined(OS_WIN) 214 215 // Executes the application specified by |cl| and wait for it to exit. Stores 216 // the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true 217 // on success (application launched and exited cleanly, with exit code 218 // indicating success). 219 BASE_EXPORT bool GetAppOutput(const CommandLine& cl, std::string* output); 220 221 #if defined(OS_WIN) 222 // A Windows-specific version of GetAppOutput that takes a command line string 223 // instead of a CommandLine object. Useful for situations where you need to 224 // control the command line arguments directly. 225 BASE_EXPORT bool GetAppOutput(const StringPiece16& cl, std::string* output); 226 #endif 227 228 #if defined(OS_POSIX) 229 // A POSIX-specific version of GetAppOutput that takes an argv array 230 // instead of a CommandLine. Useful for situations where you need to 231 // control the command line arguments directly. 232 BASE_EXPORT bool GetAppOutput(const std::vector<std::string>& argv, 233 std::string* output); 234 235 // A restricted version of |GetAppOutput()| which (a) clears the environment, 236 // and (b) stores at most |max_output| bytes; also, it doesn't search the path 237 // for the command. 238 BASE_EXPORT bool GetAppOutputRestricted(const CommandLine& cl, 239 std::string* output, size_t max_output); 240 241 // A version of |GetAppOutput()| which also returns the exit code of the 242 // executed command. Returns true if the application runs and exits cleanly. If 243 // this is the case the exit code of the application is available in 244 // |*exit_code|. 245 BASE_EXPORT bool GetAppOutputWithExitCode(const CommandLine& cl, 246 std::string* output, int* exit_code); 247 #endif // defined(OS_POSIX) 248 249 // If supported on the platform, and the user has sufficent rights, increase 250 // the current process's scheduling priority to a high priority. 251 BASE_EXPORT void RaiseProcessToHighPriority(); 252 253 #if defined(OS_MACOSX) 254 // Restore the default exception handler, setting it to Apple Crash Reporter 255 // (ReportCrash). When forking and execing a new process, the child will 256 // inherit the parent's exception ports, which may be set to the Breakpad 257 // instance running inside the parent. The parent's Breakpad instance should 258 // not handle the child's exceptions. Calling RestoreDefaultExceptionHandler 259 // in the child after forking will restore the standard exception handler. 260 // See http://crbug.com/20371/ for more details. 261 void RestoreDefaultExceptionHandler(); 262 263 // Look up the bootstrap server named |replacement_bootstrap_name| via the 264 // current |bootstrap_port|. Then replace the task's bootstrap port with the 265 // received right. 266 void ReplaceBootstrapPort(const std::string& replacement_bootstrap_name); 267 #endif // defined(OS_MACOSX) 268 269 // Creates a LaunchOptions object suitable for launching processes in a test 270 // binary. This should not be called in production/released code. 271 BASE_EXPORT LaunchOptions LaunchOptionsForTest(); 272 273 } // namespace base 274 275 #endif // BASE_PROCESS_LAUNCH_H_ 276