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.
5 #include "ppapi/native_client/src/trusted/plugin/temporary_file.h"
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/service_runtime/include/sys/stat.h"
11 #include "ppapi/cpp/core.h"
12 #include "ppapi/cpp/instance.h"
13 #include "ppapi/cpp/module.h"
14 #include "ppapi/c/private/pp_file_handle.h"
16 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
17 #include "ppapi/native_client/src/trusted/plugin/utility.h"
20 //////////////////////////////////////////////////////////////////////
21 // Temporary file access.
22 //////////////////////////////////////////////////////////////////////
26 uint32_t TempFile::next_identifier = 0;
28 TempFile::TempFile(Plugin* plugin) : plugin_(plugin),
29 existing_handle_(PP_kInvalidFileHandle) {
30 PLUGIN_PRINTF(("TempFile::TempFile\n"));
32 SNPRINTF(reinterpret_cast<char *>(identifier_), sizeof identifier_,
33 "%" NACL_PRIu32, next_identifier);
36 TempFile::~TempFile() {
37 PLUGIN_PRINTF(("TempFile::~TempFile\n"));
40 void TempFile::Open(const pp::CompletionCallback& cb, bool writeable) {
41 PLUGIN_PRINTF(("TempFile::Open\n"));
42 PP_FileHandle file_handle;
43 if (existing_handle_ == PP_kInvalidFileHandle) {
45 plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance());
47 file_handle = existing_handle_;
50 pp::Core* core = pp::Module::Get()->core();
51 if (file_handle == PP_kInvalidFileHandle) {
52 PLUGIN_PRINTF(("TempFile::Open failed w/ PP_kInvalidFileHandle\n"));
53 core->CallOnMainThread(0, cb, PP_ERROR_FAILED);
57 HANDLE handle = file_handle;
59 //////// Now try the posix view.
60 int rdwr_flag = writeable ? _O_RDWR : _O_RDONLY;
61 int32_t posix_desc = _open_osfhandle(reinterpret_cast<intptr_t>(handle),
63 | _O_TEMPORARY | _O_SHORT_LIVED );
64 if (posix_desc == -1) {
65 PLUGIN_PRINTF(("TempFile::Open failed to convert HANDLE to posix\n"));
66 // Close the Windows HANDLE if it can't be converted.
69 int32_t fd = posix_desc;
71 int32_t fd = file_handle;
75 PLUGIN_PRINTF(("TempFile::Open failed\n"));
76 core->CallOnMainThread(0, cb, PP_ERROR_FAILED);
80 // dup the fd to make allow making a non-Quota-based wrapper.
81 // sel_ldr currently does not allow loading from Quota-backed descs,
82 // only plain host descs. It's probably good hygiene to separate the
83 // read wrapper from the write wrapper anyway.
84 int32_t read_fd = DUP(fd);
85 if (read_fd == NACL_NO_FILE_DESC) {
86 PLUGIN_PRINTF(("TempFile::Open DUP failed\n"));
87 core->CallOnMainThread(0, cb, PP_ERROR_FAILED);
91 // The descriptor for a writeable file needs to have quota management.
94 plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_));
97 plugin_->wrapper_factory()->MakeFileDesc(read_fd, O_RDONLY));
98 core->CallOnMainThread(0, cb, PP_OK);
101 bool TempFile::Reset() {
102 PLUGIN_PRINTF(("TempFile::Reset\n"));
103 // Use the read_wrapper_ to reset the file pos. The write_wrapper_ is also
104 // backed by the same file, so it should also reset.
105 CHECK(read_wrapper_.get() != NULL);
106 nacl_off64_t newpos = read_wrapper_->Seek(0, SEEK_SET);
110 } // namespace plugin