#include #include /* * Check whether or not a character is ready to be read, or time out. * This version uses a poll call. * * Args: time_out -- number of seconds before it will time out. * * Result: NO_OP_IDLE: timed out before any chars ready, time_out > 25 * NO_OP_COMMAND: timed out before any chars ready, time_out <= 25 * READ_INTR: read was interrupted * READY_TO_READ: input is available * BAIL_OUT: reading input failed, time to bail gracefully * PANIC_NOW: system call error, die now */ int input_ready(time_out) int time_out; { struct pollfd pollfd; int res; fflush(stdout); if(time_out > 0){ /* Check to see if there are bytes to read with a timeout */ pollfd.fd = STDIN_FD; pollfd.events = POLLIN; res = poll (&pollfd, 1, time_out * 1000); if(res >= 0){ /* status bits OK? */ if(pollfd.revents & (POLLERR | POLLNVAL)) res = -1; /* bad news, exit below! */ else if(pollfd.revents & POLLHUP) return(BAIL_OUT); } if(res < 0){ if(errno == EINTR || errno == EAGAIN) return(READ_INTR); return(PANIC_NOW); } if(res == 0){ /* the select timed out */ if(getppid() == 1){ /* Parent is init! */ return(BAIL_OUT); } /* * "15" is the minimum allowed mail check interval. * Anything less, and we're being told to cycle thru * the command loop because some task is pending... */ return(time_out < 15 ? NO_OP_COMMAND : NO_OP_IDLE); } } return(READY_TO_READ); } /* * Read one character from STDIN. * * Result: -- the single character read * READ_INTR -- read was interrupted * BAIL_OUT -- read error of some sort */ int read_one_char() { int res; unsigned char c; res = read(STDIN_FD, &c, 1); if(res <= 0){ /* * Error reading from terminal! * The only acceptable failure is being interrupted. If so, * return a value indicating such... */ if(res < 0 && errno == EINTR) return(READ_INTR); else return(BAIL_OUT); } return((int)c); }