【发布时间】:2011-06-09 16:47:23
【问题描述】:
在 C 中,我可以说
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int continue_running = 1;
void handler(int signal, siginfo_t* info, void* data) {
printf("got signal %d from process %d running as user %d\n",
signal, info->si_pid, info->si_uid);
continue_running = 0;
}
int main(int argc, char** argv) {
struct sigaction sa;
sigset_t mask;
sigemptyset(&mask);
sa.sa_sigaction = &handler;
sa.sa_mask = mask;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
printf("pid is %d\n", getpid());
while (continue_running) { sleep(1); };
return 0;
}
这会打印出类似的东西
pid is 31980
got signal 15 from process 31985 running as user 1000
当从进程 31985 发送SIGTERM 时。
我可以使用POSIX::sigaction 编写类似的 Perl 5 代码:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX;
use Data::Dumper;
my $sigset = POSIX::SigSet->new;
$sigset->emptyset;
my $sa = POSIX::SigAction->new(
sub { print "caught signal\n" . Dumper \@_; $a = 0 },
$sigset,
);
$sa->flags(POSIX::SA_SIGINFO);
$sa->safe(1); #defer the signal until we are in a safe place in the intrepeter
POSIX::sigaction(POSIX::SIGTERM, $sa);
print "$$\n";
$a = 1;
sleep 1 while $a;
但处理程序仍然只接收一个参数(信号)。我怎样才能获得siginfo_t 结构?是否必须编写我自己的 XS 代码来设置自己的处理程序,然后将信息传递给 Perl 回调?在 XS 中编写我自己的处理程序会以某种方式搞砸解释器吗?
【问题讨论】:
-
我希望我能多次对此表示赞同。这是一个非常棒的问题。您是否查看过 POSIX 模块中现有的 XS 代码?我没有,但我敢打赌这就是你问题的答案所在。至于搞砸解释器,你知道解释器循环的“安全信号”变化吗?
-
@tchrist 是的,我知道在 5.8 行的某个时间点发生的变化。这就是我所担心的。我不知道如何与这些东西的工作方式交互。阅读 POSIX XS 的东西可能是要走的路。我希望有人已经为我完成了艰苦的工作。
-
如果@tchrist 喜欢它,那对我来说已经足够了:+1