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