OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file/namespace contains utility functions for enumerating, ending and | 5 // This file/namespace contains utility functions for enumerating, ending and |
6 // computing statistics of processes. | 6 // computing statistics of processes. |
7 | 7 |
8 #ifndef BASE_PROCESS_UTIL_H_ | 8 #ifndef BASE_PROCESS_UTIL_H_ |
9 #define BASE_PROCESS_UTIL_H_ | 9 #define BASE_PROCESS_UTIL_H_ |
10 #pragma once | 10 #pragma once |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 #if defined(OS_POSIX) | 183 #if defined(OS_POSIX) |
184 // Returns the ID for the parent of the given process. | 184 // Returns the ID for the parent of the given process. |
185 BASE_API ProcessId GetParentProcessId(ProcessHandle process); | 185 BASE_API ProcessId GetParentProcessId(ProcessHandle process); |
186 | 186 |
187 // Close all file descriptors, except those which are a destination in the | 187 // Close all file descriptors, except those which are a destination in the |
188 // given multimap. Only call this function in a child process where you know | 188 // given multimap. Only call this function in a child process where you know |
189 // that there aren't any other threads. | 189 // that there aren't any other threads. |
190 BASE_API void CloseSuperfluousFds(const InjectiveMultimap& saved_map); | 190 BASE_API void CloseSuperfluousFds(const InjectiveMultimap& saved_map); |
191 #endif | 191 #endif |
192 | 192 |
| 193 // TODO(evan): rename these to use StudlyCaps. |
| 194 typedef std::vector<std::pair<std::string, std::string> > environment_vector; |
| 195 typedef std::vector<std::pair<int, int> > file_handle_mapping_vector; |
| 196 |
| 197 // Options for launching a subprocess that are passed to LaunchApp(). |
| 198 struct LaunchOptions { |
| 199 LaunchOptions() : wait(false), process_handle(NULL), |
| 200 #if defined(OS_WIN) |
| 201 start_hidden(false), inherit_handles(false), as_user(NULL), |
| 202 empty_desktop_name(false) |
| 203 #else |
| 204 environ(NULL), fds_to_remap(NULL), new_process_group(false) |
| 205 #endif |
| 206 {} |
| 207 |
| 208 // If true, wait for the process to complete. |
| 209 bool wait; |
| 210 |
| 211 // If non-NULL, will be filled in with the handle of the launched process. |
| 212 // NOTE: In this case, the caller is responsible for closing the handle so |
| 213 // that it doesn't leak! Otherwise, the handle will be implicitly |
| 214 // closed. |
| 215 // Not especially useful unless |wait| is false. |
| 216 ProcessHandle* process_handle; |
| 217 |
| 218 #if defined(OS_WIN) |
| 219 bool start_hidden; |
| 220 |
| 221 // If true, the new process inherits handles from the parent. |
| 222 bool inherit_handles; |
| 223 |
| 224 // If non-NULL, runs as if the user represented by the token had launched it. |
| 225 // Whether the application is visible on the interactive desktop depends on |
| 226 // the token belonging to an interactive logon session. |
| 227 // |
| 228 // To avoid hard to diagnose problems, when specified this loads the |
| 229 // environment variables associated with the user and if this operation fails |
| 230 // the entire call fails as well. |
| 231 UserTokenHandle as_user; |
| 232 |
| 233 // If true, use an empty string for the desktop name. |
| 234 bool empty_desktop_name; |
| 235 #else |
| 236 // If non-NULL, set/unset environment variables. |
| 237 // See documentation of AlterEnvironment(). |
| 238 // This pointer is owned by the caller and must live through the |
| 239 // call to LaunchProcess(). |
| 240 const environment_vector* environ; |
| 241 |
| 242 // If non-NULL, remap file descriptors according to the mapping of |
| 243 // src fd->dest fd to propagate FDs into the child process. |
| 244 // This pointer is owned by the caller and must live through the |
| 245 // call to LaunchProcess(). |
| 246 const file_handle_mapping_vector* fds_to_remap; |
| 247 |
| 248 // If true, start the process in a new process group, instead of |
| 249 // inheriting the parent's process group. The pgid of the child process |
| 250 // will be the same as its pid. |
| 251 bool new_process_group; |
| 252 #endif |
| 253 }; |
| 254 |
| 255 // Launch a process via the command line |cmdline|. |
| 256 // See the documentation of LaunchOptions for details on launching options. |
| 257 // |
| 258 // Unix-specific notes: |
| 259 // - Before launching, all FDs open in the parent process will be marked as |
| 260 // close-on-exec. |
| 261 // - If the first argument on the command line does not contain a slash, |
| 262 // PATH will be searched. (See man execvp.) |
| 263 BASE_API bool LaunchProcess(const CommandLine& cmdline, |
| 264 const LaunchOptions& options); |
| 265 |
193 #if defined(OS_WIN) | 266 #if defined(OS_WIN) |
194 | 267 |
195 enum IntegrityLevel { | 268 enum IntegrityLevel { |
196 INTEGRITY_UNKNOWN, | 269 INTEGRITY_UNKNOWN, |
197 LOW_INTEGRITY, | 270 LOW_INTEGRITY, |
198 MEDIUM_INTEGRITY, | 271 MEDIUM_INTEGRITY, |
199 HIGH_INTEGRITY, | 272 HIGH_INTEGRITY, |
200 }; | 273 }; |
201 // Determine the integrity level of the specified process. Returns false | 274 // Determine the integrity level of the specified process. Returns false |
202 // if the system does not support integrity levels (pre-Vista) or in the case | 275 // if the system does not support integrity levels (pre-Vista) or in the case |
203 // of an underlying system failure. | 276 // of an underlying system failure. |
204 BASE_API bool GetProcessIntegrityLevel(ProcessHandle process, | 277 BASE_API bool GetProcessIntegrityLevel(ProcessHandle process, |
205 IntegrityLevel *level); | 278 IntegrityLevel *level); |
206 | 279 |
207 // Runs the given application name with the given command line. Normally, the | 280 // Windows-specific LaunchProcess that takes the command line as a |
208 // first command line argument should be the path to the process, and don't | 281 // string. Useful for situations where you need to control the |
209 // forget to quote it. | 282 // command line arguments directly, but prefer the CommandLine version |
| 283 // if launching Chrome itself. |
210 // | 284 // |
211 // If wait is true, it will block and wait for the other process to finish, | 285 // The first command line argument should be the path to the process, |
212 // otherwise, it will just continue asynchronously. | 286 // and don't forget to quote it. |
213 // | 287 // |
214 // Example (including literal quotes) | 288 // Example (including literal quotes) |
215 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" | 289 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" |
216 // | 290 BASE_API bool LaunchProcess(const string16& cmdline, |
217 // If process_handle is non-NULL, the process handle of the launched app will be | 291 const LaunchOptions& options); |
218 // stored there on a successful launch. | |
219 // NOTE: In this case, the caller is responsible for closing the handle so | |
220 // that it doesn't leak! | |
221 BASE_API bool LaunchApp(const std::wstring& cmdline, | |
222 bool wait, bool start_hidden, | |
223 ProcessHandle* process_handle); | |
224 | 292 |
225 // Same as LaunchApp, except allows the new process to inherit handles of the | 293 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
226 // parent process. | 294 inline bool LaunchApp(const std::wstring& cmdline, |
227 BASE_API bool LaunchAppWithHandleInheritance(const std::wstring& cmdline, | 295 bool wait, bool start_hidden, |
228 bool wait, bool start_hidden, | 296 ProcessHandle* process_handle) { |
229 ProcessHandle* process_handle); | 297 LaunchOptions options; |
| 298 options.wait = wait; |
| 299 options.start_hidden = start_hidden; |
| 300 options.process_handle = process_handle; |
| 301 return LaunchProcess(cmdline, options); |
| 302 } |
230 | 303 |
231 // Runs the given application name with the given command line as if the user | 304 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
232 // represented by |token| had launched it. The caveats about |cmdline| and | 305 inline bool LaunchAppWithHandleInheritance(const std::wstring& cmdline, |
233 // |process_handle| explained for LaunchApp above apply as well. | 306 bool wait, bool start_hidden, |
234 // | 307 ProcessHandle* process_handle) { |
235 // Whether the application is visible on the interactive desktop depends on | 308 LaunchOptions options; |
236 // the token belonging to an interactive logon session. | 309 options.wait = wait; |
237 // | 310 options.start_hidden = start_hidden; |
238 // To avoid hard to diagnose problems, this function internally loads the | 311 options.process_handle = process_handle; |
239 // environment variables associated with the user and if this operation fails | 312 options.inherit_handles = true; |
240 // the entire call fails as well. | 313 return LaunchProcess(cmdline, options); |
241 BASE_API bool LaunchAppAsUser(UserTokenHandle token, | 314 } |
242 const std::wstring& cmdline, | |
243 bool start_hidden, | |
244 ProcessHandle* process_handle); | |
245 | 315 |
246 // Has the same behavior as LaunchAppAsUser, but offers the boolean option to | 316 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
247 // use an empty string for the desktop name and a boolean for allowing the | 317 inline bool LaunchAppAsUser(UserTokenHandle token, |
248 // child process to inherit handles from its parent. | 318 const std::wstring& cmdline, |
249 BASE_API bool LaunchAppAsUser(UserTokenHandle token, | 319 bool start_hidden, |
250 const std::wstring& cmdline, | 320 ProcessHandle* process_handle) { |
251 bool start_hidden, ProcessHandle* process_handle, | 321 LaunchOptions options; |
252 bool empty_desktop_name, bool inherit_handles); | 322 options.start_hidden = start_hidden; |
| 323 options.process_handle = process_handle; |
| 324 options.as_user = token; |
| 325 return LaunchProcess(cmdline, options); |
| 326 } |
253 | 327 |
| 328 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 329 inline bool LaunchAppAsUser(UserTokenHandle token, |
| 330 const std::wstring& cmdline, |
| 331 bool start_hidden, ProcessHandle* process_handle, |
| 332 bool empty_desktop_name, bool inherit_handles) { |
| 333 LaunchOptions options; |
| 334 options.start_hidden = start_hidden; |
| 335 options.process_handle = process_handle; |
| 336 options.as_user = token; |
| 337 options.empty_desktop_name = empty_desktop_name; |
| 338 options.inherit_handles = inherit_handles; |
| 339 return LaunchProcess(cmdline, options); |
| 340 } |
254 | 341 |
255 #elif defined(OS_POSIX) | 342 #elif defined(OS_POSIX) |
256 // Runs the application specified in argv[0] with the command line argv. | 343 // A POSIX-specific version of LaunchProcess that takes an argv array |
257 // Before launching all FDs open in the parent process will be marked as | 344 // instead of a CommandLine. Useful for situations where you need to |
258 // close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to | 345 // control the command line arguments directly, but prefer the |
259 // propagate FDs into the child process. | 346 // CommandLine version if launching Chrome itself. |
260 // | 347 BASE_API bool LaunchProcess(const std::vector<std::string>& argv, |
261 // As above, if wait is true, execute synchronously. The pid will be stored | 348 const LaunchOptions& options); |
262 // in process_handle if that pointer is non-null. | |
263 // | |
264 // Note that the first argument in argv must point to the executable filename. | |
265 // If the filename is not fully specified, PATH will be searched. | |
266 typedef std::vector<std::pair<int, int> > file_handle_mapping_vector; | |
267 BASE_API bool LaunchApp(const std::vector<std::string>& argv, | |
268 const file_handle_mapping_vector& fds_to_remap, | |
269 bool wait, ProcessHandle* process_handle); | |
270 | 349 |
271 // Similar to the above, but also (un)set environment variables in child process | 350 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
272 // through |environ|. | 351 inline bool LaunchApp(const std::vector<std::string>& argv, |
273 typedef std::vector<std::pair<std::string, std::string> > environment_vector; | 352 const file_handle_mapping_vector& fds_to_remap, |
274 BASE_API bool LaunchApp(const std::vector<std::string>& argv, | 353 bool wait, ProcessHandle* process_handle) { |
275 const environment_vector& environ, | 354 LaunchOptions options; |
276 const file_handle_mapping_vector& fds_to_remap, | 355 options.fds_to_remap = &fds_to_remap; |
277 bool wait, ProcessHandle* process_handle); | 356 options.wait = wait; |
| 357 options.process_handle = process_handle; |
| 358 return LaunchProcess(argv, options); |
| 359 } |
278 | 360 |
279 // Similar to the above two methods, but starts the child process in a process | 361 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
280 // group of its own, instead of allowing it to inherit the parent's process | 362 inline bool LaunchApp(const std::vector<std::string>& argv, |
281 // group. The pgid of the child process will be the same as its pid. | 363 const environment_vector& environ, |
282 BASE_API bool LaunchAppInNewProcessGroup( | 364 const file_handle_mapping_vector& fds_to_remap, |
| 365 bool wait, ProcessHandle* process_handle) { |
| 366 LaunchOptions options; |
| 367 options.environ = &environ; |
| 368 options.fds_to_remap = &fds_to_remap; |
| 369 options.wait = wait; |
| 370 options.process_handle = process_handle; |
| 371 return LaunchProcess(argv, options); |
| 372 } |
| 373 |
| 374 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 375 inline bool LaunchAppInNewProcessGroup( |
283 const std::vector<std::string>& argv, | 376 const std::vector<std::string>& argv, |
284 const environment_vector& environ, | 377 const environment_vector& environ, |
285 const file_handle_mapping_vector& fds_to_remap, | 378 const file_handle_mapping_vector& fds_to_remap, |
286 bool wait, | 379 bool wait, |
287 ProcessHandle* process_handle); | 380 ProcessHandle* process_handle) { |
| 381 LaunchOptions options; |
| 382 options.environ = &environ; |
| 383 options.fds_to_remap = &fds_to_remap; |
| 384 options.wait = wait; |
| 385 options.process_handle = process_handle; |
| 386 options.new_process_group = true; |
| 387 return LaunchProcess(argv, options); |
| 388 } |
288 | 389 |
289 // AlterEnvironment returns a modified environment vector, constructed from the | 390 // AlterEnvironment returns a modified environment vector, constructed from the |
290 // given environment and the list of changes given in |changes|. Each key in | 391 // given environment and the list of changes given in |changes|. Each key in |
291 // the environment is matched against the first element of the pairs. In the | 392 // the environment is matched against the first element of the pairs. In the |
292 // event of a match, the value is replaced by the second of the pair, unless | 393 // event of a match, the value is replaced by the second of the pair, unless |
293 // the second is empty, in which case the key-value is removed. | 394 // the second is empty, in which case the key-value is removed. |
294 // | 395 // |
295 // The returned array is allocated using new[] and must be freed by the caller. | 396 // The returned array is allocated using new[] and must be freed by the caller. |
296 BASE_API char** AlterEnvironment(const environment_vector& changes, | 397 BASE_API char** AlterEnvironment(const environment_vector& changes, |
297 const char* const* const env); | 398 const char* const* const env); |
298 #endif // defined(OS_POSIX) | 399 #endif // defined(OS_POSIX) |
299 | 400 |
300 // Executes the application specified by cl. This function delegates to one | 401 // Executes the application specified by cl. This function delegates to one |
301 // of the above two platform-specific functions. | 402 // of the above platform-specific functions. |
302 BASE_API bool LaunchApp(const CommandLine& cl, bool wait, bool start_hidden, | 403 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
303 ProcessHandle* process_handle); | 404 inline bool LaunchApp(const CommandLine& cl, bool wait, bool start_hidden, |
| 405 ProcessHandle* process_handle) { |
| 406 LaunchOptions options; |
| 407 options.wait = wait; |
| 408 options.process_handle = process_handle; |
| 409 |
| 410 return LaunchProcess(cl, options); |
| 411 } |
304 | 412 |
305 // Executes the application specified by |cl| and wait for it to exit. Stores | 413 // Executes the application specified by |cl| and wait for it to exit. Stores |
306 // the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true | 414 // the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true |
307 // on success (application launched and exited cleanly, with exit code | 415 // on success (application launched and exited cleanly, with exit code |
308 // indicating success). | 416 // indicating success). |
309 BASE_API bool GetAppOutput(const CommandLine& cl, std::string* output); | 417 BASE_API bool GetAppOutput(const CommandLine& cl, std::string* output); |
310 | 418 |
311 #if defined(OS_POSIX) | 419 #if defined(OS_POSIX) |
312 // A restricted version of |GetAppOutput()| which (a) clears the environment, | 420 // A restricted version of |GetAppOutput()| which (a) clears the environment, |
313 // and (b) stores at most |max_output| bytes; also, it doesn't search the path | 421 // and (b) stores at most |max_output| bytes; also, it doesn't search the path |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 // instance running inside the parent. The parent's Breakpad instance should | 783 // instance running inside the parent. The parent's Breakpad instance should |
676 // not handle the child's exceptions. Calling RestoreDefaultExceptionHandler | 784 // not handle the child's exceptions. Calling RestoreDefaultExceptionHandler |
677 // in the child after forking will restore the standard exception handler. | 785 // in the child after forking will restore the standard exception handler. |
678 // See http://crbug.com/20371/ for more details. | 786 // See http://crbug.com/20371/ for more details. |
679 void RestoreDefaultExceptionHandler(); | 787 void RestoreDefaultExceptionHandler(); |
680 #endif // defined(OS_MACOSX) | 788 #endif // defined(OS_MACOSX) |
681 | 789 |
682 } // namespace base | 790 } // namespace base |
683 | 791 |
684 #endif // BASE_PROCESS_UTIL_H_ | 792 #endif // BASE_PROCESS_UTIL_H_ |
OLD | NEW |