113923Sedward #ifndef lint 2*24958Sedward static char sccsid[] = "@(#)wwiomux.c 3.15 09/19/85"; 313923Sedward #endif 413923Sedward 518744Sedward /* 618744Sedward * Copyright (c) 1983 Regents of the University of California, 718744Sedward * All rights reserved. Redistribution permitted subject to 818744Sedward * the terms of the Berkeley Software License Agreement. 918744Sedward */ 1018744Sedward 1113923Sedward #include "ww.h" 1215872Sedward #include <sys/time.h> 13*24958Sedward #include <sys/types.h> 1413923Sedward 1515872Sedward /* 1616124Sedward * Multiple window output handler. 1716124Sedward * The idea is to copy window outputs to the terminal, via the 1816124Sedward * display package. We try to give the top most window highest 1916124Sedward * priority. The only return condition is when there is keyboard 2016124Sedward * input, which is serviced asynchronously by wwrint(). 2116124Sedward * When there's nothing to do, we sleep in a select(). 2216124Sedward * This can be done better with interrupt driven io. But that's 2316124Sedward * not supported on ptys, yet. 2416124Sedward * The history of this routine is interesting. 2515872Sedward */ 2615872Sedward wwiomux() 2713923Sedward { 2815872Sedward register struct ww *w; 29*24958Sedward fd_set imask; 3016124Sedward register n; 3115872Sedward register char *p; 3215872Sedward char c; 3315872Sedward static struct timeval tv = { 0, 0 }; 3416124Sedward char noblock; 3513923Sedward 3615872Sedward loop: 3716124Sedward if (wwinterrupt()) 3816124Sedward return; 3916124Sedward 40*24958Sedward FD_ZERO(&imask); 4116124Sedward noblock = 0; 4215872Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 4315872Sedward if (w->ww_pty < 0) 4415872Sedward continue; 4518332Sedward if (w->ww_obq < w->ww_obe) 46*24958Sedward FD_SET(w->ww_pty, &imask); 4716313Sedward if (w->ww_obq > w->ww_obp && !w->ww_stopped) 4816124Sedward noblock = 1; 4915872Sedward } 5016124Sedward 5116124Sedward if (!noblock) { 5216124Sedward if (wwcurwin != 0) 5316124Sedward wwcurtowin(wwcurwin); 5415872Sedward wwupdate(); 5515872Sedward wwflush(); 5616124Sedward if (setjmp(wwjmpbuf)) 5716124Sedward return; 5816124Sedward wwsetjmp = 1; 5916124Sedward if (wwinterrupt()) { 6016124Sedward wwsetjmp = 0; 6116124Sedward return; 6216124Sedward } 6315872Sedward } 6415872Sedward wwnselect++; 65*24958Sedward n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0, 6616124Sedward noblock ? &tv : (struct timeval *)0); 6716124Sedward wwsetjmp = 0; 6816124Sedward 6915872Sedward if (n < 0) 7015872Sedward wwnselecte++; 7116313Sedward else if (n == 0) 7216313Sedward wwnselectz++; 7316313Sedward else 7416313Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 75*24958Sedward if (w->ww_pty < 0 || !FD_ISSET(w->ww_pty, &imask)) 7616313Sedward continue; 7716313Sedward wwnwread++; 7816313Sedward p = w->ww_obq; 7916313Sedward if (w->ww_ispty) { 8016313Sedward if (p == w->ww_ob) { 8115872Sedward w->ww_obp++; 8216313Sedward w->ww_obq++; 8316313Sedward } else 8415872Sedward p--; 8515872Sedward c = *p; 8616313Sedward } 8716313Sedward n = read(w->ww_pty, p, w->ww_obe - p); 8816313Sedward if (n < 0) { 8916313Sedward wwnwreade++; 9016313Sedward (void) close(w->ww_pty); 9116313Sedward w->ww_pty = -1; 9216313Sedward } else if (n == 0) { 9316313Sedward wwnwreadz++; 9418129Sedward (void) close(w->ww_pty); 9518129Sedward w->ww_pty = -1; 9616313Sedward } else if (!w->ww_ispty) { 9716313Sedward wwnwreadd++; 9816313Sedward wwnwreadc += n; 9916313Sedward w->ww_obq += n; 10016313Sedward } else if (*p == TIOCPKT_DATA) { 10116313Sedward n--; 10216313Sedward wwnwreadd++; 10316313Sedward wwnwreadc += n; 10416313Sedward w->ww_obq += n; 10516313Sedward } else { 10616313Sedward wwnwreadp++; 10716313Sedward if (*p & TIOCPKT_STOP) 10816313Sedward w->ww_stopped = 1; 10916313Sedward if (*p & TIOCPKT_START) 11016313Sedward w->ww_stopped = 0; 11116313Sedward if (*p & TIOCPKT_FLUSHWRITE) { 11216313Sedward w->ww_stopped = 0; 11316313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 11415872Sedward } 11516313Sedward } 11616313Sedward if (w->ww_ispty) 11715872Sedward *p = c; 11816313Sedward } 11916127Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 12016313Sedward if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) { 12116313Sedward n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp); 12216313Sedward if ((w->ww_obp += n) == w->ww_obq) 12316313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 12416127Sedward if (wwinterrupt()) 12516127Sedward return; 12616127Sedward break; 12713923Sedward } 12816124Sedward goto loop; 12913923Sedward } 130