Hi, I have finally made up my mind and implemented my own workaround, which I'll include in 4.0.3-3. It gets by without alarm signals and jumping (which is always a bit awkward to debug) but uses an additional call to select() instead to make sure the socket in question won't block.
The solution is still rather hackish (the unblocking ^Q is sometimes consumed by screen itself when it happens to be in the other select() waiting for input for the copy mode - a second ^Q is necessary in those cases), but this is only a small inconvenience that downgrades the bug from important to minor. Regards, Jan
#! /bin/sh /usr/share/dpatch/dpatch-run
## 19flowcontrol_lockup.dpatch by <[EMAIL PROTECTED]>
##
## 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
signature.asc
Description: Digital signature

