15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/srpc/nacl_srpc.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/plugin_error.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/srpc_params.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace plugin { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nacl::string NaClSubprocess::detailed_description() const { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl::stringstream ss; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << description() 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "={ this=" << static_cast<const void*>(this) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", srpc_client=" << static_cast<void*>(srpc_client_.get()) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", service_runtime=" << static_cast<void*>(service_runtime_.get()) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " }"; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ss.str(); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Shutdown the socket connection and service runtime, in that order. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NaClSubprocess::Shutdown() { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srpc_client_.reset(NULL); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service_runtime_.get() != NULL) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_runtime_->Shutdown(); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_runtime_.reset(NULL); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NaClSubprocess::~NaClSubprocess() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shutdown(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NaClSubprocess::StartSrpcServices() { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srpc_client_.reset(service_runtime_->SetupAppChannel()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL != srpc_client_.get(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NaClSubprocess::InvokeSrpcMethod(const nacl::string& method_name, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const nacl::string& input_signature, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrpcParams* params, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list vl; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start(vl, params); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = VInvokeSrpcMethod(method_name, input_signature, params, vl); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end(vl); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NaClSubprocess::VInvokeSrpcMethod(const nacl::string& method_name, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const nacl::string& input_signature, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrpcParams* params, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list vl) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == srpc_client_.get()) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("VInvokeSrpcMethod (no srpc_client_)\n")); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!srpc_client_->HasMethod(method_name)) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("VInvokeSrpcMethod (no %s method found)\n", 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_name.c_str())); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!srpc_client_->InitParams(method_name, params)) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("VInvokeSrpcMethod (InitParams failed)\n")); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Marshall inputs. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < input_signature.length(); ++i) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c = input_signature[i]; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only handle the limited number of SRPC types used for PNaCl. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add more as needed. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (c) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("PnaclSrpcLib::InvokeSrpcMethod unhandled type: %c\n", 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NACL_SRPC_ARG_TYPE_BOOL: { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int input = va_arg(vl, int); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->u.bval = input; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NACL_SRPC_ARG_TYPE_DOUBLE: { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double input = va_arg(vl, double); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->u.dval = input; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SrpcParam's destructor *should* free the allocated array 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* orig_arr = va_arg(vl, const char*); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t len = va_arg(vl, size_t); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* input = (char *)malloc(len); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("VInvokeSrpcMethod (allocation failure)\n")); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(input, orig_arr, len); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->arrays.carr = input; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->u.count = static_cast<nacl_abi_size_t>(len); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NACL_SRPC_ARG_TYPE_HANDLE: { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClSrpcImcDescType input = va_arg(vl, NaClSrpcImcDescType); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->u.hval = input; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NACL_SRPC_ARG_TYPE_INT: { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t input = va_arg(vl, int32_t); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->u.ival = input; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NACL_SRPC_ARG_TYPE_LONG: { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t input = va_arg(vl, int64_t); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->u.lval = input; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NACL_SRPC_ARG_TYPE_STRING: { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SrpcParam's destructor *should* free the dup'ed string. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* orig_str = va_arg(vl, const char*); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* input = strdup(orig_str); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(("VInvokeSrpcMethod (allocation failure)\n")); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ins()[i]->arrays.str = input; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return srpc_client_->Invoke(method_name, params); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace plugin 137