static void command_signal(char * token, Channel * c) { int err = 0; char id[256]; int signal = 0; pid_t pid, parent; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); signal = (int)json_read_long(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, &parent); write_stringz(&c->out, "R"); write_stringz(&c->out, token); #if defined(WIN32) err = ENOSYS; #elif defined(_WRS_KERNEL) if (kill(pid, signal) < 0) err = errno; #elif defined(__APPLE__) if (kill(pid, signal) < 0) err = errno; #else if (parent == 0) { if (kill(pid, signal) < 0) err = errno; } else { if (tkill(pid, signal) < 0) err = errno; } #endif write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_terminate(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid, parent; 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, &parent); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (parent != 0) { err = ERR_INV_CONTEXT; } else { #if defined(WIN32) HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid); if (h == NULL) { err = ERR_INV_CONTEXT; } else { TerminateProcess(h, 1); CloseHandle(h); } #else if (kill(pid, SIGTERM) < 0) err = errno; #endif } write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_set_win_size(char * token, Channel * c) { int err = 0; char id[256]; unsigned tid; Terminal * term = NULL; unsigned ws_col; unsigned ws_row; int changed = 0; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); ws_col = json_read_ulong(&c->inp); json_test_char(&c->inp, MARKER_EOA); ws_row = json_read_ulong(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); tid = id2tid(id); if (tid == 0 || (term = find_terminal(tid)) == NULL) { err = ERR_INV_CONTEXT; } else if (set_process_tty_win_size(term->prs, ws_col, ws_row, &changed) < 0) { err = errno; } if (changed) send_event_terminal_win_size_changed(&term->bcg->out, term); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_disassemble(char * token, Channel * c) { int error = 0; Context * ctx = NULL; DisassembleCmdArgs * args = (DisassembleCmdArgs *)loc_alloc_zero(sizeof(DisassembleCmdArgs)); json_read_string(&c->inp, args->id, sizeof(args->id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args->addr = (ContextAddress)json_read_uint64(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args->size = (ContextAddress)json_read_uint64(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); json_read_struct(&c->inp, read_disassembly_params, args); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(args->id); if (ctx == NULL) error = ERR_INV_CONTEXT; else if (ctx->exited) error = ERR_ALREADY_EXITED; else if (context_get_group(ctx, CONTEXT_GROUP_PROCESS)->mem_access == 0) error = ERR_INV_CONTEXT; if (error != 0) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, error); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); loc_free(args); } else { channel_lock(args->c = c); strlcpy(args->token, token, sizeof(args->token)); post_safe_event(ctx, safe_event_disassemble, args); } }
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_set_signal_mask(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; Context * ctx = NULL; int dont_stop; int dont_pass; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); dont_stop = json_read_long(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); dont_pass = json_read_long(&c->inp); 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; } else { ctx->sig_dont_stop = dont_stop; ctx->sig_dont_pass = dont_pass; } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_eos(char * token, Channel * c) { char id[256]; StreamClient * client = NULL; size_t done = 0; WriteRequest * r = NULL; 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); client = find_client(id, c); if (client == NULL) err = errno; if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED; if (!err && !list_is_empty(&client->write_requests)) r = loc_alloc_zero(sizeof(WriteRequest)); if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno; if (r != NULL) { list_init(&r->link_client); r->client = client; r->eos = 1; strncpy(r->token, token, sizeof(r->token) - 1); list_add_last(&r->link_client, &client->write_requests); } else { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); 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 command_subscribe(char * token, Channel * c) { char type[256]; int err = 0; LINK * l; json_read_string(&c->inp, type, sizeof(type)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { err = ERR_OTHER; break; } } if (err == 0) { Subscription * s = loc_alloc_zero(sizeof(Subscription)); list_init(&s->link_all); list_add_first(&s->link_all, &subscriptions); strncpy(s->type, type, sizeof(s->type) - 1); s->channel = c; } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); 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 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 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 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)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(id); if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); } else { /* Need to stop everything to access context properties. * In particular, proc FS access can fail when process is running. */ GetContextArgs * s = loc_alloc_zero(sizeof(GetContextArgs)); s->c = c; stream_lock(c); strcpy(s->token, token); s->ctx = ctx; context_lock(ctx); id2pid(id, &s->parent); post_safe_event(ctx->mem, event_get_context, s); } }
static void command_get_context_cache_client(void * x) { GetContextArgs * args = (GetContextArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; RegisterDefinition * reg_def = NULL; Trap trap; if (set_trap(&trap)) { if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); if (reg_def != NULL) { write_context(&c->out, args->id, ctx, frame, reg_def); } 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); }
int virtual_stream_eos(Channel * c, char * token, char * id) { size_t done = 0; WriteRequest * r = NULL; int err = 0; StreamClient * client = find_client(id, c); if (client == NULL) err = errno; if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED; if (!err && !list_is_empty(&client->write_requests)) r = (WriteRequest *)loc_alloc_zero(sizeof(WriteRequest)); if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno; if (r != NULL) { list_init(&r->link_client); r->client = client; r->eos = 1; strlcpy(r->token, token, sizeof(r->token)); list_add_last(&r->link_client, &client->write_requests); } else if (err == 0) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); } if (err != 0) errno = err; return err == 0 ? 0 : -1; }
static void command_write(char * token, Channel * c) { char id[256]; long size; int err = 0; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); size = json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); if (virtual_stream_write(c, token, id, size, &c->inp) < 0) err = errno; json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); if (err != 0) { /* * Handle reply with an error. If none error was detected, the reply * was sent back by virtual_stream_write() or delayed. */ write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); } }
static void command_find_by_addr_cache_client(void * x) { CommandFindByAddrArgs * args = (CommandFindByAddrArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; Symbol * sym = NULL; int err = 0; if (id2frame(args->id, &ctx, &frame) < 0) ctx = id2ctx(args->id); if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->id); else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err == 0 && find_symbol_by_addr(ctx, frame, args->addr, &sym) < 0) err = errno; list_cnt = 0; if (err == 0) { list_add(sym); while (find_next_symbol(&sym) == 0) list_add(sym); if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno; } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); write_symbol_list(&c->out); write_stream(&c->out, MARKER_EOM); }
static void command_reset_cache_client(void * x) { CommandResetArgs * args = (CommandResetArgs *)x; Channel * c = cache_channel(); Context * ctx = id2ctx(args->id); OutputStream * out = &c->out; int err = 0; if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; if (!err) { Context * grp = get_reset_context(ctx); ResetInfo * rst = find_reset(grp, args->type); if (rst == NULL) err = set_errno(ERR_OTHER, "Unsupported reset type"); else if (rst->reset(ctx, &args->params) < 0) err = errno; } cache_exit(); while (args->params.list != NULL) { ResetParameter * p = args->params.list; args->params.list = p->next; loc_free(p->name); loc_free(p->value); loc_free(p); } write_stringz(out, "R"); write_stringz(out, args->token); write_errno(out, err); write_stream(out, MARKER_EOM); }
static void command_find_in_scope_cache_client(void * x) { CommandFindInScopeArgs * args = (CommandFindInScopeArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; Symbol * scope = NULL; Symbol * sym = NULL; int err = 0; if (id2frame(args->frame_id, &ctx, &frame) < 0) ctx = id2ctx(args->frame_id); if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->frame_id); else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err == 0 && args->scope_id[0] && id2symbol(args->scope_id, &scope) < 0) err = errno; if (err == 0 && args->name == NULL) err = set_errno(EINVAL, "Symbol name must not be null"); if (err == 0 && find_symbol_in_scope(ctx, frame, args->ip, scope, args->name, &sym) < 0) err = errno; list_cnt = 0; if (err == 0) { list_add(sym); while (find_next_symbol(&sym) == 0) list_add(sym); if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno; } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); write_symbol_list(&c->out); write_stream(&c->out, MARKER_EOM); loc_free(args->name); }
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); }
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 command_attach(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid, parent; 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, &parent); if (parent != 0) { err = ERR_INV_CONTEXT; } else if (context_find_from_pid(pid) != NULL) { err = ERR_ALREADY_ATTACHED; } else { AttachDoneArgs * data = loc_alloc_zero(sizeof *data); data->c = c; strcpy(data->token, token); if (context_attach(pid, attach_done, data, 0) == 0) { stream_lock(c); return; } err = errno; loc_free(data); } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
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_unsubscribe(char * token, Channel * c) { char type[256]; int err = 0; Subscription * s = NULL; LINK * l; json_read_string(&c->inp, type, sizeof(type)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { s = h; break; } } if (s == NULL) err = ERR_INV_CONTEXT; if (err == 0) delete_subscription(s); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); 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 command_get_signal_list(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; 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); write_stringz(&c->out, "R"); write_stringz(&c->out, token); /* pid is ignored, same signal list for all */ write_errno(&c->out, err); if (err) { write_stringz(&c->out, "null"); } else { int i = 0; int n = 0; write_stream(&c->out, '['); for (i = 0; i < 32; i++) { char * name = signal_name(i); char * desc = signal_description(i); if (name != NULL || desc != NULL) { if (n > 0) write_stream(&c->out, ','); write_stream(&c->out, '{'); json_write_string(&c->out, "Index"); write_stream(&c->out, ':'); json_write_long(&c->out, i); if (name != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Name"); write_stream(&c->out, ':'); json_write_string(&c->out, name); } if (desc != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Description"); write_stream(&c->out, ':'); json_write_string(&c->out, desc); } write_stream(&c->out, ','); json_write_string(&c->out, "Code"); write_stream(&c->out, ':'); json_write_ulong(&c->out, signal_code(i)); write_stream(&c->out, '}'); n++; } } write_stream(&c->out, ']'); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void command_get_children(char * token, Channel * c) { char id[256]; 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); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, 0); write_stream(&c->out, '['); if (id[0] == 0) { LINK * qp; int cnt = 0; for (qp = context_root.next; qp != &context_root; qp = qp->next) { Context * ctx = ctxl2ctxp(qp); if (ctx->exited) continue; if (ctx->parent != NULL) continue; if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, container_id(ctx)); cnt++; } } else if (id[0] == 'P') { LINK * qp; int cnt = 0; pid_t ppd = 0; Context * parent = id2ctx(id); id2pid(id, &ppd); if (parent != NULL && parent->parent == NULL && ppd == 0) { if (!parent->exited && context_has_state(parent)) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, thread_id(parent)); cnt++; } for (qp = parent->children.next; qp != &parent->children; qp = qp->next) { Context * ctx = cldl2ctxp(qp); assert(!ctx->exited); assert(ctx->parent == parent); if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out,thread_id(ctx)); cnt++; } } } write_stream(&c->out, ']'); write_stream(&c->out, 0); write_stream(&c->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); }