Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(434)

Side by Side Diff: base/process_util.h

Issue 7283019: base: refactor LaunchApp variants into a single function (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | base/process_util_posix.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | base/process_util_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698