| 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);
|
| }
|
|
|