OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 The Native Client 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 "native_client/src/untrusted/init/process_lib.h" |
| 6 |
| 7 #include <errno.h> |
| 8 #include <fcntl.h> |
| 9 #include <stdlib.h> |
| 10 #include <unistd.h> |
| 11 |
| 12 #include "native_client/src/public/imc_syscalls.h" |
| 13 #include "native_client/src/public/name_service.h" |
| 14 #include "native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h
" |
| 15 #include "native_client/src/trusted/service_runtime/include/sys/nacl_kernel_serv
ice.h" |
| 16 |
| 17 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
| 18 |
| 19 namespace { |
| 20 |
| 21 void InsertHandler( |
| 22 struct NaClSrpcRpc *rpc, |
| 23 struct NaClSrpcArg *in_args[], |
| 24 struct NaClSrpcArg *out_args[], |
| 25 struct NaClSrpcClosure *done_cls) { |
| 26 NameService *service = |
| 27 reinterpret_cast<NameService *>(rpc->channel->server_instance_data); |
| 28 NaClSrpcClosureRunner on_return(done_cls); |
| 29 rpc->result = NACL_SRPC_RESULT_OK; |
| 30 |
| 31 char *name = in_args[0]->arrays.str; |
| 32 int mode = in_args[1]->u.ival; |
| 33 int d = in_args[2]->u.hval; |
| 34 |
| 35 out_args[0]->u.ival = service->CreateEntry(std::string(name), mode, d); |
| 36 } |
| 37 |
| 38 void LookupHandler( |
| 39 struct NaClSrpcRpc *rpc, |
| 40 struct NaClSrpcArg **in_args, |
| 41 struct NaClSrpcArg **out_args, |
| 42 struct NaClSrpcClosure *done_cls) { |
| 43 NameService *service = |
| 44 reinterpret_cast<NameService *>(rpc->channel->server_instance_data); |
| 45 NaClSrpcClosureRunner on_return(done_cls); |
| 46 rpc->result = NACL_SRPC_RESULT_OK; |
| 47 |
| 48 char *name = in_args[0]->arrays.str; |
| 49 int flags = in_args[1]->u.ival; |
| 50 int d; |
| 51 |
| 52 int status = service->Resolve(std::string(name), flags, &d); |
| 53 out_args[0]->u.ival = status; |
| 54 out_args[1]->u.hval = (NACL_NAME_SERVICE_SUCCESS == status) ? d : -1; |
| 55 } |
| 56 |
| 57 void DeleteHandler( |
| 58 struct NaClSrpcRpc *rpc, |
| 59 struct NaClSrpcArg **in_args, |
| 60 struct NaClSrpcArg **out_args, |
| 61 struct NaClSrpcClosure *done_cls) { |
| 62 NameService *service = |
| 63 reinterpret_cast<NameService *>(rpc->channel->server_instance_data); |
| 64 NaClSrpcClosureRunner on_return(done_cls); |
| 65 rpc->result = NACL_SRPC_RESULT_OK; |
| 66 |
| 67 char *name = in_args[0]->arrays.str; |
| 68 |
| 69 out_args[0]->u.ival = static_cast<int32_t>( |
| 70 service->Delete(std::string(name))); |
| 71 } |
| 72 |
| 73 void ListHandler( |
| 74 struct NaClSrpcRpc *rpc, |
| 75 struct NaClSrpcArg *in_args[], |
| 76 struct NaClSrpcArg *out_args[], |
| 77 struct NaClSrpcClosure *done_cls) { |
| 78 NameService *service = |
| 79 reinterpret_cast<NameService *>(rpc->channel->server_instance_data); |
| 80 NaClSrpcClosureRunner on_return(done_cls); |
| 81 rpc->result = NACL_SRPC_RESULT_OK; |
| 82 |
| 83 size_t nbytes = out_args[0]->u.count; |
| 84 char *dest = out_args[0]->arrays.carr; |
| 85 |
| 86 out_args[0]->u.count = static_cast<uint32_t>( |
| 87 service->Enumerate(dest, nbytes)); |
| 88 } |
| 89 |
| 90 } |
| 91 |
| 92 namespace nacl { |
| 93 |
| 94 struct NaClSrpcHandlerDesc const NameService::handlers[] = { |
| 95 { NACL_NAME_SERVICE_LIST, ListHandler, }, |
| 96 { NACL_NAME_SERVICE_INSERT, InsertHandler, }, |
| 97 { NACL_NAME_SERVICE_LOOKUP, LookupHandler, }, |
| 98 { NACL_NAME_SERVICE_DELETE, DeleteHandler, }, |
| 99 { static_cast<char const *>(NULL), static_cast<NaClSrpcMethod>(NULL), }, |
| 100 }; |
| 101 |
| 102 int NameService::CreateEntry(std::string name, int mode, int d) { |
| 103 } |
| 104 |
| 105 int NameService::ResolveEntry(std::string name, int flags, int *out) { |
| 106 int status = NACL_NAME_SERVICE_NAME_NOT_FOUND; |
| 107 |
| 108 iterator it = entries_.find(name); |
| 109 if (it != entries_.end()) { |
| 110 } |
| 111 return status; |
| 112 } |
| 113 |
| 114 int NameService::DeleteEntry(std::string name) { |
| 115 ScopedLock(mu_); |
| 116 |
| 117 iterator it = entries_.find(name); |
| 118 if (it != entries_.end()) { |
| 119 entries_.erase(it); |
| 120 |
| 121 } |
| 122 |
| 123 entries_.erase(name); |
| 124 |
| 125 return status; |
| 126 } |
| 127 |
| 128 int NameService::List() { |
| 129 } |
| 130 |
| 131 std::vector<std::string> NameServiceClient::List() { |
| 132 std::vector<std::string> rv; |
| 133 if (!initialized()) { |
| 134 return rv; |
| 135 } |
| 136 NaClSrpcResultCodes result; |
| 137 uint32_t buffer_size = 4096; |
| 138 uint32_t used_bytes; |
| 139 char *buffer = NULL; |
| 140 for (;;) { |
| 141 buffer = new char[buffer_size]; |
| 142 used_bytes = buffer_size; |
| 143 result = NaClSrpcInvokeBySignature(chan(), |
| 144 NACL_NAME_SERVICE_LIST, |
| 145 &used_bytes, buffer); |
| 146 if (NACL_SRPC_RESULT_OK != result) { |
| 147 // Some kind of internal error, abort and indicate by returning |
| 148 // an empty vector. |
| 149 return rv; |
| 150 } |
| 151 if (used_bytes < buffer_size) { |
| 152 break; |
| 153 } |
| 154 buffer_size = 2 * buffer_size; |
| 155 delete[] buffer; |
| 156 buffer = new char[buffer_size]; |
| 157 } |
| 158 std::string name_list(buffer, used_bytes); |
| 159 delete[] buffer; |
| 160 // Parse name_list, separating at the ASCII NUL character |
| 161 // (forbidden in names), into a vector of strings. |
| 162 size_t start_ix = 0; |
| 163 size_t space_ix; |
| 164 |
| 165 while (start_ix < name_list.size()) { |
| 166 space_ix = name_list.find('\0', start_ix); |
| 167 if (space_ix == std::string::npos) { |
| 168 space_ix = used_bytes; |
| 169 } |
| 170 rv.push_back(name_list.substr(start_ix, space_ix - start_ix)); |
| 171 if (space_ix != std::string::npos) { |
| 172 start_ix = space_ix + 1; |
| 173 } else { |
| 174 start_ix = space_ix; |
| 175 } |
| 176 } |
| 177 return rv; |
| 178 } |
| 179 |
| 180 int NameServiceClient::Resolve(std::string name) { |
| 181 NaClSrpcResultCodes result; |
| 182 int status; |
| 183 int desc = -1; |
| 184 if (!initialized()) { |
| 185 return -1; |
| 186 } |
| 187 result = NaClSrpcInvokeBySignature(chan(), NACL_NAME_SERVICE_LOOKUP, |
| 188 name.c_str(), O_RDONLY, |
| 189 &status, &desc); |
| 190 if (NACL_SRPC_RESULT_OK != result) { |
| 191 fprintf(stderr, "Service lookup RPC failed (%d): %s\n", result, |
| 192 NaClSrpcErrorString(result)); |
| 193 return -1; |
| 194 } |
| 195 if (NACL_NAME_SERVICE_SUCCESS != status) { |
| 196 fprintf(stderr, "Resolve failed for \"%s\"; error %d\n", name.c_str(), |
| 197 status); |
| 198 return -1; |
| 199 } |
| 200 |
| 201 return desc; |
| 202 } |
| 203 |
| 204 int NameServiceFactory::name_service_cap; |
| 205 NameServiceFactory *NameServiceFactory::singleton = NULL; |
| 206 |
| 207 NameServiceFactory *NameServiceFactory::NameServiceFactorySingleton() { |
| 208 return singleton; |
| 209 } |
| 210 |
| 211 NameServiceFactory::NameServiceFactory() {} |
| 212 |
| 213 typedef int (*nameservice_tramp_t)(int *desc); |
| 214 |
| 215 bool NameServiceFactory::Init() { |
| 216 if (NULL != singleton) { |
| 217 return false; |
| 218 } |
| 219 |
| 220 name_service_cap = -1; |
| 221 if (-1 == nacl_nameservice(&name_service_cap)) { |
| 222 return false; |
| 223 } |
| 224 singleton = new NameServiceFactory(); |
| 225 return (NULL != singleton); |
| 226 } |
| 227 |
| 228 NameServiceClient *NameServiceFactory::NameService() { |
| 229 NameServiceClient *client = new NameServiceClient(); |
| 230 if (!client->InitializeFromConnectionCapability(name_service_cap)) { |
| 231 delete client; |
| 232 return NULL; |
| 233 } |
| 234 return client; |
| 235 } |
| 236 |
| 237 } // namespace nacl |
OLD | NEW |