#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 < 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);
}


