即使在control-C之后也能恢复串行端口属性吗?
通过 POSIX 使用串行端口时,建议先使用 tcgetattr() 保存原始属性,然后再使用 tcsetattr() 更改它们,然后在关闭端口之前恢复它们。当程序通过按 control-C 终止或程序收到 SIGINT
时会怎样?我还没有在任何系列教程中看到过这一点。
显然 atexit()
函数是不够的,因为它不是由默认的 SIGINT
处理程序调用的。因此,似乎有必要安装信号处理程序来恢复任何仍然打开的串行端口的属性。从信号处理程序调用 tcsetattr() 是否安全?
人们可能会认为这个问题无关紧要,但使用 control-C 终止程序是很常见的,尤其是那些可能需要数十秒才能完成操作的程序。如果在这种情况下不保留串行端口设置是可以的,那么似乎根本没有理由保留它们。如果有的话,最好不要打扰,而不是不一致地做。
我发现了一些执行上述操作的源代码示例,但没有任何详细记录。我想我有兴趣讨论这是否是一个好主意。谢谢。
When using a serial port via POSIX, it's recommended to save the original attributes using tcgetattr()
before changing them with tcsetattr()
, and then restore them before closing the port. What about when a program is terminated by pressing control-C or when the program receives SIGINT
? I haven't seen this covered in any of the serial tutorials.
Apparently an atexit()
function wouldn't be sufficient, because it's not called by the default SIGINT
handler. So it seems installation of a signal handler would be necessary that restores the attributes to any serial ports still open. Is it even safe to call tcsetattr()
from a signal handler?
One might simply dismiss this issue as insignificant, but it's common to terminate a program with control-C, especially one that can take tens of seconds to complete operations. If it's OK not to preserve serial port settings in this case, then there seems little reason to preserve them at all. If anything, it might be better not to bother, rather than do it inconsistently.
I found some examples of source code doing the above, but nothing well-documented. I guess I'm interested in some discussion of whether this is a good idea. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过进一步的研究,我想我已经满意地回答了这个问题。
首先,在信号手册页中,我注意到信号处理程序专门允许调用tcsetattr() 以及其他一些:
这强烈表明 POSIX 委员会有这种确切的类型记住这一点,并导致一种直接的方法,在打开串行并保存其属性后,您可以更改
SIGINT
处理程序,然后在处理程序中恢复它们和旧的SIGINT< /code> handler,然后重新发出信号:
After further research I think I've answered this to my satisfaction.
First, in the man page for signal I noticed that a signal handler is specifically allowed to call
tcsetattr()
, along with a few others:This strongly suggests that the POSIX committee had this exact kind of thing in mind, and leads to a straight forward approach where you change the
SIGINT
handler once you've opened serial and saved its attributes, then in your handler, restore them and the oldSIGINT
handler, then re-raise the signal: