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

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: desktop 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 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
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_
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