/* This file contains the unix-specific versions the ttyread() functions.
* There are actually three versions of ttyread() defined here, because
* BSD, SysV, and V7 all need quite different implementations.
/* For BSD, we use select() to wait for characters to become available,
* and then do a read() to actually get the characters. We also try to
* handle SIGWINCH -- if the signal arrives during the select() call, then
* we adjust the o_columns and o_lines variables, and fake a control-L.
int ttyread(buf
, len
, time
)
char *buf
; /* where to store the gotten characters */
int len
; /* maximum number of characters to read */
int time
; /* maximum time to allow for reading */
fd_set rd
; /* the file descriptors that we want to read from */
static tty
; /* 'y' if reading from tty, or 'n' if not a tty */
/* do we know whether this is a tty or not? */
tty
= (isatty(0) ? 'y' : 'n');
/* compute the timeout value */
t
.tv_usec
= (time
% 10) * 100000L;
tp
= (struct timeval
*)0;
/* loop until we get characters or a definite EOF */
/* wait until timeout or characters are available */
i
= select(1, &rd
, (fd_set
*)0, (fd_set
*)0, tp
);
/* if reading from a file or pipe, never timeout!
* (This also affects the way that EOF is detected)
/* react accordingly... */
case -1: /* assume we got an EINTR because of SIGWINCH */
if (*o_lines
!= LINES
|| *o_columns
!= COLS
)
/* pretend the user hit ^L */
default: /* characters available */
return read(0, buf
, len
);
/* For System-V or Coherent, we use VMIN/VTIME to implement the timeout.
* For no timeout, VMIN should be 1 and VTIME should be 0; for timeout,
* VMIN should be 0 and VTIME should be the timeout value.
int ttyread(buf
, len
, time
)
char *buf
; /* where to store the gotten characters */
int len
; /* maximum number of characters to read */
int time
; /* maximum time to allow for reading */
int bytes
; /* number of bytes actually read */
/* arrange for timeout */
/* Perform the read. Loop if EINTR error happens */
while ((bytes
= read(0, buf
, len
)) < 0)
/* probably EINTR error because a SIGWINCH was received */
if (*o_lines
!= LINES
|| *o_columns
!= COLS
)
/* pretend the user hit ^L */
/* return the number of bytes read */
/* NOTE: The terminal may be left in a timeout-mode after this function
* returns. This shouldn't be a problem since Elvis *NEVER* tries to
* read from the keyboard except through this function.
# else /* any other version of UNIX, assume it is V7 compatible */
/* For V7 UNIX (including Minix) we set an alarm() before doing a blocking
* read(), and assume that the SIGALRM signal will cause the read() function
int ttyread(buf
, len
, time
)
char *buf
; /* where to store the gotten characters */
int len
; /* maximum number of characters to read */
int time
; /* maximum time to allow for reading */
/* arrange for timeout */
signal(SIGALRM
, (void (*)()) dummy
);
/* perform the blocking read */
else /* I guess we timed out */
signal(SIGALRM
, dummy
); /* <-- to work around a bug in Minix */
/* return the number of bytes read */
# endif /* !(M_SYSV || COHERENT) */