#endif
p |void |setdefout |NULLOK GV* gv
Ap |HEK* |share_hek |NN const char* str|I32 len|U32 hash
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+np |Signal_t |sighandler |int sig|...
+Anp |Signal_t |csighandler |int sig|...
+#else
np |Signal_t |sighandler |int sig
Anp |Signal_t |csighandler |int sig
+#endif
Ap |SV** |stack_grow |NN SV** sp|NN SV**p|int n
ApR |I32 |start_subparse |I32 is_format|U32 flags
p |void |sub_crush_depth|NN CV* cv
#define setdefout Perl_setdefout
#endif
#define share_hek Perl_share_hek
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
#ifdef PERL_CORE
#define sighandler Perl_sighandler
#endif
#define csighandler Perl_csighandler
+#else
+#ifdef PERL_CORE
+#define sighandler Perl_sighandler
+#endif
+#define csighandler Perl_csighandler
+#endif
#define stack_grow Perl_stack_grow
#define start_subparse Perl_start_subparse
#ifdef PERL_CORE
#define setdefout(a) Perl_setdefout(aTHX_ a)
#endif
#define share_hek(a,b,c) Perl_share_hek(aTHX_ a,b,c)
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+#ifdef PERL_CORE
+#endif
+#else
#ifdef PERL_CORE
#define sighandler Perl_sighandler
#endif
#define csighandler Perl_csighandler
+#endif
#define stack_grow(a,b,c) Perl_stack_grow(aTHX_ a,b,c)
#define start_subparse(a,b) Perl_start_subparse(aTHX_ a,b)
#ifdef PERL_CORE
SIGHUP), not a string (like "SIGHUP"), though Perl does try hard
to understand you.
+If you use the SA_SIGINFO flag, the signal handler will in addition to
+the first argument, the signal name, also receive a second argument, a
+hash reference, inside which are the following keys with the following
+semantics, as defined by POSIX/SUSv3:
+
+ signo the signal number
+ errno the error number
+ code if this is zero or less, the signal was sent by
+ a user process and the uid and pid make sense,
+ otherwise the signal was sent by the kernel
+ pid the process id generating the signal
+ uid the uid of the process id generating the signal
+ status exit value or signal for SIGCHLD
+ band band event for SIGPOLL
+
+A third argument is also passed to the handler, which contains a copy
+of the raw binary contents of the siginfo structure: if a system has
+some non-POSIX fields, this third argument is where to unpack() them
+from.
+
+Note that not all siginfo values make sense simultaneously (some are
+valid only for certain signals, for example), and not all values make
+sense from Perl perspective, you should to consult your system's
+C<sigaction> and possibly also C<siginfo> documentation.
+
=item siglongjmp
siglongjmp() is C-specific: use L<perlfunc/die> instead.
}
}
-use Test::More tests => 29;
+use Test::More tests => 30;
use strict;
use vars qw/$bad $bad7 $ok10 $bad18 $ok/;
kill 'SIGRTMIN', $$;
is($sigrtmin, 1, "SIGRTMIN handler works");
}
+
+SKIP: {
+ eval 'use POSIX qw(SA_SIGINFO); SA_SIGINFO';
+ skip("no SA_SIGINFO", 1) if $@;
+ sub hiphup {
+ is($_[1]->{pid}, $$, "SA_SIGINFO got right pid");
+ }
+ my $act = POSIX::SigAction->new('hiphup', 0, SA_SIGINFO);
+ sigaction(SIGHUP, $act);
+ kill 'HUP', $$;
+}
+
Perl_screaminstr
Perl_share_hek
Perl_csighandler
+Perl_csighandler
Perl_stack_grow
Perl_start_subparse
Perl_sv_2bool
#include "perlio.h"
#ifndef Sighandler_t
+# if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+typedef Signal_t (*Sighandler_t) (int, ...);
+# else
typedef Signal_t (*Sighandler_t) (int);
+# endif
#endif
#if defined(PERL_IMPLICIT_SYS)
# include <sys/pstat.h>
#endif
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+Signal_t Perl_csighandler(int sig, ...);
+#else
Signal_t Perl_csighandler(int sig);
+#endif
#ifdef __Lynx__
/* Missing protos on LynxOS */
if (PL_sig_handlers_initted && PL_sig_defaulting[i]) sigstate = SIG_DFL;
#endif
/* cache state so we don't fetch it again */
- if(sigstate == SIG_IGN)
+ if(sigstate == (Sighandler_t) SIG_IGN)
sv_setpv(sv,"IGNORE");
else
sv_setsv(sv,&PL_sv_undef);
PL_sig_defaulting[i] = 1;
(void)rsignal(i, PL_csighandlerp);
#else
- (void)rsignal(i, SIG_DFL);
+ (void)rsignal(i, (Sighandler_t) SIG_DFL);
#endif
if(PL_psig_name[i]) {
SvREFCNT_dec(PL_psig_name[i]);
}
Signal_t
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+Perl_csighandler(int sig, ...)
+#else
Perl_csighandler(int sig)
+#endif
{
#ifdef PERL_GET_SIG_CONTEXT
dTHXa(PERL_GET_SIG_CONTEXT);
PL_sig_ignoring[i] = 1;
(void)rsignal(i, PL_csighandlerp);
#else
- (void)rsignal(i, SIG_IGN);
+ (void)rsignal(i, (Sighandler_t) SIG_IGN);
#endif
}
}
(void)rsignal(i, PL_csighandlerp);
}
#else
- (void)rsignal(i, SIG_DFL);
+ (void)rsignal(i, (Sighandler_t) SIG_DFL);
#endif
}
else {
}
Signal_t
-Perl_sighandler(int sig)
+Perl_sighandler(int sig, ...)
{
#ifdef PERL_GET_SIG_CONTEXT
dTHXa(PERL_GET_SIG_CONTEXT);
PUSHSTACKi(PERLSI_SIGNAL);
PUSHMARK(SP);
PUSHs(sv);
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+ {
+ struct sigaction oact;
+
+ if (sigaction(sig, 0, &oact) == 0 && oact.sa_flags & SA_SIGINFO) {
+ siginfo_t *sip;
+ va_list args;
+
+ va_start(args, sig);
+ sip = (siginfo_t*)va_arg(args, siginfo_t*);
+ if (sip) {
+ HV *sih = newHV();
+ SV *rv = newRV_noinc((SV*)sih);
+ /* The siginfo fields signo, code, errno, pid, uid,
+ * addr, status, and band are defined by POSIX/SUSv3. */
+ hv_store(sih, "signo", 5, newSViv(sip->si_signo), 0);
+ hv_store(sih, "code", 4, newSViv(sip->si_code), 0);
+ hv_store(sih, "errno", 5, newSViv(sip->si_errno), 0);
+ hv_store(sih, "uid", 3, newSViv(sip->si_uid), 0);
+ hv_store(sih, "pid", 3, newSViv(sip->si_pid), 0);
+ hv_store(sih, "addr", 4, newSVuv(PTR2UV(sip->si_addr)), 0);
+ hv_store(sih, "status", 6, newSViv(sip->si_status), 0);
+ hv_store(sih, "band", 4, newSViv(sip->si_band), 0);
+ EXTEND(SP, 2);
+ PUSHs((SV*)rv);
+ PUSHs(newSVpv((void*)sip, sizeof(*sip)));
+ }
+ }
+ }
+#endif
PUTBACK;
call_sv((SV*)cv, G_DISCARD|G_EVAL);
SvREFCNT(&PL_sv_placeholder) = (~(U32)0)/2;
}
- PL_sighandlerp = Perl_sighandler;
+ PL_sighandlerp = (Sighandler_t) Perl_sighandler;
PL_pidstatus = newHV();
}
# define SIGCHLD SIGCLD
#endif
Sighandler_t sigstate = rsignal_state(SIGCHLD);
- if (sigstate == SIG_IGN) {
+ if (sigstate == (Sighandler_t) SIG_IGN) {
if (ckWARN(WARN_SIGNAL))
Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
"Can't ignore signal CHLD, forcing to default");
# define PERL_FPU_INIT fpsetmask(0);
# else
# if defined(SIGFPE) && defined(SIG_IGN) && !defined(PERL_MICRO)
-# define PERL_FPU_INIT PL_sigfpe_saved = signal(SIGFPE, SIG_IGN);
+# define PERL_FPU_INIT PL_sigfpe_saved = (Sighandler_t) signal(SIGFPE, SIG_IGN);
# define PERL_FPU_PRE_EXEC { Sigsave_t xfpe; rsignal_save(SIGFPE, PL_sigfpe_saved, &xfpe);
# define PERL_FPU_POST_EXEC rsignal_restore(SIGFPE, &xfpe); }
# else
if (did_pipes)
PerlLIO_close(pp[1]);
#ifndef PERL_MICRO
- rsignal_save(SIGINT, SIG_IGN, &ihand);
- rsignal_save(SIGQUIT, SIG_IGN, &qhand);
+ rsignal_save(SIGINT, (Sighandler_t) SIG_IGN, &ihand);
+ rsignal_save(SIGQUIT, (Sighandler_t) SIG_IGN, &qhand);
#endif
do {
result = wait4pid(childpid, &status, 0);
PERL_CALLCONV HEK* Perl_share_hek(pTHX_ const char* str, I32 len, U32 hash)
__attribute__nonnull__(pTHX_1);
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+PERL_CALLCONV Signal_t Perl_sighandler(int sig, ...);
+PERL_CALLCONV Signal_t Perl_csighandler(int sig, ...);
+#else
PERL_CALLCONV Signal_t Perl_sighandler(int sig);
PERL_CALLCONV Signal_t Perl_csighandler(int sig);
+#endif
PERL_CALLCONV SV** Perl_stack_grow(pTHX_ SV** sp, SV**p, int n)
__attribute__nonnull__(pTHX_1)
__attribute__nonnull__(pTHX_2);
#ifdef USE_ITHREADS
/* only "parent" interpreter can diddle signals */
if (PL_curinterp != aTHX)
- return SIG_ERR;
+ return (Sighandler_t) SIG_ERR;
#endif
- act.sa_handler = handler;
+ act.sa_handler = (void(*)(int))handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
#endif
#if defined(SA_NOCLDWAIT) && !defined(BSDish) /* See [perl #18849] */
- if (signo == SIGCHLD && handler == (Sighandler_t)SIG_IGN)
+ if (signo == SIGCHLD && handler == (Sighandler_t) SIG_IGN)
act.sa_flags |= SA_NOCLDWAIT;
#endif
if (sigaction(signo, &act, &oact) == -1)
- return SIG_ERR;
+ return (Sighandler_t) SIG_ERR;
else
- return oact.sa_handler;
+ return (Sighandler_t) oact.sa_handler;
}
Sighandler_t
struct sigaction oact;
if (sigaction(signo, (struct sigaction *)NULL, &oact) == -1)
- return SIG_ERR;
+ return (Sighandler_t) SIG_ERR;
else
- return oact.sa_handler;
+ return (Sighandler_t) oact.sa_handler;
}
int
return -1;
#endif
- act.sa_handler = handler;
+ act.sa_handler = (void(*)(int))handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
#endif
#if defined(SA_NOCLDWAIT) && !defined(BSDish) /* See [perl #18849] */
- if (signo == SIGCHLD && handler == (Sighandler_t)SIG_IGN)
+ if (signo == SIGCHLD && handler == (Sighandler_t) SIG_IGN)
act.sa_flags |= SA_NOCLDWAIT;
#endif
return sigaction(signo, &act, save);
#if defined(USE_ITHREADS) && !defined(WIN32)
/* only "parent" interpreter can diddle signals */
if (PL_curinterp != aTHX)
- return SIG_ERR;
+ return (Sighandler_t) SIG_ERR;
#endif
return PerlProc_signal(signo, handler);
#if defined(USE_ITHREADS) && !defined(WIN32)
/* only "parent" interpreter can diddle signals */
if (PL_curinterp != aTHX)
- return SIG_ERR;
+ return (Sighandler_t) SIG_ERR;
#endif
PL_sig_trapped = 0;
return -1;
#endif
*save = PerlProc_signal(signo, handler);
- return (*save == SIG_ERR) ? -1 : 0;
+ return (*save == (Sighandler_t) SIG_ERR) ? -1 : 0;
}
int
if (PL_curinterp != aTHX)
return -1;
#endif
- return (PerlProc_signal(signo, *save) == SIG_ERR) ? -1 : 0;
+ return (PerlProc_signal(signo, *save) == (Sighandler_t) SIG_ERR) ? -1 : 0;
}
#endif /* !HAS_SIGACTION */
if(PerlProc_kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */
#endif
#ifndef PERL_MICRO
- rsignal_save(SIGHUP, SIG_IGN, &hstat);
- rsignal_save(SIGINT, SIG_IGN, &istat);
- rsignal_save(SIGQUIT, SIG_IGN, &qstat);
+ rsignal_save(SIGHUP, (Sighandler_t) SIG_IGN, &hstat);
+ rsignal_save(SIGINT, (Sighandler_t) SIG_IGN, &istat);
+ rsignal_save(SIGQUIT, (Sighandler_t) SIG_IGN, &qstat);
#endif
do {
pid2 = wait4pid(pid, &status, 0);