xref: /csrg-svn/usr.bin/window/wwiomux.c (revision 16313)
113923Sedward #ifndef lint
2*16313Sedward static	char *sccsid = "@(#)wwiomux.c	3.10 84/04/08";
313923Sedward #endif
413923Sedward 
513923Sedward #include "ww.h"
615872Sedward #include <sys/time.h>
713923Sedward 
815872Sedward /*
916124Sedward  * Multiple window output handler.
1016124Sedward  * The idea is to copy window outputs to the terminal, via the
1116124Sedward  * display package.  We try to give the top most window highest
1216124Sedward  * priority.  The only return condition is when there is keyboard
1316124Sedward  * input, which is serviced asynchronously by wwrint().
1416124Sedward  * When there's nothing to do, we sleep in a select().
1516124Sedward  * This can be done better with interrupt driven io.  But that's
1616124Sedward  * not supported on ptys, yet.
1716124Sedward  * The history of this routine is interesting.
1815872Sedward  */
1915872Sedward wwiomux()
2013923Sedward {
2115872Sedward 	register struct ww *w;
2215872Sedward 	int imask;
2316124Sedward 	register n;
2415872Sedward 	register char *p;
2515872Sedward 	char c;
2615872Sedward 	static struct timeval tv = { 0, 0 };
2716124Sedward 	char noblock;
2813923Sedward 
2915872Sedward loop:
3016124Sedward 	if (wwinterrupt())
3116124Sedward 		return;
3216124Sedward 
3316124Sedward 	imask = 0;
3416124Sedward 	noblock = 0;
3515872Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
3615872Sedward 		if (w->ww_pty < 0)
3715872Sedward 			continue;
3816124Sedward 		imask |= 1 << w->ww_pty;
39*16313Sedward 		if (w->ww_obq > w->ww_obp && !w->ww_stopped)
4016124Sedward 			noblock = 1;
4115872Sedward 	}
4216124Sedward 
4316124Sedward 	if (!noblock) {
4416124Sedward 		if (wwcurwin != 0)
4516124Sedward 			wwcurtowin(wwcurwin);
4615872Sedward 		wwupdate();
4715872Sedward 		wwflush();
4816124Sedward 		if (setjmp(wwjmpbuf))
4916124Sedward 			return;
5016124Sedward 		wwsetjmp = 1;
5116124Sedward 		if (wwinterrupt()) {
5216124Sedward 			wwsetjmp = 0;
5316124Sedward 			return;
5416124Sedward 		}
5515872Sedward 	}
5615872Sedward 	wwnselect++;
5715872Sedward 	n = select(wwdtablesize, &imask, (int *)0, (int *)0,
5816124Sedward 		noblock ? &tv : (struct timeval *)0);
5916124Sedward 	wwsetjmp = 0;
6016124Sedward 
6115872Sedward 	if (n < 0)
6215872Sedward 		wwnselecte++;
63*16313Sedward 	else if (n == 0)
64*16313Sedward 		wwnselectz++;
65*16313Sedward 	else
66*16313Sedward 		for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
67*16313Sedward 			if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0)
68*16313Sedward 				continue;
69*16313Sedward 			wwnwread++;
70*16313Sedward 			p = w->ww_obq;
71*16313Sedward 			if (w->ww_ispty) {
72*16313Sedward 				if (p == w->ww_ob) {
7315872Sedward 					w->ww_obp++;
74*16313Sedward 					w->ww_obq++;
75*16313Sedward 				} else
7615872Sedward 					p--;
7715872Sedward 				c = *p;
78*16313Sedward 			}
79*16313Sedward 			n = read(w->ww_pty, p, w->ww_obe - p);
80*16313Sedward 			if (n < 0) {
81*16313Sedward 				wwnwreade++;
82*16313Sedward 				(void) close(w->ww_pty);
83*16313Sedward 				w->ww_pty = -1;
84*16313Sedward 				continue;
85*16313Sedward 			} else if (n == 0) {
86*16313Sedward 				wwnwreadz++;
87*16313Sedward 			} else if (!w->ww_ispty) {
88*16313Sedward 				wwnwreadd++;
89*16313Sedward 				wwnwreadc += n;
90*16313Sedward 				w->ww_obq += n;
91*16313Sedward 			} else if (*p == TIOCPKT_DATA) {
92*16313Sedward 				n--;
93*16313Sedward 				wwnwreadd++;
94*16313Sedward 				wwnwreadc += n;
95*16313Sedward 				w->ww_obq += n;
96*16313Sedward 			} else {
97*16313Sedward 				wwnwreadp++;
98*16313Sedward 				if (*p & TIOCPKT_STOP)
99*16313Sedward 					w->ww_stopped = 1;
100*16313Sedward 				if (*p & TIOCPKT_START)
101*16313Sedward 					w->ww_stopped = 0;
102*16313Sedward 				if (*p & TIOCPKT_FLUSHWRITE) {
103*16313Sedward 					w->ww_stopped = 0;
104*16313Sedward 					w->ww_obq = w->ww_obp = w->ww_ob;
10515872Sedward 				}
106*16313Sedward 			}
107*16313Sedward 			if (w->ww_ispty)
10815872Sedward 				*p = c;
109*16313Sedward 		}
11016127Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
111*16313Sedward 		if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) {
112*16313Sedward 			n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp);
113*16313Sedward 			if ((w->ww_obp += n) == w->ww_obq)
114*16313Sedward 				w->ww_obq = w->ww_obp = w->ww_ob;
11516127Sedward 			if (wwinterrupt())
11616127Sedward 				return;
11716127Sedward 			break;
11813923Sedward 		}
11916124Sedward 	goto loop;
12013923Sedward }
121