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 std::string NaClSubprocess::detailed_description() const { 16 std::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 std::string& method_name, 44 const std::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 std::string& method_name, 55 const std::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