Home | History | Annotate | Download | only in plugin
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
      6 
      7 #include <stdarg.h>
      8 
      9 #include "native_client/src/shared/srpc/nacl_srpc.h"
     10 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
     11 #include "ppapi/native_client/src/trusted/plugin/srpc_params.h"
     12 
     13 namespace plugin {
     14 
     15 nacl::string NaClSubprocess::detailed_description() const {
     16   nacl::stringstream ss;
     17   ss << description()
     18      << "={ this=" << static_cast<const void*>(this)
     19      << ", srpc_client=" << static_cast<void*>(srpc_client_.get())
     20      << ", service_runtime=" << static_cast<void*>(service_runtime_.get())
     21      << " }";
     22   return ss.str();
     23 }
     24 
     25 // Shutdown the socket connection and service runtime, in that order.
     26 void NaClSubprocess::Shutdown() {
     27   srpc_client_.reset(NULL);
     28   if (service_runtime_.get() != NULL) {
     29     service_runtime_->Shutdown();
     30     service_runtime_.reset(NULL);
     31   }
     32 }
     33 
     34 NaClSubprocess::~NaClSubprocess() {
     35   Shutdown();
     36 }
     37 
     38 bool NaClSubprocess::StartSrpcServices() {
     39   srpc_client_.reset(service_runtime_->SetupAppChannel());
     40   return NULL != srpc_client_.get();
     41 }
     42 
     43 bool NaClSubprocess::InvokeSrpcMethod(const nacl::string& method_name,
     44                                       const nacl::string& input_signature,
     45                                       SrpcParams* params,
     46                                       ...) {
     47   va_list vl;
     48   va_start(vl, params);
     49   bool result = VInvokeSrpcMethod(method_name, input_signature, params, vl);
     50   va_end(vl);
     51   return result;
     52 }
     53 
     54 bool NaClSubprocess::VInvokeSrpcMethod(const nacl::string& method_name,
     55                                        const nacl::string& input_signature,
     56                                        SrpcParams* params,
     57                                        va_list vl) {
     58   if (NULL == srpc_client_.get()) {
     59     PLUGIN_PRINTF(("VInvokeSrpcMethod (no srpc_client_)\n"));
     60     return false;
     61   }
     62   if (!srpc_client_->HasMethod(method_name)) {
     63     PLUGIN_PRINTF(("VInvokeSrpcMethod (no %s method found)\n",
     64                    method_name.c_str()));
     65     return false;
     66   }
     67   if (!srpc_client_->InitParams(method_name, params)) {
     68     PLUGIN_PRINTF(("VInvokeSrpcMethod (InitParams failed)\n"));
     69     return false;
     70   }
     71   // Marshall inputs.
     72   for (size_t i = 0; i < input_signature.length(); ++i) {
     73     char c = input_signature[i];
     74     // Only handle the limited number of SRPC types used for PNaCl.
     75     // Add more as needed.
     76     switch (c) {
     77       default:
     78         PLUGIN_PRINTF(("PnaclSrpcLib::InvokeSrpcMethod unhandled type: %c\n",
     79                        c));
     80         return false;
     81       case NACL_SRPC_ARG_TYPE_BOOL: {
     82         int input = va_arg(vl, int);
     83         params->ins()[i]->u.bval = input;
     84         break;
     85       }
     86       case NACL_SRPC_ARG_TYPE_DOUBLE: {
     87         double input = va_arg(vl, double);
     88         params->ins()[i]->u.dval = input;
     89         break;
     90       }
     91       case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: {
     92         // SrpcParam's destructor *should* free the allocated array
     93         const char* orig_arr = va_arg(vl, const char*);
     94         size_t len = va_arg(vl, size_t);
     95         char* input = (char *)malloc(len);
     96         if (!input) {
     97           PLUGIN_PRINTF(("VInvokeSrpcMethod (allocation failure)\n"));
     98           return false;
     99         }
    100         memcpy(input, orig_arr, len);
    101         params->ins()[i]->arrays.carr = input;
    102         params->ins()[i]->u.count = static_cast<nacl_abi_size_t>(len);
    103         break;
    104       }
    105       case NACL_SRPC_ARG_TYPE_HANDLE: {
    106         NaClSrpcImcDescType input = va_arg(vl, NaClSrpcImcDescType);
    107         params->ins()[i]->u.hval = input;
    108         break;
    109       }
    110       case NACL_SRPC_ARG_TYPE_INT: {
    111         int32_t input = va_arg(vl, int32_t);
    112         params->ins()[i]->u.ival = input;
    113         break;
    114       }
    115       case NACL_SRPC_ARG_TYPE_LONG: {
    116         int64_t input = va_arg(vl, int64_t);
    117         params->ins()[i]->u.lval = input;
    118         break;
    119       }
    120       case NACL_SRPC_ARG_TYPE_STRING: {
    121         // SrpcParam's destructor *should* free the dup'ed string.
    122         const char* orig_str = va_arg(vl, const char*);
    123         char* input = strdup(orig_str);
    124         if (!input) {
    125           PLUGIN_PRINTF(("VInvokeSrpcMethod (allocation failure)\n"));
    126           return false;
    127         }
    128         params->ins()[i]->arrays.str = input;
    129         break;
    130       }
    131     }
    132   }
    133   return srpc_client_->Invoke(method_name, params);
    134 }
    135 
    136 }  // namespace plugin
    137