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 |