예제 #1
0
static void channel_close_listener(Channel * c) {
    LINK * l = NULL;

    for (l = terms_list.next; l != &terms_list;) {
        Terminal * term = link2term(l);
        l = l->next;
        if (term->channel == c && !term->terminated) {
            trace(LOG_ALWAYS, "Terminal is left launched: %s", tid2id(get_process_pid(term->prs)));
            kill_term(term);
        }
    }
}
예제 #2
0
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);
}
예제 #3
0
int			handle_dollar(t_expander *exp)
{
	char	*s;

	s = exp->tmp + 1;
	if (!*s)
		return (append(exp));
	else if (*s == '?')
		return (get_exit_status(exp));
	else if (*s == '$')
		return (get_process_pid(exp));
	else if (*s == '0')
		return (get_shell_name(exp));
	else
		return (get_env_variable(exp, s));
}
예제 #4
0
static int kill_term(Terminal * term) {
    int err = 0;
    int pid = get_process_pid(term->prs);

#if defined(_WIN32) || defined(__CYGWIN__)
    HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
    if (h == NULL) {
        err = set_win32_errno(GetLastError());
    }
    else {
        if (!TerminateProcess(h, 1)) err = set_win32_errno(GetLastError());
        if (!CloseHandle(h) && !err) err = set_win32_errno(GetLastError());
    }
#else
    if (kill(pid, get_process_out_state(term->prs) ? TERM_EXIT_SIGNAL : SIGKILL) < 0) err = errno;
#endif
    term->terminated = 1;
    return err;
}
예제 #5
0
static void send_event_terminal_win_size_changed(OutputStream * out, Terminal * term) {
    unsigned ws_col = 0;
    unsigned ws_row = 0;

    get_process_tty_win_size(term->prs, &ws_col, &ws_row);

    write_stringz(out, "E");
    write_stringz(out, TERMINALS);
    write_stringz(out, "winSizeChanged");

    json_write_string(out, tid2id(get_process_pid(term->prs)));
    write_stream(out, 0);

    json_write_long(out, ws_col);
    write_stream(out, 0);

    json_write_long(out, ws_row);
    write_stream(out, 0);

    write_stream(out, MARKER_EOM);
}
예제 #6
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);
}
예제 #7
0
static void write_context(OutputStream * out, int tid) {
    Terminal * term = find_terminal(tid);
    const char * id = NULL;

    write_stream(out, '{');

    if (term != NULL) {
        unsigned ws_col = 0;
        unsigned ws_row = 0;
        get_process_tty_win_size(term->prs, &ws_col, &ws_row);

        json_write_string(out, "ProcessID");
        write_stream(out, ':');
        json_write_string(out, pid2id(get_process_pid(term->prs), 0));
        write_stream(out, ',');

        if (*term->pty_type) {
            json_write_string(out, "PtyType");
            write_stream(out, ':');
            json_write_string(out, term->pty_type);
            write_stream(out, ',');
        }

        if (*term->encoding) {
            json_write_string(out, "Encoding");
            write_stream(out, ':');
            json_write_string(out, term->encoding);
            write_stream(out, ',');
        }

        json_write_string(out, "Width");
        write_stream(out, ':');
        json_write_ulong(out, ws_col);
        write_stream(out, ',');

        json_write_string(out, "Height");
        write_stream(out, ':');
        json_write_ulong(out, ws_row);
        write_stream(out, ',');

        id = get_process_stream_id(term->prs, 0);
        if (id) {
            json_write_string(out, "StdInID");
            write_stream(out, ':');
            json_write_string(out, id);
            write_stream(out, ',');
        }
        id = get_process_stream_id(term->prs, 1);
        if (id) {
            json_write_string(out, "StdOutID");
            write_stream(out, ':');
            json_write_string(out, id);
            write_stream(out, ',');
        }
        id = get_process_stream_id(term->prs, 2);
        if (id) {
            json_write_string(out, "StdErrID");
            write_stream(out, ':');
            json_write_string(out, id);
            write_stream(out, ',');
        }
    }

    json_write_string(out, "ID");
    write_stream(out, ':');
    json_write_string(out, tid2id(tid));

    write_stream(out, '}');
}
예제 #8
0
파일: botox.c 프로젝트: stezqy/botox
int main(int argc, char *argv[])
{
	useconds_t ts = 0;
	char *target = NULL;
	pid_t min_pid = getpid();
	int c = 0, pid = 0, gdb = 0, ret_val = EXIT_FAILURE;
	int long_opt_index = 0;
	char *short_options = "p:t:gh";
	struct option long_options[] = {
			{ "pid", required_argument, NULL, 'p' },
			{ "time", required_argument, NULL, 't' },
			{ "gdb", no_argument, NULL, 'g' },
			{ "help", no_argument, NULL, 'h' },
			{ 0, 0, 0, 0 }
        };

	if(argc < 2)
	{
		usage(argv[0]);
		goto end;
	}

	while((c = getopt_long(argc, argv, short_options, long_options, &long_opt_index)) != -1)
	{
		switch(c)
		{
			case 'p':
				min_pid = atoi(optarg);
				break;
			case 't':
				ts = atoi(optarg);
				break;
			case 'g':
				gdb = 1;
				break;
			default:
				usage(argv[0]);
				goto end;
		}
	}

	target = argv[argc-1];

	printf("Waiting for process '%s' with a pid greater than %d\n", target, min_pid);

	while((pid = get_process_pid(target, min_pid)) == -1) { }

	usleep(ts);

	if(kill(pid, SIGSTOP) == -1)
	{
		perror("kill");
	}
	else
	{
		printf("%s (pid %d) has been paused.\n", target, pid);
		if(gdb)
		{
			execute_process(pid);
		}
		ret_val = EXIT_SUCCESS;
	}

end:
	return ret_val;
}