1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#! /bin/sh /usr/share/dpatch/dpatch-run
## 19flowcontrol_lockup.dpatch by <hesso@pool.math.tu-berlin.de>
##
## DP: Make Flush() truly non-blocking by employing an extra select().
## DP: Thus D_userfd is assured to be in non-blocking mode on return
## DP: (even if the return was premature due to select() timing out),
## DP: so the SetTTY() call in FreeDisplay() doesn't have to be
## DP: safeguarded on its own.
## DP:
## DP: Note - I'm not satisfied at all with this patch, but I consider
## DP: it an ugly but working kluge, meant only to stay around as long
## DP: as upstream hasn't come up with anything better.
@DPATCH@
--- screen-4.0.3.orig/display.c 2007-08-06 22:22:20.000000000 +0200
+++ screen-4.0.3/display.c 2007-08-06 22:59:29.000000000 +0200
@@ -3137,6 +3137,8 @@
{
register int l;
register char *p;
+ fd_set fd_s;
+ struct timeval sO;
ASSERT(display);
l = D_obufp - D_obuf;
@@ -3151,15 +3153,29 @@
return;
}
p = D_obuf;
- if (fcntl(D_userfd, F_SETFL, 0))
- debug1("Warning: BLOCK fcntl failed: %d\n", errno);
+ if (fcntl(D_userfd, F_SETFL, FNBLOCK))
+ debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
+ if (D_blocked == 1)
+ D_blocked = 0;
+ D_blocked_fuzz = 0;
while (l)
{
- register int wr;
+ register int wr = 0;
+ sO.tv_sec = 5; sO.tv_usec = 0;
+ while (1) {
+ int sR;
+ FD_ZERO(&fd_s);
+ FD_SET(D_userfd, &fd_s);
+ sR = select(D_userfd+1, NULL, &fd_s, NULL, &sO);
+ if (!sR) {
+ debug("Timeout while waiting for display write fd to unblock\n");
+ return;
+ } else if (sR > 0) break;
+ }
wr = write(D_userfd, p, l);
if (wr <= 0)
{
- if (errno == EINTR)
+ if (errno == EINTR || errno == EAGAIN)
continue;
debug1("Writing to display: %d\n", errno);
wr = l;
@@ -3172,11 +3188,6 @@
}
D_obuffree += l;
D_obufp = D_obuf;
- if (fcntl(D_userfd, F_SETFL, FNBLOCK))
- debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
- if (D_blocked == 1)
- D_blocked = 0;
- D_blocked_fuzz = 0;
}
void
|