Chromium Code Reviews| 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 struct LaunchOptions { | |
| 198 // If true, wait for the process to complete. | |
| 199 bool wait; | |
| 200 | |
| 201 // If non-NULL, will be filled in with the handle of the lauched process. | |
| 202 // NOTE: In this case, the caller is responsible for closing the handle so | |
| 203 // that it doesn't leak! | |
|
Mark Mentovai
2011/06/29 22:11:28
And if NULL, what happens? Does the launcher wait
Evan Martin
2011/06/29 23:09:26
Copy'n'paste from the previous code. Will clarify
| |
| 204 ProcessHandle* process_handle; | |
| 205 | |
| 206 #if defined(OS_WIN) | |
| 207 bool start_hidden; | |
| 208 | |
| 209 // If true, the new process inherits handles from the parent. | |
| 210 bool inherit_handles; | |
| 211 | |
| 212 // If non-NULL, runs as if the user represented by the token had launched it. | |
| 213 // Whether the application is visible on the interactive desktop depends on | |
| 214 // the token belonging to an interactive logon session. | |
| 215 // | |
| 216 // To avoid hard to diagnose problems, when specified this loads the | |
| 217 // environment variables associated with the user and if this operation fails | |
| 218 // the entire call fails as well. | |
| 219 UserTokenHandle as_user; | |
| 220 | |
| 221 // If true, use an empty string for the desktop name. | |
| 222 bool empty_desktop_name; | |
| 223 #else | |
| 224 // If non-NULL, set/unset environment variables. | |
|
Mark Mentovai
2011/06/29 22:11:28
What does it mean to “unset”? How would you “unset
Evan Martin
2011/06/29 23:09:26
To be honest, I didn't fully understand it myself.
| |
| 225 const environment_vector* environ; | |
| 226 | |
| 227 // If non-NULL, remap file descriptors according to the mapping of | |
| 228 // src fd->dest fd to propagate FDs into the child process. | |
| 229 const file_handle_mapping_vector* fds_to_remap; | |
|
Mark Mentovai
2011/06/29 22:11:28
Seems like this can just be a file_handle_mapping_
Evan Martin
2011/06/29 23:09:26
Hm, yeah. When I first wrote this I was designing
| |
| 230 | |
| 231 // If true, start the process in a new process group, instead of | |
| 232 // inheritng the parent's process group. The pgid of the child process | |
| 233 // will be the same as its pid. | |
| 234 bool new_process_group; | |
| 235 #endif | |
| 236 | |
| 237 LaunchOptions() : wait(false), process_handle(NULL), | |
|
Mark Mentovai
2011/06/29 22:11:28
Can you move the constructor up to the top as is o
| |
| 238 #if defined(OS_WIN) | |
| 239 start_hidden(false), inherit_handles(false), as_user(NULL), | |
| 240 empty_desktop_name(false) | |
| 241 #else | |
| 242 environ(NULL), fds_to_remap(NULL), new_process_group(false) | |
| 243 #endif | |
| 244 {} | |
| 245 }; | |
| 246 | |
| 247 // Launch a process via the command line |cmdline|. | |
| 248 // See the documentation of LaunchOptions for details on launching options. | |
| 249 // | |
| 250 // Unix-specific notes: | |
| 251 // - Before launching all FDs open in the parent process will be marked as | |
|
Mark Mentovai
2011/06/29 22:11:28
launching comma all. Because the first time I read
| |
| 252 // close-on-exec. | |
| 253 // - If the first argument on the command line is not fully specified, | |
|
Mark Mentovai
2011/06/29 22:11:28
“fully specified” means what, exactly? No slashes
Evan Martin
2011/06/29 23:09:26
Copy'n'paste from the previous code. Will clarify
| |
| 254 // PATH will be searched. | |
| 255 BASE_API bool LaunchProcess(const CommandLine& cmdline, | |
| 256 const LaunchOptions& options); | |
| 257 | |
| 193 #if defined(OS_WIN) | 258 #if defined(OS_WIN) |
| 194 | 259 |
| 195 enum IntegrityLevel { | 260 enum IntegrityLevel { |
| 196 INTEGRITY_UNKNOWN, | 261 INTEGRITY_UNKNOWN, |
| 197 LOW_INTEGRITY, | 262 LOW_INTEGRITY, |
| 198 MEDIUM_INTEGRITY, | 263 MEDIUM_INTEGRITY, |
| 199 HIGH_INTEGRITY, | 264 HIGH_INTEGRITY, |
| 200 }; | 265 }; |
| 201 // Determine the integrity level of the specified process. Returns false | 266 // 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 | 267 // if the system does not support integrity levels (pre-Vista) or in the case |
| 203 // of an underlying system failure. | 268 // of an underlying system failure. |
| 204 BASE_API bool GetProcessIntegrityLevel(ProcessHandle process, | 269 BASE_API bool GetProcessIntegrityLevel(ProcessHandle process, |
| 205 IntegrityLevel *level); | 270 IntegrityLevel *level); |
| 206 | 271 |
| 207 // Runs the given application name with the given command line. Normally, the | 272 // Windows-specific LaunchProcess that takes the command line as a string. |
| 208 // first command line argument should be the path to the process, and don't | 273 // Prefer using the CommandLine LaunchProcess if possible. |
| 209 // forget to quote it. | |
| 210 // | 274 // |
| 211 // If wait is true, it will block and wait for the other process to finish, | 275 // The first command line argument should be the path to the process, |
| 212 // otherwise, it will just continue asynchronously. | 276 // and don't forget to quote it. |
| 213 // | 277 // |
| 214 // Example (including literal quotes) | 278 // Example (including literal quotes) |
| 215 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" | 279 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" |
| 216 // | 280 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 217 // If process_handle is non-NULL, the process handle of the launched app will be | 281 BASE_API bool LaunchProcess(const string16& cmdline, |
| 218 // stored there on a successful launch. | 282 const LaunchOptions& options); |
| 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 | 283 |
| 225 // Same as LaunchApp, except allows the new process to inherit handles of the | 284 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 226 // parent process. | 285 inline bool LaunchApp(const std::wstring& cmdline, |
| 227 BASE_API bool LaunchAppWithHandleInheritance(const std::wstring& cmdline, | 286 bool wait, bool start_hidden, |
| 228 bool wait, bool start_hidden, | 287 ProcessHandle* process_handle) { |
| 229 ProcessHandle* process_handle); | 288 LaunchOptions options; |
| 289 options.wait = wait; | |
| 290 options.start_hidden = start_hidden; | |
| 291 options.process_handle = process_handle; | |
| 292 return LaunchProcess(cmdline, options); | |
| 293 } | |
| 230 | 294 |
| 231 // Runs the given application name with the given command line as if the user | 295 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 232 // represented by |token| had launched it. The caveats about |cmdline| and | 296 inline bool LaunchAppWithHandleInheritance(const std::wstring& cmdline, |
| 233 // |process_handle| explained for LaunchApp above apply as well. | 297 bool wait, bool start_hidden, |
| 234 // | 298 ProcessHandle* process_handle) { |
| 235 // Whether the application is visible on the interactive desktop depends on | 299 LaunchOptions options; |
| 236 // the token belonging to an interactive logon session. | 300 options.wait = wait; |
| 237 // | 301 options.start_hidden = start_hidden; |
| 238 // To avoid hard to diagnose problems, this function internally loads the | 302 options.process_handle = process_handle; |
| 239 // environment variables associated with the user and if this operation fails | 303 options.inherit_handles = true; |
| 240 // the entire call fails as well. | 304 return LaunchProcess(cmdline, options); |
| 241 BASE_API bool LaunchAppAsUser(UserTokenHandle token, | 305 } |
| 242 const std::wstring& cmdline, | |
| 243 bool start_hidden, | |
| 244 ProcessHandle* process_handle); | |
| 245 | 306 |
| 246 // Has the same behavior as LaunchAppAsUser, but offers the boolean option to | 307 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 247 // use an empty string for the desktop name and a boolean for allowing the | 308 inline bool LaunchAppAsUser(UserTokenHandle token, |
| 248 // child process to inherit handles from its parent. | 309 const std::wstring& cmdline, |
| 249 BASE_API bool LaunchAppAsUser(UserTokenHandle token, | 310 bool start_hidden, |
| 250 const std::wstring& cmdline, | 311 ProcessHandle* process_handle) { |
| 251 bool start_hidden, ProcessHandle* process_handle, | 312 LaunchOptions options; |
| 252 bool empty_desktop_name, bool inherit_handles); | 313 options.start_hidden = start_hidden; |
| 314 options.process_handle = process_handle; | |
| 315 options.as_user = token; | |
| 316 return LaunchProcess(cmdline, options); | |
| 317 } | |
| 253 | 318 |
| 319 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. | |
| 320 inline bool LaunchAppAsUser(UserTokenHandle token, | |
| 321 const std::wstring& cmdline, | |
| 322 bool start_hidden, ProcessHandle* process_handle, | |
| 323 bool empty_desktop_name, bool inherit_handles) { | |
| 324 LaunchOptions options; | |
| 325 options.start_hidden = start_hidden; | |
| 326 options.process_handle = process_handle; | |
| 327 options.as_user = token; | |
| 328 options.empty_desktop_name = empty_desktop_name; | |
| 329 options.inherit_handles = inherit_handles; | |
| 330 return LaunchProcess(cmdline, options); | |
| 331 } | |
| 254 | 332 |
| 255 #elif defined(OS_POSIX) | 333 #elif defined(OS_POSIX) |
| 256 // Runs the application specified in argv[0] with the command line argv. | 334 // 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 | 335 // instead of a CommandLine. Prefer the CommandLine version if possible. |
|
Mark Mentovai
2011/06/29 22:11:28
Doesn’t the CommandLine version F the argument ord
Evan Martin
2011/06/29 23:09:26
I think CommandLine() is only useful for launching
| |
| 258 // close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to | 336 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 259 // propagate FDs into the child process. | 337 BASE_API bool LaunchProcess(const std::vector<std::string>& argv, |
| 260 // | 338 const LaunchOptions& options); |
| 261 // As above, if wait is true, execute synchronously. The pid will be stored | |
| 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 | 339 |
| 271 // Similar to the above, but also (un)set environment variables in child process | 340 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 272 // through |environ|. | 341 inline bool LaunchApp(const std::vector<std::string>& argv, |
| 273 typedef std::vector<std::pair<std::string, std::string> > environment_vector; | 342 const file_handle_mapping_vector& fds_to_remap, |
| 274 BASE_API bool LaunchApp(const std::vector<std::string>& argv, | 343 bool wait, ProcessHandle* process_handle) { |
| 275 const environment_vector& environ, | 344 LaunchOptions options; |
| 276 const file_handle_mapping_vector& fds_to_remap, | 345 options.fds_to_remap = &fds_to_remap; |
| 277 bool wait, ProcessHandle* process_handle); | 346 options.wait = wait; |
| 347 options.process_handle = process_handle; | |
| 348 return LaunchProcess(argv, options); | |
| 349 } | |
| 278 | 350 |
| 279 // Similar to the above two methods, but starts the child process in a process | 351 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. |
| 280 // group of its own, instead of allowing it to inherit the parent's process | 352 inline bool LaunchApp(const std::vector<std::string>& argv, |
| 281 // group. The pgid of the child process will be the same as its pid. | 353 const environment_vector& environ, |
| 282 BASE_API bool LaunchAppInNewProcessGroup( | 354 const file_handle_mapping_vector& fds_to_remap, |
| 355 bool wait, ProcessHandle* process_handle) { | |
| 356 LaunchOptions options; | |
| 357 options.environ = &environ; | |
| 358 options.fds_to_remap = &fds_to_remap; | |
| 359 options.wait = wait; | |
| 360 options.process_handle = process_handle; | |
| 361 return LaunchProcess(argv, options); | |
| 362 } | |
| 363 | |
| 364 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. | |
| 365 inline bool LaunchAppInNewProcessGroup( | |
| 283 const std::vector<std::string>& argv, | 366 const std::vector<std::string>& argv, |
| 284 const environment_vector& environ, | 367 const environment_vector& environ, |
| 285 const file_handle_mapping_vector& fds_to_remap, | 368 const file_handle_mapping_vector& fds_to_remap, |
| 286 bool wait, | 369 bool wait, |
| 287 ProcessHandle* process_handle); | 370 ProcessHandle* process_handle) { |
| 371 LaunchOptions options; | |
| 372 options.environ = &environ; | |
| 373 options.fds_to_remap = &fds_to_remap; | |
| 374 options.wait = wait; | |
| 375 options.process_handle = process_handle; | |
| 376 options.new_process_group = true; | |
| 377 return LaunchProcess(argv, options); | |
| 378 } | |
| 288 | 379 |
| 289 // AlterEnvironment returns a modified environment vector, constructed from the | 380 // AlterEnvironment returns a modified environment vector, constructed from the |
| 290 // given environment and the list of changes given in |changes|. Each key in | 381 // 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 | 382 // 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 | 383 // 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. | 384 // the second is empty, in which case the key-value is removed. |
| 294 // | 385 // |
| 295 // The returned array is allocated using new[] and must be freed by the caller. | 386 // The returned array is allocated using new[] and must be freed by the caller. |
| 296 BASE_API char** AlterEnvironment(const environment_vector& changes, | 387 BASE_API char** AlterEnvironment(const environment_vector& changes, |
| 297 const char* const* const env); | 388 const char* const* const env); |
| 298 #endif // defined(OS_POSIX) | 389 #endif // defined(OS_POSIX) |
| 299 | 390 |
| 300 // Executes the application specified by cl. This function delegates to one | 391 // Executes the application specified by cl. This function delegates to one |
| 301 // of the above two platform-specific functions. | 392 // of the above platform-specific functions. |
| 393 // TODO(evan): deprecated; change callers to use LaunchProcess, remove. | |
| 302 BASE_API bool LaunchApp(const CommandLine& cl, bool wait, bool start_hidden, | 394 BASE_API bool LaunchApp(const CommandLine& cl, bool wait, bool start_hidden, |
| 303 ProcessHandle* process_handle); | 395 ProcessHandle* process_handle) { |
| 396 LaunchOptions options; | |
| 397 options.wait = wait; | |
| 398 options.process_handle = process_handle; | |
| 399 | |
| 400 return LaunchProcess(cl, options); | |
| 401 } | |
| 304 | 402 |
| 305 // Executes the application specified by |cl| and wait for it to exit. Stores | 403 // 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 | 404 // the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true |
| 307 // on success (application launched and exited cleanly, with exit code | 405 // on success (application launched and exited cleanly, with exit code |
| 308 // indicating success). | 406 // indicating success). |
| 309 BASE_API bool GetAppOutput(const CommandLine& cl, std::string* output); | 407 BASE_API bool GetAppOutput(const CommandLine& cl, std::string* output); |
| 310 | 408 |
| 311 #if defined(OS_POSIX) | 409 #if defined(OS_POSIX) |
| 312 // A restricted version of |GetAppOutput()| which (a) clears the environment, | 410 // 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 | 411 // 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 | 773 // instance running inside the parent. The parent's Breakpad instance should |
| 676 // not handle the child's exceptions. Calling RestoreDefaultExceptionHandler | 774 // not handle the child's exceptions. Calling RestoreDefaultExceptionHandler |
| 677 // in the child after forking will restore the standard exception handler. | 775 // in the child after forking will restore the standard exception handler. |
| 678 // See http://crbug.com/20371/ for more details. | 776 // See http://crbug.com/20371/ for more details. |
| 679 void RestoreDefaultExceptionHandler(); | 777 void RestoreDefaultExceptionHandler(); |
| 680 #endif // defined(OS_MACOSX) | 778 #endif // defined(OS_MACOSX) |
| 681 | 779 |
| 682 } // namespace base | 780 } // namespace base |
| 683 | 781 |
| 684 #endif // BASE_PROCESS_UTIL_H_ | 782 #endif // BASE_PROCESS_UTIL_H_ |
| OLD | NEW |