summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhamaji@chromium.org <hamaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-01 16:51:13 +0000
committerhamaji@chromium.org <hamaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-01 16:51:13 +0000
commit8f96cef7e737970b9e16c97de788daaa5fb3181a (patch)
tree31887c9690fdc4ae20edb89f94745bc2310b665a
parent0b4468ed16cf93bac23d5abf3ef39e400665d694 (diff)
downloadchromium_src-8f96cef7e737970b9e16c97de788daaa5fb3181a.zip
chromium_src-8f96cef7e737970b9e16c97de788daaa5fb3181a.tar.gz
chromium_src-8f96cef7e737970b9e16c97de788daaa5fb3181a.tar.bz2
Unlike GetOSFileDescriptor, this API is asynchronous.
Both GetOSFileDescriptor and RequestOSFileHandle use GetOSFileDescriptor chrome IPC for now. I'm planning to remove call sites of GetOSFileDescriptor PPAPI and rename GetOSFileDescriptor chrome IPC to RequestOSFileHandle. - Add --allow-get-os-file-handle-api. With this flag, 1. browser_tests can test this API and 2. we can use this API even before this issue is resolved: http://crbug.com/224123 - Add TestRequestOSFileHandle in FileIO. This checks if read, write, lseek, and mmap work for FD fetched by this API. - PepperFileIOHost::OnHostMsgGetOSFileDescriptor use ShareHandleWithRemote to pass a file handle - Fix ShareHandleWithRemote for in-process API BUG=183015 TEST=trybots, browser_tests Review URL: https://chromiumcodereview.appspot.com/13032002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191616 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_content_browser_client.cc1
-rw-r--r--chrome/common/chrome_switches.cc9
-rw-r--r--chrome/common/chrome_switches.h3
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc38
-rw-r--r--chrome/renderer/chrome_content_renderer_client.h10
-rw-r--r--chrome/renderer/chrome_content_renderer_client_unittest.cc37
-rw-r--r--chrome/test/ppapi/ppapi_browsertest.cc5
-rw-r--r--chrome/test/ppapi/ppapi_test.cc4
-rw-r--r--content/public/renderer/content_renderer_client.cc5
-rw-r--r--content/public/renderer/content_renderer_client.h3
-rw-r--r--content/renderer/pepper/pepper_file_io_host.cc44
-rw-r--r--content/renderer/pepper/pepper_file_io_host.h5
-rw-r--r--content/renderer/pepper/renderer_ppapi_host_impl.cc12
-rw-r--r--ppapi/api/private/ppb_file_io_private.idl26
-rw-r--r--ppapi/api/trusted/ppb_file_io_trusted.idl2
-rw-r--r--ppapi/c/pp_macros.h4
-rw-r--r--ppapi/c/private/ppb_file_io_private.h49
-rw-r--r--ppapi/c/trusted/ppb_file_io_trusted.h4
-rw-r--r--ppapi/cpp/private/file_io_private.cc39
-rw-r--r--ppapi/cpp/private/file_io_private.h42
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c23
-rw-r--r--ppapi/ppapi_shared.gypi1
-rw-r--r--ppapi/ppapi_sources.gypi2
-rw-r--r--ppapi/proxy/file_io_resource.cc41
-rw-r--r--ppapi/proxy/file_io_resource.h9
-rw-r--r--ppapi/proxy/interface_list.cc1
-rw-r--r--ppapi/proxy/ppapi_messages.h2
-rw-r--r--ppapi/tests/all_c_includes.h1
-rw-r--r--ppapi/tests/test_file_io.cc130
-rw-r--r--ppapi/tests/test_file_io.h1
-rw-r--r--ppapi/thunk/interfaces_ppb_private_no_permissions.h3
-rw-r--r--ppapi/thunk/ppb_file_io_api.h6
-rw-r--r--ppapi/thunk/ppb_file_io_private_thunk.cc44
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc1
34 files changed, 588 insertions, 19 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 45b0879..b2907254e 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1150,6 +1150,7 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
// Please keep this in alphabetical order.
static const char* const kSwitchNames[] = {
+ switches::kAllowRequestOSFileHandleAPI,
switches::kAllowHTTPBackgroundPage,
switches::kAllowLegacyExtensionManifests,
switches::kAllowScriptingGallery,
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index b0c5e12..d3ec727 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -37,13 +37,18 @@ const char kAllowHTTPBackgroundPage[] = "allow-http-background-page";
const char kAllowLegacyExtensionManifests[] =
"allow-legacy-extension-manifests";
-// Specifies comma-separated list of extension ids to grant access to TCP/UDP
-// socket APIs.
+// Specifies comma-separated list of extension ids or hosts to grant
+// access to TCP/UDP socket APIs.
const char kAllowNaClSocketAPI[] = "allow-nacl-socket-api";
// Don't block outdated plugins.
const char kAllowOutdatedPlugins[] = "allow-outdated-plugins";
+// Specifies command-separated list of extension ids or hosts to grant
+// access to RequestOSFileHandle private API.
+const char kAllowRequestOSFileHandleAPI[] =
+ "allow-request-os-file-handle-api";
+
// By default, an https page cannot run JavaScript, CSS or plug-ins from http
// URLs. This provides an override to get the old insecure behavior.
const char kAllowRunningInsecureContent[] = "allow-running-insecure-content";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index ccb79be7..312d380 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -31,6 +31,9 @@ extern const char kAllowHTTPBackgroundPage[];
extern const char kAllowLegacyExtensionManifests[];
extern const char kAllowNaClSocketAPI[];
extern const char kAllowOutdatedPlugins[];
+// TODO(hamaji): Remove this once the two issues are fixed.
+// http://crbug.com/224753 http://crbug.com/220029
+extern const char kAllowRequestOSFileHandleAPI[];
extern const char kAllowRunningInsecureContent[];
extern const char kAllowScriptingGallery[];
extern const char kAlwaysAuthorizePlugins[];
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 27fd285..5e5cde7 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
+#include "base/strings/string_tokenizer.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/child_process_logging.h"
@@ -336,6 +337,10 @@ void ChromeContentRendererClient::RenderThreadStarted() {
extension_resource_scheme);
RegisterExtensionManifestHandlers();
+
+ RegisterRequestOSFileHandleAllowedHosts(
+ command_line->GetSwitchValueASCII(
+ switches::kAllowRequestOSFileHandleAPI));
}
void ChromeContentRendererClient::RenderViewCreated(
@@ -1193,4 +1198,37 @@ bool ChromeContentRendererClient::AllowBrowserPlugin(
tag_name.equals(WebString::fromUTF8(kAdViewTagName));
}
+void ChromeContentRendererClient::RegisterRequestOSFileHandleAllowedHosts(
+ const std::string& allowed_list) {
+ if (!allowed_list.empty()) {
+ base::StringTokenizer t(allowed_list, ",");
+ while (t.GetNext()) {
+ request_os_file_handle_allowed_hosts_.insert(t.token());
+ }
+ }
+}
+
+bool ChromeContentRendererClient::IsRequestOSFileHandleAllowedForURL(
+ const GURL& url) const {
+ if (!url.is_valid() || !url.SchemeIsFileSystem() || !url.inner_url()) {
+ return false;
+ }
+
+ const GURL& inner = *url.inner_url();
+ if (!inner.is_valid())
+ return false;
+
+ if (inner.SchemeIs(extensions::kExtensionScheme)) {
+ // TODO(hamaji): We don't need this whitelist once this issue is
+ // fixed: http://crbug.com/224123 http://crbug.com/224753
+ if (inner.host() == "dolnidnbiendbodmklboojlnlpdeeipo")
+ return true;
+ }
+
+ if (request_os_file_handle_allowed_hosts_.count(inner.host()))
+ return true;
+
+ return false;
+}
+
} // namespace chrome
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index bf8312a..ab7e538 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -146,8 +146,13 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
const WebKit::WebPluginParams& params,
const ChromeViewHostMsg_GetPluginInfo_Output& output);
+ virtual bool IsRequestOSFileHandleAllowedForURL(
+ const GURL& url) const OVERRIDE;
+
private:
FRIEND_TEST_ALL_PREFIXES(ChromeContentRendererClientTest, NaClRestriction);
+ FRIEND_TEST_ALL_PREFIXES(ChromeContentRendererClientTest,
+ IsRequestOSFileHandleAllowedForURL);
const extensions::Extension* GetExtension(
const WebKit::WebSecurityOrigin& origin) const;
@@ -168,6 +173,9 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
const extensions::Extension* extension,
WebKit::WebPluginParams* params);
+ void RegisterRequestOSFileHandleAllowedHosts(
+ const std::string& allowed_list);
+
scoped_ptr<ChromeRenderProcessObserver> chrome_observer_;
scoped_ptr<extensions::Dispatcher> extension_dispatcher_;
scoped_ptr<RendererNetPredictor> net_predictor_;
@@ -175,6 +183,8 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
scoped_ptr<components::VisitedLinkSlave> visited_link_slave_;
scoped_ptr<safe_browsing::PhishingClassifierFilter> phishing_classifier_;
scoped_ptr<prerender::PrerenderDispatcher> prerender_dispatcher_;
+ // The whitelist for RequestOSFileHandle specified by commandline.
+ std::set<std::string> request_os_file_handle_allowed_hosts_;
};
} // namespace chrome
diff --git a/chrome/renderer/chrome_content_renderer_client_unittest.cc b/chrome/renderer/chrome_content_renderer_client_unittest.cc
index 17f95df..e97fe1a 100644
--- a/chrome/renderer/chrome_content_renderer_client_unittest.cc
+++ b/chrome/renderer/chrome_content_renderer_client_unittest.cc
@@ -287,5 +287,40 @@ TEST_F(ChromeContentRendererClientTest, NaClRestriction) {
}
}
-} // namespace chrome
+TEST_F(ChromeContentRendererClientTest, IsRequestOSFileHandleAllowedForURL) {
+ ChromeContentRendererClient client;
+ const std::string& kWhitelistedExtensionID =
+ "dolnidnbiendbodmklboojlnlpdeeipo";
+ const std::string& kRandomExtensionID =
+ "abcdefghijklmnopqrstuvwxyzabcdef";
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(GURL()));
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("http://example.com/")));
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("chrome-extension://" + kWhitelistedExtensionID)));
+ EXPECT_TRUE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("filesystem:chrome-extension://" +
+ kWhitelistedExtensionID + "/foo")));
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("filesystem:http://" +
+ kWhitelistedExtensionID + "/foo")));
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("filesystem:chrome-extension://" +
+ kRandomExtensionID + "/foo")));
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("filesystem:http://127.0.0.1/foo")));
+
+ client.RegisterRequestOSFileHandleAllowedHosts(
+ "127.0.0.1," + kRandomExtensionID);
+ EXPECT_TRUE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("filesystem:chrome-extension://" +
+ kRandomExtensionID + "/foo")));
+ EXPECT_TRUE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("filesystem:http://127.0.0.1/foo")));
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("http://127.0.0.1/foo")));
+ EXPECT_FALSE(client.IsRequestOSFileHandleAllowedForURL(
+ GURL("filesystem:http://192.168.0.1/foo")));
+}
+} // namespace chrome
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index 3f074876..ae0a331 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -627,6 +627,7 @@ IN_PROC_BROWSER_TEST_F(PPAPITest, FileIO) {
LIST_TEST(FileIO_ReadToArrayWriteSetLength)
LIST_TEST(FileIO_TouchQuery)
LIST_TEST(FileIO_WillWriteWillSetLength)
+ LIST_TEST(FileIO_RequestOSFileHandle)
);
}
IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, FileIO) {
@@ -640,6 +641,7 @@ IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, FileIO) {
LIST_TEST(FileIO_ReadToArrayWriteSetLength)
LIST_TEST(FileIO_TouchQuery)
LIST_TEST(FileIO_WillWriteWillSetLength)
+ LIST_TEST(FileIO_RequestOSFileHandle)
);
}
IN_PROC_BROWSER_TEST_F(PPAPINaClNewlibTest, FileIO) {
@@ -654,6 +656,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClNewlibTest, FileIO) {
LIST_TEST(FileIO_TouchQuery)
// The following test requires PPB_FileIO_Trusted, not available in NaCl.
LIST_TEST(DISABLED_FileIO_WillWriteWillSetLength)
+ LIST_TEST(FileIO_RequestOSFileHandle)
);
}
IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(FileIO)) {
@@ -668,6 +671,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(FileIO)) {
LIST_TEST(FileIO_TouchQuery)
// The following test requires PPB_FileIO_Trusted, not available in NaCl.
LIST_TEST(DISABLED_FileIO_WillWriteWillSetLength)
+ LIST_TEST(FileIO_RequestOSFileHandle)
);
}
IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, FileIO) {
@@ -682,6 +686,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, FileIO) {
LIST_TEST(FileIO_TouchQuery)
// The following test requires PPB_FileIO_Trusted, not available in NaCl.
LIST_TEST(DISABLED_FileIO_WillWriteWillSetLength)
+ LIST_TEST(FileIO_RequestOSFileHandle)
);
}
diff --git a/chrome/test/ppapi/ppapi_test.cc b/chrome/test/ppapi/ppapi_test.cc
index a2a10f9..bec32a6 100644
--- a/chrome/test/ppapi/ppapi_test.cc
+++ b/chrome/test/ppapi/ppapi_test.cc
@@ -131,6 +131,10 @@ void PPAPITestBase::SetUpCommandLine(CommandLine* command_line) {
// Smooth scrolling confuses the scrollbar test.
command_line->AppendSwitch(switches::kDisableSmoothScrolling);
+
+ // For TestRequestOSFileHandle.
+ command_line->AppendSwitchASCII(switches::kAllowRequestOSFileHandleAPI,
+ "127.0.0.1");
}
void PPAPITestBase::SetUpOnMainThread() {
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index 8997832..2223824 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -157,4 +157,9 @@ bool ContentRendererClient::ShouldCreateCompositorInputHandler() const {
return true;
}
+bool ContentRendererClient::IsRequestOSFileHandleAllowedForURL(
+ const GURL& url) const {
+ return false;
+}
+
} // namespace content
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 77a1057..00cc737 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -235,6 +235,9 @@ class CONTENT_EXPORT ContentRendererClient {
// Allow the embedder to disable input event filtering by the compositor.
virtual bool ShouldCreateCompositorInputHandler() const;
+
+ // Check if we can allow RequestOSFileHandle API access for |url|.
+ virtual bool IsRequestOSFileHandleAllowedForURL(const GURL& url) const;
};
} // namespace content
diff --git a/content/renderer/pepper/pepper_file_io_host.cc b/content/renderer/pepper/pepper_file_io_host.cc
index d0fb617..b96edf5 100644
--- a/content/renderer/pepper/pepper_file_io_host.cc
+++ b/content/renderer/pepper/pepper_file_io_host.cc
@@ -6,7 +6,10 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/command_line.h"
#include "base/files/file_util_proxy.h"
+#include "content/public/common/content_client.h"
+#include "content/public/renderer/content_renderer_client.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
@@ -147,6 +150,8 @@ int32_t PepperFileIOHost::OnResourceMessageReceived(
OnHostMsgWillSetLength)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_GetOSFileDescriptor,
OnHostMsgGetOSFileDescriptor)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_RequestOSFileHandle,
+ OnHostMsgRequestOSFileHandle)
IPC_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
@@ -446,22 +451,48 @@ int32_t PepperFileIOHost::OnHostMsgWillSetLength(
return PP_OK_COMPLETIONPENDING;
}
+int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle(
+ ppapi::host::HostMessageContext* context) {
+ if (!is_running_in_process_ &&
+ !GetContentClient()->renderer()->IsRequestOSFileHandleAllowedForURL(
+ file_system_url_))
+ return PP_ERROR_FAILED;
+
+ // TODO(hamaji): Should fail if quota is not unlimited.
+ // http://crbug.com/224123
+
+ RendererPpapiHost* renderer_ppapi_host =
+ RendererPpapiHost::GetForPPInstance(pp_instance());
+
+ IPC::PlatformFileForTransit file =
+ renderer_ppapi_host->ShareHandleWithRemote(file_, false);
+ if (file == IPC::InvalidPlatformFileForTransit())
+ return PP_ERROR_FAILED;
+ ppapi::host::ReplyMessageContext reply_context =
+ context->MakeReplyMessageContext();
+ reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle(
+ ppapi::proxy::SerializedHandle::FILE, file));
+ host()->SendReply(reply_context,
+ PpapiPluginMsg_FileIO_RequestOSFileHandleReply());
+ return PP_OK_COMPLETIONPENDING;
+}
+
int32_t PepperFileIOHost::OnHostMsgGetOSFileDescriptor(
ppapi::host::HostMessageContext* context) {
if (!is_running_in_process_)
return PP_ERROR_FAILED;
+
int32_t fd =
#if defined(OS_POSIX)
- file_;
+ file_;
#elif defined(OS_WIN)
- reinterpret_cast<uintptr_t>(file_);
+ reinterpret_cast<uintptr_t>(file_);
#else
- -1; // Platform not supported.
+ -1;
#endif
- // TODO(victorhsieh): Pass the file handle in the reply params once this works
- // in-process.
+
host()->SendReply(context->MakeReplyMessageContext(),
- PpapiPluginMsg_FileIO_GetOSFileDescriptorReply(fd));
+ PpapiPluginMsg_FileIO_GetOSFileDescriptorReply(fd));
return PP_OK_COMPLETIONPENDING;
}
@@ -569,4 +600,3 @@ void PepperFileIOHost::ExecutePlatformWillWriteCallback(
}
} // namespace content
-
diff --git a/content/renderer/pepper/pepper_file_io_host.h b/content/renderer/pepper/pepper_file_io_host.h
index b66cb6f..6f3ab97 100644
--- a/content/renderer/pepper/pepper_file_io_host.h
+++ b/content/renderer/pepper/pepper_file_io_host.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_
#define CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_
+#include <set>
#include <string>
#include "base/basictypes.h"
@@ -58,6 +59,9 @@ class PepperFileIOHost : public ppapi::host::ResourceHost,
int64_t length);
int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context);
+ // Private API.
+ int32_t OnHostMsgRequestOSFileHandle(
+ ppapi::host::HostMessageContext* context);
// Trusted API.
int32_t OnHostMsgGetOSFileDescriptor(
ppapi::host::HostMessageContext* context);
@@ -126,4 +130,3 @@ class PepperFileIOHost : public ppapi::host::ResourceHost,
} // namespace content
#endif // CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_
-
diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.cc b/content/renderer/pepper/renderer_ppapi_host_impl.cc
index 50b4fc7..4971d51 100644
--- a/content/renderer/pepper/renderer_ppapi_host_impl.cc
+++ b/content/renderer/pepper/renderer_ppapi_host_impl.cc
@@ -6,6 +6,8 @@
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/process_util.h"
+#include "content/common/sandbox_util.h"
#include "content/renderer/pepper/pepper_graphics_2d_host.h"
#include "content/renderer/pepper/pepper_in_process_resource_creation.h"
#include "content/renderer/pepper/pepper_in_process_router.h"
@@ -245,9 +247,13 @@ IPC::PlatformFileForTransit RendererPpapiHostImpl::ShareHandleWithRemote(
base::PlatformFile handle,
bool should_close_source) {
if (!dispatcher_) {
- if (should_close_source)
- base::ClosePlatformFile(handle);
- return IPC::InvalidPlatformFileForTransit();
+ DCHECK(is_running_in_process_);
+ // Duplicate the file handle for in process mode so this function
+ // has the same semantics for both in process mode and out of
+ // process mode (i.e., the remote side must cloes the handle).
+ return BrokerGetFileHandleForProcess(handle,
+ base::GetCurrentProcId(),
+ should_close_source);
}
return dispatcher_->ShareHandleWithRemote(handle, should_close_source);
}
diff --git a/ppapi/api/private/ppb_file_io_private.idl b/ppapi/api/private/ppb_file_io_private.idl
new file mode 100644
index 0000000..38b2339
--- /dev/null
+++ b/ppapi/api/private/ppb_file_io_private.idl
@@ -0,0 +1,26 @@
+/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#inline c
+#include "ppapi/c/private/pp_file_handle.h"
+#endinl
+
+/* This file contains the <code>PPB_FileIO_Private</code> interface. */
+label Chrome {
+ M28 = 0.1
+};
+
+/* PPB_FileIO_Private interface */
+interface PPB_FileIO_Private {
+ /**
+ * Returns a file handle corresponding to the given FileIO
+ * object. The FileIO object must have been opened with a
+ * successful call to FileIO::Open. The caller gets the ownership
+ * of the returned file handle and must close it.
+ */
+ int32_t RequestOSFileHandle([in] PP_Resource file_io,
+ [out] PP_FileHandle handle,
+ [in] PP_CompletionCallback callback);
+};
diff --git a/ppapi/api/trusted/ppb_file_io_trusted.idl b/ppapi/api/trusted/ppb_file_io_trusted.idl
index 1ee03ab..7ba20de 100644
--- a/ppapi/api/trusted/ppb_file_io_trusted.idl
+++ b/ppapi/api/trusted/ppb_file_io_trusted.idl
@@ -19,6 +19,8 @@ interface PPB_FileIOTrusted {
* descriptor. The FileIO object must have been opened with a successful
* call to FileIO::Open. The file descriptor will be closed automatically
* when the FileIO object is closed or destroyed.
+ *
+ * TODO(hamaji): Remove this and use RequestOSFileHandle instead.
*/
int32_t GetOSFileDescriptor([in] PP_Resource file_io);
diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h
index 83f85d6..6179380 100644
--- a/ppapi/c/pp_macros.h
+++ b/ppapi/c/pp_macros.h
@@ -3,13 +3,13 @@
* found in the LICENSE file.
*/
-/* From pp_macros.idl modified Fri Feb 15 16:46:46 2013. */
+/* From pp_macros.idl modified Tue Mar 19 12:29:49 2013. */
#ifndef PPAPI_C_PP_MACROS_H_
#define PPAPI_C_PP_MACROS_H_
-#define PPAPI_RELEASE 27
+#define PPAPI_RELEASE 28
/**
* @file
diff --git a/ppapi/c/private/ppb_file_io_private.h b/ppapi/c/private/ppb_file_io_private.h
new file mode 100644
index 0000000..cdbbae7
--- /dev/null
+++ b/ppapi/c/private/ppb_file_io_private.h
@@ -0,0 +1,49 @@
+/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* From private/ppb_file_io_private.idl modified Wed Mar 27 14:43:25 2013. */
+
+#ifndef PPAPI_C_PRIVATE_PPB_FILE_IO_PRIVATE_H_
+#define PPAPI_C_PRIVATE_PPB_FILE_IO_PRIVATE_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_FILEIO_PRIVATE_INTERFACE_0_1 "PPB_FileIO_Private;0.1"
+#define PPB_FILEIO_PRIVATE_INTERFACE PPB_FILEIO_PRIVATE_INTERFACE_0_1
+
+/**
+ * @file
+ */
+
+
+#include "ppapi/c/private/pp_file_handle.h"
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+/* PPB_FileIO_Private interface */
+struct PPB_FileIO_Private_0_1 {
+ /**
+ * Returns a file handle corresponding to the given FileIO
+ * object. The FileIO object must have been opened with a
+ * successful call to FileIO::Open. The caller gets the ownership
+ * of the returned file handle and must close it.
+ */
+ int32_t (*RequestOSFileHandle)(PP_Resource file_io,
+ PP_FileHandle* handle,
+ struct PP_CompletionCallback callback);
+};
+
+typedef struct PPB_FileIO_Private_0_1 PPB_FileIO_Private;
+/**
+ * @}
+ */
+
+#endif /* PPAPI_C_PRIVATE_PPB_FILE_IO_PRIVATE_H_ */
+
diff --git a/ppapi/c/trusted/ppb_file_io_trusted.h b/ppapi/c/trusted/ppb_file_io_trusted.h
index 53953fbd..8e05589 100644
--- a/ppapi/c/trusted/ppb_file_io_trusted.h
+++ b/ppapi/c/trusted/ppb_file_io_trusted.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From trusted/ppb_file_io_trusted.idl modified Wed Oct 5 14:06:02 2011. */
+/* From trusted/ppb_file_io_trusted.idl modified Wed Mar 27 14:50:12 2013. */
#ifndef PPAPI_C_TRUSTED_PPB_FILE_IO_TRUSTED_H_
#define PPAPI_C_TRUSTED_PPB_FILE_IO_TRUSTED_H_
@@ -35,6 +35,8 @@ struct PPB_FileIOTrusted_0_4 {
* descriptor. The FileIO object must have been opened with a successful
* call to FileIO::Open. The file descriptor will be closed automatically
* when the FileIO object is closed or destroyed.
+ *
+ * TODO(hamaji): Remove this and use RequestOSFileHandle instead.
*/
int32_t (*GetOSFileDescriptor)(PP_Resource file_io);
/**
diff --git a/ppapi/cpp/private/file_io_private.cc b/ppapi/cpp/private/file_io_private.cc
new file mode 100644
index 0000000..1479348
--- /dev/null
+++ b/ppapi/cpp/private/file_io_private.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/private/file_io_private.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_file_io_private.h"
+#include "ppapi/cpp/file_io.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+template <> const char* interface_name<PPB_FileIO_Private>() {
+ return PPB_FILEIO_PRIVATE_INTERFACE_0_1;
+}
+
+} // namespace
+
+FileIO_Private::FileIO_Private()
+ : FileIO() {
+}
+
+FileIO_Private::FileIO_Private(const InstanceHandle& instance)
+ : FileIO(instance) {
+}
+
+int32_t FileIO_Private::RequestOSFileHandle(PP_FileHandle* result_handle,
+ const CompletionCallback& cc) {
+ *result_handle = PP_kInvalidFileHandle;
+ if (has_interface<PPB_FileIO_Private>())
+ return get_interface<PPB_FileIO_Private>()->RequestOSFileHandle(
+ pp_resource(), result_handle, cc.pp_completion_callback());
+ return cc.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/private/file_io_private.h b/ppapi/cpp/private/file_io_private.h
new file mode 100644
index 0000000..c291be5
--- /dev/null
+++ b/ppapi/cpp/private/file_io_private.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_PRIVATE_FILE_IO_PRIVATE_H_
+#define PPAPI_CPP_PRIVATE_FILE_IO_PRIVATE_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/private/pp_file_handle.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/file_io.h"
+
+namespace pp {
+
+class FileIO;
+
+class FileIO_Private : public FileIO {
+ public:
+ FileIO_Private();
+ explicit FileIO_Private(const InstanceHandle& instance);
+
+ // This interface may leak the memory and file handle if the factory
+ // of |cc| is destructed. We need to use
+ // CompletionCallbackWithOutput to prevent the memory leak and
+ // create something like PassFileHandle to prevent the handle leak.
+ // See https://codereview.chromium.org/13032002/#ps33001
+ //
+ // Currently, TestCompletionCallbackWithOutput won't work for non
+ // vector types, so we should fix it first.
+ // http://crbug.com/224741
+ //
+ // Meanwhile, this interface should be used only from tests and
+ // other code should use the C interface of this API.
+ //
+ // TODO(hamaji): Fix. http://crbug.com/224745
+ int32_t RequestOSFileHandle(PP_FileHandle* result_handle,
+ const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_PRIVATE_FILE_IO_PRIVATE_H_
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index 758cb52..4f76f47 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -77,6 +77,7 @@
#include "ppapi/c/ppp_messaging.h"
#include "ppapi/c/ppp_mouse_lock.h"
#include "ppapi/c/private/ppb_content_decryptor_private.h"
+#include "ppapi/c/private/ppb_file_io_private.h"
#include "ppapi/c/private/ppb_file_ref_private.h"
#include "ppapi/c/private/ppb_flash.h"
#include "ppapi/c/private/ppb_flash_clipboard.h"
@@ -233,6 +234,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_VideoDecoder_Dev_0_11;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Widget_Dev_0_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Zoom_Dev_0_3;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_6;
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileIO_Private_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Flash_12_4;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Flash_12_5;
@@ -2429,6 +2431,16 @@ void Pnacl_M24_PPB_ContentDecryptor_Private_DeliverSamples(PP_Instance instance,
/* End wrapper methods for PPB_ContentDecryptor_Private_0_6 */
+/* Begin wrapper methods for PPB_FileIO_Private_0_1 */
+
+static __attribute__((pnaclcall))
+int32_t Pnacl_M28_PPB_FileIO_Private_RequestOSFileHandle(PP_Resource file_io, PP_FileHandle* handle, struct PP_CompletionCallback callback) {
+ const struct PPB_FileIO_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_FileIO_Private_0_1.real_iface;
+ return iface->RequestOSFileHandle(file_io, handle, callback);
+}
+
+/* End wrapper methods for PPB_FileIO_Private_0_1 */
+
/* Begin wrapper methods for PPB_FileRefPrivate_0_1 */
static __attribute__((pnaclcall))
@@ -4356,6 +4368,10 @@ struct PPB_ContentDecryptor_Private_0_6 Pnacl_Wrappers_PPB_ContentDecryptor_Priv
.DeliverSamples = (void (*)(PP_Instance instance, PP_Resource audio_frames, const struct PP_DecryptedBlockInfo* decrypted_block_info))&Pnacl_M24_PPB_ContentDecryptor_Private_DeliverSamples
};
+struct PPB_FileIO_Private_0_1 Pnacl_Wrappers_PPB_FileIO_Private_0_1 = {
+ .RequestOSFileHandle = (int32_t (*)(PP_Resource file_io, PP_FileHandle* handle, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_FileIO_Private_RequestOSFileHandle
+};
+
struct PPB_FileRefPrivate_0_1 Pnacl_Wrappers_PPB_FileRefPrivate_0_1 = {
.GetAbsolutePath = (struct PP_Var (*)(PP_Resource file_ref))&Pnacl_M15_PPB_FileRefPrivate_GetAbsolutePath
};
@@ -5281,6 +5297,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_
.real_iface = NULL
};
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileIO_Private_0_1 = {
+ .iface_macro = PPB_FILEIO_PRIVATE_INTERFACE_0_1,
+ .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_FileIO_Private_0_1,
+ .real_iface = NULL
+};
+
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1 = {
.iface_macro = PPB_FILEREFPRIVATE_INTERFACE_0_1,
.wrapped_iface = (void *) &Pnacl_Wrappers_PPB_FileRefPrivate_0_1,
@@ -5606,6 +5628,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = {
&Pnacl_WrapperInfo_PPB_Widget_Dev_0_4,
&Pnacl_WrapperInfo_PPB_Zoom_Dev_0_2,
&Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_6,
+ &Pnacl_WrapperInfo_PPB_FileIO_Private_0_1,
&Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1,
&Pnacl_WrapperInfo_PPB_Flash_12_4,
&Pnacl_WrapperInfo_PPB_Flash_12_5,
diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi
index e69c2c7..3b39112 100644
--- a/ppapi/ppapi_shared.gypi
+++ b/ppapi/ppapi_shared.gypi
@@ -160,6 +160,7 @@
'thunk/ppb_file_chooser_dev_thunk.cc',
'thunk/ppb_file_chooser_trusted_thunk.cc',
'thunk/ppb_file_io_api.h',
+ 'thunk/ppb_file_io_private_thunk.cc',
'thunk/ppb_file_io_thunk.cc',
'thunk/ppb_file_io_trusted_thunk.cc',
'thunk/ppb_file_ref_api.h',
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index 3669be6..cf01f08 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -273,6 +273,8 @@
# Private interfaces.
'cpp/private/content_decryptor_private.cc',
'cpp/private/content_decryptor_private.h',
+ 'cpp/private/file_io_private.cc',
+ 'cpp/private/file_io_private.h',
'cpp/private/flash.cc',
'cpp/private/flash.h',
'cpp/private/flash_clipboard.cc',
diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc
index 77105a1..7d98356 100644
--- a/ppapi/proxy/file_io_resource.cc
+++ b/ppapi/proxy/file_io_resource.cc
@@ -224,6 +224,23 @@ int32_t FileIOResource::ReadValidated(int64_t offset,
return PP_OK_COMPLETIONPENDING;
}
+int32_t FileIOResource::RequestOSFileHandle(
+ PP_FileHandle* handle,
+ scoped_refptr<TrackedCallback> callback) {
+ int32_t rv = state_manager_.CheckOperationState(
+ FileIOStateManager::OPERATION_EXCLUSIVE, true);
+ if (rv != PP_OK)
+ return rv;
+
+ Call<PpapiPluginMsg_FileIO_RequestOSFileHandleReply>(RENDERER,
+ PpapiHostMsg_FileIO_RequestOSFileHandle(),
+ base::Bind(&FileIOResource::OnPluginMsgRequestOSFileHandleComplete, this,
+ callback, handle));
+
+ state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
+ return PP_OK_COMPLETIONPENDING;
+}
+
void FileIOResource::OnPluginMsgGeneralComplete(
scoped_refptr<TrackedCallback> callback,
const ResourceMessageReplyParams& params) {
@@ -286,6 +303,28 @@ void FileIOResource::OnPluginMsgReadComplete(
callback->Run(result);
}
+void FileIOResource::OnPluginMsgRequestOSFileHandleComplete(
+ scoped_refptr<TrackedCallback> callback,
+ PP_FileHandle* output_handle,
+ const ResourceMessageReplyParams& params) {
+ DCHECK(state_manager_.get_pending_operation() ==
+ FileIOStateManager::OPERATION_EXCLUSIVE);
+
+ if (!TrackedCallback::IsPending(callback)) {
+ state_manager_.SetOperationFinished();
+ return;
+ }
+
+ int32_t result = params.result();
+ IPC::PlatformFileForTransit transit_file;
+ if (!params.TakeFileHandleAtIndex(0, &transit_file))
+ result = PP_ERROR_FAILED;
+ *output_handle = IPC::PlatformFileForTransitToPlatformFile(transit_file);
+
+ // End the operation now. The callback may perform another file operation.
+ state_manager_.SetOperationFinished();
+ callback->Run(result);
+}
+
} // namespace proxy
} // namespace ppapi
-
diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h
index f5a1aa8..a2b928d 100644
--- a/ppapi/proxy/file_io_resource.h
+++ b/ppapi/proxy/file_io_resource.h
@@ -7,6 +7,7 @@
#include <string>
+#include "ppapi/c/private/pp_file_handle.h"
#include "ppapi/proxy/connection.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
@@ -55,6 +56,9 @@ class PPAPI_PROXY_EXPORT FileIOResource
virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual void Close() OVERRIDE;
virtual int32_t GetOSFileDescriptor() OVERRIDE;
+ virtual int32_t RequestOSFileHandle(
+ PP_FileHandle* handle,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual int32_t WillWrite(int64_t offset,
int32_t bytes_to_write,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
@@ -82,6 +86,10 @@ class PPAPI_PROXY_EXPORT FileIOResource
PP_ArrayOutput array_output,
const ResourceMessageReplyParams& params,
const std::string& data);
+ void OnPluginMsgRequestOSFileHandleComplete(
+ scoped_refptr<TrackedCallback> callback,
+ PP_FileHandle* output_handle,
+ const ResourceMessageReplyParams& params);
FileIOStateManager state_manager_;
@@ -92,4 +100,3 @@ class PPAPI_PROXY_EXPORT FileIOResource
} // namespace ppapi
#endif // PPAPI_PROXY_FILE_IO_RESOURCE_H_
-
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc
index 5950061..1e6bbfb 100644
--- a/ppapi/proxy/interface_list.cc
+++ b/ppapi/proxy/interface_list.cc
@@ -58,6 +58,7 @@
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/c/private/ppb_content_decryptor_private.h"
+#include "ppapi/c/private/ppb_file_io_private.h"
#include "ppapi/c/private/ppb_file_ref_private.h"
#include "ppapi/c/private/ppb_flash_clipboard.h"
#include "ppapi/c/private/ppb_flash_file.h"
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index eb921d9..eb87994 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -1393,6 +1393,8 @@ IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_WillSetLength,
IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_GetOSFileDescriptor)
IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileIO_GetOSFileDescriptorReply,
int32_t /* file descriptor */)
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_RequestOSFileHandle)
+IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_RequestOSFileHandleReply)
IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_GeneralReply)
// Flash device ID.
diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h
index 51afbb4..3def529 100644
--- a/ppapi/tests/all_c_includes.h
+++ b/ppapi/tests/all_c_includes.h
@@ -97,6 +97,7 @@
#include "ppapi/c/ppp_mouse_lock.h"
#include "ppapi/c/private/pp_private_font_charset.h"
#include "ppapi/c/private/ppb_content_decryptor_private.h"
+#include "ppapi/c/private/ppb_file_io_private.h"
#include "ppapi/c/private/ppb_flash.h"
#include "ppapi/c/private/ppb_flash_clipboard.h"
#include "ppapi/c/private/ppb_flash_font_file.h"
diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc
index 29348a6..b9cfe5f 100644
--- a/ppapi/tests/test_file_io.cc
+++ b/ppapi/tests/test_file_io.cc
@@ -4,22 +4,41 @@
#include "ppapi/tests/test_file_io.h"
+#include <errno.h>
+#include <fcntl.h>
#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <vector>
#include "ppapi/c/dev/ppb_testing_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_io.h"
+#include "ppapi/c/private/pp_file_handle.h"
#include "ppapi/c/trusted/ppb_file_io_trusted.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/file_system.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/private/file_io_private.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
+#if defined(PPAPI_OS_WIN)
+# include <io.h>
+# include <windows.h>
+// TODO(hamaji): Use standard windows APIs instead of compatibility layer?
+# define lseek _lseek
+# define read _read
+# define write _write
+# define ssize_t int
+#else
+# include <sys/mman.h>
+# include <unistd.h>
+#endif
+
REGISTER_TEST_CASE(FileIO);
namespace {
@@ -148,6 +167,7 @@ void TestFileIO::RunTests(const std::string& filter) {
RUN_TEST_FORCEASYNC_AND_NOT(ParallelWrites, filter);
RUN_TEST_FORCEASYNC_AND_NOT(NotAllowMixedReadWrite, filter);
RUN_TEST_FORCEASYNC_AND_NOT(WillWriteWillSetLength, filter);
+ RUN_TEST_FORCEASYNC_AND_NOT(RequestOSFileHandle, filter);
// TODO(viettrungluu): add tests:
// - that PP_ERROR_PENDING is correctly returned
@@ -1248,6 +1268,116 @@ std::string TestFileIO::TestWillWriteWillSetLength() {
PASS();
}
+std::string TestFileIO::TestRequestOSFileHandle() {
+ TestCompletionCallback callback(instance_->pp_instance(), callback_type());
+
+ pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ pp::FileRef file_ref(file_system, "/file_os_fd");
+
+ callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
+ if (callback.result() != PP_OK)
+ return ReportError("FileSystem::Open", callback.result());
+
+ pp::FileIO_Private file_io(instance_);
+ callback.WaitForResult(file_io.Open(file_ref,
+ PP_FILEOPENFLAG_CREATE |
+ PP_FILEOPENFLAG_TRUNCATE |
+ PP_FILEOPENFLAG_READ |
+ PP_FILEOPENFLAG_WRITE,
+ callback.GetCallback()));
+ if (callback.result() != PP_OK)
+ return ReportError("FileIO::Open", callback.result());
+
+ PP_FileHandle handle = PP_kInvalidFileHandle;
+ callback.WaitForResult(
+ file_io.RequestOSFileHandle(&handle, callback.GetCallback()));
+ if (callback.result() != PP_OK)
+ return ReportError("FileIO::RequestOSFileHandle", callback.result());
+
+ if (handle == PP_kInvalidFileHandle)
+ return "FileIO::RequestOSFileHandle() returned a bad file handle.";
+#if defined(PPAPI_OS_WIN)
+ int fd = _open_osfhandle(reinterpret_cast<intptr_t>(handle),
+ _O_RDWR | _O_BINARY);
+#else
+ int fd = handle;
+#endif
+ if (fd < 0)
+ return "FileIO::RequestOSFileHandle() returned a bad file descriptor.";
+
+ // Check write(2) for the native FD.
+ const std::string msg = "foobar";
+ ssize_t cnt = write(fd, msg.data(), msg.size());
+ if (cnt < 0)
+ return ReportError("write for native FD returned error", errno);
+ if (cnt != static_cast<ssize_t>(msg.size()))
+ return ReportError("write for native FD count mismatch", cnt);
+
+ // Check lseek(2) for the native FD.
+ off_t off = lseek(fd, 0, SEEK_CUR);
+ if (off == static_cast<off_t>(-1))
+ return ReportError("lseek for native FD returned error", errno);
+ if (off != static_cast<off_t>(msg.size()))
+ return ReportError("lseek for native FD offset mismatch", off);
+
+ off = lseek(fd, 0, SEEK_SET);
+ if (off == static_cast<off_t>(-1))
+ return ReportError("lseek for native FD returned error", errno);
+ if (off != 0)
+ return ReportError("lseek for native FD offset mismatch", off);
+
+ // Check read(2) for the native FD.
+ std::string buf(msg.size(), '\0');
+ cnt = read(fd, &buf[0], msg.size());
+ if (cnt < 0)
+ return ReportError("read for native FD returned error", errno);
+ if (cnt != static_cast<ssize_t>(msg.size()))
+ return ReportError("read for native FD count mismatch", cnt);
+ if (msg != buf)
+ return ReportMismatch("read for native FD", buf, msg);
+
+ // TODO(hamaji): Test CreateFileMapping for windows.
+#if !defined(PPAPI_OS_WIN)
+ // Check mmap(2) for read.
+ char* mapped = reinterpret_cast<char*>(
+ mmap(NULL, msg.size(), PROT_READ, MAP_PRIVATE, fd, 0));
+ if (mapped == MAP_FAILED)
+ return ReportError("mmap(r) for native FD returned errno", errno);
+ // Make sure the buffer is cleared.
+ buf = std::string(msg.size(), '\0');
+ memcpy(&buf[0], mapped, msg.size());
+ if (msg != buf)
+ return ReportMismatch("mmap(r) for native FD", buf, msg);
+ int r = munmap(mapped, msg.size());
+ if (r < 0)
+ return ReportError("munmap for native FD returned error", errno);
+
+ // Check mmap(2) for write.
+ mapped = reinterpret_cast<char*>(
+ mmap(NULL, msg.size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
+ if (mapped == MAP_FAILED)
+ return ReportError("mmap(w) for native FD returned errno", errno);
+ // s/foo/baz/
+ strcpy(mapped, "baz");
+
+ r = munmap(mapped, msg.size());
+ if (r < 0)
+ return ReportError("munmap for native FD returned error", errno);
+#endif
+
+#if defined(PPAPI_OS_WIN)
+ int r = _close(fd);
+#else
+ r = close(handle);
+#endif
+ if (r < 0)
+ return ReportError("close for native FD returned error", errno);
+
+ // TODO(hamaji): Check if the file is actually updated?
+
+ PASS();
+}
+
std::string TestFileIO::MatchOpenExpectations(pp::FileSystem* file_system,
size_t open_flags,
size_t expectations) {
diff --git a/ppapi/tests/test_file_io.h b/ppapi/tests/test_file_io.h
index 8db0ba1..36917b5 100644
--- a/ppapi/tests/test_file_io.h
+++ b/ppapi/tests/test_file_io.h
@@ -47,6 +47,7 @@ class TestFileIO : public TestCase {
std::string TestParallelWrites();
std::string TestNotAllowMixedReadWrite();
std::string TestWillWriteWillSetLength();
+ std::string TestRequestOSFileHandle();
// Helper method used by TestOpen().
// |expectations| is a combination of OpenExpectation values. The followings
diff --git a/ppapi/thunk/interfaces_ppb_private_no_permissions.h b/ppapi/thunk/interfaces_ppb_private_no_permissions.h
index 059f603..b00bddc 100644
--- a/ppapi/thunk/interfaces_ppb_private_no_permissions.h
+++ b/ppapi/thunk/interfaces_ppb_private_no_permissions.h
@@ -44,4 +44,7 @@ PROXIED_IFACE(PPB_NetworkMonitor_Private,
PPB_NETWORKMONITOR_PRIVATE_INTERFACE_0_2,
PPB_NetworkMonitor_Private_0_2)
+PROXIED_IFACE(NoAPIName, PPB_FILEIO_PRIVATE_INTERFACE_0_1,
+ PPB_FileIO_Private_0_1)
+
#include "ppapi/thunk/interfaces_postamble.h"
diff --git a/ppapi/thunk/ppb_file_io_api.h b/ppapi/thunk/ppb_file_io_api.h
index b7b3d90..ec7f16d 100644
--- a/ppapi/thunk/ppb_file_io_api.h
+++ b/ppapi/thunk/ppb_file_io_api.h
@@ -7,6 +7,7 @@
#include "base/memory/ref_counted.h"
#include "ppapi/c/ppb_file_io.h"
+#include "ppapi/c/private/pp_file_handle.h"
#include "ppapi/thunk/ppapi_thunk_export.h"
namespace ppapi {
@@ -51,6 +52,11 @@ class PPAPI_THUNK_EXPORT PPB_FileIO_API {
scoped_refptr<TrackedCallback> callback) = 0;
virtual int32_t WillSetLength(int64_t length,
scoped_refptr<TrackedCallback> callback) = 0;
+
+ // Private API.
+ virtual int32_t RequestOSFileHandle(
+ PP_FileHandle* handle,
+ scoped_refptr<TrackedCallback> callback) = 0;
};
} // namespace thunk
diff --git a/ppapi/thunk/ppb_file_io_private_thunk.cc b/ppapi/thunk/ppb_file_io_private_thunk.cc
new file mode 100644
index 0000000..20c7971
--- /dev/null
+++ b/ppapi/thunk/ppb_file_io_private_thunk.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// From private/ppb_file_io_private.idl modified Tue Mar 26 15:29:46 2013.
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_file_io_private.h"
+#include "ppapi/shared_impl/tracked_callback.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_file_io_api.h"
+#include "ppapi/thunk/ppb_instance_api.h"
+#include "ppapi/thunk/resource_creation_api.h"
+#include "ppapi/thunk/thunk.h"
+
+namespace ppapi {
+namespace thunk {
+
+namespace {
+
+int32_t RequestOSFileHandle(PP_Resource file_io,
+ PP_FileHandle* handle,
+ struct PP_CompletionCallback callback) {
+ EnterResource<PPB_FileIO_API> enter(file_io, callback, true);
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(enter.object()->RequestOSFileHandle(
+ handle,
+ enter.callback()));
+}
+
+const PPB_FileIO_Private_0_1 g_ppb_fileio_private_thunk_0_1 = {
+ &RequestOSFileHandle
+};
+
+} // namespace
+
+const PPB_FileIO_Private_0_1* GetPPB_FileIO_Private_0_1_Thunk() {
+ return &g_ppb_fileio_private_thunk_0_1;
+}
+
+} // namespace thunk
+} // namespace ppapi
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index 16dec4a..a35f69c 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -71,6 +71,7 @@
#include "ppapi/c/ppb_view.h"
#include "ppapi/c/ppp.h"
#include "ppapi/c/ppp_instance.h"
+#include "ppapi/c/private/ppb_file_io_private.h"
#include "ppapi/c/private/ppb_file_ref_private.h"
#include "ppapi/c/private/ppb_flash.h"
#include "ppapi/c/private/ppb_flash_clipboard.h"