Linux 进程是否可以阻止外部信号但接受来自其自身进程的信号?

问题描述 投票:0回答:3

我正在尝试设置一个 Linux 进程,它阻止从

SIGTERM
命令(或任何其他进程)发送的
kill
,但允许从其内部发送
SIGTERM
(通过
kill(2)
系统调用)。

可能吗?

这是我写的一个示例程序,但是它

SIG_BLOCKS
外部和内部信号,所以它不做我想要的:

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

int main(int argc, char **argv)
{
  sigset_t sigs;

  sigemptyset(&sigs);
  sigaddset(&sigs, SIGTERM);
  sigprocmask(SIG_BLOCK, &sigs, 0);

  printf("Sleeping 30 secs, try killing me! (pid: %d)\n", getpid());
  sleep(30);
  printf("About to call kill\n");
  kill(getpid(), SIGTERM);
  printf("This never happens!\n");

  return 1;
}

输出为:

Sleeping 30 secs, try killing me! (pid: 29416)
About to call kill
This never happens!

但应该是:

Sleeping 30 secs, try killing me! (pid: 29416)
About to call kill

因为进程应该通过

kill(getpid(), SIGTERM)
从内部被杀死。

linux process signals
3个回答
4
投票

不确定这是否是您想要的,但是您可以使用带有

sigaction
标志的
SA_SIGINFO
设置信号处理程序,让您的
SIGTERM
处理程序仅在
_exit
是您的 PID
 时调用 
siginfo.si_pid


0
投票

根据我的测试,如果你不屏蔽信号。你可以看到预期的行为。

但是如果你阻止了信号,kill 将返回值 0,并且由于程序继续执行,它会打印该行并退出。我正在使用 ubuntu 12.04LTS 进行测试。


0
投票

我的回答是根据您的评论:

这是我想和朋友解决的理论问题。他说如果一个外部进程不能杀死一个进程,那么一个进程也不能杀死自己。

有可能阻止信号并仍然自杀。使用

abort()
https://man7.org/linux/man-pages/man3/abort.3.html):

abort()函数首先解除对SIGABRT信号的阻塞,然后 为调用进程引发该信号(就像 raise(3) 被称为)。这导致异常终止 除非捕捉到 SIGABRT 信号并且信号 处理程序不返回(请参阅 longjmp(3))。

如果 SIGABRT 信号被忽略,或者被处理程序捕获 返回,abort() 函数仍将终止进程。 它通过恢复 SIGABRT 和 然后第二次发出信号。

© www.soinside.com 2019 - 2024. All rights reserved.