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