3 * Keith Bostic. All rights reserved.
5 * See the LICENSE file for redistribution information.
11 static const char sccsid
[] = "$Id: ip_read.c,v 8.15 1996/12/17 20:15:22 bostic Exp $ (Berkeley) $Date: 1996/12/17 20:15:22 $";
14 #include <sys/types.h>
15 #include <sys/queue.h>
18 #include <bitstring.h>
26 #include "../common/common.h"
27 #include "../ex/script.h"
30 extern GS
*__global_list
;
32 typedef enum { INP_OK
=0, INP_EOF
, INP_ERR
, INP_TIMEOUT
} input_t
;
34 static input_t ip_read
__P((SCR
*, IP_PRIVATE
*, struct timeval
*));
35 static int ip_resize
__P((SCR
*, u_int32_t
, u_int32_t
));
36 static int ip_trans
__P((SCR
*, IP_PRIVATE
*, EVENT
*));
40 * Return a single event.
42 * PUBLIC: int ip_event __P((SCR *, EVENT *, u_int32_t, int));
45 ip_event(sp
, evp
, flags
, ms
)
52 struct timeval t
, *tp
;
54 if (LF_ISSET(EC_INTERRUPT
)) { /* XXX */
55 evp
->e_event
= E_TIMEOUT
;
59 ipp
= sp
== NULL
? GIPP(__global_list
) : IPP(sp
);
61 /* Discard the last command. */
62 if (ipp
->iskip
!= 0) {
63 ipp
->iblen
-= ipp
->iskip
;
64 memmove(ipp
->ibuf
, ipp
->ibuf
+ ipp
->iskip
, ipp
->iblen
);
73 t
.tv_usec
= (ms
% 1000) * 1000;
77 /* Read input events. */
79 switch (ip_read(sp
, ipp
, tp
)) {
81 if (!ip_trans(sp
, ipp
, evp
))
91 evp
->e_event
= E_TIMEOUT
;
103 * Read characters from the input.
120 gp
= sp
== NULL
? __global_list
: sp
->gp
;
121 bp
= ipp
->ibuf
+ ipp
->iblen
;
122 blen
= sizeof(ipp
->ibuf
) - ipp
->iblen
;
125 * 1: A read with an associated timeout, e.g., trying to complete
126 * a map sequence. If input exists, we fall into #2.
132 FD_SET(ipp
->i_fd
, &rdfd
);
133 switch (select(ipp
->i_fd
+ 1,
134 &rdfd
, NULL
, NULL
, tp
== NULL
? &poll
: tp
)) {
136 return (INP_TIMEOUT
);
147 * Select on the command input and scripting window file descriptors.
148 * It's ugly that we wait on scripting file descriptors here, but it's
149 * the only way to keep from locking out scripting windows.
151 if (sp
!= NULL
&& F_ISSET(gp
, G_SCRWIN
)) {
152 loop
: FD_ZERO(&rdfd
);
153 FD_SET(ipp
->i_fd
, &rdfd
);
155 for (tsp
= gp
->dq
.cqh_first
;
156 tsp
!= (void *)&gp
->dq
; tsp
= tsp
->q
.cqe_next
)
157 if (F_ISSET(sp
, SC_SCRIPT
)) {
158 FD_SET(sp
->script
->sh_master
, &rdfd
);
159 if (sp
->script
->sh_master
> maxfd
)
160 maxfd
= sp
->script
->sh_master
;
162 switch (select(maxfd
+ 1, &rdfd
, NULL
, NULL
, NULL
)) {
170 if (!FD_ISSET(ipp
->i_fd
, &rdfd
)) {
180 switch (nr
= read(ipp
->i_fd
, bp
, blen
)) {
184 case -1: /* Error or interrupt. */
186 msgq(sp
, M_SYSERR
, "input");
188 default: /* Input characters. */
198 * Translate messages into events.
201 ip_trans(sp
, ipp
, evp
)
209 switch (ipp
->ibuf
[0]) {
224 evp
->e_event
= E_IPCOMMAND
;
225 evp
->e_ipcom
= ipp
->ibuf
[0];
226 ipp
->iskip
= IPO_CODE_LEN
;
233 evp
->e_event
= E_IPCOMMAND
;
234 evp
->e_ipcom
= ipp
->ibuf
[0];
238 evp
->e_event
= E_IPCOMMAND
;
239 evp
->e_ipcom
= ipp
->ibuf
[0];
246 evp
->e_event
= E_IPCOMMAND
;
247 evp
->e_ipcom
= ipp
->ibuf
[0];
251 evp
->e_event
= E_IPCOMMAND
;
252 evp
->e_ipcom
= ipp
->ibuf
[0];
256 evp
->e_event
= E_EOF
;
257 ipp
->iskip
= IPO_CODE_LEN
;
260 evp
->e_event
= E_ERR
;
261 ipp
->iskip
= IPO_CODE_LEN
;
264 evp
->e_event
= E_INTERRUPT
;
265 ipp
->iskip
= IPO_CODE_LEN
;
270 evp
->e_event
= E_IPCOMMAND
;
271 evp
->e_ipcom
= ipp
->ibuf
[0];
275 evp
->e_event
= E_WRESIZE
;
279 evp
->e_event
= E_SIGHUP
;
280 ipp
->iskip
= IPO_CODE_LEN
;
283 evp
->e_event
= E_SIGTERM
;
284 ipp
->iskip
= IPO_CODE_LEN
;
287 evp
->e_event
= E_STRING
;
292 * XXX: Protocol is out of sync?
297 for (skip
= IPO_CODE_LEN
; *fmt
!= '\0'; ++fmt
)
301 if (ipp
->iblen
< skip
+ IPO_INT_LEN
)
303 memcpy(&val
, ipp
->ibuf
+ skip
, IPO_INT_LEN
);
313 if (ipp
->iblen
< skip
+ IPO_INT_LEN
)
315 memcpy(&val
, ipp
->ibuf
+ skip
, IPO_INT_LEN
);
318 if (ipp
->iblen
< skip
+ val
)
321 evp
->e_str1
= ipp
->ibuf
+ skip
;
324 evp
->e_str2
= ipp
->ibuf
+ skip
;
333 if (evp
->e_event
== E_WRESIZE
)
334 (void)ip_resize(sp
, evp
->e_val1
, evp
->e_val2
);
341 * Reset the options for a resize event.
344 ip_resize(sp
, lines
, columns
)
346 u_int32_t lines
, columns
;
353 * The IP screen has to know the lines and columns before anything
354 * else happens. So, we may not have a valid SCR pointer, and we
355 * have to deal with that.
359 OG_VAL(gp
, GO_LINES
) = OG_D_VAL(gp
, GO_LINES
) = lines
;
360 OG_VAL(gp
, GO_COLUMNS
) = OG_D_VAL(gp
, GO_COLUMNS
) = columns
;
364 rval
= api_opts_set(sp
, "lines", NULL
, lines
, 0);
365 if (api_opts_set(sp
, "columns", NULL
, columns
, 0))