/** * mutt_getch - Read a character from the input buffer * @retval obj Event to process * * The priority for reading events is: * 1. UngetKeyEvents buffer * 2. MacroEvents buffer * 3. Keyboard * * This function can return: * - Error `{ -1, OP_NULL }` * - Timeout `{ -2, OP_NULL }` */ struct Event mutt_getch(void) { int ch; struct Event err = { -1, OP_NULL }, ret; struct Event timeout = { -2, OP_NULL }; if (UngetCount) return UngetKeyEvents[--UngetCount]; if (!OptIgnoreMacroEvents && MacroBufferCount) return MacroEvents[--MacroBufferCount]; SigInt = 0; mutt_sig_allow_interrupt(1); #ifdef KEY_RESIZE /* ncurses 4.2 sends this when the screen is resized */ ch = KEY_RESIZE; while (ch == KEY_RESIZE) #endif /* KEY_RESIZE */ #ifdef USE_INOTIFY ch = mutt_monitor_getch(); #else ch = getch(); #endif /* USE_INOTIFY */ mutt_sig_allow_interrupt(0); if (SigInt) { mutt_query_exit(); return err; } /* either timeout, a sigwinch (if timeout is set), or the terminal * has been lost */ if (ch == ERR) { if (!isatty(0)) mutt_exit(1); return timeout; } if ((ch & 0x80) && C_MetaKey) { /* send ALT-x as ESC-x */ ch &= ~0x80; mutt_unget_event(ch, 0); ret.ch = '\033'; ret.op = 0; return ret; } ret.ch = ch; ret.op = 0; return (ch == ctrl('G')) ? err : ret; }
event_t mutt_getch (void) { int ch; event_t err = {-1, OP_NULL }, ret; if (UngetCount) return (KeyEvent[--UngetCount]); SigInt = 0; #ifdef KEY_RESIZE /* ncurses 4.2 sends this when the screen is resized */ ch = KEY_RESIZE; while (ch == KEY_RESIZE) #endif /* KEY_RESIZE */ ch = getch (); if (SigInt) mutt_query_exit (); if(ch == ERR) return err; if ((ch & 0x80) && option (OPTMETAKEY)) { /* send ALT-x as ESC-x */ ch &= ~0x80; mutt_ungetch (ch, 0); ret.ch = '\033'; ret.op = 0; return ret; } ret.ch = ch; ret.op = 0; return (ch == ctrl ('G') ? err : ret); }
/** * raw_socket_poll - Checks whether reads would block - Implements Connection::conn_poll() */ int raw_socket_poll(struct Connection *conn, time_t wait_secs) { fd_set rfds; unsigned long wait_millis; struct timeval tv, pre_t, post_t; if (conn->fd < 0) return -1; wait_millis = wait_secs * 1000UL; while (true) { tv.tv_sec = wait_millis / 1000; tv.tv_usec = (wait_millis % 1000) * 1000; FD_ZERO(&rfds); FD_SET(conn->fd, &rfds); gettimeofday(&pre_t, NULL); const int rc = select(conn->fd + 1, &rfds, NULL, NULL, &tv); gettimeofday(&post_t, NULL); if ((rc > 0) || ((rc < 0) && (errno != EINTR))) return rc; if (SigInt) mutt_query_exit(); wait_millis += (pre_t.tv_sec * 1000UL) + (pre_t.tv_usec / 1000); const unsigned long post_t_millis = (post_t.tv_sec * 1000UL) + (post_t.tv_usec / 1000); if (wait_millis <= post_t_millis) return 0; wait_millis -= post_t_millis; } }