-
-
Notifications
You must be signed in to change notification settings - Fork 727
Description
Contact Details
What happened?
I have some code (attached below as a minimal example) that switches the terminal to raw mode (disabling the echoing of pressed keys). This works fine using tcsetattr() from termios.h, both on Linux and Windows, no problem here.
As far as I know, tcsetattr() is only a shortcut to an internal call to ioctl with special parameters.
And indeed, when I replace this:
tcsetattr(STDIN_FILENO, TCSANOW, &raw);
with this:
ioctl(STDIN_FILENO, TCSETS, &raw);
it works exactly like before on Linux. On Windows, when using ioctl, it does however not work as expected, the terminal stays in the old mode.
Is this a known issue?
It can easily be replicated with the attached demo by switching the USE_IOCTL define and testing both on Linux vs. Windows.
Also I noticed that cosmocc does not define TCSETSF (which is set and flush in one operation), which is not a big issue, just curious why it was omitted but TCSETS and TCGETS exist.
Version
cosmocc (GCC) 14.1.0
What operating system are you seeing the problem on?
Windows
Relevant log output
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
// #define USE_IOCTL
int main() {
struct termios ori_termios;
char buf[1024] = { 0 };
printf("Enter some text (characters should not be shown) and press enter: ");
fflush(stdout);
// enable raw terminal mode
#ifdef USE_IOCTL
ioctl(STDIN_FILENO, TCGETS, &ori_termios);
#else
tcgetattr(STDIN_FILENO, &ori_termios);
#endif
struct termios raw = ori_termios;
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_cflag |= (CS8);
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN);
#ifdef USE_IOCTL
ioctl(STDIN_FILENO, TCSETS, &raw);
#else
tcsetattr(STDIN_FILENO, TCSANOW, &raw);
#endif
fflush(stdin);
scanf("%s", buf);
// restore old terminal mode
#ifdef USE_IOCTL
ioctl(STDIN_FILENO, TCSETS, &ori_termios);
#else
tcsetattr(STDIN_FILENO, TCSANOW, &ori_termios);
#endif
fflush(stdin);
printf("\nUser input: %s\n", buf);
return 0;
}