define UCB_NTTY
[unix-history] / usr / src / usr.bin / window / wwiomux.c
CommitLineData
abbfd2f2 1#ifndef lint
60de5df9 2static char sccsid[] = "@(#)wwiomux.c 3.14 %G%";
abbfd2f2
EW
3#endif
4
60de5df9
EW
5/*
6 * Copyright (c) 1983 Regents of the University of California,
7 * All rights reserved. Redistribution permitted subject to
8 * the terms of the Berkeley Software License Agreement.
9 */
10
abbfd2f2 11#include "ww.h"
8fa6d94c 12#include <sys/time.h>
abbfd2f2 13
8fa6d94c 14/*
b1189050
EW
15 * Multiple window output handler.
16 * The idea is to copy window outputs to the terminal, via the
17 * display package. We try to give the top most window highest
18 * priority. The only return condition is when there is keyboard
19 * input, which is serviced asynchronously by wwrint().
20 * When there's nothing to do, we sleep in a select().
21 * This can be done better with interrupt driven io. But that's
22 * not supported on ptys, yet.
23 * The history of this routine is interesting.
8fa6d94c
EW
24 */
25wwiomux()
abbfd2f2 26{
8fa6d94c
EW
27 register struct ww *w;
28 int imask;
8fa6d94c 29 register n;
b1189050 30 register char *p;
8fa6d94c
EW
31 char c;
32 static struct timeval tv = { 0, 0 };
b1189050 33 char noblock;
abbfd2f2 34
8fa6d94c 35loop:
b1189050
EW
36 if (wwinterrupt())
37 return;
38
39 imask = 0;
40 noblock = 0;
8fa6d94c
EW
41 for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
42 if (w->ww_pty < 0)
43 continue;
9d1a4d0c
EW
44 if (w->ww_obq < w->ww_obe)
45 imask |= 1 << w->ww_pty;
7ecf4dca 46 if (w->ww_obq > w->ww_obp && !w->ww_stopped)
b1189050 47 noblock = 1;
8fa6d94c 48 }
b1189050
EW
49
50 if (!noblock) {
51 if (wwcurwin != 0)
52 wwcurtowin(wwcurwin);
8fa6d94c
EW
53 wwupdate();
54 wwflush();
b1189050
EW
55 if (setjmp(wwjmpbuf))
56 return;
57 wwsetjmp = 1;
58 if (wwinterrupt()) {
59 wwsetjmp = 0;
60 return;
61 }
8fa6d94c
EW
62 }
63 wwnselect++;
64 n = select(wwdtablesize, &imask, (int *)0, (int *)0,
b1189050
EW
65 noblock ? &tv : (struct timeval *)0);
66 wwsetjmp = 0;
67
8fa6d94c
EW
68 if (n < 0)
69 wwnselecte++;
7ecf4dca
EW
70 else if (n == 0)
71 wwnselectz++;
72 else
73 for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
74 if (w->ww_pty < 0 || (imask & 1 << w->ww_pty) == 0)
75 continue;
76 wwnwread++;
77 p = w->ww_obq;
78 if (w->ww_ispty) {
79 if (p == w->ww_ob) {
8fa6d94c 80 w->ww_obp++;
7ecf4dca
EW
81 w->ww_obq++;
82 } else
8fa6d94c
EW
83 p--;
84 c = *p;
7ecf4dca
EW
85 }
86 n = read(w->ww_pty, p, w->ww_obe - p);
87 if (n < 0) {
88 wwnwreade++;
89 (void) close(w->ww_pty);
90 w->ww_pty = -1;
7ecf4dca
EW
91 } else if (n == 0) {
92 wwnwreadz++;
13d809c1
EW
93 (void) close(w->ww_pty);
94 w->ww_pty = -1;
7ecf4dca
EW
95 } else if (!w->ww_ispty) {
96 wwnwreadd++;
97 wwnwreadc += n;
98 w->ww_obq += n;
99 } else if (*p == TIOCPKT_DATA) {
100 n--;
101 wwnwreadd++;
102 wwnwreadc += n;
103 w->ww_obq += n;
104 } else {
105 wwnwreadp++;
106 if (*p & TIOCPKT_STOP)
107 w->ww_stopped = 1;
108 if (*p & TIOCPKT_START)
109 w->ww_stopped = 0;
110 if (*p & TIOCPKT_FLUSHWRITE) {
111 w->ww_stopped = 0;
112 w->ww_obq = w->ww_obp = w->ww_ob;
8fa6d94c 113 }
8fa6d94c 114 }
7ecf4dca
EW
115 if (w->ww_ispty)
116 *p = c;
117 }
0706a02d 118 for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
7ecf4dca
EW
119 if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) {
120 n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp);
121 if ((w->ww_obp += n) == w->ww_obq)
122 w->ww_obq = w->ww_obp = w->ww_ob;
0706a02d
EW
123 if (wwinterrupt())
124 return;
125 break;
126 }
b1189050 127 goto loop;
abbfd2f2 128}