Commit | Line | Data |
---|---|---|
abbfd2f2 | 1 | #ifndef lint |
8fa6d94c | 2 | static char *sccsid = "@(#)wwiomux.c 3.7 84/01/16"; |
abbfd2f2 EW |
3 | #endif |
4 | ||
5 | #include "ww.h" | |
8fa6d94c | 6 | #include <sys/time.h> |
abbfd2f2 | 7 | |
8fa6d94c EW |
8 | /* |
9 | * Multiple window IO handler. | |
10 | */ | |
11 | wwiomux() | |
abbfd2f2 | 12 | { |
8fa6d94c EW |
13 | register struct ww *w; |
14 | int imask; | |
15 | char dont_block; | |
16 | register char *p; | |
17 | register n; | |
18 | char c; | |
19 | static struct timeval tv = { 0, 0 }; | |
abbfd2f2 | 20 | |
8fa6d94c EW |
21 | loop: |
22 | imask = 1; | |
23 | dont_block = 0; | |
24 | for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { | |
25 | if (w->ww_pty < 0) | |
26 | continue; | |
27 | if (w->ww_obp + w->ww_obc < w->ww_obe) | |
28 | imask |= 1 << w->ww_pty; | |
29 | if (w->ww_obc != 0 && !w->ww_stopped) | |
30 | dont_block = 1; | |
31 | } | |
32 | if (!dont_block) { | |
33 | wwupdate(); | |
34 | wwflush(); | |
35 | } | |
36 | wwnselect++; | |
37 | n = select(wwdtablesize, &imask, (int *)0, (int *)0, | |
38 | dont_block ? &tv : (struct timeval *)0); | |
39 | if (n < 0) | |
40 | wwnselecte++; | |
41 | else if (imask & 1) { | |
42 | if (wwibc == 0) | |
43 | p = wwibp = wwib; | |
44 | else | |
45 | p = wwibp + wwibc; | |
46 | n = wwibe - p; | |
47 | wwnread++; | |
48 | if ((n = read(0, p, n)) > 0) { | |
49 | wwibc += n; | |
50 | wwnreadc += n; | |
51 | } else if (n == 0) | |
52 | wwnreadz++; | |
53 | else | |
54 | wwnreade++; | |
55 | } else if (imask != 0 || dont_block) { | |
56 | char first_time = 1; | |
57 | if (n == 0) | |
58 | wwnselectz++; | |
59 | for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) { | |
60 | if (w->ww_pty < 0) | |
61 | continue; | |
62 | if (imask & 1 << w->ww_pty) { | |
63 | wwnwread++; | |
64 | p = w->ww_obp + w->ww_obc; | |
65 | if (p == w->ww_ob) | |
66 | w->ww_obp++; | |
67 | else | |
68 | p--; | |
69 | c = *p; | |
70 | n = read(w->ww_pty, p, w->ww_obe - p); | |
71 | if (n < 0) { | |
72 | wwnwreade++; | |
73 | (void) close(w->ww_pty); | |
74 | w->ww_pty = -1; | |
75 | continue; | |
76 | } else if (n == 0) { | |
77 | wwnwreadz++; | |
78 | } else if (*p == TIOCPKT_DATA) { | |
79 | wwnwreadd++; | |
80 | wwnwreadc += n - 1; | |
81 | w->ww_obc += n - 1; | |
82 | } else { | |
83 | wwnwreadp++; | |
84 | if (*p & TIOCPKT_STOP) | |
85 | w->ww_stopped = 1; | |
86 | if (*p & TIOCPKT_START) | |
87 | w->ww_stopped = 0; | |
88 | if (*p & TIOCPKT_FLUSHWRITE) { | |
89 | w->ww_obp = w->ww_ob; | |
90 | w->ww_obc = 0; | |
91 | w->ww_stopped = 0; | |
92 | } | |
93 | } | |
94 | *p = c; | |
95 | } | |
96 | if (first_time && w->ww_obc != 0 && !w->ww_stopped) { | |
97 | first_time = 0; | |
98 | /* XXX */ | |
99 | n = wwwrite(w, w->ww_obp, MIN(w->ww_obc, 50)); | |
100 | if (w->ww_obc -= n) | |
101 | w->ww_obp += n; | |
102 | else | |
103 | w->ww_obp = w->ww_ob; | |
104 | } | |
abbfd2f2 | 105 | } |
8fa6d94c | 106 | } |
abbfd2f2 | 107 | } |