| Index: base/process_util_posix.cc
|
| diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
|
| index efe74425ad1c5a07c5513a5fe39b93e512742665..29c60b5919f76b170d757c8937cfdf8483d4be44 100644
|
| --- a/base/process_util_posix.cc
|
| +++ b/base/process_util_posix.cc
|
| @@ -14,6 +14,7 @@
|
| #include <unistd.h>
|
|
|
| #include <limits>
|
| +#include <set>
|
|
|
| #include "base/basictypes.h"
|
| #include "base/logging.h"
|
| @@ -89,8 +90,57 @@ class ScopedDIRClose {
|
| };
|
| typedef scoped_ptr_malloc<DIR, ScopedDIRClose> ScopedDIR;
|
|
|
| +void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
|
| + std::set<int> saved_fds;
|
| +
|
| + // Don't close stdin, stdout and stderr
|
| + saved_fds.insert(STDIN_FILENO);
|
| + saved_fds.insert(STDOUT_FILENO);
|
| + saved_fds.insert(STDERR_FILENO);
|
| +
|
| + for (base::InjectiveMultimap::const_iterator
|
| + i = saved_mapping.begin(); i != saved_mapping.end(); ++i) {
|
| + saved_fds.insert(i->dest);
|
| + }
|
| +
|
| +#if defined(OS_LINUX)
|
| + static const char fd_dir[] = "/proc/self/fd";
|
| +#elif defined(OS_MACOSX)
|
| + static const char fd_dir[] = "/dev/fd";
|
| +#endif
|
| +
|
| + ScopedDIR dir_closer(opendir(fd_dir));
|
| + DIR *dir = dir_closer.get();
|
| + if (NULL == dir) {
|
| + DLOG(ERROR) << "Unable to open " << fd_dir;
|
| + return;
|
| + }
|
| +
|
| + struct dirent *ent;
|
| + while ((ent = readdir(dir))) {
|
| + // Skip . and .. entries.
|
| + if (ent->d_name[0] == '.')
|
| + continue;
|
| +
|
| + char *endptr;
|
| + errno = 0;
|
| + const long int fd = strtol(ent->d_name, &endptr, 10);
|
| + if (ent->d_name[0] == 0 || *endptr || fd < 0 || fd >= INT_MAX || errno)
|
| + continue;
|
| + if (saved_fds.find(fd) != saved_fds.end())
|
| + continue;
|
| +
|
| + int result;
|
| + do {
|
| + result = close(fd);
|
| + } while (result == -1 && errno == EINTR);
|
| + }
|
| +}
|
| +
|
| // Sets all file descriptors to close on exec except for stdin, stdout
|
| // and stderr.
|
| +// TODO(agl): Remove this function. It's fundamentally broken for multithreaded
|
| +// apps.
|
| void SetAllFDsToCloseOnExec() {
|
| #if defined(OS_LINUX)
|
| const char fd_dir[] = "/proc/self/fd";
|
| @@ -348,19 +398,15 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) {
|
| if (dev_null < 0)
|
| exit(127);
|
|
|
| - int rv;
|
| - do {
|
| - rv = dup2(pipe_fd[1], STDOUT_FILENO);
|
| - } while (rv == -1 && errno == EINTR);
|
| - do {
|
| - rv = dup2(dev_null, STDERR_FILENO);
|
| - } while (rv == -1 && errno == EINTR);
|
| - if (pipe_fd[0] != STDOUT_FILENO && pipe_fd[0] != STDERR_FILENO)
|
| - close(pipe_fd[0]);
|
| - if (pipe_fd[1] != STDOUT_FILENO && pipe_fd[1] != STDERR_FILENO)
|
| - close(pipe_fd[1]);
|
| - if (dev_null != STDOUT_FILENO && dev_null != STDERR_FILENO)
|
| - close(dev_null);
|
| + InjectiveMultimap fd_shuffle;
|
| + fd_shuffle.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
|
| + fd_shuffle.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
|
| + fd_shuffle.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
|
| +
|
| + if (!ShuffleFileDescriptors(fd_shuffle))
|
| + exit(127);
|
| +
|
| + CloseSuperfluousFds(fd_shuffle);
|
|
|
| const std::vector<std::string> argv = cl.argv();
|
| scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
|
|
|