void json_write_string_len(OutputStream * out, const char * str, size_t len) { if (str == NULL) { write_string(out, "null"); } else { const char * end = str + len; write_stream(out, '"'); while (str < end) { const char * ptr = str; while (str < end && !char_escaping[(unsigned char)*str]) str++; if (ptr < str) { unsigned len = str - ptr; if (out->cur + len <= out->end) { memcpy(out->cur, ptr, len); out->cur += len; } else { out->write_block(out, ptr, len); } } if (str == end) break; write_escape_seq(out, *str++); } write_stream(out, '"'); } }
static void command_read(char * token, Channel * c) { char id[256]; size_t size; int err = 0; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); size = json_read_ulong(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); if (virtual_stream_read(c, token, id, size) < 0) err = errno; if (err != 0) { /* * Handle reply with an error. If none error was detected, the reply * was sent back by virtual_stream_read() or delayed. */ write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_stringz(&c->out, "null"); write_errno(&c->out, err); json_write_long(&c->out, 0); write_stream(&c->out, 0); json_write_boolean(&c->out, 0); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); } }
static void command_get_children_cache_client(void * x) { CommandGetChildrenArgs * args = (CommandGetChildrenArgs *)x; Channel * c = cache_channel(); int err = 0; Symbol * sym = NULL; Symbol ** list = NULL; int cnt = 0; if (id2symbol(args->id, &sym) < 0) err = errno; if (err == 0 && get_symbol_children(sym, &list, &cnt) < 0) err = errno; cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (err == 0) { int i; write_stream(&c->out, '['); for (i = 0; i < cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, symbol2id(list[i])); } write_stream(&c->out, ']'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; int tid; Terminal * term = NULL; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); tid = id2tid(id); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (tid == 0 || (term = find_terminal(tid)) == NULL) { err = ERR_INV_CONTEXT; } write_errno(&c->out, err); if (term != NULL) { write_context(&c->out, tid); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void port_server_cmd_create(char * token, Channel * c) { int err = 0; PortAttribute * attrs = NULL; PortServer * server; Channel * port_channel; json_read_struct(&c->inp, read_port_server_property, &attrs); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); /* In case the current channel is a proxy (value-add), use the * target channel. Otherwise, use the provided channel. */ port_channel = proxy_get_target_channel(c); if (port_channel == NULL) port_channel = c; server = create_port_server(c, attrs, NULL, NULL, NULL, NULL); if (server == NULL) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err) write_stringz(&c->out, "null"); else { write_port_server_info(&c->out, server); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
void send_event_memory_changed(Context * ctx, ContextAddress addr, unsigned long size) { OutputStream * out = &broadcast_group->out; if (!context_has_state(ctx) || is_intercepted(ctx)) { write_stringz(out, "E"); write_stringz(out, MEMORY); write_stringz(out, "memoryChanged"); json_write_string(out, ctx->id); write_stream(out, 0); /* <array of addres ranges> */ write_stream(out, '['); write_stream(out, '{'); json_write_string(out, "addr"); write_stream(out, ':'); json_write_uint64(out, addr); write_stream(out, ','); json_write_string(out, "size"); write_stream(out, ':'); json_write_ulong(out, size); write_stream(out, '}'); write_stream(out, ']'); write_stream(out, 0); write_stream(out, MARKER_EOM); } }
static void command_get_signal_mask(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; Context * ctx = NULL; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, NULL); ctx = context_find_from_pid(pid); if (ctx == NULL) err = ERR_INV_CONTEXT; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (ctx == NULL) { write_stringz(&c->out, "null"); write_stringz(&c->out, "null"); write_stringz(&c->out, "null"); } else { json_write_long(&c->out, ctx->sig_dont_stop); write_stream(&c->out, 0); json_write_long(&c->out, ctx->sig_dont_pass); write_stream(&c->out, 0); json_write_long(&c->out, ctx->pending_signals); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void command_get_array_type_cache_client(void * x) { CommandGetArrayTypeArgs * args = (CommandGetArrayTypeArgs *)x; Channel * c = cache_channel(); Symbol * sym = NULL; Symbol * arr = NULL; int err = 0; if (id2symbol(args->id, &sym) < 0) err = errno; if (err == 0 && get_array_symbol(sym, (ContextAddress)args->length, &arr) < 0) err = errno; cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (err == 0) { json_write_string(&c->out, symbol2id(arr)); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void port_server_cmd_create(char * token, Channel * c) { int err = 0; PortRedirectionInfo * port = loc_alloc_zero(sizeof(PortRedirectionInfo)); PortServer * server; json_read_struct(&c->inp, read_port_server_property, port); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); /* In case the current channel is a proxy (value-add), use the * target channel. */ port->c = proxy_get_target_channel(c); if (port->c == NULL) port->c = c; server = create_port_redirection(port); if (server == NULL) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err) write_stringz(&c->out, "null"); else { write_port_server_info(&c->out, server); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void delete_config_done(Channel *c, void *client_data, int error) { PortConnection * conn = (PortConnection *) client_data; Trap trap; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } if (!conn->auto_connect_stream) { protocol_send_command(conn->server->channel, "Streams", "disconnect", disconnect_stream_done, conn); json_write_string(&conn->server->channel->out, conn->out_stream_id); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); } else { loc_free(conn->out_stream_id); conn->out_stream_id = NULL; loc_free(conn->in_stream_id); conn->in_stream_id = NULL; port_unlock(conn); port_connection_close(conn); } }
static void command_get_state(char * token, Channel * c) { char id[256]; Context * ctx; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(id); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; write_errno(&c->out, err); json_write_boolean(&c->out, ctx != NULL && ctx->intercepted); write_stream(&c->out, 0); if (err) { write_stringz(&c->out, "0"); write_stringz(&c->out, "null"); write_stringz(&c->out, "null"); } else { write_context_state(&c->out, ctx); } write_stream(&c->out, MARKER_EOM); }
void send_event_register_changed(const char * id) { unsigned i; Context * ctx = NULL; int frame = STACK_NO_FRAME; RegisterDefinition * def = NULL; OutputStream * out = &broadcast_group->out; id2register(id, &ctx, &frame, &def); if (ctx == NULL) return; for (i = 0; i < listener_cnt; i++) { Listener * l = listeners + i; if (l->func->register_changed == NULL) continue; l->func->register_changed(ctx, frame, def, l->args); } if (frame >= 0 && frame == get_top_frame(ctx)) { id = register2id(ctx, STACK_TOP_FRAME, def); } write_stringz(out, "E"); write_stringz(out, REGISTERS); write_stringz(out, "registerChanged"); json_write_string(out, id); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void event_get_context(void * arg) { GetContextArgs * s = (GetContextArgs *)arg; Channel * c = s->c; Context * ctx = s->ctx; if (!is_stream_closed(c)) { int err = 0; write_stringz(&c->out, "R"); write_stringz(&c->out, s->token); if (ctx->exited) err = ERR_ALREADY_EXITED; write_errno(&c->out, err); if (err == 0) { write_context(&c->out, ctx, s->parent != 0); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); flush_stream(&c->out); } stream_unlock(c); context_unlock(ctx); loc_free(s); }
static int send_packet(PortConnection * conn, char * buffer, size_t size) { JsonWriteBinaryState state; assert (is_dispatch_thread()); assert (conn->pending_write_request < MAX_STREAM_WRITE); protocol_send_command(conn->server->channel, "Streams", "write", write_stream_done, conn); json_write_string(&conn->server->channel->out, conn->out_stream_id); write_stream(&conn->server->channel->out, 0); json_write_long(&conn->server->channel->out, size); write_stream(&conn->server->channel->out, MARKER_EOA); json_write_binary_start(&state, &conn->server->channel->out, size); json_write_binary_data(&state, buffer, size); json_write_binary_end(&state); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); conn->pending_write_request ++; if (conn->pending_write_request == MAX_STREAM_WRITE) { return 0; } else { send_packet_callback(conn, 0); } return 0; }
static void send_eof_and_close(Channel * channel, int err) { ChannelNP * c = channel2np(channel); assert(c->magic == CHANNEL_MAGIC); if (channel->state == ChannelStateDisconnected) return; ibuf_flush(&c->ibuf); if (c->ibuf.handling_msg == HandleMsgTriggered) { /* Cancel pending message handling */ cancel_event(handle_channel_msg, c, 0); c->ibuf.handling_msg = HandleMsgIdle; } write_stream(&c->chan.out, MARKER_EOS); write_errno(&c->chan.out, err); write_stream(&c->chan.out, MARKER_EOM); np_flush_with_flags(c, 0); #if ENABLE_OutputQueue if (output_queue_is_empty(&c->out_queue)) #endif nopoll_conn_shutdown(c->np_socket); c->chan.state = ChannelStateDisconnected; np_post_read(&c->ibuf, c->ibuf.buf, c->ibuf.buf_size); notify_channel_closed(channel); if (channel->disconnected) { channel->disconnected(channel); } else { trace(LOG_PROTOCOL, "channel %#lx disconnected", c); if (channel->protocol != NULL) protocol_release(channel->protocol); } channel->protocol = NULL; }
static void command_get_children(char * token, Channel * c) { int err = 0; char id[256]; Symbol sym; Symbol * list = NULL; int cnt = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (id2symbol(id, &sym) < 0) err = errno; if (err == 0 && get_symbol_children(&sym, &list, &cnt) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err == 0) { int i; write_stream(&c->out, '['); for (i = 0; i < cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, symbol2id(list + i)); } write_stream(&c->out, ']'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); loc_free(list); }
static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; Context * ctx = NULL; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); ctx = id2ctx(id); if (ctx == NULL || ctx->mem_access == 0) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err == 0) { write_context(&c->out, ctx); } else { write_string(&c->out, "null"); } write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void send_read_reply(StreamClient * client, char * token, size_t size) { VirtualStream * stream = client->stream; Channel * c = client->channel; unsigned lost = 0; unsigned read1 = 0; unsigned read2 = 0; int eos = 0; char * data1 = NULL; char * data2 = NULL; unsigned pos = 0; unsigned len = (stream->buf_inp + stream->buf_len - stream->buf_out) % stream->buf_len; assert(len > 0 || stream->eos); assert(client->pos <= stream->pos); if ((uint64_t)len < stream->pos - client->pos) { lost = (long)(stream->pos - client->pos - len); } else { len = (unsigned)(stream->pos - client->pos); } pos = (stream->buf_inp + stream->buf_len - len) % stream->buf_len; if (len > size) len = size; data1 = stream->buf + pos; if (pos + len <= stream->buf_len) { read1 = len; } else { read1 = stream->buf_len - pos; data2 = stream->buf; read2 = len - read1; } assert(read1 + read2 == len); client->pos += lost + read1 + read2; assert(client->pos <= stream->pos); if (client->pos == stream->pos && stream->eos) eos = 1; assert(eos || lost + read1 + read2 > 0); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (read1 + read2 > 0) { JsonWriteBinaryState state; json_write_binary_start(&state, &c->out, read1 + read2); json_write_binary_data(&state, data1, read1); json_write_binary_data(&state, data2, read2); json_write_binary_end(&state); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_errno(&c->out, 0); json_write_long(&c->out, lost); write_stream(&c->out, 0); json_write_boolean(&c->out, eos); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); flush_stream(&c->out); }
static void write_boolean_member(OutputStream * out, const char * name, int val) { /* For this service FALSE is same as absence of the member */ if (!val) return; write_stream(out, ','); json_write_string(out, name); write_stream(out, ':'); json_write_boolean(out, 1); }
void OopMap::copy_to(address addr) { memcpy(addr,this,sizeof(OopMap)); memcpy(addr + sizeof(OopMap),write_stream()->buffer(),write_stream()->position()); OopMap* new_oop = (OopMap*)addr; new_oop->set_omv_data_size(write_stream()->position()); new_oop->set_omv_data((unsigned char *)(addr + sizeof(OopMap))); new_oop->set_write_stream(NULL); }
void json_write_char(OutputStream * out, char ch) { unsigned n = ch & 0xff; if (n < ' ') { write_stream(out, '\\'); write_stream(out, 'u'); write_stream(out, '0'); write_stream(out, '0'); write_stream(out, hex_digit(n >> 4)); write_stream(out, hex_digit(n)); }
static void reply_read(char * token, OutputStream * out, int err, void * buf, unsigned len, int eof) { write_stringz(out, "R"); write_stringz(out, token); json_write_binary(out, buf, len); write_stream(out, 0); write_fs_errno(out, err); json_write_boolean(out, eof); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void disconnect_port(PortConnection * conn) { assert (is_dispatch_thread()); conn->shutdown_in_progress = 1; port_lock(conn); protocol_send_command(conn->server->channel, "PortForward", "delete", delete_config_done, conn); json_write_string(&conn->server->channel->out, conn->id); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); }
static void write_port_server_info(OutputStream * out, PortServer * server) { PortAttribute * attr = server->attrs; write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, server->id); write_stream(out, ','); json_write_string(out, "AutoConnect"); write_stream(out, ':'); json_write_boolean(out, server->auto_connect); write_stream(out, ','); if (server->is_udp) json_write_string(out, "UdpPort"); else json_write_string(out, "TcpPort"); write_stream(out, ':'); json_write_ulong(out, server->local_port); while (attr != NULL) { if (strcmp(attr->name, "AutoConnect") != 0) { write_stream(out, ','); json_write_string(out, attr->name); write_stream(out, ':'); write_string(out, attr->value); } attr = attr->next; } write_stream(out, '}'); }
static void connect_port(PortConnection * conn) { assert(is_dispatch_thread()); sprintf(conn->id, "%s@%" PRIu64, conn->server->id, conn->server->port_index++); port_lock(conn); conn->pending = protocol_send_command(conn->server->channel, "PortForward", "getCapabilities", getcapabilities_cb, conn); write_string(&conn->server->channel->out, "null"); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); }
int OopMap::heap_size() const { int size = sizeof(OopMap); int align = sizeof(void *) - 1; if(write_stream() != NULL) { size += write_stream()->position(); } else { size += omv_data_size(); } // Align to a reasonable ending point size = ((size+align) & ~align); return size; }
static void send_event_process_exited(OutputStream * out, ChildProcess * prs) { write_stringz(out, "E"); write_stringz(out, PROCESSES); write_stringz(out, "exited"); json_write_string(out, pid2id(prs->pid, 0)); write_stream(out, 0); json_write_long(out, prs->exit_code); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void send_event_terminal_exited(OutputStream * out, Terminal * term) { write_stringz(out, "E"); write_stringz(out, TERMINALS); write_stringz(out, "exited"); json_write_string(out, tid2id(get_process_pid(term->prs))); write_stream(out, 0); json_write_ulong(out, get_process_exit_code(term->prs)); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void reply_stat(char * token, OutputStream * out, int err, struct stat * buf) { FileAttrs attrs; if (err == 0) fill_attrs(&attrs, buf); else memset(&attrs, 0, sizeof(attrs)); write_stringz(out, "R"); write_stringz(out, token); write_fs_errno(out, err); write_file_attrs(out, &attrs); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void command_get_children_cache_client(void * x) { GetChildrenArgs * args = (GetChildrenArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; StackFrame * frame_info = NULL; RegisterDefinition * defs = NULL; RegisterDefinition * parent = NULL; Trap trap; if (set_trap(&trap)) { if (id2register(args->id, &ctx, &frame, &parent) == 0) { if (frame != STACK_TOP_FRAME && get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else if (id2frame(args->id, &ctx, &frame) == 0) { if (get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else { ctx = id2ctx(args->id); frame = STACK_TOP_FRAME; } if (ctx != NULL) defs = get_reg_definitions(ctx); clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, '['); if (defs != NULL) { int cnt = 0; RegisterDefinition * reg_def; for (reg_def = defs; reg_def->name != NULL; reg_def++) { if (reg_def->parent != parent) continue; if (frame < 0 || frame_info->is_top_frame || reg_def->size == 0 || read_reg_value(frame_info, reg_def, NULL) == 0) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, register2id(ctx, frame, reg_def)); cnt++; } } } write_stream(&c->out, ']'); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }