|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: static char sccsid[] = "@(#)wwiomux.c 3.19 (Berkeley) 6/29/88"; ! 20: #endif /* not lint */ ! 21: ! 22: #include "ww.h" ! 23: #include <sys/time.h> ! 24: #include <sys/types.h> ! 25: #include <fcntl.h> ! 26: ! 27: /* ! 28: * Multiple window output handler. ! 29: * The idea is to copy window outputs to the terminal, via the ! 30: * display package. We try to give the top most window highest ! 31: * priority. The only return condition is when there is keyboard ! 32: * input or when a child process dies which are serviced by signal ! 33: * catchers (wwrint() and wwchild()). ! 34: * When there's nothing to do, we sleep in a select(). ! 35: * This can be done better with interrupt driven io. But that's ! 36: * not supported on ptys, yet. ! 37: * The history of this routine is interesting. ! 38: */ ! 39: wwiomux() ! 40: { ! 41: register struct ww *w; ! 42: fd_set imask; ! 43: register n; ! 44: register char *p; ! 45: char c; ! 46: struct timeval tv; ! 47: char noblock; ! 48: ! 49: for (;;) { ! 50: if (wwinterrupt()) { ! 51: wwclrintr(); ! 52: return; ! 53: } ! 54: ! 55: FD_ZERO(&imask); ! 56: noblock = 0; ! 57: for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { ! 58: if (w->ww_pty < 0) ! 59: continue; ! 60: if (w->ww_obq < w->ww_obe) ! 61: FD_SET(w->ww_pty, &imask); ! 62: if (w->ww_obq > w->ww_obp && !w->ww_stopped) ! 63: noblock = 1; ! 64: } ! 65: ! 66: if (!noblock) { ! 67: if (wwcurwin != 0) ! 68: wwcurtowin(wwcurwin); ! 69: wwupdate(); ! 70: wwflush(); ! 71: setjmp(wwjmpbuf); ! 72: wwsetjmp = 1; ! 73: if (wwinterrupt()) { ! 74: wwsetjmp = 0; ! 75: wwclrintr(); ! 76: return; ! 77: } ! 78: /* ! 79: * Defensive code. If somebody else (for example, ! 80: * wall) clears the ASYNC flag on us, we will block ! 81: * forever. So we need a finite timeout and set ! 82: * the flag again. Anything more clever will probably ! 83: * need even more system calls. (This is a bug ! 84: * in the kernel.) ! 85: * I don't like this one bit. ! 86: */ ! 87: fcntl(0, F_SETFL, wwnewtty.ww_fflags); ! 88: tv.tv_sec = 30; ! 89: } else ! 90: tv.tv_sec = 0; ! 91: tv.tv_usec = 0; ! 92: wwnselect++; ! 93: n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0, &tv); ! 94: wwsetjmp = 0; ! 95: ! 96: if (n < 0) ! 97: wwnselecte++; ! 98: else if (n == 0) ! 99: wwnselectz++; ! 100: else ! 101: for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { ! 102: if (w->ww_pty < 0 || ! 103: !FD_ISSET(w->ww_pty, &imask)) ! 104: continue; ! 105: wwnwread++; ! 106: p = w->ww_obq; ! 107: if (w->ww_ispty) { ! 108: if (p == w->ww_ob) { ! 109: w->ww_obp++; ! 110: w->ww_obq++; ! 111: } else ! 112: p--; ! 113: c = *p; ! 114: } ! 115: n = read(w->ww_pty, p, w->ww_obe - p); ! 116: if (n < 0) { ! 117: wwnwreade++; ! 118: (void) close(w->ww_pty); ! 119: w->ww_pty = -1; ! 120: } else if (n == 0) { ! 121: wwnwreadz++; ! 122: (void) close(w->ww_pty); ! 123: w->ww_pty = -1; ! 124: } else if (!w->ww_ispty) { ! 125: wwnwreadd++; ! 126: wwnwreadc += n; ! 127: w->ww_obq += n; ! 128: } else if (*p == TIOCPKT_DATA) { ! 129: n--; ! 130: wwnwreadd++; ! 131: wwnwreadc += n; ! 132: w->ww_obq += n; ! 133: } else { ! 134: wwnwreadp++; ! 135: if (*p & TIOCPKT_STOP) ! 136: w->ww_stopped = 1; ! 137: if (*p & TIOCPKT_START) ! 138: w->ww_stopped = 0; ! 139: if (*p & TIOCPKT_FLUSHWRITE) { ! 140: w->ww_stopped = 0; ! 141: w->ww_obq = w->ww_obp = ! 142: w->ww_ob; ! 143: } ! 144: } ! 145: if (w->ww_ispty) ! 146: *p = c; ! 147: } ! 148: for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) ! 149: if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && ! 150: !w->ww_stopped) { ! 151: n = wwwrite(w, w->ww_obp, ! 152: w->ww_obq - w->ww_obp); ! 153: if ((w->ww_obp += n) == w->ww_obq) ! 154: w->ww_obq = w->ww_obp = w->ww_ob; ! 155: if (wwinterrupt()) { ! 156: wwclrintr(); ! 157: return; ! 158: } ! 159: break; ! 160: } ! 161: } ! 162: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.