| Index: base/file_descriptor_shuffle.cc
|
| diff --git a/base/file_descriptor_shuffle.cc b/base/file_descriptor_shuffle.cc
|
| index e722a29e89fc5f3f0b646fbbef4188550ae68c51..2bb156bf3c7d5005cd55242744f6e5e0d5f0e38e 100644
|
| --- a/base/file_descriptor_shuffle.cc
|
| +++ b/base/file_descriptor_shuffle.cc
|
| @@ -12,28 +12,36 @@
|
|
|
| namespace base {
|
|
|
| -bool PerformInjectiveMultimap(const InjectiveMultimap& m_in,
|
| - InjectionDelegate* delegate) {
|
| - InjectiveMultimap m(m_in);
|
| - std::vector<int> extra_fds;
|
| +bool PerformInjectiveMultimapDestructive(
|
| + InjectiveMultimap* m, InjectionDelegate* delegate) {
|
| + static const size_t kMaxExtraFDs = 16;
|
| + int extra_fds[kMaxExtraFDs];
|
| + unsigned next_extra_fd = 0;
|
|
|
| - for (InjectiveMultimap::iterator i = m.begin(); i != m.end(); ++i) {
|
| + // DANGER: this function may not allocate.
|
| +
|
| + for (InjectiveMultimap::iterator i = m->begin(); i != m->end(); ++i) {
|
| int temp_fd = -1;
|
|
|
| // We DCHECK the injectiveness of the mapping.
|
| - for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j) {
|
| + for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) {
|
| DCHECK(i->dest != j->dest) << "Both fd " << i->source
|
| << " and " << j->source << " map to " << i->dest;
|
| }
|
|
|
| const bool is_identity = i->source == i->dest;
|
|
|
| - for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j) {
|
| + for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) {
|
| if (!is_identity && i->dest == j->source) {
|
| if (temp_fd == -1) {
|
| if (!delegate->Duplicate(&temp_fd, i->dest))
|
| return false;
|
| - extra_fds.push_back(temp_fd);
|
| + if (next_extra_fd < kMaxExtraFDs) {
|
| + extra_fds[next_extra_fd++] = temp_fd;
|
| + } else {
|
| + RAW_LOG(ERROR, "PerformInjectiveMultimapDestructive overflowed "
|
| + "extra_fds. Leaking file descriptors!");
|
| + }
|
| }
|
|
|
| j->source = temp_fd;
|
| @@ -58,14 +66,18 @@ bool PerformInjectiveMultimap(const InjectiveMultimap& m_in,
|
| delegate->Close(i->source);
|
| }
|
|
|
| - for (std::vector<int>::const_iterator
|
| - i = extra_fds.begin(); i != extra_fds.end(); ++i) {
|
| - delegate->Close(*i);
|
| - }
|
| + for (unsigned i = 0; i < next_extra_fd; i++)
|
| + delegate->Close(extra_fds[i]);
|
|
|
| return true;
|
| }
|
|
|
| +bool PerformInjectiveMultimap(const InjectiveMultimap& m_in,
|
| + InjectionDelegate* delegate) {
|
| + InjectiveMultimap m(m_in);
|
| + return PerformInjectiveMultimapDestructive(&m, delegate);
|
| +}
|
| +
|
| bool FileDescriptorTableInjection::Duplicate(int* result, int fd) {
|
| *result = HANDLE_EINTR(dup(fd));
|
| return *result >= 0;
|
|
|