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

Attachment: signature.asc
Description: Digital signature

Reply via email to