118744Sedward /* 233514Sbostic * Copyright (c) 1983 Regents of the University of California. 333514Sbostic * All rights reserved. 433514Sbostic * 533514Sbostic * Redistribution and use in source and binary forms are permitted 6*34909Sbostic * provided that the above copyright notice and this paragraph are 7*34909Sbostic * duplicated in all such forms and that any documentation, 8*34909Sbostic * advertising materials, and other materials related to such 9*34909Sbostic * distribution and use acknowledge that the software was developed 10*34909Sbostic * by the University of California, Berkeley. The name of the 11*34909Sbostic * University may not be used to endorse or promote products derived 12*34909Sbostic * from this software without specific prior written permission. 13*34909Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34909Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34909Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1618744Sedward */ 1718744Sedward 1833514Sbostic #ifndef lint 19*34909Sbostic static char sccsid[] = "@(#)wwiomux.c 3.19 (Berkeley) 06/29/88"; 2033514Sbostic #endif /* not lint */ 2133514Sbostic 2213923Sedward #include "ww.h" 2315872Sedward #include <sys/time.h> 2424958Sedward #include <sys/types.h> 2533751Sedward #include <fcntl.h> 2613923Sedward 2715872Sedward /* 2816124Sedward * Multiple window output handler. 2916124Sedward * The idea is to copy window outputs to the terminal, via the 3016124Sedward * display package. We try to give the top most window highest 3116124Sedward * priority. The only return condition is when there is keyboard 3231443Sedward * input or when a child process dies which are serviced by signal 3331443Sedward * catchers (wwrint() and wwchild()). 3416124Sedward * When there's nothing to do, we sleep in a select(). 3516124Sedward * This can be done better with interrupt driven io. But that's 3616124Sedward * not supported on ptys, yet. 3716124Sedward * The history of this routine is interesting. 3815872Sedward */ 3915872Sedward wwiomux() 4013923Sedward { 4115872Sedward register struct ww *w; 4224958Sedward fd_set imask; 4316124Sedward register n; 4415872Sedward register char *p; 4515872Sedward char c; 4633751Sedward struct timeval tv; 4716124Sedward char noblock; 4813923Sedward 4931443Sedward for (;;) { 5016124Sedward if (wwinterrupt()) { 5131443Sedward wwclrintr(); 5216124Sedward return; 5316124Sedward } 5416124Sedward 5531443Sedward FD_ZERO(&imask); 5631443Sedward noblock = 0; 5716313Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 5831443Sedward if (w->ww_pty < 0) 5916313Sedward continue; 6031443Sedward if (w->ww_obq < w->ww_obe) 6131443Sedward FD_SET(w->ww_pty, &imask); 6231443Sedward if (w->ww_obq > w->ww_obp && !w->ww_stopped) 6331443Sedward noblock = 1; 6431443Sedward } 6531443Sedward 6631443Sedward if (!noblock) { 6731443Sedward if (wwcurwin != 0) 6831443Sedward wwcurtowin(wwcurwin); 6931443Sedward wwupdate(); 7031443Sedward wwflush(); 7131443Sedward setjmp(wwjmpbuf); 7231443Sedward wwsetjmp = 1; 7331443Sedward if (wwinterrupt()) { 7431443Sedward wwsetjmp = 0; 7531443Sedward wwclrintr(); 7631443Sedward return; 7716313Sedward } 7833751Sedward /* 7933751Sedward * Defensive code. If somebody else (for example, 8033751Sedward * wall) clears the ASYNC flag on us, we will block 8133751Sedward * forever. So we need a finite timeout and set 8233751Sedward * the flag again. Anything more clever will probably 8333751Sedward * need even more system calls. (This is a bug 8433751Sedward * in the kernel.) 8533751Sedward * I don't like this one bit. 8633751Sedward */ 8733751Sedward fcntl(0, F_SETFL, wwnewtty.ww_fflags); 8833751Sedward tv.tv_sec = 30; 8933751Sedward } else 9033751Sedward tv.tv_sec = 0; 9133751Sedward tv.tv_usec = 0; 9231443Sedward wwnselect++; 9333751Sedward n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0, &tv); 9431443Sedward wwsetjmp = 0; 9531443Sedward 9631443Sedward if (n < 0) 9731443Sedward wwnselecte++; 9831443Sedward else if (n == 0) 9931443Sedward wwnselectz++; 10031443Sedward else 10131443Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { 10231443Sedward if (w->ww_pty < 0 || 10331443Sedward !FD_ISSET(w->ww_pty, &imask)) 10431443Sedward continue; 10531443Sedward wwnwread++; 10631443Sedward p = w->ww_obq; 10731443Sedward if (w->ww_ispty) { 10831443Sedward if (p == w->ww_ob) { 10931443Sedward w->ww_obp++; 11031443Sedward w->ww_obq++; 11131443Sedward } else 11231443Sedward p--; 11331443Sedward c = *p; 11431443Sedward } 11531443Sedward n = read(w->ww_pty, p, w->ww_obe - p); 11631443Sedward if (n < 0) { 11731443Sedward wwnwreade++; 11831443Sedward (void) close(w->ww_pty); 11931443Sedward w->ww_pty = -1; 12031443Sedward } else if (n == 0) { 12131443Sedward wwnwreadz++; 12231443Sedward (void) close(w->ww_pty); 12331443Sedward w->ww_pty = -1; 12431443Sedward } else if (!w->ww_ispty) { 12531443Sedward wwnwreadd++; 12631443Sedward wwnwreadc += n; 12731443Sedward w->ww_obq += n; 12831443Sedward } else if (*p == TIOCPKT_DATA) { 12931443Sedward n--; 13031443Sedward wwnwreadd++; 13131443Sedward wwnwreadc += n; 13231443Sedward w->ww_obq += n; 13331443Sedward } else { 13431443Sedward wwnwreadp++; 13531443Sedward if (*p & TIOCPKT_STOP) 13631443Sedward w->ww_stopped = 1; 13731443Sedward if (*p & TIOCPKT_START) 13831443Sedward w->ww_stopped = 0; 13931443Sedward if (*p & TIOCPKT_FLUSHWRITE) { 14031443Sedward w->ww_stopped = 0; 14131443Sedward w->ww_obq = w->ww_obp = 14231443Sedward w->ww_ob; 14331443Sedward } 14431443Sedward } 14531443Sedward if (w->ww_ispty) 14631443Sedward *p = c; 14731443Sedward } 14831443Sedward for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) 14931443Sedward if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && 15031443Sedward !w->ww_stopped) { 15131443Sedward n = wwwrite(w, w->ww_obp, 15231443Sedward w->ww_obq - w->ww_obp); 15331443Sedward if ((w->ww_obp += n) == w->ww_obq) 15416313Sedward w->ww_obq = w->ww_obp = w->ww_ob; 15531443Sedward if (wwinterrupt()) { 15631443Sedward wwclrintr(); 15731443Sedward return; 15815872Sedward } 15931443Sedward break; 16016313Sedward } 16131443Sedward } 16213923Sedward } 163