113923Sedward #ifndef lint 2*31443Sedward static char sccsid[] = "@(#)wwiomux.c 3.16 06/08/87"; 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> 1324958Sedward #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 20*31443Sedward * input or when a child process dies which are serviced by signal 21*31443Sedward * catchers (wwrint() and wwchild()). 2216124Sedward * When there's nothing to do, we sleep in a select(). 2316124Sedward * This can be done better with interrupt driven io. But that's 2416124Sedward * not supported on ptys, yet. 2516124Sedward * The history of this routine is interesting. 2615872Sedward */ 2715872Sedward wwiomux() 2813923Sedward { 2915872Sedward register struct ww *w; 3024958Sedward fd_set imask; 3116124Sedward register n; 3215872Sedward register char *p; 3315872Sedward char c; 3415872Sedward static struct timeval tv = { 0, 0 }; 3516124Sedward char noblock; 3613923Sedward 37*31443Sedward for (;;) { 3816124Sedward if (wwinterrupt()) { 39*31443Sedward wwclrintr(); 4016124Sedward return; 4116124Sedward } 4216124Sedward 43*31443Sedward FD_ZERO(&imask); 44*31443Sedward noblock = 0; 4516313Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 46*31443Sedward if (w->ww_pty < 0) 4716313Sedward continue; 48*31443Sedward if (w->ww_obq < w->ww_obe) 49*31443Sedward FD_SET(w->ww_pty, &imask); 50*31443Sedward if (w->ww_obq > w->ww_obp && !w->ww_stopped) 51*31443Sedward noblock = 1; 52*31443Sedward } 53*31443Sedward 54*31443Sedward if (!noblock) { 55*31443Sedward if (wwcurwin != 0) 56*31443Sedward wwcurtowin(wwcurwin); 57*31443Sedward wwupdate(); 58*31443Sedward wwflush(); 59*31443Sedward setjmp(wwjmpbuf); 60*31443Sedward wwsetjmp = 1; 61*31443Sedward if (wwinterrupt()) { 62*31443Sedward wwsetjmp = 0; 63*31443Sedward wwclrintr(); 64*31443Sedward return; 6516313Sedward } 66*31443Sedward } 67*31443Sedward wwnselect++; 68*31443Sedward n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0, 69*31443Sedward noblock ? &tv : (struct timeval *)0); 70*31443Sedward wwsetjmp = 0; 71*31443Sedward 72*31443Sedward if (n < 0) 73*31443Sedward wwnselecte++; 74*31443Sedward else if (n == 0) 75*31443Sedward wwnselectz++; 76*31443Sedward else 77*31443Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 78*31443Sedward if (w->ww_pty < 0 || 79*31443Sedward !FD_ISSET(w->ww_pty, &imask)) 80*31443Sedward continue; 81*31443Sedward wwnwread++; 82*31443Sedward p = w->ww_obq; 83*31443Sedward if (w->ww_ispty) { 84*31443Sedward if (p == w->ww_ob) { 85*31443Sedward w->ww_obp++; 86*31443Sedward w->ww_obq++; 87*31443Sedward } else 88*31443Sedward p--; 89*31443Sedward c = *p; 90*31443Sedward } 91*31443Sedward n = read(w->ww_pty, p, w->ww_obe - p); 92*31443Sedward if (n < 0) { 93*31443Sedward wwnwreade++; 94*31443Sedward (void) close(w->ww_pty); 95*31443Sedward w->ww_pty = -1; 96*31443Sedward } else if (n == 0) { 97*31443Sedward wwnwreadz++; 98*31443Sedward (void) close(w->ww_pty); 99*31443Sedward w->ww_pty = -1; 100*31443Sedward } else if (!w->ww_ispty) { 101*31443Sedward wwnwreadd++; 102*31443Sedward wwnwreadc += n; 103*31443Sedward w->ww_obq += n; 104*31443Sedward } else if (*p == TIOCPKT_DATA) { 105*31443Sedward n--; 106*31443Sedward wwnwreadd++; 107*31443Sedward wwnwreadc += n; 108*31443Sedward w->ww_obq += n; 109*31443Sedward } else { 110*31443Sedward wwnwreadp++; 111*31443Sedward if (*p & TIOCPKT_STOP) 112*31443Sedward w->ww_stopped = 1; 113*31443Sedward if (*p & TIOCPKT_START) 114*31443Sedward w->ww_stopped = 0; 115*31443Sedward if (*p & TIOCPKT_FLUSHWRITE) { 116*31443Sedward w->ww_stopped = 0; 117*31443Sedward w->ww_obq = w->ww_obp = 118*31443Sedward w->ww_ob; 119*31443Sedward } 120*31443Sedward } 121*31443Sedward if (w->ww_ispty) 122*31443Sedward *p = c; 123*31443Sedward } 124*31443Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 125*31443Sedward if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && 126*31443Sedward !w->ww_stopped) { 127*31443Sedward n = wwwrite(w, w->ww_obp, 128*31443Sedward w->ww_obq - w->ww_obp); 129*31443Sedward if ((w->ww_obp += n) == w->ww_obq) 13016313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 131*31443Sedward if (wwinterrupt()) { 132*31443Sedward wwclrintr(); 133*31443Sedward return; 13415872Sedward } 135*31443Sedward break; 13616313Sedward } 137*31443Sedward } 13813923Sedward } 139