int context_attach(pid_t pid, ContextAttachCallBack * done, void * data, int mode) { Context * ctx = NULL; assert(done != NULL); trace(LOG_CONTEXT, "context: attaching pid %d", pid); if ((mode & CONTEXT_ATTACH_SELF) == 0 && ptrace(PT_ATTACH, pid, 0, 0) < 0) { int err = errno; trace(LOG_ALWAYS, "error: ptrace(PT_ATTACH) failed: pid %d, error %d %s", pid, err, errno_to_str(err)); errno = err; return -1; } add_waitpid_process(pid); ctx = create_context(pid2id(pid, 0)); ctx->mem = ctx; ctx->mem_access |= MEM_ACCESS_INSTRUCTION; ctx->mem_access |= MEM_ACCESS_DATA; ctx->mem_access |= MEM_ACCESS_USER; ctx->big_endian = big_endian_host(); EXT(ctx)->pid = pid; EXT(ctx)->attach_callback = done; EXT(ctx)->attach_data = data; list_add_first(&ctx->ctxl, &pending_list); /* TODO: context_attach works only for main task in a process */ return 0; }
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); }