| OLD | NEW |
| 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 // Set the process's "environment" (i.e. the thing that setenv/getenv | 70 // Set the process's "environment" (i.e. the thing that setenv/getenv |
| 71 // work with). | 71 // work with). |
| 72 void SetEnvironment(char** env) { | 72 void SetEnvironment(char** env) { |
| 73 #if defined(OS_MACOSX) | 73 #if defined(OS_MACOSX) |
| 74 *_NSGetEnviron() = env; | 74 *_NSGetEnviron() = env; |
| 75 #else | 75 #else |
| 76 environ = env; | 76 environ = env; |
| 77 #endif | 77 #endif |
| 78 } | 78 } |
| 79 | 79 |
| 80 // Set the calling thread's signal mask to new_sigmask and return |
| 81 // the previous signal mask. |
| 82 sigset_t SetSignalMask(const sigset_t& new_sigmask) { |
| 83 sigset_t old_sigmask; |
| 84 #if defined(OS_ANDROID) |
| 85 // POSIX says pthread_sigmask() must be used in multi-threaded processes, |
| 86 // but Android's pthread_sigmask() was broken until 4.1: |
| 87 // https://code.google.com/p/android/issues/detail?id=15337 |
| 88 // http://stackoverflow.com/questions/13777109/pthread-sigmask-on-android-not-
working |
| 89 RAW_CHECK(sigprocmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0); |
| 90 #else |
| 91 RAW_CHECK(pthread_sigmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0); |
| 92 #endif |
| 93 return old_sigmask; |
| 94 } |
| 95 |
| 80 #if !defined(OS_LINUX) || \ | 96 #if !defined(OS_LINUX) || \ |
| 81 (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) | 97 (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) |
| 82 void ResetChildSignalHandlersToDefaults() { | 98 void ResetChildSignalHandlersToDefaults() { |
| 83 // The previous signal handlers are likely to be meaningless in the child's | 99 // The previous signal handlers are likely to be meaningless in the child's |
| 84 // context so we reset them to the defaults for now. http://crbug.com/44953 | 100 // context so we reset them to the defaults for now. http://crbug.com/44953 |
| 85 // These signal handlers are set up at least in browser_main_posix.cc: | 101 // These signal handlers are set up at least in browser_main_posix.cc: |
| 86 // BrowserMainPartsPosix::PreEarlyInitialization and stack_trace_posix.cc: | 102 // BrowserMainPartsPosix::PreEarlyInitialization and stack_trace_posix.cc: |
| 87 // EnableInProcessStackDumping. | 103 // EnableInProcessStackDumping. |
| 88 signal(SIGHUP, SIG_DFL); | 104 signal(SIGHUP, SIG_DFL); |
| 89 signal(SIGINT, SIG_DFL); | 105 signal(SIGINT, SIG_DFL); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 InjectiveMultimap fd_shuffle1; | 403 InjectiveMultimap fd_shuffle1; |
| 388 InjectiveMultimap fd_shuffle2; | 404 InjectiveMultimap fd_shuffle2; |
| 389 fd_shuffle1.reserve(fd_shuffle_size); | 405 fd_shuffle1.reserve(fd_shuffle_size); |
| 390 fd_shuffle2.reserve(fd_shuffle_size); | 406 fd_shuffle2.reserve(fd_shuffle_size); |
| 391 | 407 |
| 392 scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]); | 408 scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]); |
| 393 scoped_ptr<char*[]> new_environ; | 409 scoped_ptr<char*[]> new_environ; |
| 394 if (options.environ) | 410 if (options.environ) |
| 395 new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment())); | 411 new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment())); |
| 396 | 412 |
| 413 sigset_t full_sigset; |
| 414 sigfillset(&full_sigset); |
| 415 const sigset_t orig_sigmask = SetSignalMask(full_sigset); |
| 416 |
| 397 pid_t pid; | 417 pid_t pid; |
| 398 #if defined(OS_LINUX) | 418 #if defined(OS_LINUX) |
| 399 if (options.clone_flags) { | 419 if (options.clone_flags) { |
| 420 // Signal handling in this function assumes the creation of a new |
| 421 // process, so we check that a thread is not being created by mistake |
| 422 // and that signal handling follows the process-creation rules. |
| 423 RAW_CHECK( |
| 424 !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM))); |
| 400 pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0); | 425 pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0); |
| 401 } else | 426 } else |
| 402 #endif | 427 #endif |
| 403 { | 428 { |
| 404 pid = fork(); | 429 pid = fork(); |
| 405 } | 430 } |
| 406 | 431 |
| 432 // Always restore the original signal mask in the parent. |
| 433 if (pid != 0) { |
| 434 SetSignalMask(orig_sigmask); |
| 435 } |
| 436 |
| 407 if (pid < 0) { | 437 if (pid < 0) { |
| 408 DPLOG(ERROR) << "fork"; | 438 DPLOG(ERROR) << "fork"; |
| 409 return false; | 439 return false; |
| 410 } else if (pid == 0) { | 440 } else if (pid == 0) { |
| 411 // Child process | 441 // Child process |
| 412 | 442 |
| 413 // DANGER: fork() rule: in the child, if you don't end up doing exec*(), | 443 // DANGER: fork() rule: in the child, if you don't end up doing exec*(), |
| 414 // you call _exit() instead of exit(). This is because _exit() does not | 444 // you call _exit() instead of exit(). This is because _exit() does not |
| 415 // call any previously-registered (in the parent) exit handlers, which | 445 // call any previously-registered (in the parent) exit handlers, which |
| 416 // might do things like block waiting for threads that don't even exist | 446 // might do things like block waiting for threads that don't even exist |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 492 } |
| 463 } | 493 } |
| 464 } | 494 } |
| 465 } | 495 } |
| 466 | 496 |
| 467 #if defined(OS_MACOSX) | 497 #if defined(OS_MACOSX) |
| 468 RestoreDefaultExceptionHandler(); | 498 RestoreDefaultExceptionHandler(); |
| 469 #endif // defined(OS_MACOSX) | 499 #endif // defined(OS_MACOSX) |
| 470 | 500 |
| 471 ResetChildSignalHandlersToDefaults(); | 501 ResetChildSignalHandlersToDefaults(); |
| 502 SetSignalMask(orig_sigmask); |
| 472 | 503 |
| 473 #if 0 | 504 #if 0 |
| 474 // When debugging it can be helpful to check that we really aren't making | 505 // When debugging it can be helpful to check that we really aren't making |
| 475 // any hidden calls to malloc. | 506 // any hidden calls to malloc. |
| 476 void *malloc_thunk = | 507 void *malloc_thunk = |
| 477 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095); | 508 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095); |
| 478 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); | 509 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); |
| 479 memset(reinterpret_cast<void*>(malloc), 0xff, 8); | 510 memset(reinterpret_cast<void*>(malloc), 0xff, 8); |
| 480 #endif // 0 | 511 #endif // 0 |
| 481 | 512 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 std::string* output, | 751 std::string* output, |
| 721 int* exit_code) { | 752 int* exit_code) { |
| 722 // Run |execve()| with the current environment and store "unlimited" data. | 753 // Run |execve()| with the current environment and store "unlimited" data. |
| 723 GetAppOutputInternalResult result = GetAppOutputInternal( | 754 GetAppOutputInternalResult result = GetAppOutputInternal( |
| 724 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, | 755 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, |
| 725 exit_code); | 756 exit_code); |
| 726 return result == EXECUTE_SUCCESS; | 757 return result == EXECUTE_SUCCESS; |
| 727 } | 758 } |
| 728 | 759 |
| 729 } // namespace base | 760 } // namespace base |
| OLD | NEW |