0

I have a C program running inside a Docker container and calling a function getkey() as below:

int getkey() {

int ch;
struct termios orig_term_attr, new_term_attr;

/* set terminal to raw mode */

   tcgetattr(fileno(stdin), &orig_term_attr);
   memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
   new_term_attr.c_lflag &= ~(ECHO|ICANON);
   new_term_attr.c_cc[VTIME] = 0;
   new_term_attr.c_cc[VMIN] = 0;
   tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);

   ch = fgetc(stdin);  /* read one char from stdin stream without blocking. Returns EOF (-1) if none available */

   tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);  /* restore original terminal attributes */

   return ch;
}

In a host or VM terminal window this works fine, but inside a container fgetc(stdin) input is ignored. By ignore I mean if I press keys they show up on the container command line after the program finishes. The docker run command line is:

docker run -it keybd_test /bin/bash

I have tried with --init and with -a stdin -a stdout -a stderr. I suspect it has something to do with temporarily placing the terminal in raw mode, but in searching the closest I can find is ctrl-C handling

Is there something I'm missing in the docker run command ? Is there a known issue with terminal raw mode inside containers ?

Docker --version shows 20.10.17, build 100c70180f

  • What happens if you replace `fgetc()` with something like `read( STDIN_FILENO,...)`? Or set `stdin()` to non-buffered with `setbuf( stdin, NULL );`? – Andrew Henle Feb 23 '23 at 01:06
  • @AndrewHenle dang, good catch ! setbuf(stdin, NULL) has no effect, but read(fileno(stdin), (char*)&ch, 1) fixes the problem. Note that I used stdin(fileno) vs STDIN_FILENO, as per https://rtems-users.rtems.narkive.com/dIl6m5yS/fileno-stdin-versus-stdin-fileno-and-friends they can conceivably be different. Other than EOF, what is the difference between fgetc() and read( one char ) ? I found https://stackoverflow.com/questions/50225595/difference-between-freadc-1-1-input-and-fgetcinput-for-reading-one-byte which focuses on EOF but not buffering or other underlying terminal comm – Jeff Brower Feb 23 '23 at 05:58
  • @AndrewHenle please make an answer so I can accept, thanks – Jeff Brower Feb 23 '23 at 06:01

0 Answers0