[Openmcl-devel] Raw-mode terminal weirdness redux

Ron Garret ron at flownet.com
Mon Mar 26 07:51:03 PDT 2018


On Mar 16, 2018, at 2:31 PM, Ron Garret <ron at flownet.com> wrote:

> Aargh, no, it’s not a CCL bug, it’s rlwrap that does this:

Turns out I was wrong about this.  There really is some serious weirdness going on here, which I have now reliably (sort of) reproduced in both CCL and C.  The reason I hedge on “reliably” is that the C version produces the problem *intermittently*, whereas the Lisp version produces the problem (or not — see below) 100% reliably.  Which is really weird because the Lisp version now consists of nothing but FFI calls, so its behavior should be indistinguishable from C code, but it’s not.  Even stranger, the problem seems to be a regression that was introduced in CCL version 1.9.  The problem does not manifest itself in version 1.8.  But, as I said, the code that reproduces the problem doesn’t actually use any Lisp functionality.

So here’s the code:

/////////////////////////////////////////////////////////

#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void) {
  char buf;
  int c = TCSAFLUSH; // TCSANOW TCSADRAIN TCSASOFT TCSAFLUSH;
  if (write(fileno(stdout), "123\r\n", 5) != 5) return -1;
  struct termios normal, raw;
  cfmakeraw(&raw);
  tcgetattr(fileno(stdin), &normal);
  if (tcsetattr(fileno(stdin), c, &raw)) return -1;
  usleep(100000);
  if (write(fileno(stdout), "456\r\n", 5) != 5) return -1;
  read(fileno(stdin), &buf, 1);
  if (write(fileno(stdout), "789\r\n", 5) != 5) return -1;
  if (tcsetattr(fileno(stdin), c, &normal)) return -1;
  return 0;
}

///////////////////////////////////////////////////////////

(defun set-tty-raw (tty)
  (rlet ((attr :termios))
    (#_cfmakeraw attr)
    (eql 0 (#_tcsetattr tty #$TCSAFLUSH attr))))

(defmacro with-raw-input (&body body)
  `(rlet ((attr :termios))
     (unwind-protect
	  (progn
	    (#_tcgetattr 0 attr)
	    (set-tty-raw 0)
	    , at body)
       (#_tcsetattr 0 #$TCSAFLUSH attr))))

(defun %write (s)
  (with-cstrs ((cs s))
    (#_write 1 cs (length s))))

(defun test ()
  (with-raw-input
    (%write "foo")
    (read-char)
    (%write "baz")
    (with-raw-input
      (%write "bar"))))

/////////////////////////////////////////////////////////////////

The problem is that when the terminal is in raw input mode, all output is lost until a key is pressed.  In C this happens intermittently.  In CCL this happens in every version of CCL since 1.9.  It does NOT happen in 1.8.  This is true for both 32 and 64 bit versions, and it is true whether or not the code runs until rlwrap (for both Lisp and C).  The same results obtain in the native OSX terminal and under iTerm.  All this is running on OS X 10.9 (Mavericks).  I would be grateful is someone running a more recent MacOS would see if they can reproduce these results.

I am also herewith offering a $500 bug bounty to the first person who figures out how to fix this.

rg




More information about the Openmcl-devel mailing list