예제 #1
0
static int stdin_input ()
{
    char buf[MAXLINE];
    size_t size;
    size_t i;

    int masterfd = pty_pair_get_masterfd (pty_pair);
    if (masterfd == -1) {
      logger_write_pos ( logger, __FILE__, __LINE__, "pty_pair_get_masterfd error");
      return -1;
    }

    size = read (STDIN_FILENO, buf, MAXLINE-1);
    if (size == -1){
        logger_write_pos ( logger, __FILE__, __LINE__, "read error");
        return -1;
    }

    buf[size] = 0;

    /* Display GDB output 
     * The strlen check is here so that if_print does not get called
     * when displaying the filedlg. If it does get called, then the 
     * gdb window gets displayed when the filedlg is up
     */
    for(i = 0; i < size; ++i)
        if(write(masterfd, &(buf[i]), 1) != 1 ){
            logger_write_pos ( logger, __FILE__, __LINE__,  "could not write byte");
	    return -1;
	}

    return 0;
    return 0;
}
예제 #2
0
파일: cgdb.c 프로젝트: i4fumi/cgdb
int init_readline(void)
{
    int slavefd, masterfd;
    int length;

    slavefd = pty_pair_get_slavefd(pty_pair);
    if (slavefd == -1)
        return -1;

    masterfd = pty_pair_get_masterfd(pty_pair);
    if (masterfd == -1)
        return -1;

    if (tty_off_xon_xoff(slavefd) == -1)
        return -1;

    /* The 16 is because I don't know how many char's the directory separator 
     * is going to be, I expect it to be 1, but who knows. */
    length = strlen(cgdb_home_dir) + strlen(readline_history_filename) + 16;
    readline_history_path = (char *) malloc(sizeof (char) * length);
    fs_util_get_path(cgdb_home_dir, readline_history_filename,
            readline_history_path);
    rline = rline_initialize(slavefd, rlctx_send_user_command, tab_completion,
            "dumb");
    rline_read_history(rline, readline_history_path);
    return 0;
}
예제 #3
0
파일: a2-tgdb.cpp 프로젝트: scottlu/cgdb
int a2_open_new_tty(struct annotate_two *a2, int *inferior_stdin, int *inferior_stdout)
{
    close_inferior_connection(a2);

    a2->pty_pair = pty_pair_create();
    if (!a2->pty_pair) {
        logger_write_pos(logger, __FILE__, __LINE__, "pty_pair_create failed");
        return -1;
    }

    *inferior_stdin = pty_pair_get_masterfd(a2->pty_pair);
    *inferior_stdout = pty_pair_get_masterfd(a2->pty_pair);

    a2_set_inferior_tty(a2);

    return 0;
}
예제 #4
0
파일: a2-tgdb.cpp 프로젝트: cgdb/cgdb
int a2_open_new_tty(struct annotate_two *a2, int *inferior_stdin, int *inferior_stdout)
{
    if (a2->pty_pair)
        pty_pair_destroy(a2->pty_pair);

    a2->pty_pair = pty_pair_create();
    if (!a2->pty_pair) {
        logger_write_pos(logger, __FILE__, __LINE__, "pty_pair_create failed");
        return -1;
    }

    *inferior_stdin = pty_pair_get_masterfd(a2->pty_pair);
    *inferior_stdout = pty_pair_get_masterfd(a2->pty_pair);

    commands_issue_command(a2, ANNOTATE_TTY,
        pty_pair_get_slavename(a2->pty_pair), 1);

    return 0;
}
예제 #5
0
파일: tgdb.cpp 프로젝트: ibuclaw/cgdb
static int tgdb_open_new_tty(struct tgdb *tgdb, int *inferior_stdin,
    int *inferior_stdout)
{
    if (tgdb->pty_pair)
        pty_pair_destroy(tgdb->pty_pair);

    tgdb->pty_pair = pty_pair_create();
    if (!tgdb->pty_pair) {
        clog_error(CLOG_CGDB, "pty_pair_create failed");
        return -1;
    }

    *inferior_stdin = pty_pair_get_masterfd(tgdb->pty_pair);
    *inferior_stdout = pty_pair_get_masterfd(tgdb->pty_pair);

    tgdb_request_ptr request_ptr;
    request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request));
    request_ptr->header = TGDB_REQUEST_TTY;
    request_ptr->choice.tty_command.slavename = 
        pty_pair_get_slavename(tgdb->pty_pair);
    tgdb_run_or_queue_request(tgdb, request_ptr, true);

    return 0;
}
예제 #6
0
파일: cgdb.c 프로젝트: i4fumi/cgdb
static void send_key(int focus, char key)
{
    if (focus == 1) {
        int size;
        int masterfd;

        masterfd = pty_pair_get_masterfd(pty_pair);
        if (masterfd == -1)
            logger_write_pos(logger, __FILE__, __LINE__, "send_key error");
        size = write(masterfd, &key, sizeof (char));
        if (size != 1)
            logger_write_pos(logger, __FILE__, __LINE__, "send_key error");
    } else if (focus == 2) {
        tgdb_send_inferior_char(tgdb, key);
    }
}
예제 #7
0
파일: cgdb.c 프로젝트: i4fumi/cgdb
static int readline_input()
{
    const int MAX = 1024;
    char *buf = malloc(MAX + 1);
    int size;

    int masterfd = pty_pair_get_masterfd(pty_pair);

    if (masterfd == -1) {
        logger_write_pos(logger, __FILE__, __LINE__,
                "pty_pair_get_masterfd error");
        return -1;
    }

    size = read(masterfd, buf, MAX);
    if (size == -1) {
        logger_write_pos(logger, __FILE__, __LINE__, "read error");
        free(buf);
        buf = NULL;
        return -1;
    }

    buf[size] = 0;

    /* Display GDB output 
     * The strlen check is here so that if_print does not get called
     * when displaying the filedlg. If it does get called, then the 
     * gdb window gets displayed when the filedlg is up
     */
    if (size > 0)
        if_print(buf);

    free(buf);
    buf = NULL;
    return 0;
}
예제 #8
0
파일: cgdb.c 프로젝트: i4fumi/cgdb
static int main_loop(void)
{
    fd_set rset;
    int max;
    int masterfd, slavefd;

    masterfd = pty_pair_get_masterfd(pty_pair);
    if (masterfd == -1) {
        logger_write_pos(logger, __FILE__, __LINE__,
                "pty_pair_get_masterfd error");
        return -1;
    }

    slavefd = pty_pair_get_slavefd(pty_pair);
    if (slavefd == -1) {
        logger_write_pos(logger, __FILE__, __LINE__,
                "pty_pair_get_slavefd error");
        return -1;
    }

    max = (gdb_fd > STDIN_FILENO) ? gdb_fd : STDIN_FILENO;
    max = (max > tty_fd) ? max : tty_fd;
    max = (max > resize_pipe[0]) ? max : resize_pipe[0];
    max = (max > slavefd) ? max : slavefd;
    max = (max > masterfd) ? max : masterfd;

    /* Main (infinite) loop:
     *   Sits and waits for input on either stdin (user input) or the
     *   GDB file descriptor.  When input is received, wrapper functions
     *   are called to process the input, and handle it appropriately.
     *   This will result in calls to the curses interface, typically. */

    for (;;) {
        /* Reset the fd_set, and watch for input from GDB or stdin */
        FD_ZERO(&rset);
        FD_SET(STDIN_FILENO, &rset);
        FD_SET(gdb_fd, &rset);
        FD_SET(tty_fd, &rset);
        FD_SET(resize_pipe[0], &rset);

        /* No readline activity allowed while displaying tab completion */
        if (!is_tab_completing) {
            FD_SET(slavefd, &rset);
            FD_SET(masterfd, &rset);
        }

        /* Wait for input */
        if (select(max + 1, &rset, NULL, NULL, NULL) == -1) {
            if (errno == EINTR)
                continue;
            else {
                logger_write_pos(logger, __FILE__, __LINE__,
                        "select failed: %s", strerror(errno));
                return -1;
            }
        }

        /* Input received through the pty:  Handle it 
         * Wrote to masterfd, now slavefd is ready, tell readline */
        if (FD_ISSET(slavefd, &rset))
            rline_rl_callback_read_char(rline);

        /* Input received through the pty:  Handle it
         * Readline read from slavefd, and it wrote to the masterfd. 
         */
        if (FD_ISSET(masterfd, &rset))
            if (readline_input() == -1)
                return -1;

        /* Input received:  Handle it */
        if (FD_ISSET(STDIN_FILENO, &rset)) {
            int val = user_input_loop();

            /* The below condition happens on cygwin when user types ctrl-z
             * select returns (when it shouldn't) with the value of 1. the
             * user input loop gets called, the kui gets called and does a
             * non blocking read which returns EAGAIN. The kui then passes
             * the -1 up the stack with out making any more system calls. */
            if (val == -1 && errno == EAGAIN)
                continue;
            else if (val == -1)
                return -1;
        }

        /* child's ouptut -> stdout
         * The continue is important I think. It allows all of the child
         * output to get written to stdout before tgdb's next command.
         * This is because sometimes they are both ready.
         */
        if (FD_ISSET(tty_fd, &rset)) {
            if (child_input() == -1)
                return -1;
            continue;
        }

        /* gdb's output -> stdout */
        if (FD_ISSET(gdb_fd, &rset)) {
            if (gdb_input() == -1) {
                return -1;
            }

            /* When the file dialog is opened, the user input is blocked, 
             * until GDB returns all the files that should be displayed,
             * and the file dialog can open, and be prepared to receive 
             * input. So, if we are in the file dialog, and are no longer
             * waiting for the gdb command, then read the input.
             */
            if (kui_manager_cangetkey(kui_ctx)) {
                user_input_loop();
            }
        }

        /* A resize signal occured */
        if (FD_ISSET(resize_pipe[0], &rset))
            if (cgdb_resize_term(resize_pipe[0]) == -1)
                return -1;
    }
    return 0;
}
예제 #9
0
파일: driver.c 프로젝트: keenhenry/cgdb
int main(int argc, char **argv)
{

    int gdb_fd, child_fd, slavefd, masterfd;

#if 0
    int c;

    read(0, &c, 1);
#endif

    if (tty_cbreak(STDIN_FILENO, &term_attributes) == -1)
        logger_write_pos(logger, __FILE__, __LINE__, "tty_cbreak error");

    pty_pair = pty_pair_create();
    if (!pty_pair) {
        fprintf(stderr, "%s:%d Unable to create PTY pair", __FILE__, __LINE__);
        exit(-1);
    }

    slavefd = pty_pair_get_slavefd(pty_pair);
    if (slavefd == -1) {
        fprintf(stderr, "%s:%d Unable to get slavefd", __FILE__, __LINE__);
        exit(-1);
    }

    masterfd = pty_pair_get_masterfd(pty_pair);
    if (masterfd == -1) {
        fprintf(stderr, "%s:%d Unable to get masterfd", __FILE__, __LINE__);
        exit(-1);
    }

    if (tty_off_xon_xoff(masterfd) == -1)
        exit(-1);

    rline = rline_initialize(slavefd, rlctx_send_user_command, tab_completion,
                             getenv("TERM"));

    if ((tgdb = tgdb_initialize(NULL, argc - 1, argv + 1, &gdb_fd,
                                &child_fd)) == NULL) {
        logger_write_pos(logger, __FILE__, __LINE__, "tgdb_start error");
        goto driver_end;
    }

    if (tgdb_set_verbose_error_handling(tgdb, 1) != 1) {
        logger_write_pos(logger, __FILE__, __LINE__, "driver error");
        goto driver_end;
    }

    /* Ask TGDB to print error messages */
    if (tgdb_set_verbose_gui_command_output(tgdb, 1) != 1) {
        logger_write_pos(logger, __FILE__, __LINE__, "driver error");
        goto driver_end;
    }

    set_up_signal();

    main_loop(gdb_fd, child_fd);

    if (tgdb_shutdown(tgdb) == -1)
        logger_write_pos(logger, __FILE__, __LINE__, "could not shutdown");

driver_end:

    if (tty_set_attributes(STDIN_FILENO, &term_attributes) == -1)
        logger_write_pos(logger, __FILE__, __LINE__, "tty_reset error");

    return 0;
}
예제 #10
0
파일: driver.c 프로젝트: keenhenry/cgdb
int main_loop(int gdbfd, int childfd)
{
    int max;
    fd_set rfds;
    int result;

    int masterfd, slavefd;

    masterfd = pty_pair_get_masterfd(pty_pair);
    if (masterfd == -1) {
        logger_write_pos(logger, __FILE__, __LINE__,
                         "pty_pair_get_masterfd error");
        return -1;
    }

    slavefd = pty_pair_get_slavefd(pty_pair);
    if (slavefd == -1) {
        logger_write_pos(logger, __FILE__, __LINE__,
                         "pty_pair_get_slavefd error");
        return -1;
    }

    /* When TGDB is ready, we read from STDIN, otherwise, leave the data buffered. */
    /* get max fd  for select loop */
    max = (gdbfd > STDIN_FILENO) ? gdbfd : STDIN_FILENO;
    max = (max > childfd) ? max : childfd;
    max = (max > slavefd) ? max : slavefd;
    max = (max > masterfd) ? max : masterfd;

    while (1) {
        /* Clear the set and
         *
         * READ FROM:
         * stdin          (user or gui)
         * master         (gdb's stdout)
         * gui_stdout     (gui's stdout sending new info)
         *
         */
        FD_ZERO(&rfds);

        /* Let the terminal emulate the char's when TGDB is busy */
        FD_SET(STDIN_FILENO, &rfds);
        FD_SET(gdbfd, &rfds);
        FD_SET(slavefd, &rfds);
        FD_SET(masterfd, &rfds);

        if (childfd != -1)
            FD_SET(childfd, &rfds);

        result = select(max + 1, &rfds, NULL, NULL, NULL);

        /* if the signal interuppted system call keep going */
        if (result == -1 && errno == EINTR)
            continue;
        else if (result == -1)  /* on error ... must die -> stupid OS */
            logger_write_pos(logger, __FILE__, __LINE__, "select failed");

        /* Input received through the pty:  Handle it
         * Readline read from slavefd, and it wrote to the masterfd.
         */
        if (FD_ISSET(masterfd, &rfds))
            if (readline_input() == -1)
                return -1;

        if (FD_ISSET(slavefd, &rfds))
            rline_rl_callback_read_char(rline);

        /* stdin -> readline input */
        if (FD_ISSET(STDIN_FILENO, &rfds)) {
            stdin_input();
        }

        /* child's output -> stdout */
        if (childfd != -1 && FD_ISSET(childfd, &rfds)) {
            tty_input();
            continue;
        }

        /* gdb's output -> stdout  */
        if (FD_ISSET(gdbfd, &rfds))
            if (gdb_input() == -1)
                return -1;
    }

    return 0;
}