xref: /csrg-svn/usr.bin/window/wwiomux.c (revision 18332)
113923Sedward #ifndef lint
2*18332Sedward static char sccsid[] = "@(#)wwiomux.c	3.13 03/13/85";
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;
38*18332Sedward 		if (w->ww_obq < w->ww_obe)
39*18332Sedward 			imask |= 1 << w->ww_pty;
4016313Sedward 		if (w->ww_obq > w->ww_obp && !w->ww_stopped)
4116124Sedward 			noblock = 1;
4215872Sedward 	}
4316124Sedward 
4416124Sedward 	if (!noblock) {
4516124Sedward 		if (wwcurwin != 0)
4616124Sedward 			wwcurtowin(wwcurwin);
4715872Sedward 		wwupdate();
4815872Sedward 		wwflush();
4916124Sedward 		if (setjmp(wwjmpbuf))
5016124Sedward 			return;
5116124Sedward 		wwsetjmp = 1;
5216124Sedward 		if (wwinterrupt()) {
5316124Sedward 			wwsetjmp = 0;
5416124Sedward 			return;
5516124Sedward 		}
5615872Sedward 	}
5715872Sedward 	wwnselect++;
5815872Sedward 	n = select(wwdtablesize, &imask, (int *)0, (int *)0,
5916124Sedward 		noblock ? &tv : (struct timeval *)0);
6016124Sedward 	wwsetjmp = 0;
6116124Sedward 
6215872Sedward 	if (n < 0)
6315872Sedward 		wwnselecte++;
6416313Sedward 	else if (n == 0)
6516313Sedward 		wwnselectz++;
6616313Sedward 	else
6716313Sedward 		for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
6816313Sedward 			if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0)
6916313Sedward 				continue;
7016313Sedward 			wwnwread++;
7116313Sedward 			p = w->ww_obq;
7216313Sedward 			if (w->ww_ispty) {
7316313Sedward 				if (p == w->ww_ob) {
7415872Sedward 					w->ww_obp++;
7516313Sedward 					w->ww_obq++;
7616313Sedward 				} else
7715872Sedward 					p--;
7815872Sedward 				c = *p;
7916313Sedward 			}
8016313Sedward 			n = read(w->ww_pty, p, w->ww_obe - p);
8116313Sedward 			if (n < 0) {
8216313Sedward 				wwnwreade++;
8316313Sedward 				(void) close(w->ww_pty);
8416313Sedward 				w->ww_pty = -1;
8516313Sedward 			} else if (n == 0) {
8616313Sedward 				wwnwreadz++;
8718129Sedward 				(void) close(w->ww_pty);
8818129Sedward 				w->ww_pty = -1;
8916313Sedward 			} else if (!w->ww_ispty) {
9016313Sedward 				wwnwreadd++;
9116313Sedward 				wwnwreadc += n;
9216313Sedward 				w->ww_obq += n;
9316313Sedward 			} else if (*p == TIOCPKT_DATA) {
9416313Sedward 				n--;
9516313Sedward 				wwnwreadd++;
9616313Sedward 				wwnwreadc += n;
9716313Sedward 				w->ww_obq += n;
9816313Sedward 			} else {
9916313Sedward 				wwnwreadp++;
10016313Sedward 				if (*p & TIOCPKT_STOP)
10116313Sedward 					w->ww_stopped = 1;
10216313Sedward 				if (*p & TIOCPKT_START)
10316313Sedward 					w->ww_stopped = 0;
10416313Sedward 				if (*p & TIOCPKT_FLUSHWRITE) {
10516313Sedward 					w->ww_stopped = 0;
10616313Sedward 					w->ww_obq = w->ww_obp = w->ww_ob;
10715872Sedward 				}
10816313Sedward 			}
10916313Sedward 			if (w->ww_ispty)
11015872Sedward 				*p = c;
11116313Sedward 		}
11216127Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
11316313Sedward 		if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) {
11416313Sedward 			n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp);
11516313Sedward 			if ((w->ww_obp += n) == w->ww_obq)
11616313Sedward 				w->ww_obq = w->ww_obp = w->ww_ob;
11716127Sedward 			if (wwinterrupt())
11816127Sedward 				return;
11916127Sedward 			break;
12013923Sedward 		}
12116124Sedward 	goto loop;
12213923Sedward }
123