xref: /csrg-svn/usr.bin/window/wwiomux.c (revision 24958)
113923Sedward #ifndef lint
2*24958Sedward static char sccsid[] = "@(#)wwiomux.c	3.15 09/19/85";
313923Sedward #endif
413923Sedward 
518744Sedward /*
618744Sedward  * Copyright (c) 1983 Regents of the University of California,
718744Sedward  * All rights reserved.  Redistribution permitted subject to
818744Sedward  * the terms of the Berkeley Software License Agreement.
918744Sedward  */
1018744Sedward 
1113923Sedward #include "ww.h"
1215872Sedward #include <sys/time.h>
13*24958Sedward #include <sys/types.h>
1413923Sedward 
1515872Sedward /*
1616124Sedward  * Multiple window output handler.
1716124Sedward  * The idea is to copy window outputs to the terminal, via the
1816124Sedward  * display package.  We try to give the top most window highest
1916124Sedward  * priority.  The only return condition is when there is keyboard
2016124Sedward  * input, which is serviced asynchronously by wwrint().
2116124Sedward  * When there's nothing to do, we sleep in a select().
2216124Sedward  * This can be done better with interrupt driven io.  But that's
2316124Sedward  * not supported on ptys, yet.
2416124Sedward  * The history of this routine is interesting.
2515872Sedward  */
2615872Sedward wwiomux()
2713923Sedward {
2815872Sedward 	register struct ww *w;
29*24958Sedward 	fd_set imask;
3016124Sedward 	register n;
3115872Sedward 	register char *p;
3215872Sedward 	char c;
3315872Sedward 	static struct timeval tv = { 0, 0 };
3416124Sedward 	char noblock;
3513923Sedward 
3615872Sedward loop:
3716124Sedward 	if (wwinterrupt())
3816124Sedward 		return;
3916124Sedward 
40*24958Sedward 	FD_ZERO(&imask);
4116124Sedward 	noblock = 0;
4215872Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
4315872Sedward 		if (w->ww_pty < 0)
4415872Sedward 			continue;
4518332Sedward 		if (w->ww_obq < w->ww_obe)
46*24958Sedward 			FD_SET(w->ww_pty, &imask);
4716313Sedward 		if (w->ww_obq > w->ww_obp && !w->ww_stopped)
4816124Sedward 			noblock = 1;
4915872Sedward 	}
5016124Sedward 
5116124Sedward 	if (!noblock) {
5216124Sedward 		if (wwcurwin != 0)
5316124Sedward 			wwcurtowin(wwcurwin);
5415872Sedward 		wwupdate();
5515872Sedward 		wwflush();
5616124Sedward 		if (setjmp(wwjmpbuf))
5716124Sedward 			return;
5816124Sedward 		wwsetjmp = 1;
5916124Sedward 		if (wwinterrupt()) {
6016124Sedward 			wwsetjmp = 0;
6116124Sedward 			return;
6216124Sedward 		}
6315872Sedward 	}
6415872Sedward 	wwnselect++;
65*24958Sedward 	n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0,
6616124Sedward 		noblock ? &tv : (struct timeval *)0);
6716124Sedward 	wwsetjmp = 0;
6816124Sedward 
6915872Sedward 	if (n < 0)
7015872Sedward 		wwnselecte++;
7116313Sedward 	else if (n == 0)
7216313Sedward 		wwnselectz++;
7316313Sedward 	else
7416313Sedward 		for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
75*24958Sedward 			if (w->ww_pty < 0 || !FD_ISSET(w->ww_pty, &imask))
7616313Sedward 				continue;
7716313Sedward 			wwnwread++;
7816313Sedward 			p = w->ww_obq;
7916313Sedward 			if (w->ww_ispty) {
8016313Sedward 				if (p == w->ww_ob) {
8115872Sedward 					w->ww_obp++;
8216313Sedward 					w->ww_obq++;
8316313Sedward 				} else
8415872Sedward 					p--;
8515872Sedward 				c = *p;
8616313Sedward 			}
8716313Sedward 			n = read(w->ww_pty, p, w->ww_obe - p);
8816313Sedward 			if (n < 0) {
8916313Sedward 				wwnwreade++;
9016313Sedward 				(void) close(w->ww_pty);
9116313Sedward 				w->ww_pty = -1;
9216313Sedward 			} else if (n == 0) {
9316313Sedward 				wwnwreadz++;
9418129Sedward 				(void) close(w->ww_pty);
9518129Sedward 				w->ww_pty = -1;
9616313Sedward 			} else if (!w->ww_ispty) {
9716313Sedward 				wwnwreadd++;
9816313Sedward 				wwnwreadc += n;
9916313Sedward 				w->ww_obq += n;
10016313Sedward 			} else if (*p == TIOCPKT_DATA) {
10116313Sedward 				n--;
10216313Sedward 				wwnwreadd++;
10316313Sedward 				wwnwreadc += n;
10416313Sedward 				w->ww_obq += n;
10516313Sedward 			} else {
10616313Sedward 				wwnwreadp++;
10716313Sedward 				if (*p & TIOCPKT_STOP)
10816313Sedward 					w->ww_stopped = 1;
10916313Sedward 				if (*p & TIOCPKT_START)
11016313Sedward 					w->ww_stopped = 0;
11116313Sedward 				if (*p & TIOCPKT_FLUSHWRITE) {
11216313Sedward 					w->ww_stopped = 0;
11316313Sedward 					w->ww_obq = w->ww_obp = w->ww_ob;
11415872Sedward 				}
11516313Sedward 			}
11616313Sedward 			if (w->ww_ispty)
11715872Sedward 				*p = c;
11816313Sedward 		}
11916127Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
12016313Sedward 		if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) {
12116313Sedward 			n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp);
12216313Sedward 			if ((w->ww_obp += n) == w->ww_obq)
12316313Sedward 				w->ww_obq = w->ww_obp = w->ww_ob;
12416127Sedward 			if (wwinterrupt())
12516127Sedward 				return;
12616127Sedward 			break;
12713923Sedward 		}
12816124Sedward 	goto loop;
12913923Sedward }
130