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);
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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, &reg_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);
}
Example #6
0
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);
}
Example #9
0
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);
}