int main(int argc, const char** argv) { DEHT * deht = NULL; int res = 0; unsigned int digest_size; if (argc != 2) { fprintf(stderr, "Usage: %s <prefix>\n", argv[0]); return 1; } /* load deht */ deht = load_DEHT_from_files(argv[1], my_hash_func, my_valid_func); if (deht == NULL) { return 1; } /* instructions: * Load the header into memory, but not the table of pointers (i.e. do not call * read_DEHT_pointers_table). */ /* compute digest size (determined by hash name) */ if (strcmp(deht->header.sHashName, "MD5") == 0) { digest_size = MD5_OUTPUT_LENGTH_IN_BYTES; } else if (strcmp(deht->header.sHashName, "SHA1") == 0) { digest_size = SHA1_OUTPUT_LENGTH_IN_BYTES; } else { fprintf(stderr, "invalid DEHT hash '%s'", deht->header.sHashName); res = 1; goto cleanup; } /* main loop */ user_input_loop(deht, digest_size); cleanup: if (deht != NULL) { close_DEHT_files(deht); } return res; }
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; }