xref: /csrg-svn/usr.bin/window/wwiomux.c (revision 18744)
113923Sedward #ifndef lint
2*18744Sedward static char sccsid[] = "@(#)wwiomux.c	3.14 04/24/85";
313923Sedward #endif
413923Sedward 
5*18744Sedward /*
6*18744Sedward  * Copyright (c) 1983 Regents of the University of California,
7*18744Sedward  * All rights reserved.  Redistribution permitted subject to
8*18744Sedward  * the terms of the Berkeley Software License Agreement.
9*18744Sedward  */
10*18744Sedward 
1113923Sedward #include "ww.h"
1215872Sedward #include <sys/time.h>
1313923Sedward 
1415872Sedward /*
1516124Sedward  * Multiple window output handler.
1616124Sedward  * The idea is to copy window outputs to the terminal, via the
1716124Sedward  * display package.  We try to give the top most window highest
1816124Sedward  * priority.  The only return condition is when there is keyboard
1916124Sedward  * input, which is serviced asynchronously by wwrint().
2016124Sedward  * When there's nothing to do, we sleep in a select().
2116124Sedward  * This can be done better with interrupt driven io.  But that's
2216124Sedward  * not supported on ptys, yet.
2316124Sedward  * The history of this routine is interesting.
2415872Sedward  */
2515872Sedward wwiomux()
2613923Sedward {
2715872Sedward 	register struct ww *w;
2815872Sedward 	int imask;
2916124Sedward 	register n;
3015872Sedward 	register char *p;
3115872Sedward 	char c;
3215872Sedward 	static struct timeval tv = { 0, 0 };
3316124Sedward 	char noblock;
3413923Sedward 
3515872Sedward loop:
3616124Sedward 	if (wwinterrupt())
3716124Sedward 		return;
3816124Sedward 
3916124Sedward 	imask = 0;
4016124Sedward 	noblock = 0;
4115872Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
4215872Sedward 		if (w->ww_pty < 0)
4315872Sedward 			continue;
4418332Sedward 		if (w->ww_obq < w->ww_obe)
4518332Sedward 			imask |= 1 << w->ww_pty;
4616313Sedward 		if (w->ww_obq > w->ww_obp && !w->ww_stopped)
4716124Sedward 			noblock = 1;
4815872Sedward 	}
4916124Sedward 
5016124Sedward 	if (!noblock) {
5116124Sedward 		if (wwcurwin != 0)
5216124Sedward 			wwcurtowin(wwcurwin);
5315872Sedward 		wwupdate();
5415872Sedward 		wwflush();
5516124Sedward 		if (setjmp(wwjmpbuf))
5616124Sedward 			return;
5716124Sedward 		wwsetjmp = 1;
5816124Sedward 		if (wwinterrupt()) {
5916124Sedward 			wwsetjmp = 0;
6016124Sedward 			return;
6116124Sedward 		}
6215872Sedward 	}
6315872Sedward 	wwnselect++;
6415872Sedward 	n = select(wwdtablesize, &imask, (int *)0, (int *)0,
6516124Sedward 		noblock ? &tv : (struct timeval *)0);
6616124Sedward 	wwsetjmp = 0;
6716124Sedward 
6815872Sedward 	if (n < 0)
6915872Sedward 		wwnselecte++;
7016313Sedward 	else if (n == 0)
7116313Sedward 		wwnselectz++;
7216313Sedward 	else
7316313Sedward 		for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
7416313Sedward 			if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0)
7516313Sedward 				continue;
7616313Sedward 			wwnwread++;
7716313Sedward 			p = w->ww_obq;
7816313Sedward 			if (w->ww_ispty) {
7916313Sedward 				if (p == w->ww_ob) {
8015872Sedward 					w->ww_obp++;
8116313Sedward 					w->ww_obq++;
8216313Sedward 				} else
8315872Sedward 					p--;
8415872Sedward 				c = *p;
8516313Sedward 			}
8616313Sedward 			n = read(w->ww_pty, p, w->ww_obe - p);
8716313Sedward 			if (n < 0) {
8816313Sedward 				wwnwreade++;
8916313Sedward 				(void) close(w->ww_pty);
9016313Sedward 				w->ww_pty = -1;
9116313Sedward 			} else if (n == 0) {
9216313Sedward 				wwnwreadz++;
9318129Sedward 				(void) close(w->ww_pty);
9418129Sedward 				w->ww_pty = -1;
9516313Sedward 			} else if (!w->ww_ispty) {
9616313Sedward 				wwnwreadd++;
9716313Sedward 				wwnwreadc += n;
9816313Sedward 				w->ww_obq += n;
9916313Sedward 			} else if (*p == TIOCPKT_DATA) {
10016313Sedward 				n--;
10116313Sedward 				wwnwreadd++;
10216313Sedward 				wwnwreadc += n;
10316313Sedward 				w->ww_obq += n;
10416313Sedward 			} else {
10516313Sedward 				wwnwreadp++;
10616313Sedward 				if (*p & TIOCPKT_STOP)
10716313Sedward 					w->ww_stopped = 1;
10816313Sedward 				if (*p & TIOCPKT_START)
10916313Sedward 					w->ww_stopped = 0;
11016313Sedward 				if (*p & TIOCPKT_FLUSHWRITE) {
11116313Sedward 					w->ww_stopped = 0;
11216313Sedward 					w->ww_obq = w->ww_obp = w->ww_ob;
11315872Sedward 				}
11416313Sedward 			}
11516313Sedward 			if (w->ww_ispty)
11615872Sedward 				*p = c;
11716313Sedward 		}
11816127Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
11916313Sedward 		if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) {
12016313Sedward 			n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp);
12116313Sedward 			if ((w->ww_obp += n) == w->ww_obq)
12216313Sedward 				w->ww_obq = w->ww_obp = w->ww_ob;
12316127Sedward 			if (wwinterrupt())
12416127Sedward 				return;
12516127Sedward 			break;
12613923Sedward 		}
12716124Sedward 	goto loop;
12813923Sedward }
129