int internal_if_input(int key) { int regex_icase = cgdbrc_get(CGDBRC_IGNORECASE)->variant.int_val; /* Normally, CGDB_KEY_ESC, but can be configured by the user */ int cgdb_mode_key = cgdbrc_get(CGDBRC_CGDB_MODE_KEY)->variant.int_val; /* The cgdb mode key, puts the debugger into command mode */ if (focus != CGDB && key == cgdb_mode_key) { /* Depending on which cgdb was in, it can free some memory here that * it was previously using. */ if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { ibuf_free(cur_sbc); cur_sbc = NULL; } else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; free(src_win->cur->buf.cur_line); src_win->cur->buf.cur_line = NULL; src_win->cur->sel_rline = orig_line_regex; src_win->cur->sel_line = orig_line_regex; } if_set_focus(CGDB); return 0; } /* If you are already in cgdb mode, the cgdb mode key does nothing */ else if (key == cgdb_mode_key) return 0; /* Check for global keystrokes */ switch (focus) { case CGDB: switch (key) { case 'i': if_set_focus(GDB); return 0; case 'I': if_set_focus(TTY); return 0; case ':': /* Set the type of the command the user is typing in the status bar */ sbc_kind = SBC_NORMAL; if_set_focus(CGDB_STATUS_BAR); /* Since the user is about to type in a command, allocate a buffer * in which this command can be stored. */ cur_sbc = ibuf_init(); return 0; case '/': case '?': if (src_win->cur != NULL) { regex_cur = ibuf_init(); regex_direction_cur = ('/' == key); orig_line_regex = src_win->cur->sel_line; sbc_kind = SBC_REGEX; if_set_focus(CGDB_STATUS_BAR); /* Capturing regular expressions */ source_search_regex_init(src_win); /* Initialize the function for finding a regex and tell user */ if_draw(); } return 0; case 'n': source_search_regex(src_win, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); break; case 'N': source_search_regex(src_win, ibuf_get(regex_last), 2, !regex_direction_last, regex_icase); if_draw(); break; case 'T': if (tty_win_on) { tty_win_on = 0; focus = CGDB; } else { tty_win_on = 1; focus = TTY; } if_layout(); break; case CGDB_KEY_CTRL_T: if (tgdb_tty_new(tgdb) == -1) { /* Error */ } else { scr_free(tty_win); tty_win = NULL; if_layout(); } break; case CGDB_KEY_F1: if_display_help(); return 0; case CGDB_KEY_F5: /* Issue GDB run command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_RUN); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F6: /* Issue GDB continue command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_CONTINUE); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F7: /* Issue GDB finish command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_FINISH); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F8: /* Issue GDB next command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_NEXT); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F10: /* Issue GDB step command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_STEP); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_CTRL_L: if_layout(); return 0; } source_input(src_win, key); return 0; break; case TTY: return tty_input(key); case GDB: return gdb_input(key); case FILE_DLG: { static char filedlg_file[MAX_LINE]; int ret = filedlg_recv_char(fd, key, filedlg_file); /* The user cancelled */ if (ret == -1) { if_set_focus(CGDB); return 0; /* Needs more data */ } else if (ret == 0) { return 0; /* The user picked a file */ } else if (ret == 1) { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_filename_pair(tgdb, filedlg_file); handle_request(tgdb, request_ptr); if_set_focus(CGDB); return 0; } } return 0; case CGDB_STATUS_BAR: return status_bar_input(src_win, key); } /* Never gets here */ return 0; }
int internal_if_input(int key, int *last_key) { /* Normally, CGDB_KEY_ESC, but can be configured by the user */ int cgdb_mode_key = cgdbrc_get_int(CGDBRC_CGDB_MODE_KEY); /* The cgdb mode key, puts the debugger into command mode */ if (focus != CGDB && key == cgdb_mode_key) { enum Focus new_focus = CGDB; /* Depending on which cgdb was in, it can free some memory here that * it was previously using. */ if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { ibuf_free(cur_sbc); cur_sbc = NULL; } else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; hl_regex_free(&src_viewer->hlregex); src_viewer->cur->sel_rline = orig_line_regex; src_viewer->cur->sel_line = orig_line_regex; sbc_kind = SBC_NORMAL; } else if (focus == GDB && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; gdb_scroller->in_search_mode = 0; sbc_kind = SBC_NORMAL; new_focus = GDB; } if_set_focus(new_focus); return 0; } /* If you are already in cgdb mode, the cgdb mode key does nothing */ else if (key == cgdb_mode_key) return 0; /* Check for global keystrokes */ switch (focus) { case CGDB: return cgdb_input(key, last_key); case GDB: return gdb_input(key, last_key); case FILE_DLG: { char filedlg_file[MAX_LINE]; int ret = filedlg_recv_char(fd, key, filedlg_file, last_key_pressed); /* The user cancelled */ if (ret == -1) { if_set_focus(CGDB); return 0; /* Needs more data */ } else if (ret == 0) { return 0; /* The user picked a file */ } else if (ret == 1) { if_show_file(filedlg_file, 0, 0); if_set_focus(CGDB); return 0; } } return 0; case CGDB_STATUS_BAR: return status_bar_input(src_viewer, key); } /* Never gets here */ return 0; }
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; }
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; }