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