Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Unified Diff: base/memory/shared_memory_posix.cc

Issue 27265002: Implement SharedMemory::NewAnonymousReadOnly(contents). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix signedness on Mac Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/memory/shared_memory_posix.cc
diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
index efb0caf5bc9a29d805700c3abdad18ad6671a199..ee87f8b7863b8d8262c3d8ed13e0f664c90ff2ee 100644
--- a/base/memory/shared_memory_posix.cc
+++ b/base/memory/shared_memory_posix.cc
@@ -101,6 +101,55 @@ size_t SharedMemory::GetHandleLimit() {
return base::GetMaxFds();
}
+// static
+scoped_ptr<SharedMemory> SharedMemory::NewAnonymousReadOnly(
+ StringPiece contents) {
+ // This function theoretically can block on the disk, but realistically
+ // the temporary files we create will just go into the buffer cache
+ // and be deleted before they ever make it out to disk.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+ FilePath path;
+ file_util::ScopedFILE writable_fp(
+ file_util::CreateAndOpenTemporaryShmemFile(&path, /*executable=*/false));
+ if (!writable_fp) {
+ LOG(ERROR) << "Failed to create temp shmem file.";
+ return scoped_ptr<SharedMemory>();
+ }
+
+ int readonly_fd = HANDLE_EINTR(open(path.value().c_str(), O_RDONLY));
+ if (readonly_fd < 0) {
+ PLOG(ERROR) << "Failed to reopen temp shmem file readonly.";
+ return scoped_ptr<SharedMemory>();
+ }
+ file_util::ScopedFD readonly_fd_closer(&readonly_fd);
+
+ if (unlink(path.value().c_str()))
+ PLOG(WARNING) << "unlink";
+
+ if (fwrite(contents.data(), 1, contents.size(), writable_fp.get()) !=
+ contents.size()) {
+ LOG(ERROR) << "Failed to write " << contents.size()
+ << " bytes to memory block.";
+ return scoped_ptr<SharedMemory>();
+ }
+
+ if (fclose(writable_fp.release()) != 0) {
+ PLOG(ERROR) << "Failed to flush contents of memory block.";
+ return scoped_ptr<SharedMemory>();
+ }
+
+ // Protect against people accidentally reopening as read/write. It's still
+ // possible to intentionally fchmod() the FD back and then open it from /dev,
+ // but the renderer can't open from a filesystem path.
+ if (0 != fchmod(readonly_fd, S_IRUSR))
+ PLOG(DFATAL) << "Failed to make FD " << readonly_fd << " read-only";
+
+ return make_scoped_ptr(new SharedMemory(
+ FileDescriptor(*readonly_fd_closer.release(), /*iauto_close=*/false),
+ /*read_only=*/true));
+}
+
bool SharedMemory::CreateAndMapAnonymous(size_t size) {
return CreateAnonymous(size) && Map(size);
}

Powered by Google App Engine
This is Rietveld 408576698