113923Sedward #ifndef lint 2*16124Sedward static char *sccsid = "@(#)wwiomux.c 3.8 84/03/03"; 313923Sedward #endif 413923Sedward 513923Sedward #include "ww.h" 615872Sedward #include <sys/time.h> 713923Sedward 815872Sedward /* 9*16124Sedward * Multiple window output handler. 10*16124Sedward * The idea is to copy window outputs to the terminal, via the 11*16124Sedward * display package. We try to give the top most window highest 12*16124Sedward * priority. The only return condition is when there is keyboard 13*16124Sedward * input, which is serviced asynchronously by wwrint(). 14*16124Sedward * When there's nothing to do, we sleep in a select(). 15*16124Sedward * This can be done better with interrupt driven io. But that's 16*16124Sedward * not supported on ptys, yet. 17*16124Sedward * The history of this routine is interesting. 1815872Sedward */ 1915872Sedward wwiomux() 2013923Sedward { 2115872Sedward register struct ww *w; 2215872Sedward int imask; 23*16124Sedward register n; 2415872Sedward register char *p; 2515872Sedward char c; 2615872Sedward static struct timeval tv = { 0, 0 }; 27*16124Sedward char noblock; 2813923Sedward 2915872Sedward loop: 30*16124Sedward if (wwinterrupt()) 31*16124Sedward return; 32*16124Sedward 33*16124Sedward imask = 0; 34*16124Sedward noblock = 0; 3515872Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 3615872Sedward if (w->ww_pty < 0) 3715872Sedward continue; 38*16124Sedward imask |= 1 << w->ww_pty; 39*16124Sedward if (w->ww_obc > 0 && !w->ww_stopped) 40*16124Sedward noblock = 1; 4115872Sedward } 42*16124Sedward 43*16124Sedward if (!noblock) { 44*16124Sedward if (wwcurwin != 0) 45*16124Sedward wwcurtowin(wwcurwin); 4615872Sedward wwupdate(); 4715872Sedward wwflush(); 48*16124Sedward if (setjmp(wwjmpbuf)) 49*16124Sedward return; 50*16124Sedward wwsetjmp = 1; 51*16124Sedward if (wwinterrupt()) { 52*16124Sedward wwsetjmp = 0; 53*16124Sedward return; 54*16124Sedward } 5515872Sedward } 5615872Sedward wwnselect++; 5715872Sedward n = select(wwdtablesize, &imask, (int *)0, (int *)0, 58*16124Sedward noblock ? &tv : (struct timeval *)0); 59*16124Sedward wwsetjmp = 0; 60*16124Sedward 6115872Sedward if (n < 0) 6215872Sedward wwnselecte++; 63*16124Sedward else if (n == 0) 64*16124Sedward wwnselectz++; 65*16124Sedward else { 6615872Sedward char first_time = 1; 6715872Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 6815872Sedward if (w->ww_pty < 0) 6915872Sedward continue; 7015872Sedward if (imask & 1 << w->ww_pty) { 7115872Sedward wwnwread++; 7215872Sedward p = w->ww_obp + w->ww_obc; 7315872Sedward if (p == w->ww_ob) 7415872Sedward w->ww_obp++; 7515872Sedward else 7615872Sedward p--; 7715872Sedward c = *p; 7815872Sedward n = read(w->ww_pty, p, w->ww_obe - p); 7915872Sedward if (n < 0) { 8015872Sedward wwnwreade++; 8115872Sedward (void) close(w->ww_pty); 8215872Sedward w->ww_pty = -1; 8315872Sedward continue; 8415872Sedward } else if (n == 0) { 8515872Sedward wwnwreadz++; 8615872Sedward } else if (*p == TIOCPKT_DATA) { 87*16124Sedward n--; 8815872Sedward wwnwreadd++; 89*16124Sedward wwnwreadc += n; 90*16124Sedward w->ww_obc += n; 9115872Sedward } else { 9215872Sedward wwnwreadp++; 9315872Sedward if (*p & TIOCPKT_STOP) 9415872Sedward w->ww_stopped = 1; 9515872Sedward if (*p & TIOCPKT_START) 9615872Sedward w->ww_stopped = 0; 9715872Sedward if (*p & TIOCPKT_FLUSHWRITE) { 98*16124Sedward w->ww_stopped = 0; 9915872Sedward w->ww_obp = w->ww_ob; 10015872Sedward w->ww_obc = 0; 10115872Sedward } 10215872Sedward } 10315872Sedward *p = c; 10415872Sedward } 10515872Sedward if (first_time && w->ww_obc != 0 && !w->ww_stopped) { 10615872Sedward first_time = 0; 107*16124Sedward n = wwwrite(w, w->ww_obp, w->ww_obc); 10815872Sedward if (w->ww_obc -= n) 10915872Sedward w->ww_obp += n; 11015872Sedward else 11115872Sedward w->ww_obp = w->ww_ob; 112*16124Sedward if (wwinterrupt()) 113*16124Sedward return; 11415872Sedward } 11513923Sedward } 11615872Sedward } 117*16124Sedward goto loop; 11813923Sedward } 119