使用未初始化的sigaction结构调用sigaction?

时间:2013-12-24 05:19:42

标签: c unix signals

我在一些代码中看到了以下用法:

struct sigaction term_handler;  // global variable without initialization
...
sigaction(SIGTERM, &term_handler, NULL);  // install uninitialized sigaction for SIGTERM

这段代码似乎分配了一个sigaction struct,让所有成员都为null或0,这让我很困惑。 如果触发SIGTERM会发生什么?

我使用以下代码进行了测试:

struct sigaction int_handler;
int main(int argc, char **argv) {
    sigaction(SIGINT, &int_handler, NULL);
    while(1) {}
    return 0;
}

并使用“kill -2”进行测试,该过程无论如何都被杀死了。这是否意味着该过程采取了与其信号相关的默认操作?

1 个答案:

答案 0 :(得分:1)

SIG_DFL在我的系统上为零,所以如果你有一个类似的系统,那么它会导致SIGTERM采用它的默认行为。

除非先前修改了SIGTERM的行为(包括在程序exec之前),否则这无效。如果是,则恢复默认行为(终止进程)。


以下演示:

a.c

#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

static struct sigaction term_handler;

int main(int argv, char* argc[]) {
   if (argv && strcmp(argc[0], "1") == 0)
      sigaction(SIGTERM, &term_handler, NULL);

   kill(getpid(), SIGTERM);
   sleep(2);
   return 0;
}

harness.c

#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

void test(const char* arg) {
   pid_t pid = fork();
   if (pid) {
      int status;
      waitpid(pid, &status, 0);
      printf("%d\n", WIFSIGNALED(status) ? WTERMSIG(status) : 0);
   } else {
      struct sigaction term_handler;
      char * const newargv[]    = { "./a", arg, NULL };
      char * const newenviron[] = { NULL };

      term_handler.sa_handler = SIG_IGN;
      sigaction(SIGTERM, &term_handler, NULL);

      execve("./a", newargv, newenviron);
   }
}

int main() {
   test("0");
   test("1");
   return 0;
}

输出:

$ ./harness
0     # Without sigaction in child, wasn't killed by a signal
15    # With    sigaction in child, was killed by TERM
相关问题