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)namespace plugin {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TempFile::TempFile(Plugin* plugin, PP_FileHandle handle)
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : plugin_(plugin),
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      internal_handle_(handle) { }
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TempFile::~TempFile() { }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int32_t TempFile::Open(bool writeable) {
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (internal_handle_ == PP_kInvalidFileHandle)
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return PP_ERROR_FAILED;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NACL_WINDOWS
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  HANDLE handle = internal_handle_;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //////// Now try the posix view.
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rdwr_flag = writeable ? _O_RDWR : _O_RDONLY;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t posix_desc = _open_osfhandle(reinterpret_cast<intptr_t>(handle),
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                       rdwr_flag | _O_BINARY
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       | _O_TEMPORARY | _O_SHORT_LIVED );
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Close the Windows HANDLE if it can't be converted.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (posix_desc == -1) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PLUGIN_PRINTF(("TempFile::Open failed to convert HANDLE to posix\n"));
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseHandle(handle);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t fd = posix_desc;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int32_t fd = internal_handle_;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (fd < 0)
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return PP_ERROR_FAILED;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // dup the fd to make allow making separate read and write wrappers.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t read_fd = DUP(fd);
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (read_fd == NACL_NO_FILE_DESC)
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return PP_ERROR_FAILED;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (writeable) {
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    write_wrapper_.reset(
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDWR));
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_wrapper_.reset(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      plugin_->wrapper_factory()->MakeFileDesc(read_fd, O_RDONLY));
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return PP_OK;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TempFile::Reset() {
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Use the read_wrapper_ to reset the file pos.  The write_wrapper_ is also
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backed by the same file, so it should also reset.
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CHECK(read_wrapper_.get() != NULL);
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  nacl_off64_t newpos = read_wrapper_->Seek(0, SEEK_SET);
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return newpos == 0;
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PP_FileHandle TempFile::TakeFileHandle() {
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PP_FileHandle to_return = internal_handle_;
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  internal_handle_ = PP_kInvalidFileHandle;
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  read_wrapper_.release();
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  write_wrapper_.release();
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return to_return;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace plugin
85