blob: 7db95140def6a92ba64fe1ceb44ff4f7f9ef9dba (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/file_descriptor_posix.h"
#include "base/logging.h"
DescriptorSet::DescriptorSet()
: next_descriptor_(0) {
}
DescriptorSet::~DescriptorSet() {
if (next_descriptor_ == descriptors_.size())
return;
LOG(WARNING) << "DescriptorSet destroyed with unconsumed descriptors";
// We close all the descriptors where the close flag is set. If this
// message should have been transmitted, then closing those with close
// flags set mirrors the expected behaviour.
//
// If this message was received with more descriptors than expected
// (which could a DOS against the browser by a rouge renderer) then all
// the descriptors have their close flag set and we free all the extra
// kernel resources.
for (unsigned i = next_descriptor_; i < descriptors_.size(); ++i) {
if (descriptors_[i].auto_close)
close(descriptors_[i].fd);
}
}
void DescriptorSet::Add(int fd) {
struct FileDescriptor sd;
sd.fd = fd;
sd.auto_close = false;
descriptors_.push_back(sd);
DCHECK(descriptors_.size() <= MAX_DESCRIPTORS_PER_MESSAGE);
}
void DescriptorSet::AddAndAutoClose(int fd) {
struct FileDescriptor sd;
sd.fd = fd;
sd.auto_close = true;
descriptors_.push_back(sd);
DCHECK(descriptors_.size() <= MAX_DESCRIPTORS_PER_MESSAGE);
}
int DescriptorSet::NextDescriptor() {
if (next_descriptor_ == descriptors_.size())
return -1;
return descriptors_[next_descriptor_++].fd;
}
void DescriptorSet::GetDescriptors(int* buffer) const {
for (std::vector<FileDescriptor>::const_iterator
i = descriptors_.begin(); i != descriptors_.end(); ++i) {
*(buffer++) = i->fd;
}
}
void DescriptorSet::CommitAll() {
for (std::vector<FileDescriptor>::iterator
i = descriptors_.begin(); i != descriptors_.end(); ++i) {
if (i->auto_close)
close(i->fd);
}
descriptors_.clear();
}
void DescriptorSet::SetDescriptors(const int* buffer, unsigned count) {
DCHECK(count <= MAX_DESCRIPTORS_PER_MESSAGE);
DCHECK(descriptors_.size() == 0);
descriptors_.reserve(count);
for (unsigned i = 0; i < count; ++i) {
struct FileDescriptor sd;
sd.fd = buffer[i];
sd.auto_close = true;
descriptors_.push_back(sd);
}
}
void DescriptorSet::TakeFrom(DescriptorSet* other) {
DCHECK(descriptors_.size() == 0);
descriptors_.swap(other->descriptors_);
next_descriptor_ = other->next_descriptor_;
other->next_descriptor_ = 0;
}
|