Linux:系统调用是否具有自己的信号处理程序?我可以覆盖它吗?

时间:2018-10-15 05:54:42

标签: linux signals posix system-calls signal-handling

系统调用read()上的文档说read()如果被信号中断则立即返回。返回的值反映了到目前为止已成功读取的字节数。似乎暗示某些系统调用具有自己的信号处理程序。

如果read()正在从管道中读取(由pipe()设置),但是管道中没有可用的字节,则read()正在阻塞线程。现在,如果我从终端(通过Ctrl + C)发送SIGINT,程序将终止。

假设在程序启动时,我为SIGINT安装了一个信号处理程序,它输出一条消息"SIGINT is received"。当read()被阻止并且我使用Ctrl + C时,程序将终止并显示该消息,还是由于SIGINT已经由read()的信号处理程序处理而使程序仍然静默终止。 ?

(我的实验表明是后一种情况。不确定)

1 个答案:

答案 0 :(得分:0)

  

似乎暗示某些系统调用具有自己的信号处理程序。

不,绝对不是。根据{{​​3}}手册页,当读取被信号中断时,它将返回EINTR。要实现此行为,您必须处理信号,即为其安装处理程序。如果您不处理就发送信号,则程序将终止。

现在假设您已经处理了SIGINT信号并在read(2)上阻止了程序时发送了SIGINT信号,那么根据安装信号处理程序的方式,可以观察到两种行为。

  1. 如果使用read(2)处理信号并且使用 SA_RESTART ,则根据sigaction(2)手册页,处理程序将执行并在信号处理程序返回后自动重新开始读取。
  2. 如果未使用 SA_RESTART 标志,则调用失败,并显示错误EINTR。

在两种情况下,程序都不会因为处理SIGINT而终止。

  

假设在程序启动时,我为SIGINT安装了一个信号处理程序,该处理程序将打印一条消息“收到SIGINT”。当read()处于阻塞状态并且我使用Ctrl + C时,程序将终止并显示该消息,还是由于read()的信号处理程序已经处理了SIGINT而使程序仍然以静默方式终止?

在两种情况下程序都不会终止。处理程序消息“已收到SIGINT”将被打印,程序将继续执行。