Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / native_client / src / untrusted / irt / irt_nameservice.c
1 /*
2  * Copyright (c) 2012 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 <errno.h>
8 #include <fcntl.h>
9 #include <pthread.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include "native_client/src/public/imc_syscalls.h"
15 #include "native_client/src/public/name_service.h"
16 #include "native_client/src/shared/srpc/nacl_srpc.h"
17
18
19 /*
20  * The newlib toolchain does not define dprintf.
21  * https://code.google.com/p/chromium/issues/detail?id=403825
22  */
23 #if !defined(__GLIBC__)
24 int dprintf(int, const char*, ...);
25 #endif
26
27 /*
28  * Lock to guard name service channel.  Both the local data structure and
29  * the channel itself can only be used for one request at a time.  So we
30  * serialize requests.  We could revisit this and do something that scales
31  * to multithreaded use better if there's demand for that later.
32  */
33 static pthread_mutex_t name_service_mutex = PTHREAD_MUTEX_INITIALIZER;
34 static int ns_channel_initialized = 0;
35 static struct NaClSrpcChannel ns_channel;
36
37 static int prepare_nameservice(void) {
38   int ns = -1;
39   int connected_socket;
40   int error;
41
42   if (ns_channel_initialized)
43     return 0;
44   nacl_nameservice(&ns);
45   if (-1 == ns) {
46     error = errno;
47     dprintf(2, "IRT: nacl_nameservice failed: %s\n", strerror(error));
48     return error;
49   }
50
51   connected_socket = imc_connect(ns);
52   error = errno;
53   close(ns);
54   if (-1 == connected_socket) {
55     dprintf(2, "IRT: imc_connect to nameservice failed: %s\n", strerror(error));
56     return error;
57   }
58
59   if (!NaClSrpcClientCtor(&ns_channel, connected_socket)) {
60     dprintf(2, "IRT: NaClSrpcClientCtor failed for nameservice\n");
61     return EIO;
62   }
63
64   ns_channel_initialized = 1;
65   return 0;
66 }
67
68 /*
69  * Look up a name in the nameservice.  Returns a NACL_NAME_SERVICE_* code
70  * or -1 for an SRPC error.  On returning NACL_NAME_SERVICE_SUCCESS,
71  * *out_fd has the descriptor for the service found.
72  */
73 int irt_nameservice_lookup(const char *name, int oflag, int *out_fd) {
74   int error;
75   int status = -1;
76
77   pthread_mutex_lock(&name_service_mutex);
78
79   error = prepare_nameservice();
80   if (0 == error) {
81     if (NACL_SRPC_RESULT_OK != NaClSrpcInvokeBySignature(
82             &ns_channel, NACL_NAME_SERVICE_LOOKUP, name, oflag,
83             &status, out_fd)) {
84       dprintf(2, "IRT: SRPC failure for NACL_NAME_SERVICE_LOOKUP: %s\n",
85               strerror(errno));
86     }
87   }
88
89   pthread_mutex_unlock(&name_service_mutex);
90
91   return status;
92 }