118744Sedward /* 2*33514Sbostic * Copyright (c) 1983 Regents of the University of California. 3*33514Sbostic * All rights reserved. 4*33514Sbostic * 5*33514Sbostic * Redistribution and use in source and binary forms are permitted 6*33514Sbostic * provided that this notice is preserved and that due credit is given 7*33514Sbostic * to the University of California at Berkeley. The name of the University 8*33514Sbostic * may not be used to endorse or promote products derived from this 9*33514Sbostic * software without specific prior written permission. This software 10*33514Sbostic * is provided ``as is'' without express or implied warranty. 1118744Sedward */ 1218744Sedward 13*33514Sbostic #ifndef lint 14*33514Sbostic static char sccsid[] = "@(#)wwiomux.c 3.17 (Berkeley) 02/21/88"; 15*33514Sbostic #endif /* not lint */ 16*33514Sbostic 1713923Sedward #include "ww.h" 1815872Sedward #include <sys/time.h> 1924958Sedward #include <sys/types.h> 2013923Sedward 2115872Sedward /* 2216124Sedward * Multiple window output handler. 2316124Sedward * The idea is to copy window outputs to the terminal, via the 2416124Sedward * display package. We try to give the top most window highest 2516124Sedward * priority. The only return condition is when there is keyboard 2631443Sedward * input or when a child process dies which are serviced by signal 2731443Sedward * catchers (wwrint() and wwchild()). 2816124Sedward * When there's nothing to do, we sleep in a select(). 2916124Sedward * This can be done better with interrupt driven io. But that's 3016124Sedward * not supported on ptys, yet. 3116124Sedward * The history of this routine is interesting. 3215872Sedward */ 3315872Sedward wwiomux() 3413923Sedward { 3515872Sedward register struct ww *w; 3624958Sedward fd_set imask; 3716124Sedward register n; 3815872Sedward register char *p; 3915872Sedward char c; 4015872Sedward static struct timeval tv = { 0, 0 }; 4116124Sedward char noblock; 4213923Sedward 4331443Sedward for (;;) { 4416124Sedward if (wwinterrupt()) { 4531443Sedward wwclrintr(); 4616124Sedward return; 4716124Sedward } 4816124Sedward 4931443Sedward FD_ZERO(&imask); 5031443Sedward noblock = 0; 5116313Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 5231443Sedward if (w->ww_pty < 0) 5316313Sedward continue; 5431443Sedward if (w->ww_obq < w->ww_obe) 5531443Sedward FD_SET(w->ww_pty, &imask); 5631443Sedward if (w->ww_obq > w->ww_obp && !w->ww_stopped) 5731443Sedward noblock = 1; 5831443Sedward } 5931443Sedward 6031443Sedward if (!noblock) { 6131443Sedward if (wwcurwin != 0) 6231443Sedward wwcurtowin(wwcurwin); 6331443Sedward wwupdate(); 6431443Sedward wwflush(); 6531443Sedward setjmp(wwjmpbuf); 6631443Sedward wwsetjmp = 1; 6731443Sedward if (wwinterrupt()) { 6831443Sedward wwsetjmp = 0; 6931443Sedward wwclrintr(); 7031443Sedward return; 7116313Sedward } 7231443Sedward } 7331443Sedward wwnselect++; 7431443Sedward n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0, 7531443Sedward noblock ? &tv : (struct timeval *)0); 7631443Sedward wwsetjmp = 0; 7731443Sedward 7831443Sedward if (n < 0) 7931443Sedward wwnselecte++; 8031443Sedward else if (n == 0) 8131443Sedward wwnselectz++; 8231443Sedward else 8331443Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 8431443Sedward if (w->ww_pty < 0 || 8531443Sedward !FD_ISSET(w->ww_pty, &imask)) 8631443Sedward continue; 8731443Sedward wwnwread++; 8831443Sedward p = w->ww_obq; 8931443Sedward if (w->ww_ispty) { 9031443Sedward if (p == w->ww_ob) { 9131443Sedward w->ww_obp++; 9231443Sedward w->ww_obq++; 9331443Sedward } else 9431443Sedward p--; 9531443Sedward c = *p; 9631443Sedward } 9731443Sedward n = read(w->ww_pty, p, w->ww_obe - p); 9831443Sedward if (n < 0) { 9931443Sedward wwnwreade++; 10031443Sedward (void) close(w->ww_pty); 10131443Sedward w->ww_pty = -1; 10231443Sedward } else if (n == 0) { 10331443Sedward wwnwreadz++; 10431443Sedward (void) close(w->ww_pty); 10531443Sedward w->ww_pty = -1; 10631443Sedward } else if (!w->ww_ispty) { 10731443Sedward wwnwreadd++; 10831443Sedward wwnwreadc += n; 10931443Sedward w->ww_obq += n; 11031443Sedward } else if (*p == TIOCPKT_DATA) { 11131443Sedward n--; 11231443Sedward wwnwreadd++; 11331443Sedward wwnwreadc += n; 11431443Sedward w->ww_obq += n; 11531443Sedward } else { 11631443Sedward wwnwreadp++; 11731443Sedward if (*p & TIOCPKT_STOP) 11831443Sedward w->ww_stopped = 1; 11931443Sedward if (*p & TIOCPKT_START) 12031443Sedward w->ww_stopped = 0; 12131443Sedward if (*p & TIOCPKT_FLUSHWRITE) { 12231443Sedward w->ww_stopped = 0; 12331443Sedward w->ww_obq = w->ww_obp = 12431443Sedward w->ww_ob; 12531443Sedward } 12631443Sedward } 12731443Sedward if (w->ww_ispty) 12831443Sedward *p = c; 12931443Sedward } 13031443Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 13131443Sedward if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && 13231443Sedward !w->ww_stopped) { 13331443Sedward n = wwwrite(w, w->ww_obp, 13431443Sedward w->ww_obq - w->ww_obp); 13531443Sedward if ((w->ww_obp += n) == w->ww_obq) 13616313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 13731443Sedward if (wwinterrupt()) { 13831443Sedward wwclrintr(); 13931443Sedward return; 14015872Sedward } 14131443Sedward break; 14216313Sedward } 14331443Sedward } 14413923Sedward } 145