Как в Perl 5 я могу получить pid процесса, который отправил мне сигнал?

В 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

при отправке SIGTERM из процесса 31985.

Я могу написать аналогичный код Perl 5, используя POSIX :: sigaction :

#!/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 каким-то образом испортить интерпретатор?

38
задан Chas. Owens 9 June 2011 в 16:47
поделиться