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]; 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 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_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 send_event_context_changed(OutputStream * out, Context * ctx) { write_stringz(out, "E"); write_stringz(out, RUN_CONTROL); write_stringz(out, "contextChanged"); /* <array of context data> */ write_stream(out, '['); if (ctx->parent == NULL) { write_context(out, ctx, 0); } if (context_has_state(ctx)) { if (ctx->parent == NULL) write_stream(out, ','); write_context(out, ctx, 1); } write_stream(out, ']'); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void send_event_context_changed(Context * ctx) { OutputStream * out = &broadcast_group->out; write_stringz(out, "E"); write_stringz(out, MEMORY); write_stringz(out, "contextChanged"); /* <array of context data> */ write_stream(out, '['); write_context(out, ctx); write_stream(out, ']'); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void start_done(int error, Context * ctx, void * arg) { AttachDoneArgs * data = arg; Channel * c = data->c; if (!is_stream_closed(c)) { write_stringz(&c->out, "R"); write_stringz(&c->out, data->token); write_errno(&c->out, error); if (ctx == NULL) write_string(&c->out, "null"); else write_context(&c->out, ctx->pid); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); flush_stream(&c->out); } stream_unlock(c); loc_free(data); }
static void command_get_context(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); pid = id2pid(id, &parent); if (pid != 0 && parent == 0) { #if defined(WIN32) #elif defined(_WRS_KERNEL) if (TASK_ID_VERIFY(pid) == ERROR) err = ERR_INV_CONTEXT; #elif defined(__APPLE__) #else struct stat st; char dir[FILE_PATH_SIZE]; snprintf(dir, sizeof(dir), "/proc/%d", pid); if (lstat(dir, &st) < 0) err = errno; else if (!S_ISDIR(st.st_mode)) err = ERR_INV_CONTEXT; #endif } write_errno(&c->out, err); if (err == 0 && pid != 0 && parent == 0) { write_context(&c->out, pid); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void command_launch(char * token, Channel * c) { int err = 0; char encoding[TERM_PROP_DEF_SIZE]; char pty_type[TERM_PROP_DEF_SIZE]; const char * args[] = TERM_LAUNCH_ARGS; const char * exec = TERM_LAUNCH_EXEC; int selfattach = 0; ProcessStartParams prms; Terminal * term = (Terminal *)loc_alloc_zero(sizeof(Terminal)); memset(&prms, 0, sizeof(prms)); json_read_string(&c->inp, pty_type, sizeof(pty_type)); json_test_char(&c->inp, MARKER_EOA); json_read_string(&c->inp, encoding, sizeof(encoding)); json_test_char(&c->inp, MARKER_EOA); prms.envp = read_env(&c->inp); json_test_char(&c->inp, MARKER_EOM); #if !defined(_WIN32) && !defined(__CYGWIN__) { struct stat st; if (err == 0 && stat(exec, &st) != 0) { err = errno; if (err == ENOENT) { static char fnm[FILE_PATH_SIZE]; /* On some systems (e.g. Free DSB) bash is installed under /usr/local */ assert(exec[0] == '/'); snprintf(fnm, sizeof(fnm), "/usr/local%s", exec); if (stat(fnm, &st) == 0) { args[0] = exec = fnm; err = 0; } } if (err == ENOENT && strcmp(exec, "/bin/bash") == 0) { /* "bash" not found, try "sh" */ const char * fnm = "/bin/sh"; if (stat(fnm, &st) == 0) { args[0] = exec = fnm; err = 0; } } if (err) err = set_fmt_errno(err, "Cannot start %s", exec); } } set_terminal_env(&prms.envp, pty_type, encoding, exec); prms.dir = getenv("HOME"); if (prms.dir) prms.dir = tmp_strdup(prms.dir); #else { const char * home_drv = getenv("HOMEDRIVE"); const char * home_dir = getenv("HOMEPATH"); if (home_drv && home_dir) { prms.dir = tmp_strdup2(home_drv, home_dir); } } #endif prms.exe = exec; prms.args = (char **)args; prms.service = TERMINALS; prms.use_terminal = 1; prms.exit_cb = terminal_exited; prms.exit_args = term; if (err == 0 && start_process(c, &prms, &selfattach, &term->prs) < 0) err = errno; if (!err) { term->bcg = c->bcg; channel_lock_with_msg(term->channel = c, TERMINALS); strlcpy(term->pty_type, pty_type, sizeof(term->pty_type)); strlcpy(term->encoding, encoding, sizeof(term->encoding)); list_add_first(&term->link, &terms_list); assert(find_terminal(get_process_pid(term->prs)) == term); } else { assert(term->prs == NULL); loc_free(term); } /* write result back */ write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err) { write_stringz(&c->out, "null"); } else { write_context(&c->out, get_process_pid(term->prs)); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void command_start(char * token, Channel * c) { int pid = 0; int err = 0; char dir[FILE_PATH_SIZE]; char exe[FILE_PATH_SIZE]; char ** args = NULL; char ** envp = NULL; int args_len = 0; int envp_len = 0; int attach = 0; int selfattach = 0; int pending = 0; ChildProcess * prs = NULL; Trap trap; if (set_trap(&trap)) { json_read_string(&c->inp, dir, sizeof(dir)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); json_read_string(&c->inp, exe, sizeof(exe)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args = json_read_alloc_string_array(&c->inp, &args_len); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); envp = json_read_alloc_string_array(&c->inp, &envp_len); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); attach = json_read_boolean(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (dir[0] != 0 && chdir(dir) < 0) err = errno; if (err == 0 && start_process(c, envp, dir, exe, args, attach, &pid, &selfattach, &prs) < 0) err = errno; if (prs != NULL) { write_process_input(prs); prs->out_struct = read_process_output(prs, prs->out, prs->out_id, sizeof(prs->out_id)); if (prs->out != prs->err) prs->err_struct = read_process_output(prs, prs->err, prs->err_id, sizeof(prs->err_id)); strncpy(prs->name, exe, sizeof(prs->name) - 1); } if (!err) { if (attach) { AttachDoneArgs * data = loc_alloc_zero(sizeof *data); data->c = c; strcpy(data->token, token); pending = context_attach(pid, start_done, data, selfattach) == 0; if (pending) { stream_lock(c); } else { err = errno; loc_free(data); } } else { add_waitpid_process(pid); } } if (!pending) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err || pid == 0) { write_stringz(&c->out, "null"); } else { write_context(&c->out, pid); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); } clear_trap(&trap); } loc_free(args); loc_free(envp); if (trap.error) exception(trap.error); }