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.17 2000/04/30 17:15:55 skimo Exp $ (Berkeley) $Date: 2000/04/30 17:15:55 $";
14 #include <sys/types.h>
15 #include <sys/queue.h>
18 #include <bitstring.h>
26 #include "../common/common.h"
27 #include "../ex/script.h"
28 #include "../ipc/ip.h"
31 extern GS
*__global_list
;
33 typedef enum { INP_OK
=0, INP_EOF
, INP_ERR
, INP_TIMEOUT
} input_t
;
35 static input_t ip_read
__P((SCR
*, IP_PRIVATE
*, struct timeval
*));
36 static int ip_resize
__P((SCR
*, u_int32_t
, u_int32_t
));
37 static int ip_trans
__P((SCR
*, IP_PRIVATE
*, EVENT
*));
41 * Return a single event.
43 * PUBLIC: int ip_event __P((SCR *, EVENT *, u_int32_t, int));
46 ip_event(sp
, evp
, flags
, ms
)
53 struct timeval t
, *tp
;
55 if (LF_ISSET(EC_INTERRUPT
)) { /* XXX */
56 evp
->e_event
= E_TIMEOUT
;
60 ipp
= sp
== NULL
? GIPP(__global_list
) : IPP(sp
);
62 /* Discard the last command. */
63 if (ipp
->iskip
!= 0) {
64 ipp
->iblen
-= ipp
->iskip
;
65 memmove(ipp
->ibuf
, ipp
->ibuf
+ ipp
->iskip
, ipp
->iblen
);
69 /* Process possible remaining commands */
70 if (ipp
->iblen
>= IPO_CODE_LEN
&& ip_trans(sp
, ipp
, evp
))
78 t
.tv_usec
= (ms
% 1000) * 1000;
82 /* Read input events. */
84 switch (ip_read(sp
, ipp
, tp
)) {
86 if (!ip_trans(sp
, ipp
, evp
))
96 evp
->e_event
= E_TIMEOUT
;
108 * Read characters from the input.
125 gp
= sp
== NULL
? __global_list
: sp
->gp
;
126 bp
= ipp
->ibuf
+ ipp
->iblen
;
127 blen
= sizeof(ipp
->ibuf
) - ipp
->iblen
;
130 * 1: A read with an associated timeout, e.g., trying to complete
131 * a map sequence. If input exists, we fall into #2.
137 FD_SET(ipp
->i_fd
, &rdfd
);
138 switch (select(ipp
->i_fd
+ 1,
139 &rdfd
, NULL
, NULL
, tp
== NULL
? &poll
: tp
)) {
141 return (INP_TIMEOUT
);
152 * Select on the command input and scripting window file descriptors.
153 * It's ugly that we wait on scripting file descriptors here, but it's
154 * the only way to keep from locking out scripting windows.
156 if (sp
!= NULL
&& F_ISSET(gp
, G_SCRWIN
)) {
157 loop
: FD_ZERO(&rdfd
);
158 FD_SET(ipp
->i_fd
, &rdfd
);
160 for (tsp
= gp
->dq
.cqh_first
;
161 tsp
!= (void *)&gp
->dq
; tsp
= tsp
->q
.cqe_next
)
162 if (F_ISSET(sp
, SC_SCRIPT
)) {
163 FD_SET(sp
->script
->sh_master
, &rdfd
);
164 if (sp
->script
->sh_master
> maxfd
)
165 maxfd
= sp
->script
->sh_master
;
167 switch (select(maxfd
+ 1, &rdfd
, NULL
, NULL
, NULL
)) {
175 if (!FD_ISSET(ipp
->i_fd
, &rdfd
)) {
185 switch (nr
= read(ipp
->i_fd
, bp
, blen
)) {
189 case -1: /* Error or interrupt. */
191 msgq(sp
, M_SYSERR
, "input");
193 default: /* Input characters. */
203 * Translate messages into events.
206 ip_trans(sp
, ipp
, evp
)
214 switch (ipp
->ibuf
[0]) {
229 evp
->e_event
= E_IPCOMMAND
;
230 evp
->e_ipcom
= ipp
->ibuf
[0];
231 ipp
->iskip
= IPO_CODE_LEN
;
238 evp
->e_event
= E_IPCOMMAND
;
239 evp
->e_ipcom
= ipp
->ibuf
[0];
243 evp
->e_event
= E_IPCOMMAND
;
244 evp
->e_ipcom
= ipp
->ibuf
[0];
251 evp
->e_event
= E_IPCOMMAND
;
252 evp
->e_ipcom
= ipp
->ibuf
[0];
256 evp
->e_event
= E_IPCOMMAND
;
257 evp
->e_ipcom
= ipp
->ibuf
[0];
261 evp
->e_event
= E_EOF
;
262 ipp
->iskip
= IPO_CODE_LEN
;
265 evp
->e_event
= E_ERR
;
266 ipp
->iskip
= IPO_CODE_LEN
;
269 evp
->e_event
= E_INTERRUPT
;
270 ipp
->iskip
= IPO_CODE_LEN
;
275 evp
->e_event
= E_IPCOMMAND
;
276 evp
->e_ipcom
= ipp
->ibuf
[0];
280 evp
->e_event
= E_WRESIZE
;
284 evp
->e_event
= E_SIGHUP
;
285 ipp
->iskip
= IPO_CODE_LEN
;
288 evp
->e_event
= E_SIGTERM
;
289 ipp
->iskip
= IPO_CODE_LEN
;
292 evp
->e_event
= E_STRING
;
297 * XXX: Protocol is out of sync?
302 for (skip
= IPO_CODE_LEN
; *fmt
!= '\0'; ++fmt
)
306 if (ipp
->iblen
< skip
+ IPO_INT_LEN
)
308 memcpy(&val
, ipp
->ibuf
+ skip
, IPO_INT_LEN
);
318 if (ipp
->iblen
< skip
+ IPO_INT_LEN
)
320 memcpy(&val
, ipp
->ibuf
+ skip
, IPO_INT_LEN
);
323 if (ipp
->iblen
< skip
+ val
)
326 evp
->e_str1
= ipp
->ibuf
+ skip
;
329 evp
->e_str2
= ipp
->ibuf
+ skip
;
338 if (evp
->e_event
== E_WRESIZE
)
339 (void)ip_resize(sp
, evp
->e_val1
, evp
->e_val2
);
346 * Reset the options for a resize event.
349 ip_resize(sp
, lines
, columns
)
351 u_int32_t lines
, columns
;
358 * The IP screen has to know the lines and columns before anything
359 * else happens. So, we may not have a valid SCR pointer, and we
360 * have to deal with that.
364 OG_VAL(gp
, GO_LINES
) = OG_D_VAL(gp
, GO_LINES
) = lines
;
365 OG_VAL(gp
, GO_COLUMNS
) = OG_D_VAL(gp
, GO_COLUMNS
) = columns
;
369 rval
= api_opts_set(sp
, "lines", NULL
, lines
, 0);
370 if (api_opts_set(sp
, "columns", NULL
, columns
, 0))