次のコードがSIGINT信号のロックを解除できない理由

次のコードがSIGINT信号のロックを解除できない理由

私はLinux Signalsを試しています。私は次のようなシナリオを作成しました。

  1. 最初はすべてのSIGINT信号をブロックしますsigprocmask()
  2. 発信者がシグナルSIGUSR1を送信すると、SIGINT残りのプロセス寿命中にブロックが解除されます。

ただし、最初のステップは正常に実装されましたが、プロセスマスクのロック解除(または変更)はできませんでしたsigprocmask()

私は何が間違っていましたか?

#include<stdio.h>
#include<signal.h>
#include<stdlib.h>

sigset_t block_list, unblock_list;

void sigint_handler(int sig)
{
        printf("Ouch!!\n");
}

void sigusr1_handler(int sig)
{
        sigemptyset(&unblock_list);
        sigprocmask(SIG_SETMASK, &unblock_list, NULL);
}


int main(int argc, char **argv)
{
    int count;

    signal(SIGINT, &sigint_handler);
    signal(SIGUSR1, &sigusr1_handler);

    sigemptyset(&block_list);
    sigaddset(&block_list, SIGINT);
    sigprocmask(SIG_SETMASK, &block_list, NULL);

    for(count=1; ;++count)
    {
            printf("Process id: %ld\t%d\n", (long)getpid(), count);
            sleep(4);
    }

    exit(EXIT_SUCCESS);
    }

$kill -n SIGINT <pid>

$kill -n SIGUSER1 <pid> //This call should unblock sigint_handler() for rest of the process life, but it is only unblocking for one time. Everytime I have call $kill -n SIGUSER1 <pid> to unblock SIGINT.

注:単純化のためにエラー処理が削除されました。

答え1

シグナルハンドラから返された後、カーネルはシグナルマスクを復元します。これは次のために発生します。基準:

取り付けられたシグナルキャッチ機能内でスレッドのシグナルマスクが変更された場合は、シグナルキャッチsigaction()機能から戻るとシグナルマスクを復元して変更を上書きします(参照sigaction())。信号キャプチャがインストールされていると、signal()これが発生するかどうかはわかりません。

Linuxではsignal(2)廃止互換ラッパーsigaction(2)、これは使用時にも発生しますsignal(2)

関連情報