96 lines
2.3 KiB
Plaintext
96 lines
2.3 KiB
Plaintext
#include <stropts.h>
|
|
#include <poll.h>
|
|
|
|
/*
|
|
* 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 < IDLE_TIMEOUT ? NO_OP_COMMAND : NO_OP_IDLE);
|
|
}
|
|
}
|
|
|
|
time_of_last_input = time((time_t *) 0);
|
|
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);
|
|
}
|
|
|
|
|