113923Sedward #ifndef lint 2*16313Sedward static char *sccsid = "@(#)wwiomux.c 3.10 84/04/08"; 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; 3816124Sedward imask |= 1 << w->ww_pty; 39*16313Sedward if (w->ww_obq > w->ww_obp && !w->ww_stopped) 4016124Sedward noblock = 1; 4115872Sedward } 4216124Sedward 4316124Sedward if (!noblock) { 4416124Sedward if (wwcurwin != 0) 4516124Sedward wwcurtowin(wwcurwin); 4615872Sedward wwupdate(); 4715872Sedward wwflush(); 4816124Sedward if (setjmp(wwjmpbuf)) 4916124Sedward return; 5016124Sedward wwsetjmp = 1; 5116124Sedward if (wwinterrupt()) { 5216124Sedward wwsetjmp = 0; 5316124Sedward return; 5416124Sedward } 5515872Sedward } 5615872Sedward wwnselect++; 5715872Sedward n = select(wwdtablesize, &imask, (int *)0, (int *)0, 5816124Sedward noblock ? &tv : (struct timeval *)0); 5916124Sedward wwsetjmp = 0; 6016124Sedward 6115872Sedward if (n < 0) 6215872Sedward wwnselecte++; 63*16313Sedward else if (n == 0) 64*16313Sedward wwnselectz++; 65*16313Sedward else 66*16313Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 67*16313Sedward if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0) 68*16313Sedward continue; 69*16313Sedward wwnwread++; 70*16313Sedward p = w->ww_obq; 71*16313Sedward if (w->ww_ispty) { 72*16313Sedward if (p == w->ww_ob) { 7315872Sedward w->ww_obp++; 74*16313Sedward w->ww_obq++; 75*16313Sedward } else 7615872Sedward p--; 7715872Sedward c = *p; 78*16313Sedward } 79*16313Sedward n = read(w->ww_pty, p, w->ww_obe - p); 80*16313Sedward if (n < 0) { 81*16313Sedward wwnwreade++; 82*16313Sedward (void) close(w->ww_pty); 83*16313Sedward w->ww_pty = -1; 84*16313Sedward continue; 85*16313Sedward } else if (n == 0) { 86*16313Sedward wwnwreadz++; 87*16313Sedward } else if (!w->ww_ispty) { 88*16313Sedward wwnwreadd++; 89*16313Sedward wwnwreadc += n; 90*16313Sedward w->ww_obq += n; 91*16313Sedward } else if (*p == TIOCPKT_DATA) { 92*16313Sedward n--; 93*16313Sedward wwnwreadd++; 94*16313Sedward wwnwreadc += n; 95*16313Sedward w->ww_obq += n; 96*16313Sedward } else { 97*16313Sedward wwnwreadp++; 98*16313Sedward if (*p & TIOCPKT_STOP) 99*16313Sedward w->ww_stopped = 1; 100*16313Sedward if (*p & TIOCPKT_START) 101*16313Sedward w->ww_stopped = 0; 102*16313Sedward if (*p & TIOCPKT_FLUSHWRITE) { 103*16313Sedward w->ww_stopped = 0; 104*16313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 10515872Sedward } 106*16313Sedward } 107*16313Sedward if (w->ww_ispty) 10815872Sedward *p = c; 109*16313Sedward } 11016127Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 111*16313Sedward if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) { 112*16313Sedward n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp); 113*16313Sedward if ((w->ww_obp += n) == w->ww_obq) 114*16313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 11516127Sedward if (wwinterrupt()) 11616127Sedward return; 11716127Sedward break; 11813923Sedward } 11916124Sedward goto loop; 12013923Sedward } 121