OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ipc/ipc_message_attachment_set.h" | 5 #include "ipc/ipc_message_attachment_set.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/posix/eintr_wrapper.h" | 9 #include "base/posix/eintr_wrapper.h" |
10 #include "ipc/ipc_message_attachment.h" | 10 #include "ipc/ipc_message_attachment.h" |
11 #include "ipc/ipc_platform_file_attachment.h" | |
12 | 11 |
13 #if defined(OS_POSIX) | 12 #if defined(OS_POSIX) |
14 #include <sys/types.h> | 13 #include <sys/types.h> |
15 #include <sys/stat.h> | 14 #include <sys/stat.h> |
16 #include <unistd.h> | 15 #include <unistd.h> |
| 16 #include "ipc/ipc_platform_file_attachment_posix.h" |
17 #endif // OS_POSIX | 17 #endif // OS_POSIX |
18 | 18 |
19 namespace IPC { | 19 namespace IPC { |
20 | 20 |
21 MessageAttachmentSet::MessageAttachmentSet() | 21 MessageAttachmentSet::MessageAttachmentSet() |
22 : consumed_descriptor_highwater_(0) { | 22 : consumed_descriptor_highwater_(0) { |
23 } | 23 } |
24 | 24 |
25 MessageAttachmentSet::~MessageAttachmentSet() { | 25 MessageAttachmentSet::~MessageAttachmentSet() { |
26 if (consumed_descriptor_highwater_ == size()) | 26 if (consumed_descriptor_highwater_ == size()) |
(...skipping 15 matching lines...) Expand all Loading... |
42 return std::count_if(attachments_.begin(), attachments_.end(), | 42 return std::count_if(attachments_.begin(), attachments_.end(), |
43 [](scoped_refptr<MessageAttachment> i) { | 43 [](scoped_refptr<MessageAttachment> i) { |
44 return i->GetType() == MessageAttachment::TYPE_PLATFORM_FILE; | 44 return i->GetType() == MessageAttachment::TYPE_PLATFORM_FILE; |
45 }); | 45 }); |
46 } | 46 } |
47 | 47 |
48 unsigned MessageAttachmentSet::size() const { | 48 unsigned MessageAttachmentSet::size() const { |
49 return static_cast<unsigned>(attachments_.size()); | 49 return static_cast<unsigned>(attachments_.size()); |
50 } | 50 } |
51 | 51 |
52 void MessageAttachmentSet::AddAttachment( | 52 bool MessageAttachmentSet::AddAttachment( |
53 scoped_refptr<MessageAttachment> attachment) { | 53 scoped_refptr<MessageAttachment> attachment) { |
| 54 #if defined(OS_POSIX) |
| 55 if (attachment->GetType() != MessageAttachment::TYPE_PLATFORM_FILE || |
| 56 num_descriptors() == kMaxDescriptorsPerMessage) { |
| 57 DLOG(WARNING) << "Cannot add file descriptor. MessageAttachmentSet full."; |
| 58 return false; |
| 59 } |
| 60 #endif |
| 61 |
54 attachments_.push_back(attachment); | 62 attachments_.push_back(attachment); |
| 63 return true; |
55 } | 64 } |
56 | 65 |
57 scoped_refptr<MessageAttachment> MessageAttachmentSet::GetAttachmentAt( | 66 scoped_refptr<MessageAttachment> MessageAttachmentSet::GetAttachmentAt( |
58 unsigned index) { | 67 unsigned index) { |
59 if (index >= size()) { | 68 if (index >= size()) { |
60 DLOG(WARNING) << "Accessing out of bound index:" << index << "/" << size(); | 69 DLOG(WARNING) << "Accessing out of bound index:" << index << "/" << size(); |
61 return scoped_refptr<MessageAttachment>(); | 70 return scoped_refptr<MessageAttachment>(); |
62 } | 71 } |
63 | 72 |
64 // We should always walk the descriptors in order, so it's reasonable to | 73 // We should always walk the descriptors in order, so it's reasonable to |
(...skipping 23 matching lines...) Expand all Loading... |
88 if (index != consumed_descriptor_highwater_) | 97 if (index != consumed_descriptor_highwater_) |
89 return scoped_refptr<MessageAttachment>(); | 98 return scoped_refptr<MessageAttachment>(); |
90 | 99 |
91 consumed_descriptor_highwater_ = index + 1; | 100 consumed_descriptor_highwater_ = index + 1; |
92 | 101 |
93 return attachments_[index]; | 102 return attachments_[index]; |
94 } | 103 } |
95 | 104 |
96 #if defined(OS_POSIX) | 105 #if defined(OS_POSIX) |
97 | 106 |
98 bool MessageAttachmentSet::AddToBorrow(base::PlatformFile fd) { | |
99 DCHECK_EQ(consumed_descriptor_highwater_, 0u); | |
100 | |
101 if (num_descriptors() == kMaxDescriptorsPerMessage) { | |
102 DLOG(WARNING) << "Cannot add file descriptor. MessageAttachmentSet full."; | |
103 return false; | |
104 } | |
105 | |
106 AddAttachment(new internal::PlatformFileAttachment(fd)); | |
107 return true; | |
108 } | |
109 | |
110 bool MessageAttachmentSet::AddToOwn(base::ScopedFD fd) { | |
111 DCHECK_EQ(consumed_descriptor_highwater_, 0u); | |
112 | |
113 if (num_descriptors() == kMaxDescriptorsPerMessage) { | |
114 DLOG(WARNING) << "Cannot add file descriptor. MessageAttachmentSet full."; | |
115 return false; | |
116 } | |
117 | |
118 AddAttachment(new internal::PlatformFileAttachment(fd.get())); | |
119 owned_descriptors_.push_back(new base::ScopedFD(fd.Pass())); | |
120 DCHECK(num_descriptors() <= kMaxDescriptorsPerMessage); | |
121 return true; | |
122 } | |
123 | |
124 base::PlatformFile MessageAttachmentSet::TakeDescriptorAt(unsigned index) { | |
125 scoped_refptr<MessageAttachment> attachment = GetAttachmentAt(index); | |
126 if (!attachment) | |
127 return -1; | |
128 | |
129 base::PlatformFile file = internal::GetPlatformFile(attachment); | |
130 | |
131 // TODO(morrita): In production, attachments_.size() should be same as | |
132 // owned_descriptors_.size() as all read descriptors are owned by Message. | |
133 // We have to do this because unit test breaks this assumption. It should be | |
134 // changed to exercise with own-able descriptors. | |
135 for (ScopedVector<base::ScopedFD>::const_iterator i = | |
136 owned_descriptors_.begin(); | |
137 i != owned_descriptors_.end(); ++i) { | |
138 if ((*i)->get() == file) { | |
139 ignore_result((*i)->release()); | |
140 break; | |
141 } | |
142 } | |
143 | |
144 return file; | |
145 } | |
146 | |
147 void MessageAttachmentSet::PeekDescriptors(base::PlatformFile* buffer) const { | 107 void MessageAttachmentSet::PeekDescriptors(base::PlatformFile* buffer) const { |
148 for (size_t i = 0; i != attachments_.size(); ++i) | 108 for (size_t i = 0; i != attachments_.size(); ++i) |
149 buffer[i] = internal::GetPlatformFile(attachments_[i]); | 109 buffer[i] = internal::GetPlatformFile(attachments_[i]); |
150 } | 110 } |
151 | 111 |
152 bool MessageAttachmentSet::ContainsDirectoryDescriptor() const { | 112 bool MessageAttachmentSet::ContainsDirectoryDescriptor() const { |
153 struct stat st; | 113 struct stat st; |
154 | 114 |
155 for (auto i = attachments_.begin(); i != attachments_.end(); ++i) { | 115 for (auto i = attachments_.begin(); i != attachments_.end(); ++i) { |
156 if (fstat(internal::GetPlatformFile(*i), &st) == 0 && S_ISDIR(st.st_mode)) | 116 if (fstat(internal::GetPlatformFile(*i), &st) == 0 && S_ISDIR(st.st_mode)) |
157 return true; | 117 return true; |
158 } | 118 } |
159 | 119 |
160 return false; | 120 return false; |
161 } | 121 } |
162 | 122 |
163 void MessageAttachmentSet::CommitAll() { | 123 void MessageAttachmentSet::CommitAll() { |
164 attachments_.clear(); | 124 attachments_.clear(); |
165 owned_descriptors_.clear(); | |
166 consumed_descriptor_highwater_ = 0; | 125 consumed_descriptor_highwater_ = 0; |
167 } | 126 } |
168 | 127 |
169 void MessageAttachmentSet::ReleaseFDsToClose( | 128 void MessageAttachmentSet::ReleaseFDsToClose( |
170 std::vector<base::PlatformFile>* fds) { | 129 std::vector<base::PlatformFile>* fds) { |
171 for (ScopedVector<base::ScopedFD>::iterator i = owned_descriptors_.begin(); | 130 for (size_t i = 0; i < attachments_.size(); ++i) { |
172 i != owned_descriptors_.end(); ++i) { | 131 internal::PlatformFileAttachment* file = |
173 fds->push_back((*i)->release()); | 132 static_cast<internal::PlatformFileAttachment*>(attachments_[i].get()); |
| 133 if (file->Owns()) |
| 134 fds->push_back(file->TakePlatformFile()); |
174 } | 135 } |
175 | 136 |
176 CommitAll(); | 137 CommitAll(); |
177 } | 138 } |
178 | 139 |
179 void MessageAttachmentSet::AddDescriptorsToOwn(const base::PlatformFile* buffer, | 140 void MessageAttachmentSet::AddDescriptorsToOwn(const base::PlatformFile* buffer, |
180 unsigned count) { | 141 unsigned count) { |
181 DCHECK(count <= kMaxDescriptorsPerMessage); | 142 DCHECK(count <= kMaxDescriptorsPerMessage); |
182 DCHECK_EQ(num_descriptors(), 0u); | 143 DCHECK_EQ(num_descriptors(), 0u); |
183 DCHECK_EQ(consumed_descriptor_highwater_, 0u); | 144 DCHECK_EQ(consumed_descriptor_highwater_, 0u); |
184 | 145 |
185 attachments_.reserve(count); | 146 attachments_.reserve(count); |
186 owned_descriptors_.reserve(count); | 147 for (unsigned i = 0; i < count; ++i) |
187 for (unsigned i = 0; i < count; ++i) { | 148 AddAttachment( |
188 AddAttachment(new internal::PlatformFileAttachment(buffer[i])); | 149 new internal::PlatformFileAttachment(base::ScopedFD(buffer[i]))); |
189 owned_descriptors_.push_back(new base::ScopedFD(buffer[i])); | |
190 } | |
191 } | 150 } |
192 | 151 |
193 #endif // OS_POSIX | 152 #endif // OS_POSIX |
194 | 153 |
195 } // namespace IPC | 154 } // namespace IPC |
196 | 155 |
197 | 156 |
OLD | NEW |