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