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.
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"
15 const int kMaxObjectFiles
= 16;
17 const struct nacl_irt_pnacl_compile_funcs
* g_funcs
;
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
);
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
;
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
);
44 g_funcs
->init_callback(num_threads
, obj_fds
, num_valid_fds
, argv
, argc
);
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
);
54 rpc
->result
= NACL_SRPC_RESULT_OK
;
55 out_args
[0]->arrays
.str
= strdup("");
60 void StreamChunk(NaClSrpcRpc
* rpc
,
61 NaClSrpcArg
** in_args
,
62 NaClSrpcArg
** out_args
,
63 NaClSrpcClosure
* done
) {
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
;
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("");
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
);
84 rpc
->result
= NACL_SRPC_RESULT_OK
;
85 out_args
[3]->arrays
.str
= strdup("");
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
},
102 void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs
* funcs
) {
104 if (!NaClSrpcModuleInit()) {
105 NaClLog(LOG_FATAL
, "NaClSrpcModuleInit() failed\n");
107 if (!NaClSrpcAcceptClientConnection(kSrpcMethods
)) {
108 NaClLog(LOG_FATAL
, "NaClSrpcAcceptClientConnection() failed\n");
114 const struct nacl_irt_private_pnacl_translator_compile
115 nacl_irt_private_pnacl_translator_compile
= {
116 ServeTranslateRequest