Skip to content

Bug: ioctl for terminal settings not working as expected on Windows #1453

@tobybear

Description

@tobybear

Contact Details

[email protected]

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;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    medium severityUsed to report medium severity bugs (e.g. Malfunctioning Features but still useable)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions