Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / manifest_file / srpc_manifest_file_test.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 /*
8  * Test for simple rpc based access to name services.
9  */
10
11 #include <assert.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <inttypes.h>
15 #include <sys/fcntl.h>
16 #include <string.h>
17 #include <unistd.h>
18
19 #include "native_client/src/public/imc_syscalls.h"
20 #include "native_client/src/public/name_service.h"
21 #include "native_client/src/shared/srpc/nacl_srpc.h"
22
23 struct StringBuffer {
24   size_t  nbytes;
25   size_t  insert;
26   char    *buffer;
27 };
28
29 NaClSrpcChannel ns_channel;
30
31 void StringBufferCtor(struct StringBuffer *sb) {
32   sb->nbytes = 1024;
33   sb->insert = 0;
34   sb->buffer = malloc(sb->nbytes);
35   if (NULL == sb->buffer) {
36     perror("StringBufferInit::malloc");
37     abort();
38   }
39   sb->buffer[0] = '\0';
40 }
41
42 void StringBufferDiscardOutput(struct StringBuffer *sb) {
43   sb->insert = 0;
44   sb->buffer[0] = '\0';
45 }
46
47 void StringBufferDtor(struct StringBuffer *sb) {
48   sb->nbytes = 0;
49   sb->insert = 0;
50   free(sb->buffer);
51   sb->buffer = NULL;
52 }
53
54 void StringBufferPrintf(struct StringBuffer *sb,
55                         char const *fmt, ...)
56     __attribute__((format(printf, 2, 3)));
57
58 void StringBufferPrintf(struct StringBuffer *sb,
59                         char const *fmt, ...) {
60   size_t space;
61   char *insert_pt;
62   va_list ap;
63   int written = 0;
64   char *new_buffer;
65
66   va_start(ap, fmt);
67   vfprintf(stderr, fmt, ap);
68   va_end(ap);
69
70   for (;;) {
71     space = sb->nbytes - sb->insert;
72     insert_pt = sb->buffer + sb->insert;
73     va_start(ap, fmt);
74     written = vsnprintf(insert_pt, space, fmt, ap);
75     va_end(ap);
76     if (written < space) {
77       sb->insert += written;
78       break;
79     }
80     /* insufficient space -- grow the buffer */
81     new_buffer = realloc(sb->buffer, 2 * sb->nbytes);
82     if (NULL == new_buffer) {
83       /* give up */
84       fprintf(stderr, "StringBufferPrintf: no memory\n");
85       break;
86     }
87     sb->nbytes *= 2;
88     sb->buffer = new_buffer;
89   }
90 }
91
92
93 int EnumerateNames(struct StringBuffer *sb, NaClSrpcChannel *nschan) {
94   char      buffer[1024];
95   uint32_t  nbytes = sizeof buffer;
96   char      *p;
97   size_t    name_len;
98
99   if (NACL_SRPC_RESULT_OK != NaClSrpcInvokeBySignature(nschan,
100                                                        NACL_NAME_SERVICE_LIST,
101                                                        &nbytes, buffer)) {
102     return 0;
103   }
104   StringBufferPrintf(sb, "nbytes = %zu\n", (size_t) nbytes);
105   if (nbytes == sizeof buffer) {
106     fprintf(stderr, "Insufficent space for namespace enumeration\n");
107     return 0;
108   }
109   for (p = buffer; p - buffer < nbytes; p += name_len) {
110     name_len = strlen(p) + 1;
111     StringBufferPrintf(sb, "%s\n", p);
112   }
113   return 1;
114 }
115
116 /*
117  * Return name service output
118  */
119 void NameServiceDump(NaClSrpcRpc *rpc,
120                      NaClSrpcArg **in_args,
121                      NaClSrpcArg **out_args,
122                      NaClSrpcClosure *done) {
123   struct StringBuffer sb;
124   StringBufferCtor(&sb);
125
126   if (EnumerateNames(&sb, &ns_channel)) {
127     out_args[0]->arrays.str = strdup(sb.buffer);
128     rpc->result = NACL_SRPC_RESULT_OK;
129   } else {
130     rpc->result = NACL_SRPC_RESULT_APP_ERROR;
131   }
132   done->Run(done);
133   StringBufferDtor(&sb);
134 }
135
136
137 void ManifestTest(NaClSrpcRpc *rpc,
138                   NaClSrpcArg **in_args,
139                   NaClSrpcArg **out_args,
140                   NaClSrpcClosure *done) {
141   struct StringBuffer sb;
142   int                 status;
143   int                 manifest;
144   char                buffer[1024];
145   uint32_t            nbytes = sizeof buffer;
146   char                *p;
147   size_t              name_len;
148
149   /* just get the descriptor for now */
150   StringBufferCtor(&sb);
151   if (NACL_SRPC_RESULT_OK !=
152       NaClSrpcInvokeBySignature(&ns_channel, NACL_NAME_SERVICE_LOOKUP,
153                                 "ManifestNameService", O_RDWR,
154                                 &status, &manifest)) {
155     fprintf(stderr, "nameservice lookup RPC failed\n");
156   }
157   StringBufferPrintf(&sb, "Got manifest descriptor %d\n", manifest);
158   if (-1 == manifest) {
159     fprintf(stderr, "nameservice lookup failed: status %d\n", status);
160   } else {
161     /* connect to manifest name server */
162     int manifest_conn;
163     struct NaClSrpcChannel manifest_channel;
164
165     manifest_conn = imc_connect(manifest);
166     StringBufferPrintf(&sb, "got manifest connection %d\n", manifest_conn);
167     if (-1 == manifest_conn) {
168       StringBufferPrintf(&sb, "could not connect\n");
169       goto done;
170     }
171     close(manifest);
172     if (!NaClSrpcClientCtor(&manifest_channel, manifest_conn)) {
173       StringBufferPrintf(&sb, "could not build srpc client\n");
174       goto done;
175     }
176     if (NACL_SRPC_RESULT_OK !=
177         NaClSrpcInvokeBySignature(&manifest_channel, NACL_NAME_SERVICE_LIST,
178                                   &nbytes, buffer)) {
179       StringBufferPrintf(&sb, "manifest list failed\n");
180       goto done;
181     }
182     StringBufferDiscardOutput(&sb);
183     StringBufferPrintf(&sb, "Manifest Contents:\n");
184     for (p = buffer; p - buffer < nbytes; p += name_len + 1) {
185       name_len = strlen(p);
186       StringBufferPrintf(&sb, "%.*s\n", (int) name_len, p);
187     }
188   }
189  done:
190   out_args[0]->arrays.str = strdup(sb.buffer);
191   rpc->result = NACL_SRPC_RESULT_OK;
192   done->Run(done);
193   StringBufferDtor(&sb);
194 }
195
196 const struct NaClSrpcHandlerDesc srpc_methods[] = {
197   /* Export the methods as taking no arguments and returning a string. */
198   { "namedump::s", NameServiceDump },
199   { "manifest_test::s", ManifestTest },
200   { NULL, NULL },
201 };
202
203 int main(void) {
204   int ns;
205   int connected_socket;
206
207   if (!NaClSrpcModuleInit()) {
208     return 1;
209   }
210   ns = -1;
211   nacl_nameservice(&ns);
212   assert(-1 != ns);
213
214   connected_socket = imc_connect(ns);
215   assert(-1 != connected_socket);
216   if (!NaClSrpcClientCtor(&ns_channel, connected_socket)) {
217     fprintf(stderr, "Srpc client channel ctor failed\n");
218     return 1;
219   }
220   close(ns);
221
222   if (!NaClSrpcAcceptClientConnection(srpc_methods)) {
223     return 1;
224   }
225   NaClSrpcModuleFini();
226   return 0;
227 }