15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2012 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Post-message based test for simple rpc based access to name services.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Converted from srpc_nameservice_test (deprecated), i.e., C -> C++,
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * srpc -> post message.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <inttypes.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/fcntl.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/nacl_scoped_ptr.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "native_client/src/public/imc_syscalls.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "native_client/src/public/name_service.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/srpc/nacl_srpc.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
329ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "ppapi/native_client/src/untrusted/nacl_ppapi_util/nacl_ppapi_util.h"
339ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "ppapi/native_client/src/untrusted/nacl_ppapi_util/string_buffer.h"
349ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RNG_OUTPUT_BYTES  1024
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BYTES_PER_LINE    32
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BYTE_SPACING      4
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool            g_ns_channel_initialized = false;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NaClSrpcChannel g_ns_channel;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void dump_output(nacl::StringBuffer *sb, int d, size_t nbytes) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::scoped_array<uint8_t> bytes;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t                      got;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int                         copied;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes.reset(new uint8_t[nbytes]);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == bytes.get()) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    perror("dump_output");
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "No memory\n");
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the RNG output.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (got = 0; got < nbytes; got += copied) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    copied = read(d, bytes.get() + got, nbytes - got);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (-1 == copied) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      perror("dump_output:read");
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fprintf(stderr, "read failure\n");
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("read(%d, ..., %u) -> %d\n", d, nbytes - got, copied);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hex dump it so we can eyeball it for randomness.  Ideally we
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would have a chi-square test here to test randomness.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ix = 0; ix < got; ++ix) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (0 == (ix & (BYTES_PER_LINE - 1))) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sb->Printf("\n%04x:", ix);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (0 == (ix & (BYTE_SPACING - 1))) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sb->Printf(" ");
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sb->Printf("%02x", bytes[ix]);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sb->Printf("\n");
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Initialize(const pp::Var& message_data, nacl::StringBuffer* sb) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_ns_channel_initialized) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ns = -1;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl_nameservice(&ns);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("ns = %d\n", ns);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(-1 != ns);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int connected_socket = imc_connect(ns);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(-1 != connected_socket);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!NaClSrpcClientCtor(&g_ns_channel, connected_socket)) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sb->Printf("Srpc client channel ctor failed\n");
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    close(ns);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sb->Printf("NaClSrpcClientCtor succeeded\n");
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  close(ns);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_ns_channel_initialized = 1;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Dump RNG output into a string.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RngDump(const pp::Var& message_data, nacl::StringBuffer* sb) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClSrpcError rpc_result;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int status;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rng;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(message_data, sb);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rpc_result = NaClSrpcInvokeBySignature(&g_ns_channel,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         NACL_NAME_SERVICE_LOOKUP,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "SecureRandom", O_RDONLY,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &status, &rng);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(NACL_SRPC_RESULT_OK == rpc_result);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("rpc status %d\n", status);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(NACL_NAME_SERVICE_SUCCESS == status);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf("rng descriptor %d\n", rng);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dump_output(sb, rng, RNG_OUTPUT_BYTES);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  close(rng);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ManifestTest(const pp::Var& message_data, nacl::StringBuffer* sb) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int status = -1;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int manifest;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(message_data, sb);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make the name service lookup for the manifest service descriptor.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NACL_SRPC_RESULT_OK !=
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NaClSrpcInvokeBySignature(&g_ns_channel, NACL_NAME_SERVICE_LOOKUP,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                "ManifestNameService", O_RDWR,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &status, &manifest) ||
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NACL_NAME_SERVICE_SUCCESS != status) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "nameservice lookup failed, status %d\n", status);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sb->Printf("Got manifest descriptor %d\n", manifest);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (-1 == manifest) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect to manifest name server.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int manifest_conn = imc_connect(manifest);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  close(manifest);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sb->Printf("got manifest connection %d\n", manifest_conn);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (-1 == manifest_conn) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sb->Printf("could not connect\n");
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sb->DiscardOutput();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sb->Printf("ManifestTest: basic connectivity ok\n");
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  close(manifest_conn);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PostMessageHandlerDesc {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char const *request;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void (*handler)(const pp::Var& message_data, nacl::StringBuffer* out);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This object represents one time the page says <embed>.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MyInstance : public pp::Instance {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MyInstance(PP_Instance instance) : pp::Instance(instance) {}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MyInstance() {}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void HandleMessage(const pp::Var& message_data);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HandleMessage gets invoked when postMessage is called on the DOM
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// element associated with this plugin instance.  In this case, if we
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are given a string, we'll post a message back to JavaScript with a
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reply string -- essentially treating this as a string-based RPC.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MyInstance::HandleMessage(const pp::Var& message_data) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static struct PostMessageHandlerDesc kMsgHandlers[] = {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "init", Initialize },
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "rng", RngDump },
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "manifest_test", ManifestTest },
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { reinterpret_cast<char const *>(NULL),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<void (*)(const pp::Var&, nacl::StringBuffer*)>(NULL) }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::StringBuffer sb;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message_data.is_string()) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string op_name(message_data.AsString());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string reply;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t len;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "Searching for handler for request \"%s\".\n",
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            op_name.c_str());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t ix = 0; kMsgHandlers[ix].request != NULL; ++ix) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (op_name == kMsgHandlers[ix].request) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(stderr, "found at index %u\n", ix);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kMsgHandlers[ix].handler(message_data, &sb);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reply = sb.ToString();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    len = strlen(reply.c_str());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "posting reply len %d\n", len);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fprintf(stderr, "posting reply \"%s\".\n", sb.ToString().c_str());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "posting reply \"");
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fflush(stderr);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    write(2, reply.c_str(), len);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "\".\n");
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fflush(stderr);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PostMessage(pp::Var(sb.ToString()));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "returning\n");
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fflush(stderr);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This object is the global object representing this plugin library as long
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as it is loaded.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MyModule : public pp::Module {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MyModule() : pp::Module() {}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MyModule() {}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override CreateInstance to create your customized Instance object.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual pp::Instance* CreateInstance(PP_Instance instance) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new MyInstance(instance);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Factory function for your specialization of the Module object.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Module* CreateModule() {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new MyModule();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace pp
233