Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / subprocess / process_lib.cc
1 /*
2  * Copyright (c) 2013 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #include "native_client/tests/subprocess/process_lib.h"
8
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13
14 // TODO(bsy) get rid of debug printfs
15
16 // The header files below access private, not-guaranteed-to-be-stable
17 // ABIs/APIs.
18 #include "native_client/src/public/imc_syscalls.h"
19 #include "native_client/src/public/name_service.h"
20 #include "native_client/src/public/secure_service.h"
21 #include "native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h"
22 #include "native_client/src/trusted/service_runtime/include/sys/nacl_kernel_service.h"
23 // get NACL_SYSCALL_BLOCK_SIZE, NACL_SYSCALL_START_ADDR
24 #include "native_client/src/trusted/service_runtime/nacl_config.h"
25
26 namespace NaClProcessLib {
27
28 SrpcClientConnection::SrpcClientConnection() : initialized_(false) {}
29
30 SrpcClientConnection::~SrpcClientConnection() {
31   if (initialized_) {
32     close(desc_);
33     NaClSrpcDtor(&chan_);
34   }
35 }
36
37 bool SrpcClientConnection::InitializeFromConnectedDesc(int desc) {
38   if (!NaClSrpcClientCtor(&chan_, desc)) {
39     fprintf(stderr,
40             "SrpcClientConnection::InitializeFromConnectedDesc failed\n");
41     return false;
42   }
43   desc_ = desc;
44   initialized_ = true;
45   return true;
46 }
47
48 bool SrpcClientConnection::InitializeFromConnectionCapability(int cap) {
49   int conn = imc_connect(cap);
50   if (-1 == conn) {
51     fprintf(stderr,
52             "SrpcClientConnection:InitializeFromConnectionCapability"
53             " imc_connect failed, error %d\n", errno);
54     return false;
55   }
56   return InitializeFromConnectedDesc(conn);
57 }
58
59 int NameServiceClient::Resolve(std::string name) {
60   NaClSrpcResultCodes result;
61   int status;
62   int desc = -1;
63   if (!initialized()) {
64     return -1;
65   }
66   result = NaClSrpcInvokeBySignature(chan(), NACL_NAME_SERVICE_LOOKUP,
67                                      name.c_str(), O_RDONLY,
68                                      &status, &desc);
69   if (NACL_SRPC_RESULT_OK != result) {
70     fprintf(stderr, "Service lookup RPC failed (%d): %s\n", result,
71             NaClSrpcErrorString(result));
72     return -1;
73   }
74   if (NACL_NAME_SERVICE_SUCCESS != status) {
75     fprintf(stderr, "Resolve failed for \"%s\"; error %d\n", name.c_str(),
76             status);
77     return -1;
78   }
79
80   return desc;
81 }
82
83 int NameServiceFactory::name_service_cap;
84 NameServiceFactory *NameServiceFactory::singleton = NULL;
85
86 NameServiceFactory *NameServiceFactory::NameServiceFactorySingleton() {
87   return singleton;
88 }
89
90 NameServiceFactory::NameServiceFactory() {}
91
92 typedef int (*nameservice_tramp_t)(int *desc);
93
94 bool NameServiceFactory::Init() {
95   if (NULL != singleton) {
96     return false;
97   }
98   nameservice_tramp_t nameservice_tramp =
99       reinterpret_cast<nameservice_tramp_t>(
100           (NACL_SYSCALL_START_ADDR +
101            NACL_SYSCALL_BLOCK_SIZE * NACL_sys_nameservice));
102
103   name_service_cap = -1;
104   if (-1 == (*nameservice_tramp)(&name_service_cap)) {
105     return false;
106   }
107   singleton = new NameServiceFactory();
108   return (NULL != singleton);
109 }
110
111 NameServiceClient *NameServiceFactory::NameService() {
112   NameServiceClient *client = new NameServiceClient();
113   if (!client->InitializeFromConnectionCapability(name_service_cap)) {
114     delete client;
115     return NULL;
116   }
117   return client;
118 }
119
120 bool KernelServiceClient::CreateProcess(int *child_sockaddr,
121                                         int *app_sockaddr) {
122   if (!initialized()) {
123     return 0;
124   }
125   NaClSrpcResultCodes result;
126   int status;
127   result = NaClSrpcInvokeBySignature(chan(), NACL_KERNEL_SERVICE_CREATE_PROCESS,
128                                      &status, child_sockaddr, app_sockaddr);
129   if (NACL_SRPC_RESULT_OK != result) {
130     fprintf(stderr, "create process failed (%d): %s\n", result,
131             NaClSrpcErrorString(result));
132     return 0;
133   }
134   return 1;
135 }
136
137 ServiceRuntimeClient* KernelServiceClient::ServiceRuntimeClientFactory(
138     int child_sockaddr) {
139   ServiceRuntimeClient* src = new ServiceRuntimeClient;
140   if (!src->InitializeFromConnectionCapability(child_sockaddr)) {
141     delete src;
142     return NULL;
143   }
144   return src;
145 }
146
147 NaClErrorCode ServiceRuntimeClient::RunNaClModule(int module_descriptor) {
148   NaClSrpcResultCodes result;
149   int status;
150   if (!initialized()) {
151     return LOAD_INTERNAL;
152   }
153   printf("Entered RunNaClModule\n");
154   printf("chan: %p\n", (void*) chan());
155   result = NaClSrpcInvokeBySignature(chan(), NACL_SECURE_SERVICE_LOAD_MODULE,
156                                      module_descriptor);
157   printf("load_module result %d\n", result);
158   if (NACL_SRPC_RESULT_OK != result) {
159     fprintf(stderr, "load_module RPC failed (%d): %s\n",
160             result, NaClSrpcErrorString(result));
161     return LOAD_INTERNAL;
162   }
163   result = NaClSrpcInvokeBySignature(chan(), "start_module::i", &status);
164   printf("start_module result %d\n", result);
165   if (NACL_SRPC_RESULT_OK != result) {
166     fprintf(stderr, "start_module RPC failed (%d): %s\n",
167             result, NaClSrpcErrorString(result));
168     return LOAD_INTERNAL;
169   }
170   printf("start_module status: %d\n", status);
171   return static_cast<NaClErrorCode>(status);
172 }
173
174 }  // namespace NaClProcessLib