Commit | Line | Data |
---|---|---|
abbfd2f2 | 1 | #ifndef lint |
60de5df9 | 2 | static 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 | */ |
25 | wwiomux() | |
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 | 35 | loop: |
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 | } |