Index: src/trusted/service_runtime/name_service/name_service.c |
diff --git a/src/trusted/service_runtime/name_service/name_service.c b/src/trusted/service_runtime/name_service/name_service.c |
deleted file mode 100644 |
index b0666f843a837f17dcc6ea8673385dd69446bd12..0000000000000000000000000000000000000000 |
--- a/src/trusted/service_runtime/name_service/name_service.c |
+++ /dev/null |
@@ -1,457 +0,0 @@ |
-/* |
- * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-#include <string.h> |
- |
-#include "native_client/src/include/portability.h" |
-#include "native_client/src/include/portability_string.h" |
- |
-#include "native_client/src/trusted/service_runtime/name_service/name_service.h" |
- |
-#include "native_client/src/public/name_service.h" |
- |
-#include "native_client/src/shared/platform/nacl_log.h" |
-#include "native_client/src/shared/platform/nacl_sync.h" |
-#include "native_client/src/shared/platform/nacl_sync_checked.h" |
- |
-#include "native_client/src/shared/srpc/nacl_srpc.h" |
- |
-#include "native_client/src/trusted/desc/nacl_desc_base.h" |
-#include "native_client/src/trusted/desc/nacl_desc_conn_cap.h" |
-#include "native_client/src/trusted/desc/nacl_desc_invalid.h" |
-#include "native_client/src/trusted/desc/nrd_xfer.h" |
- |
-#include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" |
-#include "native_client/src/trusted/service_runtime/sel_ldr.h" |
- |
-#include "native_client/src/trusted/simple_service/nacl_simple_service.h" |
-#include "native_client/src/trusted/simple_service/nacl_simple_ltd_service.h" |
-#include "native_client/src/trusted/threading/nacl_thread_interface.h" |
- |
- |
-/* |
- * Name service is a linear linked list. We could use a hash |
- * container eventually, but performance is not a goal for this simple |
- * bootstrap name service. Static entry and factory-based generation |
- * are mutually exclusive; the |factory| function is used iff |entry| |
- * is NULL. Client code is expected to cache lookup results. |
- */ |
-struct NaClNameServiceEntry { |
- struct NaClNameServiceEntry *next; |
- char const *name; |
- int mode; |
- struct NaClDesc *entry; /* static entry, or, ... */ |
- |
- NaClNameServiceFactoryFn_t factory; |
- void *state; |
-}; |
- |
-struct NaClSrpcHandlerDesc const kNaClNameServiceHandlers[]; |
-/* fwd */ |
- |
-int NaClNameServiceCtor(struct NaClNameService *self, |
- NaClThreadIfFactoryFunction thread_factory_fn, |
- void *thread_factory_data) { |
- int retval = 0; /* fail */ |
- |
- NaClLog(4, "Entered NaClNameServiceCtor\n"); |
- if (!NaClSimpleLtdServiceCtor(&self->base, |
- kNaClNameServiceHandlers, |
- NACL_NAME_SERVICE_CONNECTION_MAX, |
- thread_factory_fn, |
- thread_factory_data)) { |
- NaClLog(4, "NaClSimpleLtdServiceCtor failed\n"); |
- goto done; |
- } |
- if (!NaClMutexCtor(&self->mu)) { |
- NaClLog(4, "NaClMutexCtor failed\n"); |
- goto abort_mu; |
- } |
- NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl *) |
- &kNaClNameServiceVtbl; |
- /* success return path */ |
- self->head = (struct NaClNameServiceEntry *) NULL; |
- retval = 1; |
- goto done; |
- |
- /* cleanup unwind */ |
- abort_mu: /* mutex ctor failed */ |
- (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self); |
- done: |
- return retval; |
-} |
- |
-void NaClNameServiceDtor(struct NaClRefCount *vself) { |
- struct NaClNameService *self = (struct NaClNameService *) vself; |
- |
- struct NaClNameServiceEntry *p; |
- struct NaClNameServiceEntry *next; |
- |
- for (p = self->head; NULL != p; p = next) { |
- next = p->next; |
- if (NULL != p->entry) { |
- NaClRefCountUnref((struct NaClRefCount *) p->entry); |
- } else { |
- /* |
- * Tell the factory fn that this particular use can be GC'd. |
- */ |
- (void) (*p->factory)(p->state, p->name, 0, (struct NaClDesc **) NULL); |
- } |
- free(p); |
- } |
- NaClMutexDtor(&self->mu); |
- NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl *) |
- &kNaClSimpleLtdServiceVtbl; |
- (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self); |
-} |
- |
-static struct NaClNameServiceEntry **NameServiceSearch( |
- struct NaClNameServiceEntry **hd, |
- char const *name) { |
- while (NULL != *hd && 0 != strcmp((*hd)->name, name)) { |
- hd = &(*hd)->next; |
- } |
- return hd; |
-} |
- |
- |
-int NaClNameServiceCreateDescEntry( |
- struct NaClNameService *nnsp, |
- char const *name, |
- int mode, |
- struct NaClDesc *new_desc) { |
- int retval = NACL_NAME_SERVICE_INSUFFICIENT_RESOURCES; |
- struct NaClNameServiceEntry *name_entry = NULL; |
- struct NaClNameServiceEntry *found = NULL; |
- char *dup_name = STRDUP(name); |
- |
- NaClLog(3, |
- "NaClNameServiceCreateDescEntry: entering %s, %d (0x%x)\n", |
- name, |
- mode, mode); |
- /* |
- * common case is insertion success, so we pre-allocate memory |
- * (strdup, malloc) to avoid doing memory allocations while holding |
- * the name service lock. |
- */ |
- if (NULL == dup_name) { |
- goto dup_failed; |
- } |
- name_entry = (struct NaClNameServiceEntry *) malloc(sizeof *name_entry); |
- if (NULL == name_entry) { |
- goto entry_alloc_failed; |
- } |
- |
- NaClXMutexLock(&nnsp->mu); |
- found = *NameServiceSearch(&nnsp->head, name); |
- if (NULL != found) { |
- retval = NACL_NAME_SERVICE_DUPLICATE_NAME; |
- goto unlock_and_cleanup; |
- } |
- name_entry->next = nnsp->head; |
- name_entry->name = dup_name; |
- dup_name = (char *) NULL; |
- name_entry->mode = mode; |
- name_entry->entry = new_desc; |
- name_entry->factory = (NaClNameServiceFactoryFn_t) NULL; |
- name_entry->state = (void *) NULL; |
- nnsp->head = name_entry; |
- name_entry = NULL; |
- retval = NACL_NAME_SERVICE_SUCCESS; |
- |
- unlock_and_cleanup: |
- NaClXMutexUnlock(&nnsp->mu); |
- free(name_entry); |
- entry_alloc_failed: |
- free(dup_name); |
- dup_failed: |
- return retval; |
-} |
- |
-int NaClNameServiceCreateFactoryEntry( |
- struct NaClNameService *nnsp, |
- char const *name, |
- NaClNameServiceFactoryFn_t factory_fn, |
- void *factory_state) { |
- int retval = NACL_NAME_SERVICE_INSUFFICIENT_RESOURCES; |
- struct NaClNameServiceEntry *name_entry = NULL; |
- struct NaClNameServiceEntry *found = NULL; |
- char *dup_name = STRDUP(name); |
- |
- NaClLog(3, |
- ("NaClNameServiceCreateFactoryEntry: entering %s," |
- " 0x%"NACL_PRIxPTR", 0x%"NACL_PRIxPTR"\n"), |
- name, |
- (uintptr_t) factory_fn, |
- (uintptr_t) factory_state); |
- /* |
- * common case is insertion success, so we pre-allocate memory |
- * (strdup, malloc) to avoid doing memory allocation while holding |
- * the name service lock. |
- */ |
- if (NULL == dup_name) { |
- goto dup_failed; |
- } |
- name_entry = (struct NaClNameServiceEntry *) malloc(sizeof *name_entry); |
- if (NULL == name_entry) { |
- goto entry_alloc_failed; |
- } |
- |
- NaClXMutexLock(&nnsp->mu); |
- found = *NameServiceSearch(&nnsp->head, name); |
- if (NULL != found) { |
- retval = NACL_NAME_SERVICE_DUPLICATE_NAME; |
- goto unlock_and_cleanup; |
- } |
- name_entry->next = nnsp->head; |
- name_entry->name = dup_name; |
- dup_name = (char *) NULL; |
- name_entry->entry = (struct NaClDesc *) NULL; |
- name_entry->factory = factory_fn; |
- name_entry->state = factory_state; |
- nnsp->head = name_entry; |
- name_entry = NULL; |
- retval = NACL_NAME_SERVICE_SUCCESS; |
- |
- unlock_and_cleanup: |
- NaClXMutexUnlock(&nnsp->mu); |
- free(name_entry); |
- entry_alloc_failed: |
- free(dup_name); |
- dup_failed: |
- return retval; |
-} |
- |
-int NaClNameServiceResolveName(struct NaClNameService *nnsp, |
- char const *name, |
- int flags, |
- struct NaClDesc **out) { |
- struct NaClNameServiceEntry *nnsep; |
- int status = NACL_NAME_SERVICE_NAME_NOT_FOUND; |
- |
- NaClLog(3, |
- "NaClNameServiceResolveName: looking up %s, flags %d (0x%x)\n", |
- name, |
- flags, flags); |
- if (0 != (flags & ~NACL_ABI_O_ACCMODE)) { |
- NaClLog(2, "NaClNameServiceResolveName: bad flags!\n"); |
- status = NACL_NAME_SERVICE_PERMISSION_DENIED; |
- goto quit; |
- } |
- |
- NaClXMutexLock(&nnsp->mu); |
- nnsep = *NameServiceSearch(&nnsp->head, name); |
- if (NULL != nnsep) { |
- if (NULL != nnsep->entry) { |
- NaClLog(3, |
- "NaClNameServiceResolveName: found %s, mode %d (0x%x)\n", |
- name, |
- nnsep->mode, nnsep->mode); |
- /* check flags against nnsep->mode */ |
- NaClLog(4, |
- ("NaClNameServiceResolveName: checking mode/flags" |
- " compatibility\n")); |
- switch (flags) { |
- case NACL_ABI_O_RDONLY: |
- if (NACL_ABI_O_WRONLY == nnsep->mode) { |
- status = NACL_NAME_SERVICE_PERMISSION_DENIED; |
- NaClLog(4, |
- "NaClNameServiceResolveName: incompatible," |
- " not readable\n"); |
- goto unlock_and_quit; |
- } |
- break; |
- case NACL_ABI_O_WRONLY: |
- if (NACL_ABI_O_RDONLY == nnsep->mode) { |
- status = NACL_NAME_SERVICE_PERMISSION_DENIED; |
- NaClLog(4, |
- "NaClNameServiceResolveName: incompatible," |
- " not writeable\n"); |
- goto unlock_and_quit; |
- } |
- break; |
- case NACL_ABI_O_RDWR: |
- if (NACL_ABI_O_RDWR != nnsep->mode) { |
- status = NACL_NAME_SERVICE_PERMISSION_DENIED; |
- NaClLog(4, "NaClNameServiceResolveName: incompatible," |
- " not for both read and write\n"); |
- goto unlock_and_quit; |
- } |
- break; |
- default: |
- status = NACL_NAME_SERVICE_INVALID_ARGUMENT; |
- NaClLog(4, "NaClNameServiceResolveName: invalid flag\n"); |
- goto unlock_and_quit; |
- } |
- NaClLog(4, "NaClNameServiceResolveName: mode and flags are compatible\n"); |
- *out = NaClDescRef(nnsep->entry); |
- status = NACL_NAME_SERVICE_SUCCESS; |
- } else { |
- status = (*nnsep->factory)(nnsep->state, name, flags, out); |
- } |
- } |
- unlock_and_quit: |
- nnsep = NULL; |
- NaClXMutexUnlock(&nnsp->mu); |
- quit: |
- return status; |
-} |
- |
-int NaClNameServiceDeleteName(struct NaClNameService *nnsp, |
- char const *name) { |
- struct NaClNameServiceEntry **nnsepp; |
- struct NaClNameServiceEntry *to_free = NULL; |
- int status = NACL_NAME_SERVICE_NAME_NOT_FOUND; |
- |
- NaClXMutexLock(&nnsp->mu); |
- nnsepp = NameServiceSearch(&nnsp->head, name); |
- if (NULL != *nnsepp) { |
- to_free = *nnsepp; |
- *nnsepp = to_free->next; |
- status = NACL_NAME_SERVICE_SUCCESS; |
- } |
- NaClXMutexUnlock(&nnsp->mu); |
- |
- /* do the free operations w/o holding the lock */ |
- if (NULL != to_free) { |
- NaClDescSafeUnref(to_free->entry); |
- if (NULL != to_free->factory) { |
- (void) (*to_free->factory)(to_free->state, |
- to_free->name, |
- 0, |
- (struct NaClDesc **) NULL); |
- } |
- free((void *) to_free->name); |
- free(to_free); |
- } |
- return status; |
-} |
- |
-static void NaClNameServiceNameInsertRpc( |
- struct NaClSrpcRpc *rpc, |
- struct NaClSrpcArg **in_args, |
- struct NaClSrpcArg **out_args, |
- struct NaClSrpcClosure *done_cls) { |
- struct NaClNameService *nnsp = |
- (struct NaClNameService *) rpc->channel->server_instance_data; |
- char *name = in_args[0]->arrays.str; |
- int mode = in_args[1]->u.ival; |
- struct NaClDesc *desc = in_args[2]->u.hval; |
- |
- NaClLog(3, |
- "NaClNameServiceNameInsertRpc: inserting %s, %d (0x%x)\n", |
- name, |
- mode, mode); |
- out_args[0]->u.ival = (*NACL_VTBL(NaClNameService, nnsp)->CreateDescEntry)( |
- nnsp, name, mode, desc); |
- rpc->result = NACL_SRPC_RESULT_OK; |
- (*done_cls->Run)(done_cls); |
-} |
- |
-static void NaClNameServiceNameLookupOldRpc( |
- struct NaClSrpcRpc *rpc, |
- struct NaClSrpcArg **in_args, |
- struct NaClSrpcArg **out_args, |
- struct NaClSrpcClosure *done_cls) { |
- struct NaClNameService *nnsp = |
- (struct NaClNameService *) rpc->channel->server_instance_data; |
- char *name = in_args[0]->arrays.str; |
- int status; |
- struct NaClDesc *desc; |
- |
- NaClLog(LOG_WARNING, |
- "NaClNameServiceNameLookupOldRpc: DEPRECATED interface used.\n"); |
- NaClLog(3, "NaClNameServiceNameLookupOldRpc: looking up %s\n", name); |
- status = (*NACL_VTBL(NaClNameService, nnsp)->ResolveName)( |
- nnsp, name, NACL_ABI_O_RDONLY, &desc); |
- out_args[0]->u.ival = status; |
- out_args[1]->u.hval = (NACL_NAME_SERVICE_SUCCESS == status) |
- ? desc |
- : (struct NaClDesc *) NaClDescInvalidMake(); |
- rpc->result = NACL_SRPC_RESULT_OK; |
- (*done_cls->Run)(done_cls); |
-} |
- |
-static void NaClNameServiceNameLookupRpc( |
- struct NaClSrpcRpc *rpc, |
- struct NaClSrpcArg **in_args, |
- struct NaClSrpcArg **out_args, |
- struct NaClSrpcClosure *done_cls) { |
- struct NaClNameService *nnsp = |
- (struct NaClNameService *) rpc->channel->server_instance_data; |
- char *name = in_args[0]->arrays.str; |
- int flags = in_args[1]->u.ival; |
- int status; |
- struct NaClDesc *desc; |
- |
- NaClLog(3, "NaClNameServiceNameLookupRpc: looking up %s\n", name); |
- NaClLog(3, "NaClNameServiceNameLookupRpc: flags %d (0x%x)\n", flags, flags); |
- status = (*NACL_VTBL(NaClNameService, nnsp)->ResolveName)( |
- nnsp, name, flags, &desc); |
- out_args[0]->u.ival = status; |
- out_args[1]->u.hval = (NACL_NAME_SERVICE_SUCCESS == status) |
- ? desc |
- : (struct NaClDesc *) NaClDescInvalidMake(); |
- NaClLog(3, "NaClNameServiceNameLookupRpc: status %d\n", status); |
- NaClLog(3, "NaClNameServiceNameLookupRpc: desc 0x%"NACL_PRIxPTR"\n", |
- (uintptr_t) desc); |
- rpc->result = NACL_SRPC_RESULT_OK; |
- (*done_cls->Run)(done_cls); |
-} |
- |
-static void NaClNameServiceNameDeleteRpc( |
- struct NaClSrpcRpc *rpc, |
- struct NaClSrpcArg **in_args, |
- struct NaClSrpcArg **out_args, |
- struct NaClSrpcClosure *done_cls) { |
- struct NaClNameService *nnsp = |
- (struct NaClNameService *) rpc->channel->server_instance_data; |
- char *name = in_args[0]->arrays.str; |
- |
- out_args[0]->u.ival = (*NACL_VTBL(NaClNameService, nnsp)->DeleteName)( |
- nnsp, name); |
- rpc->result = NACL_SRPC_RESULT_OK; |
- (*done_cls->Run)(done_cls); |
-} |
- |
-struct NaClSrpcHandlerDesc const kNaClNameServiceHandlers[] = { |
- { NACL_NAME_SERVICE_INSERT, NaClNameServiceNameInsertRpc, }, |
- { NACL_NAME_SERVICE_LOOKUP_DEPRECATED, NaClNameServiceNameLookupOldRpc, }, |
- { NACL_NAME_SERVICE_LOOKUP, NaClNameServiceNameLookupRpc, }, |
- { NACL_NAME_SERVICE_DELETE, NaClNameServiceNameDeleteRpc, }, |
- { (char const *) NULL, (NaClSrpcMethod) NULL, }, |
-}; |
- |
-void NaClNameServiceLaunch(struct NaClNameService *self) { |
- |
- NaClLog(4, "NaClNameServiceThread: starting service\n"); |
- NaClSimpleServiceStartServiceThread((struct NaClSimpleService *) self); |
-} |
- |
-struct NaClNameServiceVtbl kNaClNameServiceVtbl = { |
- { |
- /* really NaClSimpleLtdServiceVtbl contents */ |
- { |
- NaClNameServiceDtor, |
- }, |
- NaClSimpleServiceConnectionFactory, |
- /* |
- * To implement name service ownership, the ConnectionFactory will |
- * need to build a subclass of a NaClSimpleServiceConnection where |
- * the connection can be marked as an owner, and the NameService |
- * would contain a mutex protected flag specifying whether it is |
- * owned that blocks mutations by all but the owning connection. |
- * The Connection object's Dtor can release ownership. |
- */ |
- NaClSimpleLtdServiceAcceptConnection, |
- NaClSimpleServiceAcceptAndSpawnHandler, |
- NaClSimpleLtdServiceRpcHandler, |
- }, |
- NaClNameServiceCreateDescEntry, |
- NaClNameServiceCreateFactoryEntry, |
- NaClNameServiceResolveName, |
- NaClNameServiceDeleteName, |
-}; |