containers / krunvm

Create microVMs from OCI images
Apache License 2.0
1.43k stars 43 forks source link

Control-Q and Control-S not working for emacs inside krunvm (XON/XOFF management) #39

Open c3d opened 1 year ago

c3d commented 1 year ago

Follow these steps on macOS with M1:

% krunvm create ubuntu --name ubuntu-test
% krunvm start ubuntu-test
% apt update
% apt install emacs
% emacs

Then in Emacs, Control-X Control-F /tmp/glop RET to open a file named /tmp/glop, then put some text in the file, then Control-X Control-S (which normally would save the file) and notice that the ** along the file name in the status bar is still there, indicating that the file was not saved. Then type S (which completes the Control-X S command) and notice it will save all files. So the Control-S was not presented to Emacs.

I suspect this is related to XON/XOFF management (historically, Control-S was XOFF, stop terminal output, and Control-Q was XON, resume terminal output).

c3d commented 1 year ago

Note that Control-Q does not work either, which reinforces the idea that it's an XON/XOFF problem.

c3d commented 1 year ago

Interestingly, Control-Q and Control-S work as XON/XOFF in the terminal itself. So this is more of a problem with Emacs in text mode being able to disable them.

c3d commented 1 year ago

Reduced test case:

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

int main()
{
  struct termios ti;
  int rc = tcgetattr(0, &ti);
  printf("tcgetattr=%d, c_iflag=%x, Terminal IXON is %s\n", rc, ti.c_iflag, ti.c_iflag & IXON ? "on" : "off");
  ti.c_iflag &= ~IXON;
  rc = tcsetattr(0, TCSANOW, &ti);
  printf("tcsettattr=%d, c_iflag=%x, Terminal IXON is %s\n", rc, ti.c_iflag, ti.c_iflag & IXON ? "on" : "off");
  rc = tcgetattr(0, &ti);
  printf("tcgetattr=%d, c_iflag=%x, Terminal IXON is %s\n", rc, ti.c_iflag, ti.c_iflag & IXON ? "on" : "off");

  int i = 0;
  for(;;)
    printf("Hello %d\n", i++);
}

Ran this on macOS: I cannot use control-S to stop control flow (expected). Ran this on krunvm, I can use Control-S to stop control flow (seems bogus).

So I suspect that you do not correctly transmit the corresponding ioctls to the calling terminal.