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 <fcntl.h> | 8 #include <fcntl.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
111 // the temporary files we create will just go into the buffer cache | 111 // the temporary files we create will just go into the buffer cache |
112 // and be deleted before they ever make it out to disk. | 112 // and be deleted before they ever make it out to disk. |
113 base::ThreadRestrictions::ScopedAllowIO allow_io; | 113 base::ThreadRestrictions::ScopedAllowIO allow_io; |
114 | 114 |
115 ScopedFILE fp; | 115 ScopedFILE fp; |
116 bool fix_size = true; | 116 bool fix_size = true; |
117 ScopedFD readonly_fd; | 117 ScopedFD readonly_fd; |
118 | 118 |
119 FilePath path; | 119 FilePath path; |
120 if (options.name_deprecated == NULL || options.name_deprecated->empty()) { | 120 if (options.name_deprecated == NULL || options.name_deprecated->empty()) { |
121 bool result = | 121 bool result = CreateAnonymousSharedMemory(options, &fp, &readonly_fd, &path, |
122 CreateAnonymousSharedMemory(options, &fp, &readonly_fd, &path); | 122 &last_error_); |
123 if (!result) | 123 if (!result) |
124 return false; | 124 return false; |
125 } else { | 125 } else { |
126 if (!FilePathForMemoryName(*options.name_deprecated, &path)) | 126 if (!FilePathForMemoryName(*options.name_deprecated, &path)) |
127 return false; | 127 return false; |
128 | 128 |
129 // Make sure that the file is opened without any permission | 129 // Make sure that the file is opened without any permission |
130 // to other users on the system. | 130 // to other users on the system. |
131 const mode_t kOwnerOnly = S_IRUSR | S_IWUSR; | 131 const mode_t kOwnerOnly = S_IRUSR | S_IWUSR; |
132 | 132 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 } | 179 } |
180 } | 180 } |
181 if (fd >= 0) { | 181 if (fd >= 0) { |
182 // "a+" is always appropriate: if it's a new file, a+ is similar to w+. | 182 // "a+" is always appropriate: if it's a new file, a+ is similar to w+. |
183 fp.reset(fdopen(fd, "a+")); | 183 fp.reset(fdopen(fd, "a+")); |
184 } | 184 } |
185 } | 185 } |
186 if (fp && fix_size) { | 186 if (fp && fix_size) { |
187 // Get current size. | 187 // Get current size. |
188 struct stat stat; | 188 struct stat stat; |
189 if (fstat(fileno(fp.get()), &stat) != 0) | 189 if (fstat(fileno(fp.get()), &stat) != 0) |
erikchen
2017/05/10 17:42:11
shouldn't every "return false" be prefixed with la
Alexei Svitkine (slow)
2017/05/10 17:46:22
This is in shared_memory_posix.cc code which Mac d
| |
190 return false; | 190 return false; |
191 const size_t current_size = stat.st_size; | 191 const size_t current_size = stat.st_size; |
192 if (current_size != options.size) { | 192 if (current_size != options.size) { |
193 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) | 193 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) |
194 return false; | 194 return false; |
195 } | 195 } |
196 requested_size_ = options.size; | 196 requested_size_ = options.size; |
197 } | 197 } |
198 if (fp == NULL) { | 198 if (fp == NULL) { |
199 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; | 199 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; |
200 FilePath dir = path.DirName(); | 200 FilePath dir = path.DirName(); |
201 if (access(dir.value().c_str(), W_OK | X_OK) < 0) { | 201 if (access(dir.value().c_str(), W_OK | X_OK) < 0) { |
202 PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value(); | 202 PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value(); |
203 if (dir.value() == "/dev/shm") { | 203 if (dir.value() == "/dev/shm") { |
204 LOG(FATAL) << "This is frequently caused by incorrect permissions on " | 204 LOG(FATAL) << "This is frequently caused by incorrect permissions on " |
205 << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix."; | 205 << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix."; |
206 } | 206 } |
207 } | 207 } |
208 return false; | 208 return false; |
209 } | 209 } |
210 | 210 |
211 int mapped_file = -1; | 211 int mapped_file = -1; |
212 int readonly_mapped_file = -1; | 212 int readonly_mapped_file = -1; |
213 bool result = PrepareMapFile(std::move(fp), std::move(readonly_fd), | 213 bool result = |
214 &mapped_file, &readonly_mapped_file); | 214 PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, |
215 &readonly_mapped_file, &last_error_); | |
215 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), | 216 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), |
216 UnguessableToken::Create()); | 217 UnguessableToken::Create()); |
217 readonly_shm_ = SharedMemoryHandle( | 218 readonly_shm_ = SharedMemoryHandle( |
218 base::FileDescriptor(readonly_mapped_file, false), shm_.GetGUID()); | 219 base::FileDescriptor(readonly_mapped_file, false), shm_.GetGUID()); |
219 return result; | 220 return result; |
220 } | 221 } |
221 | 222 |
222 // Our current implementation of shmem is with mmap()ing of files. | 223 // Our current implementation of shmem is with mmap()ing of files. |
223 // These files need to be deleted explicitly. | 224 // These files need to be deleted explicitly. |
224 // In practice this call is only needed for unit tests. | 225 // In practice this call is only needed for unit tests. |
(...skipping 18 matching lines...) Expand all Loading... | |
243 | 244 |
244 const char *mode = read_only ? "r" : "r+"; | 245 const char *mode = read_only ? "r" : "r+"; |
245 ScopedFILE fp(base::OpenFile(path, mode)); | 246 ScopedFILE fp(base::OpenFile(path, mode)); |
246 ScopedFD readonly_fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); | 247 ScopedFD readonly_fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); |
247 if (!readonly_fd.is_valid()) { | 248 if (!readonly_fd.is_valid()) { |
248 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed"; | 249 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed"; |
249 return false; | 250 return false; |
250 } | 251 } |
251 int mapped_file = -1; | 252 int mapped_file = -1; |
252 int readonly_mapped_file = -1; | 253 int readonly_mapped_file = -1; |
253 bool result = PrepareMapFile(std::move(fp), std::move(readonly_fd), | 254 bool result = |
254 &mapped_file, &readonly_mapped_file); | 255 PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, |
256 &readonly_mapped_file, &last_error_); | |
255 // This form of sharing shared memory is deprecated. https://crbug.com/345734. | 257 // This form of sharing shared memory is deprecated. https://crbug.com/345734. |
256 // However, we can't get rid of it without a significant refactor because its | 258 // However, we can't get rid of it without a significant refactor because its |
257 // used to communicate between two versions of the same service process, very | 259 // used to communicate between two versions of the same service process, very |
258 // early in the life cycle. | 260 // early in the life cycle. |
259 // Technically, we should also pass the GUID from the original shared memory | 261 // Technically, we should also pass the GUID from the original shared memory |
260 // region. We don't do that - this means that we will overcount this memory, | 262 // region. We don't do that - this means that we will overcount this memory, |
261 // which thankfully isn't relevant since Chrome only communicates with a | 263 // which thankfully isn't relevant since Chrome only communicates with a |
262 // single version of the service process. | 264 // single version of the service process. |
263 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), | 265 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), |
264 UnguessableToken::Create()); | 266 UnguessableToken::Create()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 struct stat file_stat; | 387 struct stat file_stat; |
386 if (HANDLE_EINTR( | 388 if (HANDLE_EINTR( |
387 ::fstat(static_cast<int>(handle().GetHandle()), &file_stat)) != 0) | 389 ::fstat(static_cast<int>(handle().GetHandle()), &file_stat)) != 0) |
388 return false; | 390 return false; |
389 id->first = file_stat.st_dev; | 391 id->first = file_stat.st_dev; |
390 id->second = file_stat.st_ino; | 392 id->second = file_stat.st_ino; |
391 return true; | 393 return true; |
392 } | 394 } |
393 | 395 |
394 } // namespace base | 396 } // namespace base |
OLD | NEW |