diff options
-rw-r--r-- | base/process_util.h | 3 | ||||
-rw-r--r-- | base/process_util_linux.cc | 77 | ||||
-rw-r--r-- | base/process_util_mac.mm | 72 | ||||
-rw-r--r-- | base/process_util_posix.cc | 76 |
4 files changed, 77 insertions, 151 deletions
diff --git a/base/process_util.h b/base/process_util.h index 31d8de7..450dbc2 100644 --- a/base/process_util.h +++ b/base/process_util.h @@ -142,7 +142,7 @@ typedef std::vector<std::pair<int, int> > file_handle_mapping_vector; bool LaunchApp(const std::vector<std::string>& argv, const file_handle_mapping_vector& fds_to_remap, bool wait, ProcessHandle* process_handle); -#if defined(OS_LINUX) + // Similar to above, but also (un)set environment variables in child process // through |environ|. typedef std::vector<std::pair<const char*, const char*> > environment_vector; @@ -150,7 +150,6 @@ bool LaunchApp(const std::vector<std::string>& argv, const environment_vector& environ, const file_handle_mapping_vector& fds_to_remap, bool wait, ProcessHandle* process_handle); -#endif // defined(OS_LINUX) #endif // defined(OS_POSIX) // Executes the application specified by cl. This function delegates to one diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc index 50eb4a2..a05e9bb 100644 --- a/base/process_util_linux.cc +++ b/base/process_util_linux.cc @@ -13,7 +13,6 @@ #include <string> -#include "base/eintr_wrapper.h" #include "base/file_util.h" #include "base/logging.h" #include "base/string_tokenizer.h" @@ -86,82 +85,6 @@ FilePath GetProcessExecutablePath(ProcessHandle process) { return FilePath(std::string(exename, len)); } -bool LaunchApp(const std::vector<std::string>& argv, - const environment_vector& environ, - const file_handle_mapping_vector& fds_to_remap, - bool wait, ProcessHandle* process_handle) { - pid_t pid = fork(); - if (pid < 0) - return false; - - if (pid == 0) { - // Child process - InjectiveMultimap fd_shuffle; - for (file_handle_mapping_vector::const_iterator - it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) { - fd_shuffle.push_back(InjectionArc(it->first, it->second, false)); - } - - for (environment_vector::const_iterator it = environ.begin(); - it != environ.end(); ++it) { - if (it->first) { - if (it->second) { - setenv(it->first, it->second, 1); - } else { - unsetenv(it->first); - } - } - } - - // Obscure fork() rule: in the child, if you don't end up doing exec*(), - // you call _exit() instead of exit(). This is because _exit() does not - // call any previously-registered (in the parent) exit handlers, which - // might do things like block waiting for threads that don't even exist - // in the child. - if (!ShuffleFileDescriptors(fd_shuffle)) - _exit(127); - - // If we are using the SUID sandbox, it sets a magic environment variable - // ("SBX_D"), so we remove that variable from the environment here on the - // off chance that it's already set. - unsetenv("SBX_D"); - - CloseSuperfluousFds(fd_shuffle); - - scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); - for (size_t i = 0; i < argv.size(); i++) - argv_cstr[i] = const_cast<char*>(argv[i].c_str()); - argv_cstr[argv.size()] = NULL; - execvp(argv_cstr[0], argv_cstr.get()); - LOG(ERROR) << "LaunchApp: exec failed!, argv_cstr[0] " << argv_cstr[0] - << ", errno " << errno; - _exit(127); - } else { - // Parent process - if (wait) - HANDLE_EINTR(waitpid(pid, 0, 0)); - - if (process_handle) - *process_handle = pid; - } - - return true; -} - -bool LaunchApp(const std::vector<std::string>& argv, - const file_handle_mapping_vector& fds_to_remap, - bool wait, ProcessHandle* process_handle) { - base::environment_vector no_env; - return LaunchApp(argv, no_env, fds_to_remap, wait, process_handle); -} - -bool LaunchApp(const CommandLine& cl, - bool wait, bool start_hidden, - ProcessHandle* process_handle) { - file_handle_mapping_vector no_files; - return LaunchApp(cl.argv(), no_files, wait, process_handle); -} - NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name, const ProcessFilter* filter) : executable_name_(executable_name), filter_(filter) { diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm index 9653ada..de9b3f1 100644 --- a/base/process_util_mac.mm +++ b/base/process_util_mac.mm @@ -21,78 +21,6 @@ namespace base { -bool LaunchApp(const std::vector<std::string>& argv, - const file_handle_mapping_vector& fds_to_remap, - bool wait, ProcessHandle* process_handle) { - bool retval = true; - - char* argv_copy[argv.size() + 1]; - for (size_t i = 0; i < argv.size(); i++) { - argv_copy[i] = const_cast<char*>(argv[i].c_str()); - } - argv_copy[argv.size()] = NULL; - - // Make sure we don't leak any FDs to the child process by marking all FDs - // as close-on-exec. - SetAllFDsToCloseOnExec(); - - posix_spawn_file_actions_t file_actions; - if (posix_spawn_file_actions_init(&file_actions) != 0) { - return false; - } - - // Turn fds_to_remap array into a set of dup2 calls. - for (file_handle_mapping_vector::const_iterator it = fds_to_remap.begin(); - it != fds_to_remap.end(); - ++it) { - int src_fd = it->first; - int dest_fd = it->second; - - if (src_fd == dest_fd) { - int flags = fcntl(src_fd, F_GETFD); - if (flags != -1) { - fcntl(src_fd, F_SETFD, flags & ~FD_CLOEXEC); - } - } else { - if (posix_spawn_file_actions_adddup2(&file_actions, src_fd, dest_fd) != 0) - { - posix_spawn_file_actions_destroy(&file_actions); - return false; - } - } - } - - int pid = 0; - int spawn_succeeded = (posix_spawnp(&pid, - argv_copy[0], - &file_actions, - NULL, - argv_copy, - *_NSGetEnviron()) == 0); - - posix_spawn_file_actions_destroy(&file_actions); - - bool process_handle_valid = pid > 0; - if (!spawn_succeeded || !process_handle_valid) { - retval = false; - } else { - if (wait) - HANDLE_EINTR(waitpid(pid, 0, 0)); - - if (process_handle) - *process_handle = pid; - } - - return retval; -} - -bool LaunchApp(const CommandLine& cl, - bool wait, bool start_hidden, ProcessHandle* process_handle) { - // TODO(playmobil): Do we need to respect the start_hidden flag? - file_handle_mapping_vector no_files; - return LaunchApp(cl.argv(), no_files, wait, process_handle); -} - NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name, const ProcessFilter* filter) : executable_name_(executable_name), diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc index 6ff660f..ecb4937 100644 --- a/base/process_util_posix.cc +++ b/base/process_util_posix.cc @@ -220,6 +220,82 @@ void SetAllFDsToCloseOnExec() { } } +bool LaunchApp(const std::vector<std::string>& argv, + const environment_vector& environ, + const file_handle_mapping_vector& fds_to_remap, + bool wait, ProcessHandle* process_handle) { + pid_t pid = fork(); + if (pid < 0) + return false; + + if (pid == 0) { + // Child process + InjectiveMultimap fd_shuffle; + for (file_handle_mapping_vector::const_iterator + it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) { + fd_shuffle.push_back(InjectionArc(it->first, it->second, false)); + } + + for (environment_vector::const_iterator it = environ.begin(); + it != environ.end(); ++it) { + if (it->first) { + if (it->second) { + setenv(it->first, it->second, 1); + } else { + unsetenv(it->first); + } + } + } + + // Obscure fork() rule: in the child, if you don't end up doing exec*(), + // you call _exit() instead of exit(). This is because _exit() does not + // call any previously-registered (in the parent) exit handlers, which + // might do things like block waiting for threads that don't even exist + // in the child. + if (!ShuffleFileDescriptors(fd_shuffle)) + _exit(127); + + // If we are using the SUID sandbox, it sets a magic environment variable + // ("SBX_D"), so we remove that variable from the environment here on the + // off chance that it's already set. + unsetenv("SBX_D"); + + CloseSuperfluousFds(fd_shuffle); + + scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); + for (size_t i = 0; i < argv.size(); i++) + argv_cstr[i] = const_cast<char*>(argv[i].c_str()); + argv_cstr[argv.size()] = NULL; + execvp(argv_cstr[0], argv_cstr.get()); + LOG(ERROR) << "LaunchApp: exec failed!, argv_cstr[0] " << argv_cstr[0] + << ", errno " << errno; + _exit(127); + } else { + // Parent process + if (wait) + HANDLE_EINTR(waitpid(pid, 0, 0)); + + if (process_handle) + *process_handle = pid; + } + + return true; +} + +bool LaunchApp(const std::vector<std::string>& argv, + const file_handle_mapping_vector& fds_to_remap, + bool wait, ProcessHandle* process_handle) { + base::environment_vector no_env; + return LaunchApp(argv, no_env, fds_to_remap, wait, process_handle); +} + +bool LaunchApp(const CommandLine& cl, + bool wait, bool start_hidden, + ProcessHandle* process_handle) { + file_handle_mapping_vector no_files; + return LaunchApp(cl.argv(), no_files, wait, process_handle); +} + ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process), last_time_(0), last_system_time_(0) { |