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