在收到SIGINT/SIGTERM信号时,我是否应该重置termios设置?

3

我在玩 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;
}

"// assume stdin is file descriptor 0" => 如果0不是标准输入,那么你的实现不符合POSIX规范。 - undefined
1
我看了一下,我觉得你的shell重置了自己的属性。 - undefined
我也这么怀疑。 - undefined
1个回答

3

我有点惊讶地发现在我的Arch Linux终端设置中也“被还原”了。但实际上它们保持不变。当我改变你的代码时,我成功地跟踪到了一些异常情况。

//...
new.c_lflag &= ~(ICANON | ECHO);
new.c_cc[VMIN]  = 0;
new.c_cc[VTIME] = 0;
//...

如果您没有按任何按钮,输出结果将为-1。如果您按下Ctrl-C,重新编译并从同一终端启动原始程序,它也将打印-1,因此没有自动重置。

我不知道为什么ECHO被“隐藏”,但我建议您手动恢复所有终端设置。


我无法复现你提到的行为,但如果它可以在任何地方产生,我认为你是对的,注册一个信号处理程序来重置终端设置是有意义的。最坏的情况是你需要多做一点工作。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接