OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <dirent.h> | 5 #include <dirent.h> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <signal.h> | 8 #include <signal.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <sys/resource.h> | 10 #include <sys/resource.h> |
11 #include <sys/time.h> | 11 #include <sys/time.h> |
12 #include <sys/types.h> | 12 #include <sys/types.h> |
13 #include <sys/wait.h> | 13 #include <sys/wait.h> |
14 #include <unistd.h> | 14 #include <unistd.h> |
15 | 15 |
16 #include <limits> | 16 #include <limits> |
17 #include <set> | 17 #include <set> |
18 | 18 |
19 #include "base/command_line.h" | 19 #include "base/command_line.h" |
20 #include "base/compiler_specific.h" | 20 #include "base/compiler_specific.h" |
21 #include "base/debug/stack_trace.h" | 21 #include "base/debug/stack_trace.h" |
22 #include "base/dir_reader_posix.h" | 22 #include "base/dir_reader_posix.h" |
23 #include "base/eintr_wrapper.h" | 23 #include "base/eintr_wrapper.h" |
24 #include "base/logging.h" | 24 #include "base/logging.h" |
25 #include "base/platform_thread.h" | 25 #include "base/platform_thread.h" |
26 #include "base/process_util.h" | 26 #include "base/process_util.h" |
27 #include "base/scoped_ptr.h" | 27 #include "base/scoped_ptr.h" |
28 #include "base/stringprintf.h" | 28 #include "base/stringprintf.h" |
| 29 #include "base/thread_restrictions.h" |
29 #include "base/time.h" | 30 #include "base/time.h" |
30 #include "base/waitable_event.h" | 31 #include "base/waitable_event.h" |
31 | 32 |
32 #if defined(OS_MACOSX) | 33 #if defined(OS_MACOSX) |
33 #include <crt_externs.h> | 34 #include <crt_externs.h> |
34 #define environ (*_NSGetEnviron()) | 35 #define environ (*_NSGetEnviron()) |
35 #else | 36 #else |
36 extern char** environ; | 37 extern char** environ; |
37 #endif | 38 #endif |
38 | 39 |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 for (size_t i = 0; i < argv.size(); i++) | 547 for (size_t i = 0; i < argv.size(); i++) |
547 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); | 548 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); |
548 argv_cstr[argv.size()] = NULL; | 549 argv_cstr[argv.size()] = NULL; |
549 execvp(argv_cstr[0], argv_cstr.get()); | 550 execvp(argv_cstr[0], argv_cstr.get()); |
550 RAW_LOG(ERROR, "LaunchApp: failed to execvp:"); | 551 RAW_LOG(ERROR, "LaunchApp: failed to execvp:"); |
551 RAW_LOG(ERROR, argv_cstr[0]); | 552 RAW_LOG(ERROR, argv_cstr[0]); |
552 _exit(127); | 553 _exit(127); |
553 } else { | 554 } else { |
554 // Parent process | 555 // Parent process |
555 if (wait) { | 556 if (wait) { |
| 557 // While this isn't strictly disk IO, waiting for another process to |
| 558 // finish is the sort of thing ThreadRestrictions is trying to prevent. |
| 559 base::ThreadRestrictions::AssertIOAllowed(); |
556 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); | 560 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); |
557 DPCHECK(ret > 0); | 561 DPCHECK(ret > 0); |
558 } | 562 } |
559 | 563 |
560 if (process_handle) | 564 if (process_handle) |
561 *process_handle = pid; | 565 *process_handle = pid; |
562 } | 566 } |
563 | 567 |
564 return true; | 568 return true; |
565 } | 569 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 // Executes the application specified by |cl| and wait for it to exit. Stores | 745 // Executes the application specified by |cl| and wait for it to exit. Stores |
742 // the output (stdout) in |output|. If |do_search_path| is set, it searches the | 746 // the output (stdout) in |output|. If |do_search_path| is set, it searches the |
743 // path for the application; in that case, |envp| must be null, and it will use | 747 // path for the application; in that case, |envp| must be null, and it will use |
744 // the current environment. If |do_search_path| is false, |cl| should fully | 748 // the current environment. If |do_search_path| is false, |cl| should fully |
745 // specify the path of the application, and |envp| will be used as the | 749 // specify the path of the application, and |envp| will be used as the |
746 // environment. Redirects stderr to /dev/null. Returns true on success | 750 // environment. Redirects stderr to /dev/null. Returns true on success |
747 // (application launched and exited cleanly, with exit code indicating success). | 751 // (application launched and exited cleanly, with exit code indicating success). |
748 static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[], | 752 static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[], |
749 std::string* output, size_t max_output, | 753 std::string* output, size_t max_output, |
750 bool do_search_path) { | 754 bool do_search_path) { |
| 755 // Doing a blocking wait for another command to finish counts as IO. |
| 756 base::ThreadRestrictions::AssertIOAllowed(); |
| 757 |
751 int pipe_fd[2]; | 758 int pipe_fd[2]; |
752 pid_t pid; | 759 pid_t pid; |
753 InjectiveMultimap fd_shuffle1, fd_shuffle2; | 760 InjectiveMultimap fd_shuffle1, fd_shuffle2; |
754 const std::vector<std::string>& argv = cl.argv(); | 761 const std::vector<std::string>& argv = cl.argv(); |
755 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); | 762 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); |
756 | 763 |
757 fd_shuffle1.reserve(3); | 764 fd_shuffle1.reserve(3); |
758 fd_shuffle2.reserve(3); | 765 fd_shuffle2.reserve(3); |
759 | 766 |
760 // Either |do_search_path| should be false or |envp| should be null, but not | 767 // Either |do_search_path| should be false or |envp| should be null, but not |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 const ProcessFilter* filter) { | 898 const ProcessFilter* filter) { |
892 bool exited_cleanly = | 899 bool exited_cleanly = |
893 WaitForProcessesToExit(executable_name, wait_milliseconds, | 900 WaitForProcessesToExit(executable_name, wait_milliseconds, |
894 filter); | 901 filter); |
895 if (!exited_cleanly) | 902 if (!exited_cleanly) |
896 KillProcesses(executable_name, exit_code, filter); | 903 KillProcesses(executable_name, exit_code, filter); |
897 return exited_cleanly; | 904 return exited_cleanly; |
898 } | 905 } |
899 | 906 |
900 } // namespace base | 907 } // namespace base |
OLD | NEW |