5 * 14407 SW Teal Blvd. #C
11 /* This file contains the unix-specific versions the ttyread() functions.
12 * There are actually three versions of ttyread() defined here, because
13 * BSD, SysV, and V7 all need quite different implementations.
21 /* For BSD, we use select() to wait for characters to become available,
22 * and then do a read() to actually get the characters. We also try to
23 * handle SIGWINCH -- if the signal arrives during the select() call, then
24 * we adjust the o_columns and o_lines variables, and fake a control-L.
26 # include <sys/types.h>
27 # include <sys/time.h>
28 int ttyread(buf
, len
, time
)
29 char *buf
; /* where to store the gotten characters */
30 int len
; /* maximum number of characters to read */
31 int time
; /* maximum time to allow for reading */
33 fd_set rd
; /* the file descriptors that we want to read from */
34 static tty
; /* 'y' if reading from tty, or 'n' if not a tty */
40 /* do we know whether this is a tty or not? */
43 tty
= (isatty(0) ? 'y' : 'n');
46 /* compute the timeout value */
50 t
.tv_usec
= (time
% 10) * 100000L;
55 tp
= (struct timeval
*)0;
58 /* loop until we get characters or a definite EOF */
63 /* wait until timeout or characters are available */
66 i
= select(1, &rd
, (fd_set
*)0, (fd_set
*)0, tp
);
70 /* if reading from a file or pipe, never timeout!
71 * (This also affects the way that EOF is detected)
76 /* react accordingly... */
79 case -1: /* assume we got an EINTR because of SIGWINCH */
80 if (*o_lines
!= LINES
|| *o_columns
!= COLS
)
87 *o_window
= LINES
- 1;
92 /* pretend the user hit ^L */
102 default: /* characters available */
103 return read(0, buf
, len
);
110 /* For System-V or Coherent, we use VMIN/VTIME to implement the timeout.
111 * For no timeout, VMIN should be 1 and VTIME should be 0; for timeout,
112 * VMIN should be 0 and VTIME should be the timeout value.
115 int ttyread(buf
, len
, time
)
116 char *buf
; /* where to store the gotten characters */
117 int len
; /* maximum number of characters to read */
118 int time
; /* maximum time to allow for reading */
121 int bytes
; /* number of bytes actually read */
123 /* arrange for timeout */
124 ioctl(0, TCGETA
, &tio
);
128 tio
.c_cc
[VTIME
] = time
;
135 ioctl(0, TCSETA
, &tio
);
137 /* Perform the read. Loop if EINTR error happens */
138 while ((bytes
= read(0, buf
, len
)) < 0)
140 /* probably EINTR error because a SIGWINCH was received */
141 if (*o_lines
!= LINES
|| *o_columns
!= COLS
)
148 *o_window
= LINES
- 1;
153 /* pretend the user hit ^L */
160 /* return the number of bytes read */
163 /* NOTE: The terminal may be left in a timeout-mode after this function
164 * returns. This shouldn't be a problem since Elvis *NEVER* tries to
165 * read from the keyboard except through this function.
169 # else /* any other version of UNIX, assume it is V7 compatible */
171 /* For V7 UNIX (including Minix) we set an alarm() before doing a blocking
172 * read(), and assume that the SIGALRM signal will cause the read() function
186 int ttyread(buf
, len
, time
)
187 char *buf
; /* where to store the gotten characters */
188 int len
; /* maximum number of characters to read */
189 int time
; /* maximum time to allow for reading */
191 /* arrange for timeout */
192 signal(SIGALRM
, (void (*)()) dummy
);
195 /* perform the blocking read */
196 if (setjmp(env
) == 0)
198 len
= read(0, buf
, len
);
200 else /* I guess we timed out */
205 /* cancel the alarm */
206 signal(SIGALRM
, (void (*)())dummy
); /* work around a bug in Minix */
209 /* return the number of bytes read */
215 # endif /* !(M_SYSV || COHERENT) */
218 #endif /* ANY_UNIX */