diff options
author | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-06 16:40:12 +0000 |
---|---|---|
committer | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-06 16:40:12 +0000 |
commit | aec92f83d096ca57ab6ce515ae7063b8081b630e (patch) | |
tree | 5bae3ac3500734e646ab0eb5b918e3c0334e0860 /base/process_util_posix.cc | |
parent | 09a988dd76797e19acd4702b96aa6c283d66a1e5 (diff) | |
download | chromium_src-aec92f83d096ca57ab6ce515ae7063b8081b630e.zip chromium_src-aec92f83d096ca57ab6ce515ae7063b8081b630e.tar.gz chromium_src-aec92f83d096ca57ab6ce515ae7063b8081b630e.tar.bz2 |
Fixes a bug where we were inadvertently closing Valgrind-owned FDs
when running under Valgrind.
TEST=None
http://crbug.com/11412
Review URL: http://codereview.chromium.org/108042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15414 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process_util_posix.cc')
-rw-r--r-- | base/process_util_posix.cc | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc index e66576a..c293cbe 100644 --- a/base/process_util_posix.cc +++ b/base/process_util_posix.cc @@ -98,8 +98,29 @@ class ScopedDIRClose { typedef scoped_ptr_malloc<DIR, ScopedDIRClose> ScopedDIR; void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) { +#if defined(OS_LINUX) + static const rlim_t kSystemDefaultMaxFds = 8192; + static const char fd_dir[] = "/proc/self/fd"; +#elif defined(OS_MACOSX) + static const rlim_t kSystemDefaultMaxFds = 256; + static const char fd_dir[] = "/dev/fd"; +#endif std::set<int> saved_fds; + // Get the maximum number of FDs possible. + struct rlimit nofile; + rlim_t max_fds; + if (getrlimit(RLIMIT_NOFILE, &nofile)) { + // getrlimit failed. Take a best guess. + max_fds = kSystemDefaultMaxFds; + DLOG(ERROR) << "getrlimit(RLIMIT_NOFILE) failed: " << errno; + } else { + max_fds = nofile.rlim_cur; + } + + if (max_fds > INT_MAX) + max_fds = INT_MAX; + // Don't close stdin, stdout and stderr saved_fds.insert(STDIN_FILENO); saved_fds.insert(STDOUT_FILENO); @@ -110,32 +131,13 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) { 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; - // Fallback case - struct rlimit nofile; - rlim_t num_fds; - if (getrlimit(RLIMIT_NOFILE, &nofile)) { - // getrlimit failed. Take a best guess. - num_fds = 8192; - DLOG(ERROR) << "getrlimit(RLIMIT_NOFILE) failed: " << errno; - } else { - num_fds = nofile.rlim_cur; - } - - if (num_fds > INT_MAX) - num_fds = INT_MAX; - - for (rlim_t i = 0; i < num_fds; ++i) { + // Fallback case: Try every possible fd. + for (rlim_t i = 0; i < max_fds; ++i) { const int fd = static_cast<int>(i); if (saved_fds.find(fd) != saved_fds.end()) continue; @@ -154,12 +156,17 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) { 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) + if (ent->d_name[0] == 0 || *endptr || fd < 0 || errno) continue; if (saved_fds.find(fd) != saved_fds.end()) continue; - HANDLE_EINTR(close(fd)); + // When running under Valgrind, Valgrind opens several FDs for its + // own use and will complain if we try to close them. All of + // these FDs are >= |max_fds|, so we can check against that here + // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758 + if (fd < static_cast<int>(max_fds)) + HANDLE_EINTR(close(fd)); } } |