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

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: review 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().
Mark Mentovai 2011/06/30 01:04:04 OK. I don’t like this interface because it provide
238 const environment_vector* environ;
Mark Mentovai 2011/06/30 01:04:04 It’s OK to keep the pointers, but maybe add a comm
239
240 // If non-NULL, remap file descriptors according to the mapping of
241 // src fd->dest fd to propagate FDs into the child process.
242 const file_handle_mapping_vector* fds_to_remap;
243
244 // If true, start the process in a new process group, instead of
245 // inheriting the parent's process group. The pgid of the child process
246 // will be the same as its pid.
247 bool new_process_group;
248 #endif
249 };
250
251 // Launch a process via the command line |cmdline|.
252 // See the documentation of LaunchOptions for details on launching options.
253 //
254 // Unix-specific notes:
255 // - Before launching, all FDs open in the parent process will be marked as
256 // close-on-exec.
257 // - If the first argument on the command line is not fully specified,
Mark Mentovai 2011/06/30 01:04:04 You said you’d clarify this, but it’s still ambigu
258 // PATH will be searched.
259 BASE_API bool LaunchProcess(const CommandLine& cmdline,
260 const LaunchOptions& options);
261
193 #if defined(OS_WIN) 262 #if defined(OS_WIN)
194 263
195 enum IntegrityLevel { 264 enum IntegrityLevel {
196 INTEGRITY_UNKNOWN, 265 INTEGRITY_UNKNOWN,
197 LOW_INTEGRITY, 266 LOW_INTEGRITY,
198 MEDIUM_INTEGRITY, 267 MEDIUM_INTEGRITY,
199 HIGH_INTEGRITY, 268 HIGH_INTEGRITY,
200 }; 269 };
201 // Determine the integrity level of the specified process. Returns false 270 // 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 271 // if the system does not support integrity levels (pre-Vista) or in the case
203 // of an underlying system failure. 272 // of an underlying system failure.
204 BASE_API bool GetProcessIntegrityLevel(ProcessHandle process, 273 BASE_API bool GetProcessIntegrityLevel(ProcessHandle process,
205 IntegrityLevel *level); 274 IntegrityLevel *level);
206 275
207 // Runs the given application name with the given command line. Normally, the 276 // 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 277 // string. Useful for situations where you need to control the
209 // forget to quote it. 278 // command line arguments directly, but prefer the CommandLine version
279 // if launching Chrome itself.
210 // 280 //
211 // If wait is true, it will block and wait for the other process to finish, 281 // The first command line argument should be the path to the process,
212 // otherwise, it will just continue asynchronously. 282 // and don't forget to quote it.
213 // 283 //
214 // Example (including literal quotes) 284 // Example (including literal quotes)
215 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" 285 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
216 // 286 BASE_API bool LaunchProcess(const string16& cmdline,
Mark Mentovai 2011/06/30 01:04:04 This is platform-specific code, isn’t it tolerable
brettw 2011/06/30 05:36:25 I prefer string16. I think we should be trying to
217 // If process_handle is non-NULL, the process handle of the launched app will be 287 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 288
225 // Same as LaunchApp, except allows the new process to inherit handles of the 289 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
226 // parent process. 290 inline bool LaunchApp(const std::wstring& cmdline,
227 BASE_API bool LaunchAppWithHandleInheritance(const std::wstring& cmdline, 291 bool wait, bool start_hidden,
228 bool wait, bool start_hidden, 292 ProcessHandle* process_handle) {
229 ProcessHandle* process_handle); 293 LaunchOptions options;
294 options.wait = wait;
295 options.start_hidden = start_hidden;
296 options.process_handle = process_handle;
297 return LaunchProcess(cmdline, options);
298 }
230 299
231 // Runs the given application name with the given command line as if the user 300 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
232 // represented by |token| had launched it. The caveats about |cmdline| and 301 inline bool LaunchAppWithHandleInheritance(const std::wstring& cmdline,
233 // |process_handle| explained for LaunchApp above apply as well. 302 bool wait, bool start_hidden,
234 // 303 ProcessHandle* process_handle) {
235 // Whether the application is visible on the interactive desktop depends on 304 LaunchOptions options;
236 // the token belonging to an interactive logon session. 305 options.wait = wait;
237 // 306 options.start_hidden = start_hidden;
238 // To avoid hard to diagnose problems, this function internally loads the 307 options.process_handle = process_handle;
239 // environment variables associated with the user and if this operation fails 308 options.inherit_handles = true;
240 // the entire call fails as well. 309 return LaunchProcess(cmdline, options);
241 BASE_API bool LaunchAppAsUser(UserTokenHandle token, 310 }
242 const std::wstring& cmdline,
243 bool start_hidden,
244 ProcessHandle* process_handle);
245 311
246 // Has the same behavior as LaunchAppAsUser, but offers the boolean option to 312 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
247 // use an empty string for the desktop name and a boolean for allowing the 313 inline bool LaunchAppAsUser(UserTokenHandle token,
248 // child process to inherit handles from its parent. 314 const std::wstring& cmdline,
249 BASE_API bool LaunchAppAsUser(UserTokenHandle token, 315 bool start_hidden,
250 const std::wstring& cmdline, 316 ProcessHandle* process_handle) {
251 bool start_hidden, ProcessHandle* process_handle, 317 LaunchOptions options;
252 bool empty_desktop_name, bool inherit_handles); 318 options.start_hidden = start_hidden;
319 options.process_handle = process_handle;
320 options.as_user = token;
321 return LaunchProcess(cmdline, options);
322 }
253 323
324 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
325 inline bool LaunchAppAsUser(UserTokenHandle token,
326 const std::wstring& cmdline,
327 bool start_hidden, ProcessHandle* process_handle,
328 bool empty_desktop_name, bool inherit_handles) {
329 LaunchOptions options;
330 options.start_hidden = start_hidden;
331 options.process_handle = process_handle;
332 options.as_user = token;
333 options.empty_desktop_name = empty_desktop_name;
334 options.inherit_handles = inherit_handles;
335 return LaunchProcess(cmdline, options);
336 }
254 337
255 #elif defined(OS_POSIX) 338 #elif defined(OS_POSIX)
256 // Runs the application specified in argv[0] with the command line argv. 339 // 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 340 // 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 341 // control the command line arguments directly, but prefer the
259 // propagate FDs into the child process. 342 // CommandLine version if launching Chrome itself.
260 // 343 BASE_API bool LaunchProcess(const std::vector<std::string>& argv,
261 // As above, if wait is true, execute synchronously. The pid will be stored 344 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 345
271 // Similar to the above, but also (un)set environment variables in child process 346 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
272 // through |environ|. 347 inline bool LaunchApp(const std::vector<std::string>& argv,
273 typedef std::vector<std::pair<std::string, std::string> > environment_vector; 348 const file_handle_mapping_vector& fds_to_remap,
274 BASE_API bool LaunchApp(const std::vector<std::string>& argv, 349 bool wait, ProcessHandle* process_handle) {
275 const environment_vector& environ, 350 LaunchOptions options;
276 const file_handle_mapping_vector& fds_to_remap, 351 options.fds_to_remap = &fds_to_remap;
277 bool wait, ProcessHandle* process_handle); 352 options.wait = wait;
353 options.process_handle = process_handle;
354 return LaunchProcess(argv, options);
355 }
278 356
279 // Similar to the above two methods, but starts the child process in a process 357 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
280 // group of its own, instead of allowing it to inherit the parent's process 358 inline bool LaunchApp(const std::vector<std::string>& argv,
281 // group. The pgid of the child process will be the same as its pid. 359 const environment_vector& environ,
282 BASE_API bool LaunchAppInNewProcessGroup( 360 const file_handle_mapping_vector& fds_to_remap,
361 bool wait, ProcessHandle* process_handle) {
362 LaunchOptions options;
363 options.environ = &environ;
364 options.fds_to_remap = &fds_to_remap;
365 options.wait = wait;
366 options.process_handle = process_handle;
367 return LaunchProcess(argv, options);
368 }
369
370 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
371 inline bool LaunchAppInNewProcessGroup(
283 const std::vector<std::string>& argv, 372 const std::vector<std::string>& argv,
284 const environment_vector& environ, 373 const environment_vector& environ,
285 const file_handle_mapping_vector& fds_to_remap, 374 const file_handle_mapping_vector& fds_to_remap,
286 bool wait, 375 bool wait,
287 ProcessHandle* process_handle); 376 ProcessHandle* process_handle) {
377 LaunchOptions options;
378 options.environ = &environ;
379 options.fds_to_remap = &fds_to_remap;
380 options.wait = wait;
381 options.process_handle = process_handle;
382 options.new_process_group = true;
383 return LaunchProcess(argv, options);
384 }
288 385
289 // AlterEnvironment returns a modified environment vector, constructed from the 386 // AlterEnvironment returns a modified environment vector, constructed from the
290 // given environment and the list of changes given in |changes|. Each key in 387 // 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 388 // 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 389 // 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. 390 // the second is empty, in which case the key-value is removed.
294 // 391 //
295 // The returned array is allocated using new[] and must be freed by the caller. 392 // The returned array is allocated using new[] and must be freed by the caller.
296 BASE_API char** AlterEnvironment(const environment_vector& changes, 393 BASE_API char** AlterEnvironment(const environment_vector& changes,
297 const char* const* const env); 394 const char* const* const env);
298 #endif // defined(OS_POSIX) 395 #endif // defined(OS_POSIX)
299 396
300 // Executes the application specified by cl. This function delegates to one 397 // Executes the application specified by cl. This function delegates to one
301 // of the above two platform-specific functions. 398 // of the above platform-specific functions.
302 BASE_API bool LaunchApp(const CommandLine& cl, bool wait, bool start_hidden, 399 // TODO(evan): deprecated; change callers to use LaunchProcess, remove.
303 ProcessHandle* process_handle); 400 inline bool LaunchApp(const CommandLine& cl, bool wait, bool start_hidden,
401 ProcessHandle* process_handle) {
402 LaunchOptions options;
403 options.wait = wait;
404 options.process_handle = process_handle;
405
406 return LaunchProcess(cl, options);
407 }
304 408
305 // Executes the application specified by |cl| and wait for it to exit. Stores 409 // 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 410 // the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
307 // on success (application launched and exited cleanly, with exit code 411 // on success (application launched and exited cleanly, with exit code
308 // indicating success). 412 // indicating success).
309 BASE_API bool GetAppOutput(const CommandLine& cl, std::string* output); 413 BASE_API bool GetAppOutput(const CommandLine& cl, std::string* output);
310 414
311 #if defined(OS_POSIX) 415 #if defined(OS_POSIX)
312 // A restricted version of |GetAppOutput()| which (a) clears the environment, 416 // 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 417 // 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 779 // instance running inside the parent. The parent's Breakpad instance should
676 // not handle the child's exceptions. Calling RestoreDefaultExceptionHandler 780 // not handle the child's exceptions. Calling RestoreDefaultExceptionHandler
677 // in the child after forking will restore the standard exception handler. 781 // in the child after forking will restore the standard exception handler.
678 // See http://crbug.com/20371/ for more details. 782 // See http://crbug.com/20371/ for more details.
679 void RestoreDefaultExceptionHandler(); 783 void RestoreDefaultExceptionHandler();
680 #endif // defined(OS_MACOSX) 784 #endif // defined(OS_MACOSX)
681 785
682 } // namespace base 786 } // namespace base
683 787
684 #endif // BASE_PROCESS_UTIL_H_ 788 #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