113923Sedward #ifndef lint 2*18332Sedward static char sccsid[] = "@(#)wwiomux.c 3.13 03/13/85"; 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; 38*18332Sedward if (w->ww_obq < w->ww_obe) 39*18332Sedward imask |= 1 << w->ww_pty; 4016313Sedward if (w->ww_obq > w->ww_obp && !w->ww_stopped) 4116124Sedward noblock = 1; 4215872Sedward } 4316124Sedward 4416124Sedward if (!noblock) { 4516124Sedward if (wwcurwin != 0) 4616124Sedward wwcurtowin(wwcurwin); 4715872Sedward wwupdate(); 4815872Sedward wwflush(); 4916124Sedward if (setjmp(wwjmpbuf)) 5016124Sedward return; 5116124Sedward wwsetjmp = 1; 5216124Sedward if (wwinterrupt()) { 5316124Sedward wwsetjmp = 0; 5416124Sedward return; 5516124Sedward } 5615872Sedward } 5715872Sedward wwnselect++; 5815872Sedward n = select(wwdtablesize, &imask, (int *)0, (int *)0, 5916124Sedward noblock ? &tv : (struct timeval *)0); 6016124Sedward wwsetjmp = 0; 6116124Sedward 6215872Sedward if (n < 0) 6315872Sedward wwnselecte++; 6416313Sedward else if (n == 0) 6516313Sedward wwnselectz++; 6616313Sedward else 6716313Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 6816313Sedward if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0) 6916313Sedward continue; 7016313Sedward wwnwread++; 7116313Sedward p = w->ww_obq; 7216313Sedward if (w->ww_ispty) { 7316313Sedward if (p == w->ww_ob) { 7415872Sedward w->ww_obp++; 7516313Sedward w->ww_obq++; 7616313Sedward } else 7715872Sedward p--; 7815872Sedward c = *p; 7916313Sedward } 8016313Sedward n = read(w->ww_pty, p, w->ww_obe - p); 8116313Sedward if (n < 0) { 8216313Sedward wwnwreade++; 8316313Sedward (void) close(w->ww_pty); 8416313Sedward w->ww_pty = -1; 8516313Sedward } else if (n == 0) { 8616313Sedward wwnwreadz++; 8718129Sedward (void) close(w->ww_pty); 8818129Sedward w->ww_pty = -1; 8916313Sedward } else if (!w->ww_ispty) { 9016313Sedward wwnwreadd++; 9116313Sedward wwnwreadc += n; 9216313Sedward w->ww_obq += n; 9316313Sedward } else if (*p == TIOCPKT_DATA) { 9416313Sedward n--; 9516313Sedward wwnwreadd++; 9616313Sedward wwnwreadc += n; 9716313Sedward w->ww_obq += n; 9816313Sedward } else { 9916313Sedward wwnwreadp++; 10016313Sedward if (*p & TIOCPKT_STOP) 10116313Sedward w->ww_stopped = 1; 10216313Sedward if (*p & TIOCPKT_START) 10316313Sedward w->ww_stopped = 0; 10416313Sedward if (*p & TIOCPKT_FLUSHWRITE) { 10516313Sedward w->ww_stopped = 0; 10616313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 10715872Sedward } 10816313Sedward } 10916313Sedward if (w->ww_ispty) 11015872Sedward *p = c; 11116313Sedward } 11216127Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 11316313Sedward if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) { 11416313Sedward n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp); 11516313Sedward if ((w->ww_obp += n) == w->ww_obq) 11616313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 11716127Sedward if (wwinterrupt()) 11816127Sedward return; 11916127Sedward break; 12013923Sedward } 12116124Sedward goto loop; 12213923Sedward } 123