OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/memory/shared_memory.h" | 5 #include "base/memory/shared_memory.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <mach/mach_vm.h> | 8 #include <mach/mach_vm.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 | 76 |
77 *new_handle = SharedMemoryHandle(named_right, size, base::GetCurrentProcId()); | 77 *new_handle = SharedMemoryHandle(named_right, size, base::GetCurrentProcId()); |
78 return true; | 78 return true; |
79 } | 79 } |
80 | 80 |
81 | 81 |
82 } // namespace | 82 } // namespace |
83 | 83 |
84 SharedMemory::SharedMemory() | 84 SharedMemory::SharedMemory() |
85 : mapped_memory_mechanism_(SharedMemoryHandle::MACH), | 85 : mapped_memory_mechanism_(SharedMemoryHandle::MACH), |
86 readonly_mapped_file_(-1), | |
87 mapped_size_(0), | 86 mapped_size_(0), |
88 memory_(NULL), | 87 memory_(NULL), |
89 read_only_(false), | 88 read_only_(false), |
90 requested_size_(0) {} | 89 requested_size_(0) {} |
91 | 90 |
92 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) | 91 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) |
93 : shm_(handle), | 92 : shm_(handle), |
94 mapped_memory_mechanism_(SharedMemoryHandle::POSIX), | 93 mapped_memory_mechanism_(SharedMemoryHandle::POSIX), |
95 readonly_mapped_file_(-1), | |
96 mapped_size_(0), | 94 mapped_size_(0), |
97 memory_(NULL), | 95 memory_(NULL), |
98 read_only_(read_only), | 96 read_only_(read_only), |
99 requested_size_(0) {} | 97 requested_size_(0) {} |
100 | 98 |
101 SharedMemory::~SharedMemory() { | 99 SharedMemory::~SharedMemory() { |
102 Unmap(); | 100 Unmap(); |
103 Close(); | 101 Close(); |
104 } | 102 } |
105 | 103 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 if (fstat(fileno(fp.get()), &stat) != 0) | 177 if (fstat(fileno(fp.get()), &stat) != 0) |
180 return false; | 178 return false; |
181 const size_t current_size = stat.st_size; | 179 const size_t current_size = stat.st_size; |
182 if (current_size != options.size) { | 180 if (current_size != options.size) { |
183 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) | 181 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) |
184 return false; | 182 return false; |
185 } | 183 } |
186 requested_size_ = options.size; | 184 requested_size_ = options.size; |
187 | 185 |
188 int mapped_file = -1; | 186 int mapped_file = -1; |
| 187 int readonly_mapped_file = -1; |
189 result = PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, | 188 result = PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, |
190 &readonly_mapped_file_); | 189 &readonly_mapped_file); |
191 | |
192 shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false)); | 190 shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false)); |
| 191 readonly_shm_ = |
| 192 SharedMemoryHandle(FileDescriptor(readonly_mapped_file, false)); |
193 return result; | 193 return result; |
194 } | 194 } |
195 | 195 |
196 bool SharedMemory::MapAt(off_t offset, size_t bytes) { | 196 bool SharedMemory::MapAt(off_t offset, size_t bytes) { |
197 if (!shm_.IsValid()) | 197 if (!shm_.IsValid()) |
198 return false; | 198 return false; |
199 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) | 199 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) |
200 return false; | 200 return false; |
201 if (memory_) | 201 if (memory_) |
202 return false; | 202 return false; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 SharedMemoryHandle SharedMemory::TakeHandle() { | 247 SharedMemoryHandle SharedMemory::TakeHandle() { |
248 SharedMemoryHandle dup = DuplicateHandle(handle()); | 248 SharedMemoryHandle dup = DuplicateHandle(handle()); |
249 Close(); | 249 Close(); |
250 return dup; | 250 return dup; |
251 } | 251 } |
252 | 252 |
253 void SharedMemory::Close() { | 253 void SharedMemory::Close() { |
254 shm_.Close(); | 254 shm_.Close(); |
255 shm_ = SharedMemoryHandle(); | 255 shm_ = SharedMemoryHandle(); |
256 if (shm_.type_ == SharedMemoryHandle::POSIX) { | 256 if (shm_.type_ == SharedMemoryHandle::POSIX) { |
257 if (readonly_mapped_file_ > 0) { | 257 if (readonly_shm_.IsValid()) { |
258 if (IGNORE_EINTR(close(readonly_mapped_file_)) < 0) | 258 readonly_shm_.Close(); |
259 PLOG(ERROR) << "close"; | 259 readonly_shm_ = SharedMemoryHandle(); |
260 readonly_mapped_file_ = -1; | |
261 } | 260 } |
262 } | 261 } |
263 } | 262 } |
264 | 263 |
265 bool SharedMemory::Share(SharedMemoryHandle* new_handle, ShareMode share_mode) { | 264 SharedMemoryHandle SharedMemory::GetReadOnlyHandle() { |
266 if (shm_.type_ == SharedMemoryHandle::MACH) { | 265 if (shm_.type_ == SharedMemoryHandle::POSIX) { |
267 DCHECK(shm_.IsValid()); | 266 // We could imagine re-opening the file from /dev/fd, but that can't make it |
268 | 267 // readonly on Mac: https://codereview.chromium.org/27265002/#msg10. |
269 bool success = false; | 268 CHECK(readonly_shm_.IsValid()); |
270 switch (share_mode) { | 269 return readonly_shm_.Duplicate(); |
271 case SHARE_CURRENT_MODE: | |
272 *new_handle = shm_.Duplicate(); | |
273 success = true; | |
274 break; | |
275 case SHARE_READONLY: | |
276 success = MakeMachSharedMemoryHandleReadOnly(new_handle, shm_, memory_); | |
277 break; | |
278 } | |
279 | |
280 if (success) | |
281 new_handle->SetOwnershipPassesToIPC(true); | |
282 | |
283 return success; | |
284 } | 270 } |
285 | 271 |
286 int handle_to_dup = -1; | 272 DCHECK(shm_.IsValid()); |
287 switch (share_mode) { | 273 base::SharedMemoryHandle new_handle; |
288 case SHARE_CURRENT_MODE: | 274 bool success = MakeMachSharedMemoryHandleReadOnly(&new_handle, shm_, memory_); |
289 handle_to_dup = shm_.file_descriptor_.fd; | 275 if (success) |
290 break; | 276 new_handle.SetOwnershipPassesToIPC(true); |
291 case SHARE_READONLY: | 277 return new_handle; |
292 // We could imagine re-opening the file from /dev/fd, but that can't make | 278 } |
293 // it readonly on Mac: https://codereview.chromium.org/27265002/#msg10 | |
294 CHECK_GE(readonly_mapped_file_, 0); | |
295 handle_to_dup = readonly_mapped_file_; | |
296 break; | |
297 } | |
298 | 279 |
299 const int new_fd = HANDLE_EINTR(dup(handle_to_dup)); | 280 bool SharedMemory::Share(SharedMemoryHandle* new_handle) { |
300 if (new_fd < 0) { | 281 DCHECK(shm_.IsValid()); |
301 DPLOG(ERROR) << "dup() failed."; | 282 *new_handle = shm_.Duplicate(); |
302 return false; | 283 return new_handle->IsValid(); |
303 } | |
304 | |
305 new_handle->file_descriptor_.fd = new_fd; | |
306 new_handle->type_ = SharedMemoryHandle::POSIX; | |
307 | |
308 return true; | |
309 } | 284 } |
310 | 285 |
311 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, | 286 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, |
312 SharedMemoryHandle* new_handle, | 287 SharedMemoryHandle* new_handle, |
313 bool close_self, | 288 bool close_self) { |
314 ShareMode share_mode) { | 289 bool success = Share(new_handle); |
315 bool success = Share(new_handle, share_mode); | |
316 if (close_self) { | 290 if (close_self) { |
317 Unmap(); | 291 Unmap(); |
318 Close(); | 292 Close(); |
319 } | 293 } |
320 return success; | 294 return success; |
321 } | 295 } |
322 | 296 |
323 } // namespace base | 297 } // namespace base |
OLD | NEW |