commit 60b3c6f

uint  ·  2026-06-23 13:13:00 +0000 UTC
parent cc8d5d7
Add raw mode toggles
2 files changed,  +40, -2
M tmtm.c
+1, -1
1@@ -1,5 +1,5 @@
2 CC = cc
3-CFLAGS = -std=c99 -Wall -Werror -O2
4+CFLAGS = -std=c99 -Wall -Wextra -O2
5 CPPFLAGS =
6 
7 SRC = tmtm.c
M tmtm.c
+39, -1
 1@@ -2,11 +2,16 @@
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5+#include <termios.h>
 6+#include <unistd.h>
 7 
 8 #define TMTM_VER "26.6"
 9 
10-/* print line number, message, exit with error code `ec` */
11 static void die(int ln, int ec, const char* fmt, ...);
12+static void rawon(void);
13+static void rawoff(void);
14+
15+static struct termios orig_termios;
16 
17 static void die(int ln, int ec, const char* fmt, ...)
18 {
19@@ -21,6 +26,29 @@ static void die(int ln, int ec, const char* fmt, ...)
20 	exit(ec);
21 }
22 
23+static void rawon(void)
24+{
25+	if (tcgetattr(STDIN_FILENO, &orig_termios) == -1)
26+		die(__LINE__, EXIT_FAILURE, "tcgetattr failed");
27+	if (atexit(rawoff) != 0)
28+		die(__LINE__, EXIT_FAILURE, "cannot register disable_raw_mode");
29+
30+	struct termios raw_state = orig_termios;
31+	raw_state.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
32+	raw_state.c_iflag &= ~(IXON | ICRNL);
33+	raw_state.c_oflag &= ~(OPOST);
34+	raw_state.c_cc[VMIN] = 1;
35+	raw_state.c_cc[VTIME] = 0;
36+
37+	if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_state) == -1)
38+		die(__LINE__, EXIT_FAILURE, "tcsetattr failed");
39+}
40+
41+static void rawoff(void)
42+{
43+	tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
44+}
45+
46 
47 int main(int argc, char* argv[])
48 {
49@@ -31,6 +59,16 @@ int main(int argc, char* argv[])
50 		}
51 	}
52 
53+	rawon();
54+	char c;
55+	while ((read(STDIN_FILENO, &c, 1) == 1 && c != 'q')) {
56+		if (c >= '!' && c <= '~')
57+			printf("%c", c);
58+		else
59+			printf("%d", c);
60+		fflush(stdout);
61+	}
62+
63 	return EXIT_SUCCESS;
64 }
65