我应该在 SIGINT/SIGTERM 上重置 termios 设置吗?
Should I reset termios settings on SIGINT/SIGTERM?
我在玩 termios
并且很快发现如果我更改终端设置并退出,我的更改将持续存在并搞砸我的环境。所以我设置我的程序以使用 tcgetattr
保存初始设置并在退出前重置它们。
然而,我预测,如果我在我的程序 运行 时点击 Ctrl-C
发送 SIGINT,这将导致终端仍然有我修改过的设置,因为我的程序不会有执行代码将它们重置回旧设置。
但这并没有发生。在 Ubuntu 和 macOS Sierra 中,我的终端设置都恢复了,就好像我在程序中重置了它们一样。
所以问题是: 这种行为总体上是我可以指望的吗?或者注册信号处理程序以捕获 SIGINT/SIGTERM 并在退出前恢复终端设置是否有意义?
代码
回答这个问题可能不需要看代码,但这是我的例子,以防你好奇:
#include <stdio.h>
#include <string.h>
#include <termios.h>
int main() {
// put terminal into non-canonical mode
struct termios old;
struct termios new;
tcgetattr(0, &old);
new = old;
new.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0, TCSANOW, &new);
// loop: get keypress and display (exit via 'x')
char key;
printf("Enter a key to see the ASCII value; press x to exit.\n");
while (1) {
key = getchar();
printf("%i\n", (int)key);
if (key == 'x') { break; }
}
// set terminal back to canonical
tcsetattr(0, TCSANOW, &old);
return 0;
}
我有点惊讶地发现在我的 Arch Linux 终端设置中也 "were reverted"。但实际上他们保持不变。当我更改您的代码时,我设法跟踪了一些异常情况。
//...
new.c_lflag &= ~(ICANON | ECHO);
new.c_cc[VMIN] = 0;
new.c_cc[VTIME] = 0;
//...
所以这里如果你不按任何按钮,输出是 -1
。如果你点击 Ctrl-C
,重新编译并启动原始程序(从同一个终端),它也会打印 -1
,所以没有自动重置。
我不知道为什么 ECHO
是 "hidden",我想知道,但我建议您手动还原所有终端设置。
我在玩 termios
并且很快发现如果我更改终端设置并退出,我的更改将持续存在并搞砸我的环境。所以我设置我的程序以使用 tcgetattr
保存初始设置并在退出前重置它们。
然而,我预测,如果我在我的程序 运行 时点击 Ctrl-C
发送 SIGINT,这将导致终端仍然有我修改过的设置,因为我的程序不会有执行代码将它们重置回旧设置。
但这并没有发生。在 Ubuntu 和 macOS Sierra 中,我的终端设置都恢复了,就好像我在程序中重置了它们一样。
所以问题是: 这种行为总体上是我可以指望的吗?或者注册信号处理程序以捕获 SIGINT/SIGTERM 并在退出前恢复终端设置是否有意义?
代码
回答这个问题可能不需要看代码,但这是我的例子,以防你好奇:
#include <stdio.h>
#include <string.h>
#include <termios.h>
int main() {
// put terminal into non-canonical mode
struct termios old;
struct termios new;
tcgetattr(0, &old);
new = old;
new.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0, TCSANOW, &new);
// loop: get keypress and display (exit via 'x')
char key;
printf("Enter a key to see the ASCII value; press x to exit.\n");
while (1) {
key = getchar();
printf("%i\n", (int)key);
if (key == 'x') { break; }
}
// set terminal back to canonical
tcsetattr(0, TCSANOW, &old);
return 0;
}
我有点惊讶地发现在我的 Arch Linux 终端设置中也 "were reverted"。但实际上他们保持不变。当我更改您的代码时,我设法跟踪了一些异常情况。
//...
new.c_lflag &= ~(ICANON | ECHO);
new.c_cc[VMIN] = 0;
new.c_cc[VTIME] = 0;
//...
所以这里如果你不按任何按钮,输出是 -1
。如果你点击 Ctrl-C
,重新编译并启动原始程序(从同一个终端),它也会打印 -1
,所以没有自动重置。
我不知道为什么 ECHO
是 "hidden",我想知道,但我建议您手动还原所有终端设置。