Serial port 即使在control-C之后恢复串行端口属性?

Serial port 即使在control-C之后恢复串行端口属性?,serial-port,posix,signals,Serial Port,Posix,Signals,通过POSIX使用串行端口时,建议先使用tcgetattr()保存原始属性,然后再使用tcsetattr()更改它们,然后在关闭端口之前恢复它们。当按control-C终止程序或程序接收到SIGINT时,情况如何?我还没有在任何系列教程中看到这一点 显然,一个atexit()函数是不够的,因为它不是由默认的SIGINT处理程序调用的。因此,似乎有必要安装一个信号处理程序,以便将属性恢复到任何仍然打开的串行端口。从信号处理程序调用tcsetattr()是否安全 人们可能会简单地认为这个问题无关紧要

通过POSIX使用串行端口时,建议先使用
tcgetattr()
保存原始属性,然后再使用
tcsetattr()
更改它们,然后在关闭端口之前恢复它们。当按control-C终止程序或程序接收到
SIGINT
时,情况如何?我还没有在任何系列教程中看到这一点

显然,一个
atexit()
函数是不够的,因为它不是由默认的
SIGINT
处理程序调用的。因此,似乎有必要安装一个信号处理程序,以便将属性恢复到任何仍然打开的串行端口。从信号处理程序调用
tcsetattr()
是否安全

人们可能会简单地认为这个问题无关紧要,但用control-C终止一个程序是很常见的,尤其是一个可能需要几十秒才能完成操作的程序。如果在这种情况下不保留串行端口设置是可以的,那么似乎根本没有理由保留它们。如果有什么不同的话,最好不要麻烦,而不要前后矛盾


我找到了一些,但没有详细的记录。我想我有兴趣讨论一下这是否是个好主意。谢谢。

经过进一步研究,我想我已经满意地回答了这个问题

首先,在中,我注意到一个信号处理程序被特别允许调用
tcsetattr()
,以及其他一些函数:

信号处理器例程必须非常小心,因为其他地方的处理在某个任意点被中断。POSIX具有“安全功能”的概念。如果一个信号中断了一个不安全的函数,并且处理程序调用了一个不安全的函数,那么该行为是未定义的。各种标准中明确列出了安全功能。POSIX.1-2003列表是`升起()`信号()``tcSetTTR()`[修剪为相关值] 这强烈表明POSIX委员会考虑到了这类事情,并导致了一种直截了当的方法,即在打开串行并保存其属性后更改
SIGINT
处理程序,然后在处理程序中恢复它们和旧的
SIGINT
处理程序,然后重新发出信号:

static void (*prev_sigint)( int );
static termios saved_attr;
static int fd;

static void cleanup( int ignored )
{
    tcsetattr( fd, TCSANOW, &saved_attr );
    signal( SIGINT, prev_sigint );
    raise( SIGINT );
}

int main( void )
{
    open_serial_and_save_attrs();
    prev_sigint = signal( SIGINT, cleanup );
    ...
}