113923Sedward #ifndef lint 2*18744Sedward static char sccsid[] = "@(#)wwiomux.c 3.14 04/24/85"; 313923Sedward #endif 413923Sedward 5*18744Sedward /* 6*18744Sedward * Copyright (c) 1983 Regents of the University of California, 7*18744Sedward * All rights reserved. Redistribution permitted subject to 8*18744Sedward * the terms of the Berkeley Software License Agreement. 9*18744Sedward */ 10*18744Sedward 1113923Sedward #include "ww.h" 1215872Sedward #include <sys/time.h> 1313923Sedward 1415872Sedward /* 1516124Sedward * Multiple window output handler. 1616124Sedward * The idea is to copy window outputs to the terminal, via the 1716124Sedward * display package. We try to give the top most window highest 1816124Sedward * priority. The only return condition is when there is keyboard 1916124Sedward * input, which is serviced asynchronously by wwrint(). 2016124Sedward * When there's nothing to do, we sleep in a select(). 2116124Sedward * This can be done better with interrupt driven io. But that's 2216124Sedward * not supported on ptys, yet. 2316124Sedward * The history of this routine is interesting. 2415872Sedward */ 2515872Sedward wwiomux() 2613923Sedward { 2715872Sedward register struct ww *w; 2815872Sedward int imask; 2916124Sedward register n; 3015872Sedward register char *p; 3115872Sedward char c; 3215872Sedward static struct timeval tv = { 0, 0 }; 3316124Sedward char noblock; 3413923Sedward 3515872Sedward loop: 3616124Sedward if (wwinterrupt()) 3716124Sedward return; 3816124Sedward 3916124Sedward imask = 0; 4016124Sedward noblock = 0; 4115872Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 4215872Sedward if (w->ww_pty < 0) 4315872Sedward continue; 4418332Sedward if (w->ww_obq < w->ww_obe) 4518332Sedward imask |= 1 << w->ww_pty; 4616313Sedward if (w->ww_obq > w->ww_obp && !w->ww_stopped) 4716124Sedward noblock = 1; 4815872Sedward } 4916124Sedward 5016124Sedward if (!noblock) { 5116124Sedward if (wwcurwin != 0) 5216124Sedward wwcurtowin(wwcurwin); 5315872Sedward wwupdate(); 5415872Sedward wwflush(); 5516124Sedward if (setjmp(wwjmpbuf)) 5616124Sedward return; 5716124Sedward wwsetjmp = 1; 5816124Sedward if (wwinterrupt()) { 5916124Sedward wwsetjmp = 0; 6016124Sedward return; 6116124Sedward } 6215872Sedward } 6315872Sedward wwnselect++; 6415872Sedward n = select(wwdtablesize, &imask, (int *)0, (int *)0, 6516124Sedward noblock ? &tv : (struct timeval *)0); 6616124Sedward wwsetjmp = 0; 6716124Sedward 6815872Sedward if (n < 0) 6915872Sedward wwnselecte++; 7016313Sedward else if (n == 0) 7116313Sedward wwnselectz++; 7216313Sedward else 7316313Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 7416313Sedward if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0) 7516313Sedward continue; 7616313Sedward wwnwread++; 7716313Sedward p = w->ww_obq; 7816313Sedward if (w->ww_ispty) { 7916313Sedward if (p == w->ww_ob) { 8015872Sedward w->ww_obp++; 8116313Sedward w->ww_obq++; 8216313Sedward } else 8315872Sedward p--; 8415872Sedward c = *p; 8516313Sedward } 8616313Sedward n = read(w->ww_pty, p, w->ww_obe - p); 8716313Sedward if (n < 0) { 8816313Sedward wwnwreade++; 8916313Sedward (void) close(w->ww_pty); 9016313Sedward w->ww_pty = -1; 9116313Sedward } else if (n == 0) { 9216313Sedward wwnwreadz++; 9318129Sedward (void) close(w->ww_pty); 9418129Sedward w->ww_pty = -1; 9516313Sedward } else if (!w->ww_ispty) { 9616313Sedward wwnwreadd++; 9716313Sedward wwnwreadc += n; 9816313Sedward w->ww_obq += n; 9916313Sedward } else if (*p == TIOCPKT_DATA) { 10016313Sedward n--; 10116313Sedward wwnwreadd++; 10216313Sedward wwnwreadc += n; 10316313Sedward w->ww_obq += n; 10416313Sedward } else { 10516313Sedward wwnwreadp++; 10616313Sedward if (*p & TIOCPKT_STOP) 10716313Sedward w->ww_stopped = 1; 10816313Sedward if (*p & TIOCPKT_START) 10916313Sedward w->ww_stopped = 0; 11016313Sedward if (*p & TIOCPKT_FLUSHWRITE) { 11116313Sedward w->ww_stopped = 0; 11216313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 11315872Sedward } 11416313Sedward } 11516313Sedward if (w->ww_ispty) 11615872Sedward *p = c; 11716313Sedward } 11816127Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 11916313Sedward if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) { 12016313Sedward n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp); 12116313Sedward if ((w->ww_obp += n) == w->ww_obq) 12216313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 12316127Sedward if (wwinterrupt()) 12416127Sedward return; 12516127Sedward break; 12613923Sedward } 12716124Sedward goto loop; 12813923Sedward } 129