xref: /csrg-svn/usr.bin/window/wwiomux.c (revision 31443)
113923Sedward #ifndef lint
2*31443Sedward static char sccsid[] = "@(#)wwiomux.c	3.16 06/08/87";
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>
1324958Sedward #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
20*31443Sedward  * input or when a child process dies which are serviced by signal
21*31443Sedward  * catchers (wwrint() and wwchild()).
2216124Sedward  * When there's nothing to do, we sleep in a select().
2316124Sedward  * This can be done better with interrupt driven io.  But that's
2416124Sedward  * not supported on ptys, yet.
2516124Sedward  * The history of this routine is interesting.
2615872Sedward  */
2715872Sedward wwiomux()
2813923Sedward {
2915872Sedward 	register struct ww *w;
3024958Sedward 	fd_set imask;
3116124Sedward 	register n;
3215872Sedward 	register char *p;
3315872Sedward 	char c;
3415872Sedward 	static struct timeval tv = { 0, 0 };
3516124Sedward 	char noblock;
3613923Sedward 
37*31443Sedward 	for (;;) {
3816124Sedward 		if (wwinterrupt()) {
39*31443Sedward 			wwclrintr();
4016124Sedward 			return;
4116124Sedward 		}
4216124Sedward 
43*31443Sedward 		FD_ZERO(&imask);
44*31443Sedward 		noblock = 0;
4516313Sedward 		for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
46*31443Sedward 			if (w->ww_pty < 0)
4716313Sedward 				continue;
48*31443Sedward 			if (w->ww_obq < w->ww_obe)
49*31443Sedward 				FD_SET(w->ww_pty, &imask);
50*31443Sedward 			if (w->ww_obq > w->ww_obp && !w->ww_stopped)
51*31443Sedward 				noblock = 1;
52*31443Sedward 		}
53*31443Sedward 
54*31443Sedward 		if (!noblock) {
55*31443Sedward 			if (wwcurwin != 0)
56*31443Sedward 				wwcurtowin(wwcurwin);
57*31443Sedward 			wwupdate();
58*31443Sedward 			wwflush();
59*31443Sedward 			setjmp(wwjmpbuf);
60*31443Sedward 			wwsetjmp = 1;
61*31443Sedward 			if (wwinterrupt()) {
62*31443Sedward 				wwsetjmp = 0;
63*31443Sedward 				wwclrintr();
64*31443Sedward 				return;
6516313Sedward 			}
66*31443Sedward 		}
67*31443Sedward 		wwnselect++;
68*31443Sedward 		n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0,
69*31443Sedward 			noblock ? &tv : (struct timeval *)0);
70*31443Sedward 		wwsetjmp = 0;
71*31443Sedward 
72*31443Sedward 		if (n < 0)
73*31443Sedward 			wwnselecte++;
74*31443Sedward 		else if (n == 0)
75*31443Sedward 			wwnselectz++;
76*31443Sedward 		else
77*31443Sedward 			for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
78*31443Sedward 				if (w->ww_pty < 0 ||
79*31443Sedward 				    !FD_ISSET(w->ww_pty, &imask))
80*31443Sedward 					continue;
81*31443Sedward 				wwnwread++;
82*31443Sedward 				p = w->ww_obq;
83*31443Sedward 				if (w->ww_ispty) {
84*31443Sedward 					if (p == w->ww_ob) {
85*31443Sedward 						w->ww_obp++;
86*31443Sedward 						w->ww_obq++;
87*31443Sedward 					} else
88*31443Sedward 						p--;
89*31443Sedward 					c = *p;
90*31443Sedward 				}
91*31443Sedward 				n = read(w->ww_pty, p, w->ww_obe - p);
92*31443Sedward 				if (n < 0) {
93*31443Sedward 					wwnwreade++;
94*31443Sedward 					(void) close(w->ww_pty);
95*31443Sedward 					w->ww_pty = -1;
96*31443Sedward 				} else if (n == 0) {
97*31443Sedward 					wwnwreadz++;
98*31443Sedward 					(void) close(w->ww_pty);
99*31443Sedward 					w->ww_pty = -1;
100*31443Sedward 				} else if (!w->ww_ispty) {
101*31443Sedward 					wwnwreadd++;
102*31443Sedward 					wwnwreadc += n;
103*31443Sedward 					w->ww_obq += n;
104*31443Sedward 				} else if (*p == TIOCPKT_DATA) {
105*31443Sedward 					n--;
106*31443Sedward 					wwnwreadd++;
107*31443Sedward 					wwnwreadc += n;
108*31443Sedward 					w->ww_obq += n;
109*31443Sedward 				} else {
110*31443Sedward 					wwnwreadp++;
111*31443Sedward 					if (*p & TIOCPKT_STOP)
112*31443Sedward 						w->ww_stopped = 1;
113*31443Sedward 					if (*p & TIOCPKT_START)
114*31443Sedward 						w->ww_stopped = 0;
115*31443Sedward 					if (*p & TIOCPKT_FLUSHWRITE) {
116*31443Sedward 						w->ww_stopped = 0;
117*31443Sedward 						w->ww_obq = w->ww_obp =
118*31443Sedward 							w->ww_ob;
119*31443Sedward 					}
120*31443Sedward 				}
121*31443Sedward 				if (w->ww_ispty)
122*31443Sedward 					*p = c;
123*31443Sedward 			}
124*31443Sedward 		for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
125*31443Sedward 			if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp &&
126*31443Sedward 			    !w->ww_stopped) {
127*31443Sedward 				n = wwwrite(w, w->ww_obp,
128*31443Sedward 					w->ww_obq - w->ww_obp);
129*31443Sedward 				if ((w->ww_obp += n) == w->ww_obq)
13016313Sedward 					w->ww_obq = w->ww_obp = w->ww_ob;
131*31443Sedward 				if (wwinterrupt()) {
132*31443Sedward 					wwclrintr();
133*31443Sedward 					return;
13415872Sedward 				}
135*31443Sedward 				break;
13616313Sedward 			}
137*31443Sedward 	}
13813923Sedward }
139