☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

禁用 signal 函数

15.4 ID_forbidSignalFunction
目录 › next › previous

signal 函数具有一定的局限性,且各平台实现差异较大。

示例:

#include <signal.h>

void handler(int signum) {     // #1
    signal(signum, handler);   // #2, non-compliant, race condition
    ....
}

设例中 handler 是某种信号的处理函数。在某些平台上,signal 指定的函数只能被执行一次,所以需要在 handler 中再次调用 signal 指定处理函数,但如果程序在运行到 #1 和 #2 之间时收到同样的信号,会执行不符合预期的默认处理函数,这是一种竞态条件;而在另一些平台上,signal 指定的函数会一直有效,handler 再次调用 signal 是多余的。

与 signal 函数相似的 sigaction 函数不存在这些问题,也可提供更多的功能,但要注意该函数尚未在语言标准中定义。

如果条件允许,也可以使用 sigwait、sigwaitinfo 等函数同步地处理信号,如:

sigset_t ss;
sigemptyset(&ss);
sigaddset(&ss, SIGINT);
sigprocmask(SIG_BLOCK, &ss, NULL);
while (1) {
    int signum = sigwaitinfo(&ss, NULL);   // Wait for signals
    if (signum == SIGINT) {
        ....                  // Handle the signal
    }
}

例中 sigwaitinfo 函数在没有信号到达时会阻塞,否则返回相应的信号值,这样可以同步地处理信号,避免了异步信号处理需要面对的数据竞争等问题,也使代码具有更清晰的静态结构。

相关

ID_signalInMultiThreading ID_implementationDefinedFunction

依据

ISO/IEC 9899:1999 7.14.1.1(3)-implementation ISO/IEC 9899:2011 7.14.1.1(3)-implementation ISO/IEC 9899:2011 7.14.1.1(7)-undefined

参考

MISRA C 2012 21.5 MISRA C++ 2008 18-7-1 SEI CERT SIG01-C SEI CERT SIG34-C
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.