我在一些代码中看到了以下用法:
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”进行测试,该过程无论如何都被杀死了。这是否意味着该过程采取了与其信号相关的默认操作?
答案 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