2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include <sys/types.h>
45 #include "native_client/nonnacl_util/sel_ldr_launcher.h"
46 #include "native_client/tools/npapi_runtime/nacl_npapi.h"
48 #include "native_client/npapi_plugin/origin.h"
49 #include "native_client/npapi_plugin/srpc/closure.h"
50 #include "native_client/npapi_plugin/srpc/npapi_native.h"
51 #include "native_client/npapi_plugin/srpc/plugin.h"
52 #include "native_client/npapi_plugin/srpc/srpc.h"
53 #include "native_client/npapi_plugin/srpc/connected_socket.h"
54 #include "native_client/npapi_plugin/srpc/service_runtime_interface.h"
55 #include "native_client/npapi_plugin/srpc/shared_memory.h"
56 #include "native_client/npapi_plugin/srpc/video.h"
57 #include "native_client/npapi_plugin/srpc/utility.h"
59 #include "native_client/service_runtime/include/sys/fcntl.h"
60 #include "native_client/service_runtime/nacl_desc_io.h"
61 #include "native_client/service_runtime/nacl_host_desc.h"
62 #include "native_client/service_runtime/nacl_log.h"
66 bool Plugin::identifiers_initialized
= false;
67 NPIdentifier
Plugin::kConnectIdent
;
68 NPIdentifier
Plugin::kHeightIdent
;
69 NPIdentifier
Plugin::kHrefIdent
;
70 NPIdentifier
Plugin::kLengthIdent
;
71 NPIdentifier
Plugin::kLocationIdent
;
72 NPIdentifier
Plugin::kMapIdent
;
73 NPIdentifier
Plugin::kModuleReadyIdent
;
74 NPIdentifier
Plugin::kNullNpapiMethodIdent
;
75 NPIdentifier
Plugin::kOnfailIdent
;
76 NPIdentifier
Plugin::kOnloadIdent
;
77 NPIdentifier
Plugin::kReadIdent
;
78 NPIdentifier
Plugin::kShmFactoryIdent
;
79 NPIdentifier
Plugin::kSignaturesIdent
;
80 NPIdentifier
Plugin::kSrcIdent
;
81 NPIdentifier
Plugin::kToStringIdent
;
82 NPIdentifier
Plugin::kUrlAsNaClDescIdent
;
83 NPIdentifier
Plugin::kValueOfIdent
;
84 NPIdentifier
Plugin::kVideoUpdateModeIdent
;
85 NPIdentifier
Plugin::kWidthIdent
;
86 NPIdentifier
Plugin::kWriteIdent
;
89 class LoadNaClAppNotify
: public Closure
{
91 LoadNaClAppNotify(Plugin
*plugin
);
92 virtual ~LoadNaClAppNotify();
93 virtual void Run(NPStream
* stream
, const char* fname
);
98 LoadNaClAppNotify::LoadNaClAppNotify(Plugin
* plugin
)
100 dprintf(("LoadNaClAppNotify ctor\n"));
103 LoadNaClAppNotify::~LoadNaClAppNotify() {
104 dprintf(("LoadNaClAppNotify dtor\n"));
107 void LoadNaClAppNotify::Run(NPStream
* stream
, const char* fname
) {
108 dprintf(("LoadNaClAppNotify Run %p, %p\n", stream
, fname
));
110 plugin_
->set_local_url(fname
);
115 char *MemAllocStrdup(const char *str
) {
116 int lenz
= strlen(str
) + 1;
117 char *dup
= static_cast<char *>(NPN_MemAlloc(lenz
));
119 strncpy(dup
, str
, lenz
);
125 class UrlAsNaClDescNotify
: public Closure
{
127 UrlAsNaClDescNotify(Plugin
*plugin
, std::string url
, NPObject
*callback_obj
);
128 virtual ~UrlAsNaClDescNotify();
129 virtual void Run(NPStream
*stream
, const char *fname
);
133 NPObject
* np_callback_
;
136 UrlAsNaClDescNotify::UrlAsNaClDescNotify(Plugin
* plugin
,
138 NPObject
*callback_obj
) :
141 np_callback_(callback_obj
) {
142 dprintf(("UrlAsNaClDescNotify ctor\n"));
143 NPN_RetainObject(np_callback_
);
146 UrlAsNaClDescNotify::~UrlAsNaClDescNotify() {
147 dprintf(("UrlAsNaClDescNotify dtor\n"));
148 NPN_ReleaseObject(np_callback_
);
152 void UrlAsNaClDescNotify::Run(NPStream
*stream
, const char *fname
) {
153 // open file as NaClHostDesc, create NaClDesc object, make available
155 bool success
= false;
158 NPObject
*nacl_desc
= NULL
;
159 NPIdentifier callback_selector
= Plugin::kOnfailIdent
;
161 dprintf(("UrlAsNaClDescNotify::Run(%p, %s)\n", stream
, fname
));
163 VOID_TO_NPVARIANT(retval
);
164 VOID_TO_NPVARIANT(status
);
166 // execute body once; construct to use break statement to exit body early
170 dprintf(("fetch failed\n"));
171 ScalarToNPVariant("URL fetch failed", &status
);
175 dprintf(("fetched FQ URL %s\n", stream
->url
));
176 std::string url_origin
= nacl::UrlToOrigin(stream
->url
);
177 if (url_origin
!= plugin_
->origin()) {
178 dprintf(("same origin policy forbids access: "
179 " page from origin %s attempted to"
180 " fetch page with origin %s\n",
181 plugin_
->origin().c_str(),
182 url_origin
.c_str()));
184 ScalarToNPVariant("Same origin violation", &status
);
188 NaClHostDesc
*nhd
= static_cast<NaClHostDesc
*>(malloc(sizeof *nhd
));
190 dprintf(("no memory for nhd\n"));
191 // TODO failure callback
193 ScalarToNPVariant("No memory for NaClHostDesc object", &status
);
196 int oserr
= NaClHostDescOpen(nhd
, const_cast<char *>(fname
),
197 NACL_ABI_O_RDONLY
, 0);
199 dprintf(("NaClHostDescOpen failed, NaCl error %d\n", oserr
));
202 ScalarToNPVariant("NaClHostDescOpen failed", &status
);
205 NaClDescIoDesc
*ndiod
= NaClDescIoDescMake(nhd
); // takes ownership of nhd
207 dprintf(("no memory for ndiod\n"));
208 NaClHostDescClose(nhd
);
211 ScalarToNPVariant("No memory for NaClDescIoDesc object", &status
);
214 dprintf(("created ndiod %p\n", ndiod
));
215 nacl_desc
= UnknownHandle::New(plugin_
,
216 reinterpret_cast<NaClDesc
*>(ndiod
));
217 callback_selector
= Plugin::kOnloadIdent
;
219 ScalarToNPVariant(static_cast<NPObject
*>(nacl_desc
), &status
);
220 // NPVariant takes ownership of NPObject nacl_desc
223 dprintf(("calling np_callback_ %p, nacl_desc %p, status %p\n",
224 np_callback_
, nacl_desc
, &status
));
225 NPN_Invoke(plugin_
->npp(), np_callback_
,
226 callback_selector
, &status
, 1, &retval
);
228 dprintf(("releasing status %p\n", &status
));
229 NPN_ReleaseVariantValue(&status
);
230 NPN_ReleaseVariantValue(&retval
);
233 bool Plugin::HasMethod(NPObject
* obj
, NPIdentifier name
) {
234 dprintf(("Plugin::HasMethod(%p, %s)\n", obj
, IdentToString(name
)));
236 Plugin
* plugin
= reinterpret_cast<Plugin
*>(obj
);
238 // Methods may be defined on the plugin as intrinsics.
239 // Test for them first.
240 if ((kShmFactoryIdent
== name
) || (kUrlAsNaClDescIdent
== name
))
242 // Intrinsic properties are not methods.
243 if ((kHeightIdent
== name
) ||
244 (kModuleReadyIdent
== name
) ||
245 (kSrcIdent
== name
) ||
246 (kVideoUpdateModeIdent
== name
) ||
247 (kWidthIdent
== name
))
249 // If the method was not found as an intrinsic, try the loaded module, if any.
250 if (NULL
!= plugin
->socket_
) {
251 return plugin
->socket_
->HasMethod(plugin
->socket_
, name
);
253 // Otherwise, the identifier specifies an invalid method.
257 bool Plugin::Invoke(NPObject
* obj
,
259 const NPVariant
*args
,
262 Plugin
* plugin
= reinterpret_cast<Plugin
*>(obj
);
264 dprintf(("Plugin::Invoke(%p, %s, %d)\n",
265 obj
, IdentToString(name
), arg_count
));
267 VOID_TO_NPVARIANT(*result
);
268 // Methods may be defined on the plugin as intrinsics.
269 // Test for them first.
270 if (kShmFactoryIdent
== name
) {
272 // SharedMemory* __shmFactory(integer)
273 if (1 != arg_count
) {
274 NPN_SetException(obj
, "Bad argument count to __shmFactory");
278 if (!NPVariantToScalar(&args
[0], &size
)) {
279 NPN_SetException(obj
, "incorrect type for argument");
282 SharedMemory
* shared_memory
=
283 SharedMemory::New(plugin
, static_cast<size_t>(size
));
284 if (NULL
== shared_memory
) {
285 NPN_SetException(obj
, "out of memory");
288 ScalarToNPVariant(static_cast<NPObject
*>(shared_memory
), result
);
290 } else if (kUrlAsNaClDescIdent
== name
) {
292 // __UrlAsNaClDesc(string, Function)
293 if (2 != arg_count
) {
294 NPN_SetException(obj
, "Bad argument count to __urlAsNaClDesc");
298 if (!NPVariantToScalar(&args
[0], &url
)) {
299 NPN_SetException(obj
, "Bad first argument to __urlAsNaClDesc");
302 NPObject
* callback_obj
;
303 if (!NPVariantToScalar(&args
[1], &callback_obj
)) {
304 NPN_SetException(obj
, "Bad second argument to __urlAsNaClDesc");
307 dprintf(("loading %s as file\n", url
));
308 UrlAsNaClDescNotify
* callback
=
309 new(std::nothrow
) UrlAsNaClDescNotify(plugin
, url
, callback_obj
);
310 if (NULL
== callback
) {
312 NPN_SetException(obj
, "Out of memory in __urlAsNaClDesc");
315 NPError err
= NPN_GetURLNotify(plugin
->npp_
, url
, NULL
, callback
);
317 if (NPERR_NO_ERROR
!= err
) {
318 dprintf(("failed to load URL %s to local file. Error %d\n", url
, err
));
320 NPN_SetException(obj
, "specified url could not be loaded");
325 // If the method was not found as an intrinsic, try the loaded module, if any.
326 if (NULL
!= plugin
->socket_
) {
327 // Socket/srpc client is responsible for setting exceptions.
328 bool rv
= plugin
->socket_
->Invoke(plugin
->socket_
,
334 NPN_SetException(plugin
, "Method invocation failed");
338 // Otherwise, the identifier specifies an invalid method.
339 NPN_SetException(obj
, "Unrecognized method specified");
343 bool Plugin::InvokeDefault(NPObject
* obj
,
344 const NPVariant
* args
,
347 dprintf(("Plugin::InvokeDefault(%p, %d)\n", obj
, arg_count
));
349 ScalarToNPVariant(1, result
);
353 bool Plugin::HasProperty(NPObject
* obj
, NPIdentifier name
) {
354 Plugin
* plugin
= reinterpret_cast<Plugin
*>(obj
);
356 dprintf(("Plugin::HasProperty(%p, %s)\n", obj
, IdentToString(name
)));
358 // There are some intrinsic properties to the plugin. Check for them first.
359 if ((kHeightIdent
== name
) ||
360 (kModuleReadyIdent
== name
) ||
361 (kSrcIdent
== name
) ||
362 (kVideoUpdateModeIdent
== name
) ||
363 (kWidthIdent
== name
)) {
366 // If property was not found as an intrinsic, try the loaded module, if any.
367 if (plugin
->socket_
) {
368 return plugin
->socket_
->HasProperty(plugin
->socket_
, name
);
370 // Otherwise, the identifier specifies an invalid property.
374 bool Plugin::GetProperty(NPObject
* obj
,
376 NPVariant
* variant
) {
377 Plugin
* plugin
= reinterpret_cast<Plugin
*>(obj
);
379 dprintf(("Plugin::GetProperty(%p, %s)\n", obj
, IdentToString(name
)));
381 VOID_TO_NPVARIANT(*variant
);
382 // There are some intrinsic properties to the plugin. Check for them first.
383 if (kHeightIdent
== name
) {
384 ScalarToNPVariant(plugin
->height_
, variant
);
386 } else if (kModuleReadyIdent
== name
) {
387 ScalarToNPVariant((plugin
->socket_
? 1 : 0), variant
);
389 } else if (kSrcIdent
== name
) {
390 ScalarToNPVariant(plugin
->local_url_
, variant
);
392 } else if (kVideoUpdateModeIdent
== name
) {
393 ScalarToNPVariant(plugin
->video_update_mode_
, variant
);
395 } else if (kWidthIdent
== name
) {
396 ScalarToNPVariant(plugin
->width_
, variant
);
399 // If property was not found as an intrinsic, try the loaded module, if any.
400 if (plugin
->socket_
) {
401 return plugin
->socket_
->GetProperty(plugin
->socket_
, name
, variant
);
403 // Otherwise, the identifier specifies an invalid property.
407 bool Plugin::SetProperty(NPObject
* obj
,
409 const NPVariant
* variant
) {
410 Plugin
* plugin
= reinterpret_cast<Plugin
*>(obj
);
412 dprintf(("Plugin::SetProperty(%p, %s, %p)\n",
413 obj
, IdentToString(name
), variant
));
414 dprintf(("kSrcIdent = %s\n", IdentToString(kSrcIdent
)));
416 // There are some intrinsic properties to the plugin. Check for them first.
417 if (kHeightIdent
== name
) {
419 if (!NPVariantToScalar(variant
, &height
)) {
420 NPN_SetException(obj
, "height must be an integer");
423 plugin
->height_
= height
;
425 } else if (kModuleReadyIdent
== name
) {
426 // Module ready is a read-only property.
427 NPN_SetException(obj
, "__moduleReady is a read-only property");
429 } else if (kSrcIdent
== name
) {
431 if (!NPVariantToScalar(variant
, &url
)) {
432 NPN_SetException(obj
, "src must be a string");
435 if (NULL
!= plugin
->service_runtime_interface_
) {
436 dprintf(("Plugin::SetProperty: unloading previous\n"));
437 // Plugin owns socket_, so when we change to a new socket we need to
438 // give up ownership of the old one.
439 NPN_ReleaseObject(plugin
->socket_
);
440 plugin
->socket_
= NULL
;
441 plugin
->service_runtime_interface_
= NULL
;
443 // Load the new module if the origin of the page is valid.
444 dprintf(("Plugin::SetProperty src = '%s'\n", url
));
445 LoadNaClAppNotify
* callback
=
446 new(std::nothrow
) LoadNaClAppNotify(plugin
);
447 if (NULL
== callback
) {
448 NPN_SetException(obj
, "setting src failed to create callback");
451 NPError err
= NPN_GetURLNotify(plugin
->npp_
, url
, NULL
, callback
);
452 if (NPERR_NO_ERROR
!= err
) {
453 dprintf(("Failed to load URL to local file. Error %d\n", err
));
455 NPN_SetException(obj
, "setting src failed to load url");
459 } else if (kVideoUpdateModeIdent
== name
) {
460 int32_t video_update_mode
;
461 if (!NPVariantToScalar(variant
, &video_update_mode
)) {
462 NPN_SetException(obj
, "videoUpdateMode must be an integer");
465 plugin
->video_update_mode_
= video_update_mode
;
467 } else if (kWidthIdent
== name
) {
469 if (!NPVariantToScalar(variant
, &width
)) {
470 NPN_SetException(obj
, "width must be an integer");
473 plugin
->width_
= width
;
476 // If property was not found as an intrinsic, try the loaded module, if any.
477 if (plugin
->socket_
) {
478 return plugin
->socket_
->SetProperty(plugin
->socket_
, name
, variant
);
480 // Otherwise, the identifier specifies an invalid property.
481 NPN_SetException(obj
, "Attempted to set unrecognized property");
485 Plugin
* Plugin::New(NPP instance
, nacl::SRPC_Plugin
* srpc_plugin
) {
486 static NPClass pluginClass
= {
487 NP_CLASS_STRUCT_VERSION
,
499 NPVariant href_value
;
501 dprintf(("Plugin::New()\n"));
504 reinterpret_cast<Plugin
*>(NPN_CreateObject(instance
, &pluginClass
));
505 if (NULL
== plugin
) {
509 if (!plugin
->Start()) {
510 NPN_ReleaseObject(plugin
);
513 plugin
->srpc_plugin_
= srpc_plugin
;
515 VOID_TO_NPVARIANT(loc_value
);
516 VOID_TO_NPVARIANT(href_value
);
521 != NPN_GetValue(instance
, NPNVWindowNPObject
, &win_obj
)) {
522 dprintf(("Plugin::New: No window object\n"));
523 // no window; no URL as NaCl descriptors will be allowed
527 if (!NPN_GetProperty(instance
, win_obj
, kLocationIdent
, &loc_value
)) {
528 dprintf(("Plugin::New no location property value\n"));
532 if (!NPVariantToScalar(&loc_value
, &loc_obj
)) {
533 dprintf(("Plugin::New location property of wrong type\n"));
537 if (!NPN_GetProperty(instance
, loc_obj
, kHrefIdent
, &href_value
)) {
538 dprintf(("Plugin::New no href property value\n"));
542 if (!NPVariantToScalar(&href_value
, &str
)) {
543 dprintf(("Plugin::New href property of wrong type\n"));
546 std::string
href(str
);
547 dprintf(("Plugin::New: href %s\n", href
.c_str()));
549 plugin
->origin_
= nacl::UrlToOrigin(href
);
550 dprintf(("Plugin::New: origin %s\n", plugin
->origin_
.c_str()));
551 // Check that origin is in the list of permitted origins.
552 plugin
->origin_valid_
= nacl::OriginIsInWhitelist(plugin
->origin_
);
553 // this implementation of same-origin policy does not take
554 // document.domain element into account.
558 NPN_ReleaseVariantValue(&loc_value
);
559 NPN_ReleaseVariantValue(&href_value
);
563 NPObject
*Plugin::Allocate(NPP npp
, NPClass
*theClass
) {
564 dprintf(("Plugin::Allocate()\n"));
566 return new(std::nothrow
) Plugin(npp
);
569 Plugin::Plugin(NPP npp
) :
572 service_runtime_interface_(NULL
),
575 video_update_mode_(nacl::kVideoUpdatePluginPaint
),
579 dprintf(("Plugin::Plugin(%p)\n", this));
581 if (!identifiers_initialized
) {
582 kConnectIdent
= NPN_GetStringIdentifier("connect");
583 kHeightIdent
= NPN_GetStringIdentifier("height");
584 kHrefIdent
= NPN_GetStringIdentifier("href");
585 kLengthIdent
= NPN_GetStringIdentifier("length");
586 kLocationIdent
= NPN_GetStringIdentifier("location");
587 kMapIdent
= NPN_GetStringIdentifier("map");
588 kModuleReadyIdent
= NPN_GetStringIdentifier("__moduleReady");
589 kNullNpapiMethodIdent
= NPN_GetStringIdentifier("__nullNpapiMethod");
590 kOnfailIdent
= NPN_GetStringIdentifier("onfail");
591 kOnloadIdent
= NPN_GetStringIdentifier("onload");
592 kReadIdent
= NPN_GetStringIdentifier("read");
593 kShmFactoryIdent
= NPN_GetStringIdentifier("__shmFactory");
594 kSignaturesIdent
= NPN_GetStringIdentifier("__signatures");
595 kSrcIdent
= NPN_GetStringIdentifier("src");
596 kToStringIdent
= NPN_GetStringIdentifier("toString");
597 kUrlAsNaClDescIdent
= NPN_GetStringIdentifier("__urlAsNaClDesc");
598 kValueOfIdent
= NPN_GetStringIdentifier("valueOf");
599 kVideoUpdateModeIdent
= NPN_GetStringIdentifier("videoUpdateMode");
600 kWidthIdent
= NPN_GetStringIdentifier("width");
601 kWriteIdent
= NPN_GetStringIdentifier("write");
603 identifiers_initialized
= true;
607 bool Plugin::Start() {
608 struct NaClDesc
* pair
[2];
610 if (0 != NaClCommonDescMakeBoundSock(pair
)) {
611 dprintf(("Plugin::Plugin: make bound sock failed.\n"));
614 if (!NaClNrdXferEffectorCtor(&eff_
, pair
[0])) {
615 dprintf(("Plugin::Plugin: EffectorCtor failed.\n"));
618 effp_
= (struct NaClDescEffector
*) &eff_
;
623 dprintf(("Plugin::~Plugin(%p)\n", this));
625 if (NULL
!= local_url_
)
626 NPN_MemFree(local_url_
);
629 void Plugin::Deallocate(NPObject
* obj
) {
630 Plugin
* plugin
= reinterpret_cast<Plugin
*>(obj
);
632 dprintf(("Plugin::Deallocate(%p)\n", plugin
));
635 if (NULL
!= plugin
->service_runtime_interface_
) {
636 plugin
->service_runtime_interface_
->Shutdown();
638 // Free the connected socket for this plugin, if any.
639 if (NULL
!= plugin
->socket_
) {
640 dprintf(("Plugin::Deallocate: unloading\n"));
641 // Deallocating a plugin releases ownership of the socket.
642 NPN_ReleaseObject(plugin
->socket_
);
644 // Clear the pointers to the connected socket and service runtime interface.
645 plugin
->socket_
= NULL
;
646 plugin
->service_runtime_interface_
= NULL
;
647 // Delete this plugin instance.
651 void Plugin::Invalidate(NPObject
* obj
) {
652 Plugin
* plugin
= reinterpret_cast<Plugin
*>(obj
);
654 dprintf(("Plugin::Invalidate(%p)\n", obj
));
656 // perhaps change to do soft shutdown here?
657 if (NULL
!= plugin
->service_runtime_interface_
) {
658 plugin
->service_runtime_interface_
->Shutdown();
659 // TODO: this needs to free the interface and set it to NULL.
661 // After invalidation, the browser does not respect reference counting,
662 // so we shut down here what we can and prevent attempts to shut down
663 // other linked structures in Deallocate.
666 void Plugin::set_local_url(const char* name
) {
667 dprintf(("Plugin::set_local_url(%s)\n", name
));
668 local_url_
= MemAllocStrdup(name
);
671 // Create a new service node from a downloaded service.
672 bool Plugin::Load() {
673 dprintf(("Plugin::Load(%s)\n", local_url_
));
674 // If the origin is not in the whitelist, refuse to load.
675 if (!origin_valid_
) {
676 printf("Load failed: NaCl module did not come from a whitelisted"
677 " source.\nSee npapi_plugin/origin.cc for the list.");
679 NPN_GetValue(npp(), NPNVWindowNPObject
, &window
);
681 script
.utf8characters
= "alert('Load failed: NaCl module did not"
682 " come from a whitelisted source.\\n"
683 "See npapi_plugin/origin.cc"
685 script
.utf8length
= strlen(script
.utf8characters
);
687 NPN_Evaluate(npp(), window
, &script
, &result
);
690 // Catch any bad accesses, etc., while loading.
691 nacl_srpc::ScopedCatchSignals
sigcatcher(
692 (nacl_srpc::ScopedCatchSignals::SigHandlerType
) SignalHandler
);
693 if (int signal_value
= PLUGIN_SETJMP(loader_env
, 1)) {
697 dprintf(("Load: NaCl module from '%s'\n", local_url_
));
699 // check ABI version compatibility
700 NPError np
= nacl::CheckExecutableVersion(npp(), local_url_
);
701 if (NPERR_NO_ERROR
!= np
) {
702 dprintf(("Load: FAILED due to possible ABI version mismatch\n"));
705 // Load a file via a forked sel_ldr process.
706 service_runtime_interface_
= new(std::nothrow
) ServiceRuntimeInterface(this);
707 if (NULL
== service_runtime_interface_
) {
708 dprintf((" ServiceRuntimeInterface Ctor failed\n"));
711 if (!service_runtime_interface_
->Start(local_url_
)) {
712 dprintf((" Load: FAILED to start service runtime"));
715 dprintf((" Load: started sel_ldr\n"));
716 socket_
= service_runtime_interface_
->default_socket();
717 dprintf((" Load: established socket %p\n", socket_
));
718 // Plugin takes ownership of socket_ from service_runtime_interface_,
719 // so we do not need to call NPN_RetainObject.
723 void Plugin::SignalHandler(int value
) {
724 dprintf(("Plugin::SignalHandler()\n"));
725 PLUGIN_LONGJMP(loader_env
, value
);
729 PLUGIN_JMPBUF
Plugin::loader_env
;
732 } // namespace nacl_srpc