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" | |
30 #include "base/time.h" | 29 #include "base/time.h" |
31 #include "base/waitable_event.h" | 30 #include "base/waitable_event.h" |
32 | 31 |
33 #if defined(OS_MACOSX) | 32 #if defined(OS_MACOSX) |
34 #include <crt_externs.h> | 33 #include <crt_externs.h> |
35 #define environ (*_NSGetEnviron()) | 34 #define environ (*_NSGetEnviron()) |
36 #else | 35 #else |
37 extern char** environ; | 36 extern char** environ; |
38 #endif | 37 #endif |
39 | 38 |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 for (size_t i = 0; i < argv.size(); i++) | 546 for (size_t i = 0; i < argv.size(); i++) |
548 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); | 547 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); |
549 argv_cstr[argv.size()] = NULL; | 548 argv_cstr[argv.size()] = NULL; |
550 execvp(argv_cstr[0], argv_cstr.get()); | 549 execvp(argv_cstr[0], argv_cstr.get()); |
551 RAW_LOG(ERROR, "LaunchApp: failed to execvp:"); | 550 RAW_LOG(ERROR, "LaunchApp: failed to execvp:"); |
552 RAW_LOG(ERROR, argv_cstr[0]); | 551 RAW_LOG(ERROR, argv_cstr[0]); |
553 _exit(127); | 552 _exit(127); |
554 } else { | 553 } else { |
555 // Parent process | 554 // Parent process |
556 if (wait) { | 555 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(); | |
560 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); | 556 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); |
561 DPCHECK(ret > 0); | 557 DPCHECK(ret > 0); |
562 } | 558 } |
563 | 559 |
564 if (process_handle) | 560 if (process_handle) |
565 *process_handle = pid; | 561 *process_handle = pid; |
566 } | 562 } |
567 | 563 |
568 return true; | 564 return true; |
569 } | 565 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 // Executes the application specified by |cl| and wait for it to exit. Stores | 741 // Executes the application specified by |cl| and wait for it to exit. Stores |
746 // the output (stdout) in |output|. If |do_search_path| is set, it searches the | 742 // the output (stdout) in |output|. If |do_search_path| is set, it searches the |
747 // path for the application; in that case, |envp| must be null, and it will use | 743 // path for the application; in that case, |envp| must be null, and it will use |
748 // the current environment. If |do_search_path| is false, |cl| should fully | 744 // the current environment. If |do_search_path| is false, |cl| should fully |
749 // specify the path of the application, and |envp| will be used as the | 745 // specify the path of the application, and |envp| will be used as the |
750 // environment. Redirects stderr to /dev/null. Returns true on success | 746 // environment. Redirects stderr to /dev/null. Returns true on success |
751 // (application launched and exited cleanly, with exit code indicating success). | 747 // (application launched and exited cleanly, with exit code indicating success). |
752 static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[], | 748 static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[], |
753 std::string* output, size_t max_output, | 749 std::string* output, size_t max_output, |
754 bool do_search_path) { | 750 bool do_search_path) { |
755 // Doing a blocking wait for another command to finish counts as IO. | |
756 base::ThreadRestrictions::AssertIOAllowed(); | |
757 | |
758 int pipe_fd[2]; | 751 int pipe_fd[2]; |
759 pid_t pid; | 752 pid_t pid; |
760 InjectiveMultimap fd_shuffle1, fd_shuffle2; | 753 InjectiveMultimap fd_shuffle1, fd_shuffle2; |
761 const std::vector<std::string>& argv = cl.argv(); | 754 const std::vector<std::string>& argv = cl.argv(); |
762 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); | 755 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); |
763 | 756 |
764 fd_shuffle1.reserve(3); | 757 fd_shuffle1.reserve(3); |
765 fd_shuffle2.reserve(3); | 758 fd_shuffle2.reserve(3); |
766 | 759 |
767 // Either |do_search_path| should be false or |envp| should be null, but not | 760 // 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... |
898 const ProcessFilter* filter) { | 891 const ProcessFilter* filter) { |
899 bool exited_cleanly = | 892 bool exited_cleanly = |
900 WaitForProcessesToExit(executable_name, wait_milliseconds, | 893 WaitForProcessesToExit(executable_name, wait_milliseconds, |
901 filter); | 894 filter); |
902 if (!exited_cleanly) | 895 if (!exited_cleanly) |
903 KillProcesses(executable_name, exit_code, filter); | 896 KillProcesses(executable_name, exit_code, filter); |
904 return exited_cleanly; | 897 return exited_cleanly; |
905 } | 898 } |
906 | 899 |
907 } // namespace base | 900 } // namespace base |
OLD | NEW |