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

Side by Side Diff: ppapi/native_client/src/trusted/plugin/local_temp_file.cc

Issue 10377157: Refactor Pnacl coordinator (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sehr comments Created 8 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "native_client/src/trusted/plugin/local_temp_file.h"
6
7 #include "native_client/src/include/portability_io.h"
8 #include "native_client/src/shared/platform/nacl_check.h"
9 #include "native_client/src/trusted/plugin/plugin.h"
10 #include "native_client/src/trusted/plugin/utility.h"
11
12 #include "ppapi/c/ppb_file_io.h"
13 #include "ppapi/cpp/file_io.h"
14 #include "ppapi/cpp/file_ref.h"
15 #include "ppapi/cpp/file_system.h"
16
17 //////////////////////////////////////////////////////////////////////
18 // Local temporary file access.
19 //////////////////////////////////////////////////////////////////////
20 namespace plugin {
21
22 namespace {
23 nacl::string Random32CharHexString(struct NaClDescRng* rng) {
24 struct NaClDesc* desc = reinterpret_cast<struct NaClDesc*>(rng);
25 const struct NaClDescVtbl* vtbl =
26 reinterpret_cast<const struct NaClDescVtbl*>(desc->base.vtbl);
27
28 nacl::string hex_string;
29 const int32_t kTempFileNameWords = 4;
30 for (int32_t i = 0; i < kTempFileNameWords; ++i) {
31 int32_t num;
32 CHECK(sizeof num == vtbl->Read(desc,
33 reinterpret_cast<char*>(&num),
34 sizeof num));
35 char frag[16];
36 SNPRINTF(frag, sizeof frag, "%08x", num);
37 hex_string += nacl::string(frag);
38 }
39 return hex_string;
40 }
41
42 // Some constants for LocalTempFile::GetFD readability.
43 const bool kReadOnly = false;
44 const bool kWriteable = true;
45 } // namespace
46
47 uint32_t LocalTempFile::next_identifier = 0;
48
49 LocalTempFile::LocalTempFile(Plugin* plugin,
50 pp::FileSystem* file_system,
51 const nacl::string &base_dir)
52 : plugin_(plugin),
53 file_system_(file_system),
54 base_dir_(base_dir) {
55 PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, "
56 "file_system=%p)\n",
57 static_cast<void*>(plugin), static_cast<void*>(file_system)));
58 Initialize();
59 }
60
61 LocalTempFile::LocalTempFile(Plugin* plugin,
62 pp::FileSystem* file_system,
63 const nacl::string &base_dir,
64 const nacl::string &filename)
65 : plugin_(plugin),
66 file_system_(file_system),
67 base_dir_(base_dir),
68 filename_(base_dir + "/" + filename) {
69 PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, "
70 "file_system=%p, filename=%s)\n",
71 static_cast<void*>(plugin), static_cast<void*>(file_system),
72 filename.c_str()));
73 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
74 Initialize();
75 }
76
77 void LocalTempFile::Initialize() {
78 callback_factory_.Initialize(this);
79 rng_desc_ = (struct NaClDescRng *) malloc(sizeof *rng_desc_);
80 CHECK(rng_desc_ != NULL);
81 CHECK(NaClDescRngCtor(rng_desc_));
82 file_io_trusted_ = static_cast<const PPB_FileIOTrusted*>(
83 pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE));
84 ++next_identifier;
85 SNPRINTF(reinterpret_cast<char *>(identifier_), sizeof identifier_,
86 "%"NACL_PRIu32, next_identifier);
87 }
88
89 LocalTempFile::~LocalTempFile() {
90 PLUGIN_PRINTF(("LocalTempFile::~LocalTempFile\n"));
91 NaClDescUnref(reinterpret_cast<NaClDesc*>(rng_desc_));
92 }
93
94 void LocalTempFile::OpenWrite(const pp::CompletionCallback& cb) {
95 done_callback_ = cb;
96 // If we don't already have a filename, generate one.
97 if (filename_ == "") {
98 // Get a random temp file name.
99 filename_ = base_dir_ + "/" + Random32CharHexString(rng_desc_);
100 // Remember the ref used to open for writing and reading.
101 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
102 }
103 PLUGIN_PRINTF(("LocalTempFile::OpenWrite: %s\n", filename_.c_str()));
104 // Open the writeable file.
105 write_io_.reset(new pp::FileIO(plugin_));
106 pp::CompletionCallback open_write_cb =
107 callback_factory_.NewCallback(&LocalTempFile::WriteFileDidOpen);
108 write_io_->Open(*file_ref_,
109 PP_FILEOPENFLAG_WRITE |
110 PP_FILEOPENFLAG_CREATE |
111 PP_FILEOPENFLAG_EXCLUSIVE,
112 open_write_cb);
113 }
114
115 int32_t LocalTempFile::GetFD(int32_t pp_error,
116 const pp::Resource& resource,
117 bool is_writable) {
118 PLUGIN_PRINTF(("LocalTempFile::GetFD (pp_error=%"NACL_PRId32
119 ", is_writable=%d)\n", pp_error, is_writable));
120 if (pp_error != PP_OK) {
121 PLUGIN_PRINTF(("LocalTempFile::GetFD pp_error != PP_OK\n"));
122 return -1;
123 }
124 int32_t file_desc =
125 file_io_trusted_->GetOSFileDescriptor(resource.pp_resource());
126 #if NACL_WINDOWS
127 // Convert the Windows HANDLE from Pepper to a POSIX file descriptor.
128 int32_t open_flags = ((is_writable ? _O_RDWR : _O_RDONLY) | _O_BINARY);
129 int32_t posix_desc = _open_osfhandle(file_desc, open_flags);
130 if (posix_desc == -1) {
131 // Close the Windows HANDLE if it can't be converted.
132 CloseHandle(reinterpret_cast<HANDLE>(file_desc));
133 PLUGIN_PRINTF(("LocalTempFile::GetFD _open_osfhandle failed.\n"));
134 return NACL_NO_FILE_DESC;
135 }
136 file_desc = posix_desc;
137 #endif
138 int32_t file_desc_ok_to_close = DUP(file_desc);
139 if (file_desc_ok_to_close == NACL_NO_FILE_DESC) {
140 PLUGIN_PRINTF(("LocalTempFile::GetFD dup failed.\n"));
141 return -1;
142 }
143 return file_desc_ok_to_close;
144 }
145
146 void LocalTempFile::WriteFileDidOpen(int32_t pp_error) {
147 PLUGIN_PRINTF(("LocalTempFile::WriteFileDidOpen (pp_error=%"
148 NACL_PRId32")\n", pp_error));
149 if (pp_error == PP_ERROR_FILEEXISTS) {
150 // Filenames clashed, retry.
151 filename_ = "";
152 OpenWrite(done_callback_);
153 }
154 // Run the client's completion callback.
155 pp::Core* core = pp::Module::Get()->core();
156 if (pp_error != PP_OK) {
157 core->CallOnMainThread(0, done_callback_, pp_error);
158 return;
159 }
160 // Remember the object temporary file descriptor.
161 int32_t fd = GetFD(pp_error, *write_io_, kWriteable);
162 if (fd < 0) {
163 core->CallOnMainThread(0, done_callback_, pp_error);
164 return;
165 }
166 // The descriptor for a writeable file needs to have quota management.
167 write_wrapper_.reset(
168 plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_));
169 core->CallOnMainThread(0, done_callback_, PP_OK);
170 }
171
172 void LocalTempFile::OpenRead(const pp::CompletionCallback& cb) {
173 PLUGIN_PRINTF(("LocalTempFile::OpenRead: %s\n", filename_.c_str()));
174 done_callback_ = cb;
175 // Open the read only file.
176 read_io_.reset(new pp::FileIO(plugin_));
177 pp::CompletionCallback open_read_cb =
178 callback_factory_.NewCallback(&LocalTempFile::ReadFileDidOpen);
179 read_io_->Open(*file_ref_, PP_FILEOPENFLAG_READ, open_read_cb);
180 }
181
182 void LocalTempFile::ReadFileDidOpen(int32_t pp_error) {
183 PLUGIN_PRINTF(("LocalTempFile::ReadFileDidOpen (pp_error=%"
184 NACL_PRId32")\n", pp_error));
185 // Run the client's completion callback.
186 pp::Core* core = pp::Module::Get()->core();
187 if (pp_error != PP_OK) {
188 core->CallOnMainThread(0, done_callback_, pp_error);
189 return;
190 }
191 // Remember the object temporary file descriptor.
192 int32_t fd = GetFD(pp_error, *read_io_, kReadOnly);
193 if (fd < 0) {
194 core->CallOnMainThread(0, done_callback_, PP_ERROR_FAILED);
195 return;
196 }
197 read_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY));
198 core->CallOnMainThread(0, done_callback_, PP_OK);
199 }
200
201 void LocalTempFile::Close(const pp::CompletionCallback& cb) {
202 PLUGIN_PRINTF(("LocalTempFile::Close: %s\n", filename_.c_str()));
203 // Close the open DescWrappers and FileIOs.
204 if (write_io_.get() != NULL) {
205 write_io_->Close();
206 }
207 write_wrapper_.reset(NULL);
208 write_io_.reset(NULL);
209 if (read_io_.get() != NULL) {
210 read_io_->Close();
211 }
212 read_wrapper_.reset(NULL);
213 read_io_.reset(NULL);
214 // Run the client's completion callback.
215 pp::Core* core = pp::Module::Get()->core();
216 core->CallOnMainThread(0, cb, PP_OK);
217 }
218
219 void LocalTempFile::Delete(const pp::CompletionCallback& cb) {
220 PLUGIN_PRINTF(("LocalTempFile::Delete: %s\n", filename_.c_str()));
221 file_ref_->Delete(cb);
222 }
223
224 void LocalTempFile::Rename(const nacl::string& new_name,
225 const pp::CompletionCallback& cb) {
226 // Rename the temporary file.
227 filename_ = base_dir_ + "/" + new_name;
228 PLUGIN_PRINTF(("LocalTempFile::Rename %s to %s\n",
229 file_ref_->GetName().AsString().c_str(),
230 filename_.c_str()));
231 // Remember the old ref until the rename is complete.
232 old_ref_.reset(file_ref_.release());
233 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
234 old_ref_->Rename(*file_ref_, cb);
235 }
236
237 void LocalTempFile::FinishRename() {
238 // Now we can release the old ref.
239 old_ref_.reset(NULL);
240 }
241
242 } // namespace plugin
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/local_temp_file.h ('k') | ppapi/native_client/src/trusted/plugin/plugin.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698