I now have a patch for this bug which detects when we have enabled 
non-blocking mode on stdout because it shares the file table entry with 
stdin and closes and reopens stdout to get it back to blocking mode.  I 
have tested this and it appears to solve the problem so I attach it.
Common subdirectories: gkermit-1.0.orig/debian and gkermit-1.0/debian
diff -u gkermit-1.0.orig/gunixio.c gkermit-1.0/gunixio.c
--- gkermit-1.0.orig/gunixio.c  2007-01-31 17:07:15.000000000 +0000
+++ gkermit-1.0/gunixio.c       2007-01-31 17:06:53.000000000 +0000
@@ -307,6 +307,7 @@
 
 int
 ttopen(ttname) char *ttname; {         /* "Open" the communication device */
+       int oflags, ofd;
     if (debug) {                       /* Vital statistics for debug log */
 #ifdef __STDC__
        fprintf(db,"ttopen __STDC__\n");
@@ -366,8 +367,30 @@
        errno = 0;
        if (fcntl(0, F_SETFL,ttflags|O_NDELAY) == -1)
          logerr("ttopen fcntl(0,F_SETFL,O_NDELAY)");
-       else
+       else {
          nonblock = 1;
+         /*
+          It is possible that stdin and stdout are different file
+          descriptors refering to the same kernel file table entry.
+          If this is the case then setting non-blocking mode on stdin
+          above will have set it on stdout too and that will cause a
+          loop in ttol to busy-wait thus using nearly 100% system
+          CPU.  So, we test if stdout is in non-blocking mode and if
+          it is we close it and reopen /dev/tty to get an independant
+          file table entry.
+          */
+
+         if ((oflags = fcntl(1, F_GETFL)) == -1)
+           logerr("ttopen fcntl(1,F_GETFL)");
+         else if (oflags & O_NDELAY) {
+               if ((ofd = open("/dev/tty", O_WRONLY, 0)) == -1)
+                 logerr("open(\"/dev/tty\",O_WRONLY)");
+               else if (dup2(ofd, 1) == -1)
+                 logerr("dup2");
+               else
+                 close(ofd);
+         }
+       }
     }
 #endif /* F_SETFL */
 #endif /* O_NDELAY */

Reply via email to