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

Side by Side Diff: base/process/launch_posix.cc

Issue 862133002: Update from https://crrev.com/312398 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "base/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <signal.h> 10 #include <signal.h>
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 // own use and will complain if we try to close them. All of 270 // own use and will complain if we try to close them. All of
271 // these FDs are >= |max_fds|, so we can check against that here 271 // these FDs are >= |max_fds|, so we can check against that here
272 // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758 272 // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758
273 if (fd < static_cast<int>(max_fds)) { 273 if (fd < static_cast<int>(max_fds)) {
274 int ret = IGNORE_EINTR(close(fd)); 274 int ret = IGNORE_EINTR(close(fd));
275 DPCHECK(ret == 0); 275 DPCHECK(ret == 0);
276 } 276 }
277 } 277 }
278 } 278 }
279 279
280 bool LaunchProcess(const std::vector<std::string>& argv, 280 Process LaunchProcess(const CommandLine& cmdline,
281 const LaunchOptions& options, 281 const LaunchOptions& options) {
282 ProcessHandle* process_handle) { 282 return LaunchProcess(cmdline.argv(), options);
283 }
284
285 Process LaunchProcess(const std::vector<std::string>& argv,
286 const LaunchOptions& options) {
283 size_t fd_shuffle_size = 0; 287 size_t fd_shuffle_size = 0;
284 if (options.fds_to_remap) { 288 if (options.fds_to_remap) {
285 fd_shuffle_size = options.fds_to_remap->size(); 289 fd_shuffle_size = options.fds_to_remap->size();
286 } 290 }
287 291
288 InjectiveMultimap fd_shuffle1; 292 InjectiveMultimap fd_shuffle1;
289 InjectiveMultimap fd_shuffle2; 293 InjectiveMultimap fd_shuffle2;
290 fd_shuffle1.reserve(fd_shuffle_size); 294 fd_shuffle1.reserve(fd_shuffle_size);
291 fd_shuffle2.reserve(fd_shuffle_size); 295 fd_shuffle2.reserve(fd_shuffle_size);
292 296
(...skipping 11 matching lines...) Expand all
304 const sigset_t orig_sigmask = SetSignalMask(full_sigset); 308 const sigset_t orig_sigmask = SetSignalMask(full_sigset);
305 309
306 pid_t pid; 310 pid_t pid;
307 #if defined(OS_LINUX) 311 #if defined(OS_LINUX)
308 if (options.clone_flags) { 312 if (options.clone_flags) {
309 // Signal handling in this function assumes the creation of a new 313 // Signal handling in this function assumes the creation of a new
310 // process, so we check that a thread is not being created by mistake 314 // process, so we check that a thread is not being created by mistake
311 // and that signal handling follows the process-creation rules. 315 // and that signal handling follows the process-creation rules.
312 RAW_CHECK( 316 RAW_CHECK(
313 !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM))); 317 !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM)));
314 pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0); 318
319 // We specify a null ptid and ctid.
320 RAW_CHECK(
321 !(options.clone_flags &
322 (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT_SETTID)));
323
324 // Since we use waitpid, we do not support custom termination signals in the
325 // clone flags.
326 RAW_CHECK((options.clone_flags & 0xff) == 0);
327
328 pid = ForkWithFlags(options.clone_flags | SIGCHLD, nullptr, nullptr);
315 } else 329 } else
316 #endif 330 #endif
317 { 331 {
318 pid = fork(); 332 pid = fork();
319 } 333 }
320 334
321 // Always restore the original signal mask in the parent. 335 // Always restore the original signal mask in the parent.
322 if (pid != 0) { 336 if (pid != 0) {
323 SetSignalMask(orig_sigmask); 337 SetSignalMask(orig_sigmask);
324 } 338 }
325 339
326 if (pid < 0) { 340 if (pid < 0) {
327 DPLOG(ERROR) << "fork"; 341 DPLOG(ERROR) << "fork";
328 return false; 342 return Process();
329 } else if (pid == 0) { 343 } else if (pid == 0) {
330 // Child process 344 // Child process
331 345
332 // DANGER: no calls to malloc or locks are allowed from now on: 346 // DANGER: no calls to malloc or locks are allowed from now on:
333 // http://crbug.com/36678 347 // http://crbug.com/36678
334 348
335 // DANGER: fork() rule: in the child, if you don't end up doing exec*(), 349 // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
336 // you call _exit() instead of exit(). This is because _exit() does not 350 // you call _exit() instead of exit(). This is because _exit() does not
337 // call any previously-registered (in the parent) exit handlers, which 351 // call any previously-registered (in the parent) exit handlers, which
338 // might do things like block waiting for threads that don't even exist 352 // might do things like block waiting for threads that don't even exist
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 #define PR_SET_NO_NEW_PRIVS 38 455 #define PR_SET_NO_NEW_PRIVS 38
442 #endif 456 #endif
443 if (!options.allow_new_privs) { 457 if (!options.allow_new_privs) {
444 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) { 458 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) {
445 // Only log if the error is not EINVAL (i.e. not supported). 459 // Only log if the error is not EINVAL (i.e. not supported).
446 RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed"); 460 RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed");
447 } 461 }
448 } 462 }
449 #endif 463 #endif
450 464
465 #if defined(OS_POSIX)
466 if (options.pre_exec_delegate != nullptr) {
467 options.pre_exec_delegate->RunAsyncSafe();
468 }
469 #endif
470
451 for (size_t i = 0; i < argv.size(); i++) 471 for (size_t i = 0; i < argv.size(); i++)
452 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 472 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
453 argv_cstr[argv.size()] = NULL; 473 argv_cstr[argv.size()] = NULL;
454 execvp(argv_cstr[0], argv_cstr.get()); 474 execvp(argv_cstr[0], argv_cstr.get());
455 475
456 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:"); 476 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
457 RAW_LOG(ERROR, argv_cstr[0]); 477 RAW_LOG(ERROR, argv_cstr[0]);
458 _exit(127); 478 _exit(127);
459 } else { 479 } else {
460 // Parent process 480 // Parent process
461 if (options.wait) { 481 if (options.wait) {
462 // While this isn't strictly disk IO, waiting for another process to 482 // While this isn't strictly disk IO, waiting for another process to
463 // finish is the sort of thing ThreadRestrictions is trying to prevent. 483 // finish is the sort of thing ThreadRestrictions is trying to prevent.
464 base::ThreadRestrictions::AssertIOAllowed(); 484 base::ThreadRestrictions::AssertIOAllowed();
465 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); 485 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0));
466 DPCHECK(ret > 0); 486 DPCHECK(ret > 0);
467 } 487 }
468
469 if (process_handle)
470 *process_handle = pid;
471 } 488 }
472 489
473 return true; 490 return Process(pid);
474 }
475
476 Process LaunchProcess(const std::vector<std::string>& argv,
477 const LaunchOptions& options) {
478 ProcessHandle process_handle;
479 if (LaunchProcess(argv, options, &process_handle))
480 return Process(process_handle);
481
482 return Process();
483 }
484
485
486 bool LaunchProcess(const CommandLine& cmdline,
487 const LaunchOptions& options,
488 ProcessHandle* process_handle) {
489 return LaunchProcess(cmdline.argv(), options, process_handle);
490 }
491
492 Process LaunchProcess(const CommandLine& cmdline,
493 const LaunchOptions& options) {
494 ProcessHandle process_handle;
495 if (LaunchProcess(cmdline, options, &process_handle))
496 return Process(process_handle);
497
498 return Process();
499 } 491 }
500 492
501 void RaiseProcessToHighPriority() { 493 void RaiseProcessToHighPriority() {
502 // On POSIX, we don't actually do anything here. We could try to nice() or 494 // On POSIX, we don't actually do anything here. We could try to nice() or
503 // setpriority() or sched_getscheduler, but these all require extra rights. 495 // setpriority() or sched_getscheduler, but these all require extra rights.
504 } 496 }
505 497
506 // Return value used by GetAppOutputInternal to encapsulate the various exit 498 // Return value used by GetAppOutputInternal to encapsulate the various exit
507 // scenarios from the function. 499 // scenarios from the function.
508 enum GetAppOutputInternalResult { 500 enum GetAppOutputInternalResult {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 std::string* output, 665 std::string* output,
674 int* exit_code) { 666 int* exit_code) {
675 // Run |execve()| with the current environment and store "unlimited" data. 667 // Run |execve()| with the current environment and store "unlimited" data.
676 GetAppOutputInternalResult result = GetAppOutputInternal( 668 GetAppOutputInternalResult result = GetAppOutputInternal(
677 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, 669 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true,
678 exit_code); 670 exit_code);
679 return result == EXECUTE_SUCCESS; 671 return result == EXECUTE_SUCCESS;
680 } 672 }
681 673
682 } // namespace base 674 } // namespace base
OLDNEW
« no previous file with comments | « base/process/launch.cc ('k') | base/process/launch_win.cc » ('j') | shell/BUILD.gn » ('J')

Powered by Google App Engine
This is Rietveld 408576698