15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/temporary_file.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/portability_io.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_check.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/service_runtime/include/sys/stat.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/core.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/private/pp_file_handle.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/plugin.h" 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/utility.h" 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////// 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Temporary file access. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace plugin { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t TempFile::next_identifier = 0; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTempFile::TempFile(Plugin* plugin) : plugin_(plugin), 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch existing_handle_(PP_kInvalidFileHandle) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::TempFile\n")); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++next_identifier; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SNPRINTF(reinterpret_cast<char *>(identifier_), sizeof identifier_, 33bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "%" NACL_PRIu32, next_identifier); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TempFile::~TempFile() { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::~TempFile\n")); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid TempFile::Open(const pp::CompletionCallback& cb, bool writeable) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::Open\n")); 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_FileHandle file_handle; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (existing_handle_ == PP_kInvalidFileHandle) { 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_handle = 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance()); 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_handle = existing_handle_; 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Core* core = pp::Module::Get()->core(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_handle == PP_kInvalidFileHandle) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::Open failed w/ PP_kInvalidFileHandle\n")); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core->CallOnMainThread(0, cb, PP_ERROR_FAILED); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NACL_WINDOWS 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE handle = file_handle; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////// Now try the posix view. 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rdwr_flag = writeable ? _O_RDWR : _O_RDONLY; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t posix_desc = _open_osfhandle(reinterpret_cast<intptr_t>(handle), 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rdwr_flag | _O_BINARY 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) | _O_TEMPORARY | _O_SHORT_LIVED ); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (posix_desc == -1) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::Open failed to convert HANDLE to posix\n")); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the Windows HANDLE if it can't be converted. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(handle); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t fd = posix_desc; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t fd = file_handle; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd < 0) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::Open failed\n")); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core->CallOnMainThread(0, cb, PP_ERROR_FAILED); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dup the fd to make allow making a non-Quota-based wrapper. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sel_ldr currently does not allow loading from Quota-backed descs, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only plain host descs. It's probably good hygiene to separate the 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // read wrapper from the write wrapper anyway. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t read_fd = DUP(fd); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_fd == NACL_NO_FILE_DESC) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::Open DUP failed\n")); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core->CallOnMainThread(0, cb, PP_ERROR_FAILED); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The descriptor for a writeable file needs to have quota management. 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (writeable) { 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch write_wrapper_.reset( 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_)); 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_wrapper_.reset( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_->wrapper_factory()->MakeFileDesc(read_fd, O_RDONLY)); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core->CallOnMainThread(0, cb, PP_OK); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TempFile::Reset() { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("TempFile::Reset\n")); 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Use the read_wrapper_ to reset the file pos. The write_wrapper_ is also 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // backed by the same file, so it should also reset. 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK(read_wrapper_.get() != NULL); 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch nacl_off64_t newpos = read_wrapper_->Seek(0, SEEK_SET); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return newpos >= 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace plugin 111