OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium 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 <argz.h> | |
6 #include <string.h> | |
jvoung (off chromium)
2015/07/21 21:58:06
Could use cstring
Mark Seaborn
2015/07/21 23:32:30
To be honest, I don't actually know the difference
jvoung (off chromium)
2015/07/21 23:39:48
As is is fine =)
I think the difference is that i
| |
7 | |
8 #include "native_client/src/shared/platform/nacl_log.h" | |
9 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
10 #include "native_client/src/untrusted/irt/irt_dev.h" | |
11 #include "ppapi/nacl_irt/irt_interfaces.h" | |
12 | |
13 namespace { | |
14 | |
15 const int kMaxObjectFiles = 16; | |
16 | |
17 const struct nacl_irt_pnacl_compile_funcs* g_funcs; | |
18 | |
19 void StreamInitWithSplit(NaClSrpcRpc* rpc, | |
20 NaClSrpcArg** in_args, | |
21 NaClSrpcArg** out_args, | |
22 NaClSrpcClosure* done) { | |
23 int num_threads = in_args[0]->u.ival; | |
24 if (num_threads < 0 || num_threads > kMaxObjectFiles) { | |
25 NaClLog(LOG_FATAL, "Invalid # of threads (%d)\n", num_threads); | |
26 } | |
27 int fd_start = 1; | |
28 int i = fd_start; | |
29 int num_valid_fds = 0; | |
30 int obj_fds[kMaxObjectFiles]; | |
31 while (num_valid_fds < kMaxObjectFiles && in_args[i]->u.hval >= 0) { | |
32 obj_fds[num_valid_fds] = in_args[i]->u.hval; | |
33 ++i; | |
34 ++num_valid_fds; | |
35 } | |
36 // Convert the null-delimited strings into an array of | |
37 // null-terminated strings. | |
38 char* cmd_argz = in_args[kMaxObjectFiles + fd_start]->arrays.carr; | |
39 size_t cmd_argz_len = in_args[kMaxObjectFiles + fd_start]->u.count; | |
40 size_t argc = argz_count(cmd_argz, cmd_argz_len); | |
41 char** argv = (char**)malloc((argc + 1) * sizeof(char*)); | |
42 argz_extract(cmd_argz, cmd_argz_len, argv); | |
43 char* result = | |
44 g_funcs->init_callback(num_threads, obj_fds, num_valid_fds, argv, argc); | |
45 free(argv); | |
46 if (result != NULL) { | |
47 rpc->result = NACL_SRPC_RESULT_APP_ERROR; | |
48 // SRPC wants to free() the string, so just strdup here so that the | |
49 // init_callback implementation doesn't have to know if the string | |
50 // comes from malloc or new. On error, we don't care so much | |
51 // about leaking this bit of memory. | |
52 out_args[0]->arrays.str = strdup(result); | |
53 } else { | |
54 rpc->result = NACL_SRPC_RESULT_OK; | |
55 out_args[0]->arrays.str = strdup(""); | |
56 } | |
57 done->Run(done); | |
58 } | |
59 | |
60 void StreamChunk(NaClSrpcRpc* rpc, | |
61 NaClSrpcArg** in_args, | |
62 NaClSrpcArg** out_args, | |
63 NaClSrpcClosure* done) { | |
64 int result = | |
65 g_funcs->data_callback(in_args[0]->arrays.carr, in_args[0]->u.count); | |
66 rpc->result = result == 0 ? NACL_SRPC_RESULT_OK : NACL_SRPC_RESULT_APP_ERROR; | |
67 done->Run(done); | |
68 } | |
69 | |
70 void StreamEnd(NaClSrpcRpc* rpc, | |
71 NaClSrpcArg** in_args, | |
72 NaClSrpcArg** out_args, | |
73 NaClSrpcClosure* done) { | |
74 char* result = g_funcs->end_callback(); | |
75 // Fill in the deprecated return values with dummy values. | |
76 out_args[0]->u.ival = 0; | |
77 out_args[1]->arrays.str = strdup(""); | |
78 out_args[2]->arrays.str = strdup(""); | |
79 if (result != NULL) { | |
80 rpc->result = NACL_SRPC_RESULT_APP_ERROR; | |
81 // SRPC wants to free(), so strdup() and leak to hide this detail. | |
82 out_args[3]->arrays.str = strdup(result); | |
83 } else { | |
84 rpc->result = NACL_SRPC_RESULT_OK; | |
85 out_args[3]->arrays.str = strdup(""); | |
86 } | |
87 done->Run(done); | |
88 } | |
89 | |
90 const struct NaClSrpcHandlerDesc kSrpcMethods[] = { | |
91 // Protocol for streaming: | |
92 // StreamInitWithSplit(num_threads, obj_fd x 16, cmdline_flags) -> error_str | |
93 // StreamChunk(data) + | |
94 // TODO(jvoung): remove these is_shared_lib, etc. | |
95 // StreamEnd() -> (is_shared_lib, soname, dependencies, error_str) | |
96 { "StreamInitWithSplit:ihhhhhhhhhhhhhhhhC:s", StreamInitWithSplit }, | |
97 { "StreamChunk:C:", StreamChunk }, | |
98 { "StreamEnd::isss", StreamEnd }, | |
99 { NULL, NULL }, | |
100 }; | |
101 | |
102 void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) { | |
103 g_funcs = funcs; | |
104 if (!NaClSrpcModuleInit()) { | |
105 NaClLog(LOG_FATAL, "NaClSrpcModuleInit() failed\n"); | |
106 } | |
107 if (!NaClSrpcAcceptClientConnection(kSrpcMethods)) { | |
108 NaClLog(LOG_FATAL, "NaClSrpcAcceptClientConnection() failed\n"); | |
109 } | |
110 } | |
111 | |
112 } | |
113 | |
114 const struct nacl_irt_private_pnacl_translator_compile | |
115 nacl_irt_private_pnacl_translator_compile = { | |
116 ServeTranslateRequest | |
117 }; | |
OLD | NEW |