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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 for (size_t i = 0; i < argv.size(); i++) | 504 for (size_t i = 0; i < argv.size(); i++) |
504 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); | 505 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); |
505 argv_cstr[argv.size()] = NULL; | 506 argv_cstr[argv.size()] = NULL; |
506 execvp(argv_cstr[0], argv_cstr.get()); | 507 execvp(argv_cstr[0], argv_cstr.get()); |
507 RAW_LOG(ERROR, "LaunchApp: failed to execvp:"); | 508 RAW_LOG(ERROR, "LaunchApp: failed to execvp:"); |
508 RAW_LOG(ERROR, argv_cstr[0]); | 509 RAW_LOG(ERROR, argv_cstr[0]); |
509 _exit(127); | 510 _exit(127); |
510 } else { | 511 } else { |
511 // Parent process | 512 // Parent process |
512 if (wait) { | 513 if (wait) { |
| 514 // While this isn't strictly disk IO, waiting for another process to |
| 515 // finish is the sort of thing ThreadRestrictions is trying to prevent. |
| 516 base::ThreadRestrictions::AssertIOAllowed(); |
513 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); | 517 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); |
514 DPCHECK(ret > 0); | 518 DPCHECK(ret > 0); |
515 } | 519 } |
516 | 520 |
517 if (process_handle) | 521 if (process_handle) |
518 *process_handle = pid; | 522 *process_handle = pid; |
519 } | 523 } |
520 | 524 |
521 return true; | 525 return true; |
522 } | 526 } |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 // Executes the application specified by |cl| and wait for it to exit. Stores | 701 // Executes the application specified by |cl| and wait for it to exit. Stores |
698 // the output (stdout) in |output|. If |do_search_path| is set, it searches the | 702 // the output (stdout) in |output|. If |do_search_path| is set, it searches the |
699 // path for the application; in that case, |envp| must be null, and it will use | 703 // path for the application; in that case, |envp| must be null, and it will use |
700 // the current environment. If |do_search_path| is false, |cl| should fully | 704 // the current environment. If |do_search_path| is false, |cl| should fully |
701 // specify the path of the application, and |envp| will be used as the | 705 // specify the path of the application, and |envp| will be used as the |
702 // environment. Redirects stderr to /dev/null. Returns true on success | 706 // environment. Redirects stderr to /dev/null. Returns true on success |
703 // (application launched and exited cleanly, with exit code indicating success). | 707 // (application launched and exited cleanly, with exit code indicating success). |
704 static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[], | 708 static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[], |
705 std::string* output, size_t max_output, | 709 std::string* output, size_t max_output, |
706 bool do_search_path) { | 710 bool do_search_path) { |
| 711 // Doing a blocking wait for another command to finish counts as IO. |
| 712 base::ThreadRestrictions::AssertIOAllowed(); |
| 713 |
707 int pipe_fd[2]; | 714 int pipe_fd[2]; |
708 pid_t pid; | 715 pid_t pid; |
709 InjectiveMultimap fd_shuffle1, fd_shuffle2; | 716 InjectiveMultimap fd_shuffle1, fd_shuffle2; |
710 const std::vector<std::string>& argv = cl.argv(); | 717 const std::vector<std::string>& argv = cl.argv(); |
711 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); | 718 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); |
712 | 719 |
713 fd_shuffle1.reserve(3); | 720 fd_shuffle1.reserve(3); |
714 fd_shuffle2.reserve(3); | 721 fd_shuffle2.reserve(3); |
715 | 722 |
716 // Either |do_search_path| should be false or |envp| should be null, but not | 723 // 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... |
847 const ProcessFilter* filter) { | 854 const ProcessFilter* filter) { |
848 bool exited_cleanly = | 855 bool exited_cleanly = |
849 WaitForProcessesToExit(executable_name, wait_milliseconds, | 856 WaitForProcessesToExit(executable_name, wait_milliseconds, |
850 filter); | 857 filter); |
851 if (!exited_cleanly) | 858 if (!exited_cleanly) |
852 KillProcesses(executable_name, exit_code, filter); | 859 KillProcesses(executable_name, exit_code, filter); |
853 return exited_cleanly; | 860 return exited_cleanly; |
854 } | 861 } |
855 | 862 |
856 } // namespace base | 863 } // namespace base |
OLD | NEW |