信号() 覆盖其他信号处理程序

signal() overwriting other signal handlers

本文关键字:信号处理 程序 其他 覆盖 信号      更新时间:2023-10-16

signal()函数是否会覆盖进程可能已设置的其他信号调用? 即,如果进程设置了SIGINT处理程序,并且 DLL 调用signal(SIGINT,xxx)来处理自己的终止代码,则原始SIGINT处理程序是否被禁用?

signal()调用:

  1. 安装指定为新信号处理程序的处理程序,并且
  2. 告诉您旧的处理程序是什么。

将调用新处理程序而不是旧处理程序。 如果要链接它们,则需要执行以下操作:

    typedef void (*Handler)(int signum);
    static Handler old_int_handler = SIG_IGN;
    static void int_handler(int signum)    /* New signal handler */
    {
        /* ...do your signal handling... */
        if (old_int_handler != SIG_IGN && old_int_handler != SIG_DFL)
            (*old_int_handler)(signum);
    }
    static void set_int_handler(void)  /* Install new handler */
    {
        Handler old = signal(SIGINT, SIG_IGN);
        if (old != SIG_IGN)
        {
            old_int_handler = old;
            signal(SIGINT, int_handler);
        }
    }
    static void rst_int_handler(void)    /* Restore original handler */
    {
        Handler old = signal(SIGINT, SIG_IGN);
        if (old == int_handler)
        {
            signal(SIGINT, old_int_handler);
            old_int_handler = SIG_IGN;
        }
    }
    void another_function()
    {
        /* ... */
        set_int_handler();
        /* ... */
        rst_int_handler();
        /* ... */
    }

如果中断被忽略,这会使它们被忽略。 如果中断由用户定义的中断处理程序处理,则这将调用信号处理代码和原始信号处理代码。

请注意,Christian.K 关于不处理 DLL(共享库(中的信号的建议也是相关且有效的。 上面的描述假设您决定忽略该建议。

这不是对问题的"字面"回答,而是建议:您不应该在 DLL 中执行此操作。

对于使用 DLL 的应用程序来说,这是出乎意料的,而且通常很烦人。DLL 应该(通常(是"被动的",并且只提供供应用程序调用的函数。

因此,而是从您的 DLL 中提供一个公共函数,应用程序需要调用该函数,例如 MyDllCleanup() .然后让应用程序决定如何调用该函数(通过信号处理程序或其他(。顺便说一句,初始化也是如此:而不是依赖DllMain(或 _init/_fini 在 UNIX 上libdl(为应用程序调用提供显式函数。