使用标准实用程序解锁信号

使用标准实用程序解锁信号

如何使用标准实用程序在 bash 中解锁信号?

在过去的几周里,我注意到 Macos 上的 shell 挂起(例如,yes | head不终止)。深入研究后发现,我创建的所有新 shell 都阻止了相当大的信号集。 (因此,在前面的示例中,yes正在阻止 SIGPIPE。工具编写者的警示;检查 、 等的返回值writeprintf

这种行为有点烦人,但现在我知道了问题所在,解决起来很容易。但还不够容易。 trap似乎没有达到目的(我正在使用 bash)。我可以向我的 bash 启动添加什么来使用标准实用程序清除一组被阻止的信号?我添加了以下内容,感觉非常混乱:

if { ! show-mask && which unblock; } > /dev/null 2>&1; then
        exec unblock bash
fi

其中 show-mask 和 unblock 是从以下版本构建的:

$ cat show-mask.c 
/* Show the current set of blocked signals */    
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char **argv)
{
        struct sigaction act = {{0}};
        sigset_t old;

        if(sigprocmask(SIG_SETMASK, NULL, &old)) {
                perror("sigprocmask");
                return EXIT_FAILURE;
        }
        printf("mask: %x\n", old);

        return !!old;
}
$ cat unblock.c
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

void
set_default(struct sigaction *act, int s)
{
        if(sigaction(s, act, NULL)) {
                perror("sigaction");
                exit(EXIT_FAILURE);
        }
}

int
main(int argc, char **argv)
{
        struct sigaction act = {{0}};
        sigset_t new;

        sigemptyset(&new);

        if(sigprocmask(SIG_SETMASK, &new, NULL)) {
                perror("sigprocmask");
                return EXIT_FAILURE;
        }

        act.sa_handler = SIG_DFL;
        set_default(&act, SIGPIPE);
        set_default(&act, SIGINT);
        set_default(&act, SIGTERM);

        execvp(argv[1], argv+1);

        perror("execlp");
        return EXIT_FAILURE;
}

相关内容