Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/memory/shared_memory_helper.h" | |
| 6 | |
| 7 #include "base/threading/thread_restrictions.h" | |
| 8 | |
| 9 namespace base { | |
| 10 | |
| 11 struct ScopedPathUnlinkerTraits { | |
| 12 static const FilePath* InvalidValue() { return nullptr; } | |
| 13 | |
| 14 static void Free(const FilePath* path) { | |
| 15 if (unlink(path->value().c_str())) | |
| 16 PLOG(WARNING) << "unlink"; | |
| 17 } | |
| 18 }; | |
| 19 | |
| 20 // Unlinks the FilePath when the object is destroyed. | |
| 21 using ScopedPathUnlinker = | |
| 22 ScopedGeneric<const FilePath*, ScopedPathUnlinkerTraits>; | |
| 23 | |
| 24 #if !defined(OS_ANDROID) | |
| 25 bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options, | |
| 26 ScopedFILE* fp, | |
| 27 ScopedFD* readonly_fd, | |
| 28 FilePath* path) { | |
| 29 #if !(defined(OS_MACOSX) && !defined(OS_IOS)) | |
| 30 // It doesn't make sense to have a open-existing private piece of shmem | |
| 31 DCHECK(!options.open_existing_deprecated); | |
| 32 #endif // !(defined(OS_MACOSX) && !defined(OS_IOS) | |
| 33 // Q: Why not use the shm_open() etc. APIs? | |
| 34 // A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU | |
| 35 FilePath directory; | |
| 36 ScopedPathUnlinker path_unlinker; | |
| 37 if (!GetShmemTempDir(options.executable, &directory)) | |
| 38 return false; | |
| 39 | |
| 40 fp->reset(base::CreateAndOpenTemporaryFileInDir(directory, path)); | |
| 41 | |
| 42 if (!*fp) | |
| 43 return false; | |
| 44 | |
| 45 // Deleting the file prevents anyone else from mapping it in (making it | |
| 46 // private), and prevents the need for cleanup (once the last fd is | |
| 47 // closed, it is truly freed). | |
| 48 path_unlinker.reset(path); | |
| 49 | |
| 50 if (options.share_read_only) { | |
| 51 // Also open as readonly so that we can ShareReadOnlyToProcess. | |
| 52 readonly_fd->reset(HANDLE_EINTR(open(path->value().c_str(), O_RDONLY))); | |
| 53 if (!readonly_fd->is_valid()) { | |
| 54 DPLOG(ERROR) << "open(\"" << path->value() << "\", O_RDONLY) failed"; | |
| 55 fp->reset(); | |
| 56 return false; | |
| 57 } | |
| 58 } | |
| 59 return true; | |
| 60 } | |
| 61 | |
| 62 bool PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd, int* mapped_file, | |
| 63 int* readonly_mapped_file) { | |
| 64 DCHECK_EQ(-1, *mapped_file); | |
| 65 DCHECK_EQ(-1, *readonly_mapped_file); | |
| 66 if (fp == NULL) | |
| 67 return false; | |
| 68 | |
| 69 // This function theoretically can block on the disk, but realistically | |
| 70 // the temporary files we create will just go into the buffer cache | |
| 71 // and be deleted before they ever make it out to disk. | |
| 72 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 73 | |
| 74 if (readonly_fd.is_valid()) { | |
| 75 struct stat st = {}; | |
|
Nico
2017/05/12 15:11:52
This file is posix-only; why was it not named shar
Alexei Svitkine (slow)
2017/05/12 15:22:15
Renaming SGTM. (Lawrence was an intern so someone
| |
| 76 if (fstat(fileno(fp.get()), &st)) | |
| 77 NOTREACHED(); | |
| 78 | |
| 79 struct stat readonly_st = {}; | |
| 80 if (fstat(readonly_fd.get(), &readonly_st)) | |
| 81 NOTREACHED(); | |
| 82 if (st.st_dev != readonly_st.st_dev || st.st_ino != readonly_st.st_ino) { | |
| 83 LOG(ERROR) << "writable and read-only inodes don't match; bailing"; | |
| 84 return false; | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 *mapped_file = HANDLE_EINTR(dup(fileno(fp.get()))); | |
| 89 if (*mapped_file == -1) { | |
| 90 NOTREACHED() << "Call to dup failed, errno=" << errno; | |
| 91 } | |
| 92 *readonly_mapped_file = readonly_fd.release(); | |
| 93 | |
| 94 return true; | |
| 95 } | |
| 96 #endif // !defined(OS_ANDROID) | |
| 97 | |
| 98 } // namespace base | |
| OLD | NEW |