1 #ifndef lint 2 static char sccsid[] = "@(#)wwiomux.c 3.11 05/23/84"; 3 #endif 4 5 #include "ww.h" 6 #include <sys/time.h> 7 8 /* 9 * Multiple window output handler. 10 * The idea is to copy window outputs to the terminal, via the 11 * display package. We try to give the top most window highest 12 * priority. The only return condition is when there is keyboard 13 * input, which is serviced asynchronously by wwrint(). 14 * When there's nothing to do, we sleep in a select(). 15 * This can be done better with interrupt driven io. But that's 16 * not supported on ptys, yet. 17 * The history of this routine is interesting. 18 */ 19 wwiomux() 20 { 21 register struct ww *w; 22 int imask; 23 register n; 24 register char *p; 25 char c; 26 static struct timeval tv = { 0, 0 }; 27 char noblock; 28 29 loop: 30 if (wwinterrupt()) 31 return; 32 33 imask = 0; 34 noblock = 0; 35 for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 36 if (w->ww_pty < 0) 37 continue; 38 imask |= 1 << w->ww_pty; 39 if (w->ww_obq > w->ww_obp && !w->ww_stopped) 40 noblock = 1; 41 } 42 43 if (!noblock) { 44 if (wwcurwin != 0) 45 wwcurtowin(wwcurwin); 46 wwupdate(); 47 wwflush(); 48 if (setjmp(wwjmpbuf)) 49 return; 50 wwsetjmp = 1; 51 if (wwinterrupt()) { 52 wwsetjmp = 0; 53 return; 54 } 55 } 56 wwnselect++; 57 n = select(wwdtablesize, &imask, (int *)0, (int *)0, 58 noblock ? &tv : (struct timeval *)0); 59 wwsetjmp = 0; 60 61 if (n < 0) 62 wwnselecte++; 63 else if (n == 0) 64 wwnselectz++; 65 else 66 for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 67 if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0) 68 continue; 69 wwnwread++; 70 p = w->ww_obq; 71 if (w->ww_ispty) { 72 if (p == w->ww_ob) { 73 w->ww_obp++; 74 w->ww_obq++; 75 } else 76 p--; 77 c = *p; 78 } 79 n = read(w->ww_pty, p, w->ww_obe - p); 80 if (n < 0) { 81 wwnwreade++; 82 (void) close(w->ww_pty); 83 w->ww_pty = -1; 84 continue; 85 } else if (n == 0) { 86 wwnwreadz++; 87 } else if (!w->ww_ispty) { 88 wwnwreadd++; 89 wwnwreadc += n; 90 w->ww_obq += n; 91 } else if (*p == TIOCPKT_DATA) { 92 n--; 93 wwnwreadd++; 94 wwnwreadc += n; 95 w->ww_obq += n; 96 } else { 97 wwnwreadp++; 98 if (*p & TIOCPKT_STOP) 99 w->ww_stopped = 1; 100 if (*p & TIOCPKT_START) 101 w->ww_stopped = 0; 102 if (*p & TIOCPKT_FLUSHWRITE) { 103 w->ww_stopped = 0; 104 w->ww_obq = w->ww_obp = w->ww_ob; 105 } 106 } 107 if (w->ww_ispty) 108 *p = c; 109 } 110 for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 111 if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) { 112 n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp); 113 if ((w->ww_obp += n) == w->ww_obq) 114 w->ww_obq = w->ww_obp = w->ww_ob; 115 if (wwinterrupt()) 116 return; 117 break; 118 } 119 goto loop; 120 } 121