Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 * SRPC-based 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 #define RNG_OUTPUT_BYTES 1024 | |
| 24 | |
| 25 #define BYTES_PER_LINE 32 | |
| 26 #define BYTE_SPACING 4 | |
| 27 | |
| 28 struct StringBuffer { | |
| 29 size_t nbytes; | |
| 30 size_t insert; | |
| 31 char *buffer; | |
| 32 }; | |
| 33 | |
| 34 NaClSrpcChannel ns_channel; | |
| 35 | |
| 36 void StringBufferCtor(struct StringBuffer *sb) { | |
| 37 sb->nbytes = 1024; | |
| 38 sb->insert = 0; | |
| 39 sb->buffer = malloc(sb->nbytes); | |
| 40 if (NULL == sb->buffer) { | |
| 41 perror("StringBufferInit::malloc"); | |
| 42 abort(); | |
| 43 } | |
| 44 sb->buffer[0] = '\0'; | |
| 45 } | |
| 46 | |
| 47 void StringBufferDiscardOutput(struct StringBuffer *sb) { | |
| 48 sb->insert = 0; | |
| 49 sb->buffer[0] = '\0'; | |
| 50 } | |
| 51 | |
| 52 void StringBufferDtor(struct StringBuffer *sb) { | |
| 53 sb->nbytes = 0; | |
| 54 sb->insert = 0; | |
| 55 free(sb->buffer); | |
| 56 sb->buffer = NULL; | |
| 57 } | |
| 58 | |
| 59 void StringBufferPrintf(struct StringBuffer *sb, | |
| 60 char const *fmt, ...) | |
| 61 __attribute__((format(printf, 2, 3))); | |
| 62 | |
| 63 void StringBufferPrintf(struct StringBuffer *sb, | |
| 64 char const *fmt, ...) { | |
| 65 size_t space; | |
| 66 char *insert_pt; | |
| 67 va_list ap; | |
| 68 int written = 0; | |
| 69 char *new_buffer; | |
| 70 | |
| 71 va_start(ap, fmt); | |
| 72 vfprintf(stderr, fmt, ap); | |
| 73 va_end(ap); | |
| 74 | |
| 75 for (;;) { | |
| 76 space = sb->nbytes - sb->insert; | |
| 77 insert_pt = sb->buffer + sb->insert; | |
| 78 va_start(ap, fmt); | |
| 79 written = vsnprintf(insert_pt, space, fmt, ap); | |
| 80 va_end(ap); | |
| 81 if (written < space) { | |
| 82 sb->insert += written; | |
| 83 break; | |
| 84 } | |
| 85 /* insufficient space -- grow the buffer */ | |
| 86 new_buffer = realloc(sb->buffer, 2 * sb->nbytes); | |
| 87 if (NULL == new_buffer) { | |
| 88 /* give up */ | |
| 89 fprintf(stderr, "StringBufferPrintf: no memory\n"); | |
| 90 break; | |
| 91 } | |
| 92 sb->nbytes *= 2; | |
| 93 sb->buffer = new_buffer; | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 void dump_output(struct StringBuffer *sb, int d, size_t nbytes) { | |
| 98 uint8_t *bytes; | |
| 99 int got; | |
| 100 int copied; | |
| 101 int ix; | |
| 102 | |
| 103 bytes = malloc(nbytes); | |
| 104 if (!bytes) { | |
| 105 perror("dump_output"); | |
| 106 fprintf(stderr, "No memory\n"); | |
| 107 return; | |
| 108 } | |
| 109 /* read output */ | |
| 110 for (got = 0; got < nbytes; got += copied) { | |
| 111 copied = read(d, bytes + got, nbytes - got); | |
| 112 if (-1 == copied) { | |
| 113 perror("dump_output:read"); | |
| 114 fprintf(stderr, "read failure\n"); | |
| 115 break; | |
| 116 } | |
| 117 printf("read(%d, ..., %zd) -> %d\n", d, nbytes - got, copied); | |
| 118 } | |
| 119 /* hex dump it */ | |
| 120 for (ix = 0; ix < got; ++ix) { | |
| 121 if (0 == (ix & (BYTES_PER_LINE-1))) { | |
| 122 StringBufferPrintf(sb, "\n%04x:", ix); | |
| 123 } else if (0 == (ix & (BYTE_SPACING-1))) { | |
| 124 StringBufferPrintf(sb, " "); | |
| 125 } | |
| 126 StringBufferPrintf(sb, "%02x", bytes[ix]); | |
| 127 } | |
| 128 StringBufferPrintf(sb, "\n"); | |
| 129 | |
| 130 free(bytes); | |
| 131 } | |
| 132 | |
| 133 /* | |
| 134 * Dump RNG output into a string. | |
| 135 */ | |
| 136 void RngDump(NaClSrpcRpc *rpc, | |
| 137 NaClSrpcArg **in_args, | |
| 138 NaClSrpcArg **out_args, | |
| 139 NaClSrpcClosure *done) { | |
| 140 struct StringBuffer sb; | |
| 141 NaClSrpcError rpc_result; | |
| 142 int status; | |
| 143 int rng; | |
| 144 | |
| 145 StringBufferCtor(&sb); | |
| 146 rpc_result = NaClSrpcInvokeBySignature(&ns_channel, NACL_NAME_SERVICE_LOOKUP, | |
| 147 "SecureRandom", O_RDONLY, | |
| 148 &status, &rng); | |
| 149 assert(NACL_SRPC_RESULT_OK == rpc_result); | |
| 150 printf("rpc status %d\n", status); | |
| 151 assert(NACL_NAME_SERVICE_SUCCESS == status); | |
| 152 printf("rng descriptor %d\n", rng); | |
| 153 | |
| 154 dump_output(&sb, rng, RNG_OUTPUT_BYTES); | |
| 155 out_args[0]->arrays.str = strdup(sb.buffer); | |
| 156 rpc->result = NACL_SRPC_RESULT_OK; | |
| 157 done->Run(done); | |
| 158 close(rng); | |
| 159 StringBufferDtor(&sb); | |
| 160 } | |
| 161 | |
| 162 void ManifestTest(NaClSrpcRpc *rpc, | |
| 163 NaClSrpcArg **in_args, | |
| 164 NaClSrpcArg **out_args, | |
| 165 NaClSrpcClosure *done) { | |
| 166 struct StringBuffer sb; | |
| 167 NaClSrpcError rpc_result; | |
| 168 int status; | |
| 169 int manifest; | |
| 170 int manifest_conn; | |
| 171 struct NaClSrpcChannel manifest_channel; | |
| 172 | |
| 173 /* just get the descriptor for now */ | |
| 174 StringBufferCtor(&sb); | |
| 175 if (NACL_SRPC_RESULT_OK != | |
| 176 (rpc_result = | |
| 177 NaClSrpcInvokeBySignature(&ns_channel, NACL_NAME_SERVICE_LOOKUP, | |
| 178 "ManifestNameService", O_RDWR, | |
|
jvoung (off chromium)
2015/01/09 17:36:40
I see a couple of chrome side tests that also use
Mark Seaborn
2015/01/10 07:00:36
Thanks for catching that. Done: https://coderevie
| |
| 179 &status, &manifest))) { | |
| 180 StringBufferPrintf(&sb, "nameservice lookup RPC failed (%d)\n", rpc_result); | |
| 181 goto done; | |
| 182 } | |
| 183 StringBufferPrintf(&sb, "Got manifest descriptor %d\n", manifest); | |
| 184 if (-1 == manifest) { | |
| 185 fprintf(stderr, "nameservice lookup failed, status %d\n", status); | |
| 186 goto done; | |
| 187 } | |
| 188 /* connect to manifest name server */ | |
| 189 | |
| 190 manifest_conn = imc_connect(manifest); | |
| 191 StringBufferPrintf(&sb, "got manifest connection %d\n", manifest_conn); | |
| 192 if (-1 == manifest_conn) { | |
| 193 StringBufferPrintf(&sb, "could not connect\n"); | |
| 194 goto done; | |
| 195 } | |
| 196 close(manifest); | |
| 197 if (!NaClSrpcClientCtor(&manifest_channel, manifest_conn)) { | |
| 198 StringBufferPrintf(&sb, "could not build srpc client\n"); | |
| 199 goto done; | |
| 200 } | |
| 201 StringBufferDiscardOutput(&sb); | |
| 202 StringBufferPrintf(&sb, "ManifestTest: basic connectivity ok\n"); | |
| 203 | |
| 204 done: | |
| 205 out_args[0]->arrays.str = strdup(sb.buffer); | |
| 206 rpc->result = NACL_SRPC_RESULT_OK; | |
| 207 done->Run(done); | |
| 208 StringBufferDtor(&sb); | |
| 209 } | |
| 210 | |
| 211 const struct NaClSrpcHandlerDesc srpc_methods[] = { | |
| 212 /* Export the methods as taking no arguments and returning a string. */ | |
| 213 { "rngdump::s", RngDump }, | |
| 214 { "manifest_test::s", ManifestTest }, | |
| 215 { NULL, NULL }, | |
| 216 }; | |
| 217 | |
| 218 int main(void) { | |
| 219 int ns; | |
| 220 int connected_socket; | |
| 221 | |
| 222 if (!NaClSrpcModuleInit()) { | |
| 223 return 1; | |
| 224 } | |
| 225 ns = -1; | |
| 226 nacl_nameservice(&ns); | |
| 227 assert(-1 != ns); | |
| 228 | |
| 229 connected_socket = imc_connect(ns); | |
| 230 assert(-1 != connected_socket); | |
| 231 if (!NaClSrpcClientCtor(&ns_channel, connected_socket)) { | |
| 232 fprintf(stderr, "Srpc client channel ctor failed\n"); | |
| 233 return 1; | |
| 234 } | |
| 235 close(ns); | |
| 236 | |
| 237 if (!NaClSrpcAcceptClientConnection(srpc_methods)) { | |
| 238 return 1; | |
| 239 } | |
| 240 NaClSrpcModuleFini(); | |
| 241 return 0; | |
| 242 } | |
| OLD | NEW |