sighandler
(встречается в mg.c
) - это оболочка вокруг подпрограммы обработчика сигналов Perl. Как видите, он способен отправлять нужную информацию в подпрограмму обработчика сигналов Perl.
#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
{
struct sigaction oact;
if (sigaction(sig, 0, &oact) == 0 && oact.sa_flags & SA_SIGINFO) {
if (sip) {
HV *sih = newHV();
SV *rv = newRV_noinc(MUTABLE_SV(sih));
/* The siginfo fields signo, code, errno, pid, uid,
* addr, status, and band are defined by POSIX/SUSv3. */
(void)hv_stores(sih, "signo", newSViv(sip->si_signo));
(void)hv_stores(sih, "code", newSViv(sip->si_code));
#if 0 /* XXX TODO: Configure scan for the existence of these, but even that does not help if the SA_SIGINFO is not implemented according to the spec. */
hv_stores(sih, "errno", newSViv(sip->si_errno));
hv_stores(sih, "status", newSViv(sip->si_status));
hv_stores(sih, "uid", newSViv(sip->si_uid));
hv_stores(sih, "pid", newSViv(sip->si_pid));
hv_stores(sih, "addr", newSVuv(PTR2UV(sip->si_addr)));
hv_stores(sih, "band", newSViv(sip->si_band));
#endif
EXTEND(SP, 2);
PUSHs(rv);
mPUSHp((char *)sip, sizeof(*sip));
}
}
}
}
Требуемая информация будет указана в последнем параметре, хотя вам придется распаковать *sip
на стороне Perl. Загвоздка в том, что приведенный выше код не получает упражнения. В частности, sip
всегда NULL
.
При небезопасных сигналах sighandler
вызывается из csighandler
, обработчика сигналов уровня C в Perl. В настоящее время он не передает соответствующую информацию signalhandler
, но это легко исправить.
-Perl_csighandler(int sig, siginfo_t *sip PERL_UNUSED_DECL, void *uap PERL_UNUSED_DECL)
+Perl_csighandler(int sig, siginfo_t *sip, void *uap PERL_UNUSED_DECL)
- (*PL_sighandlerp)(sig, NULL, NULL);
+ (*PL_sighandlerp)(sig, sip, NULL);
Пример прогона:
$ PERL_SIGNALS=unsafe ./perl -Ilib a.pl
31213
caught signal
$VAR1 = [
'TERM',
{
'code' => 0,
'signo' => 15
},
'...*sip as "packed/binary" string...'
];
При безопасных сигналах sighandler
вызывается с despatch_signals
(sic) через PERL_ASYNC_CHECK
. К сожалению, *sip
, ранее полученный csighandler
, больше не доступен. Чтобы это исправить, csighandler
придется поставить в очередь копию *sip
для despatch_signals
для извлечения.