summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xConfigure67
-rw-r--r--Cross/config.sh-arm-linux7
-rw-r--r--NetWare/config.wc7
-rw-r--r--Porting/config.sh7
-rwxr-xr-xconfig_h.SH42
-rw-r--r--configure.com14
-rw-r--r--ext/POSIX/t/sigaction.t31
-rw-r--r--mg.c28
-rw-r--r--plan9/config_sh.sample7
-rw-r--r--pod/perldelta.pod7
-rw-r--r--symbian/config.sh7
-rw-r--r--uconfig.h46
-rw-r--r--uconfig.sh7
-rw-r--r--uconfig64.sh7
-rw-r--r--win32/config.ce7
-rw-r--r--win32/config.gc7
-rw-r--r--win32/config.vc7
17 files changed, 291 insertions, 14 deletions
diff --git a/Configure b/Configure
index d5a7de31cf..3d65fd2428 100755
--- a/Configure
+++ b/Configure
@@ -785,6 +785,13 @@ d_shmctl=''
d_shmdt=''
d_shmget=''
d_sigaction=''
+d_siginfo_si_errno=''
+d_siginfo_si_pid=''
+d_siginfo_si_uid=''
+d_siginfo_si_addr=''
+d_siginfo_si_status=''
+d_siginfo_si_band=''
+d_siginfo_si_value=''
d_signbit=''
d_sigprocmask=''
d_sigsetjmp=''
@@ -10758,6 +10765,25 @@ set $varname;
eval $setvar;
$rm_try'
+: Define hasfield_t macro for Configure internal use
+hasfield_t='varname=$1; struct=$2; type=$3; field=$4; shift; shift; shift; shift;
+while $test $# -ge 2; do
+ case "$1" in
+ $define) echo "#include <$2>";;
+ esac ;
+ shift 2;
+done > try.c;
+echo "int main () { $struct foo; $type bar = foo.$field; }" >> try.c;
+set try;
+if eval $compile; then
+ val="$define";
+else
+ val="$undef";
+fi;
+set $varname;
+eval $setvar;
+$rm_try'
+
: see if we should include time.h, sys/time.h, or both
echo " "
if test "X$timeincl" = X; then
@@ -22697,6 +22723,40 @@ case "$uidsign" in
;;
esac
+: see what siginfo fields we have
+case "$d_sigaction" in
+"$define")
+ echo "Checking if your siginfo_t has si_errno field...">&4
+ set d_siginfo_si_errno siginfo_t int si_errno $d_sigaction signal.h
+ eval $hasfield_t;
+
+ echo "Checking if your siginfo_t has si_pid field...">&4
+ set d_siginfo_si_pid siginfo_t $pidtype si_pid $d_sigaction signal.h
+ eval $hasfield_t;
+
+ echo "Checking if your siginfo_t has si_uid field...">&4
+ set d_siginfo_si_uid siginfo_t $uidtype si_uid $d_sigaction signal.h
+ eval $hasfield_t;
+
+ echo "Checking if your siginfo_t has si_addr field...">&4
+ set d_siginfo_si_addr siginfo_t "void *" si_addr $d_sigaction signal.h
+ eval $hasfield_t;
+
+ echo "Checking if your siginfo_t has si_status field...">&4
+ set d_siginfo_si_status siginfo_t int si_status $d_sigaction signal.h
+ eval $hasfield_t;
+
+ echo "Checking if your siginfo_t has si_band field...">&4
+ set d_siginfo_si_band siginfo_t long si_band $d_sigaction signal.h
+ eval $hasfield_t;
+
+ echo "Checking if your siginfo_t has si_value field...">&4
+ set d_siginfo_si_value siginfo_t "union sigval" si_value $d_sigaction signal.h
+ eval $hasfield_t;
+
+ ;;
+esac
+
: Determine if we can use sysctl with KERN_PROC_PATHNAME to find executing program
echo " "
echo "Determining whether we can use sysctl with KERN_PROC_PATHNAME to find executing program..." >&4
@@ -24523,6 +24583,13 @@ d_shmctl='$d_shmctl'
d_shmdt='$d_shmdt'
d_shmget='$d_shmget'
d_sigaction='$d_sigaction'
+d_siginfo_si_errno='$d_siginfo_si_errno'
+d_siginfo_si_pid='$d_siginfo_si_pid'
+d_siginfo_si_uid='$d_siginfo_si_uid'
+d_siginfo_si_addr='$d_siginfo_si_addr'
+d_siginfo_si_status='$d_siginfo_si_status'
+d_siginfo_si_band='$d_siginfo_si_band'
+d_siginfo_si_value='$d_siginfo_si_value'
d_signbit='$d_signbit'
d_sigprocmask='$d_sigprocmask'
d_sigsetjmp='$d_sigsetjmp'
diff --git a/Cross/config.sh-arm-linux b/Cross/config.sh-arm-linux
index ea455bd578..776d705e6d 100644
--- a/Cross/config.sh-arm-linux
+++ b/Cross/config.sh-arm-linux
@@ -500,6 +500,13 @@ d_shmctl='define'
d_shmdt='define'
d_shmget='define'
d_sigaction='define'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='define'
d_sigprocmask='define'
d_sigsetjmp='define'
diff --git a/NetWare/config.wc b/NetWare/config.wc
index d414e984a7..cc34a801cb 100644
--- a/NetWare/config.wc
+++ b/NetWare/config.wc
@@ -490,6 +490,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='undef'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='undef'
d_sigprocmask='undef'
d_sigsetjmp='undef'
diff --git a/Porting/config.sh b/Porting/config.sh
index bd7ae1df4d..a8638b7e2a 100644
--- a/Porting/config.sh
+++ b/Porting/config.sh
@@ -511,6 +511,13 @@ d_shmctl='define'
d_shmdt='define'
d_shmget='define'
d_sigaction='define'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='define'
d_sigprocmask='define'
d_sigsetjmp='define'
diff --git a/config_h.SH b/config_h.SH
index e083524455..9dd2c095a0 100755
--- a/config_h.SH
+++ b/config_h.SH
@@ -2327,6 +2327,48 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
*/
#$d_sigaction HAS_SIGACTION /**/
+/* HAS_SIGINFO_SI_ERRNO:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_errno member
+ */
+#$d_siginfo_si_errno HAS_SIGINFO_SI_ERRNO /**/
+
+/* HAS_SIGINFO_SI_PID:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_pid member
+ */
+#$d_siginfo_si_pid HAS_SIGINFO_SI_PID /**/
+
+/* HAS_SIGINFO_SI_UID:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_uid member
+ */
+#$d_siginfo_si_uid HAS_SIGINFO_SI_UID /**/
+
+/* HAS_SIGINFO_SI_ADDR:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_addr member
+ */
+#$d_siginfo_si_addr HAS_SIGINFO_SI_ADDR /**/
+
+/* HAS_SIGINFO_SI_STATUS:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_status member
+ */
+#$d_siginfo_si_status HAS_SIGINFO_SI_STATUS /**/
+
+/* HAS_SIGINFO_SI_BAND:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_band member
+ */
+#$d_siginfo_si_band HAS_SIGINFO_SI_BAND /**/
+
+/* HAS_SIGINFO_SI_VALUE:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_value member
+ */
+#$d_siginfo_si_value HAS_SIGINFO_SI_VALUE /**/
+
/* HAS_SIGSETJMP:
* This variable indicates to the C program that the sigsetjmp()
* routine is available to save the calling process's registers
diff --git a/configure.com b/configure.com
index 2d674c5043..c138a6d4f4 100644
--- a/configure.com
+++ b/configure.com
@@ -5340,6 +5340,13 @@ $ d_clearenv="undef"
$ d_usleep="define"
$ d_setitimer="define"
$ d_sigaction="define"
+$ d_siginfo_si_addr="undef"
+$ d_siginfo_si_band="undef"
+$ d_siginfo_si_errno="undef"
+$ d_siginfo_si_pid="undef"
+$ d_siginfo_si_status="undef"
+$ d_siginfo_si_uid="undef"
+$ d_siginfo_si_value="undef"
$ d_sigprocmask="define"
$ d_truncate="define"
$ d_wait4="define"
@@ -6294,6 +6301,13 @@ $ WC "d_shmctl='" + d_shmctl + "'"
$ WC "d_shmdt='" + d_shmdt + "'"
$ WC "d_shmget='" + d_shmget + "'"
$ WC "d_sigaction='" + d_sigaction + "'"
+$ WC "d_siginfo_si_addr='" + d_siginfo_si_addr + "'"
+$ WC "d_siginfo_si_band='" + d_siginfo_si_band + "'"
+$ WC "d_siginfo_si_errno='" + d_siginfo_si_errno + "'"
+$ WC "d_siginfo_si_pid='" + d_siginfo_si_pid + "'"
+$ WC "d_siginfo_si_status='" + d_siginfo_si_status + "'"
+$ WC "d_siginfo_si_uid='" + d_siginfo_si_uid + "'"
+$ WC "d_siginfo_si_value='" + d_siginfo_si_value + "'"
$ WC "d_signbit='" + d_signbit + "'"
$ WC "d_sigprocmask='" + d_sigprocmask + "'"
$ WC "d_sigsetjmp='" + d_sigsetjmp + "'"
diff --git a/ext/POSIX/t/sigaction.t b/ext/POSIX/t/sigaction.t
index a0ad38450b..b282185ac7 100644
--- a/ext/POSIX/t/sigaction.t
+++ b/ext/POSIX/t/sigaction.t
@@ -11,7 +11,7 @@ BEGIN{
}
}
-use Test::More tests => 33;
+use Test::More tests => 36;
use strict;
use vars qw/$bad $bad7 $ok10 $bad18 $ok/;
@@ -191,12 +191,33 @@ SKIP: {
}
SKIP: {
+ my %siginfo = (
+ signo => SIGHUP,
+ pid => $$,
+ uid => $<,
+ );
+ my %opt_val = ( code => 'SI_USER' );
+ my %always = map +($_ => 1), qw(signo code);
+ my %skip = ( code => { darwin => "not set to SI_USER for kill()" } );
+ my $tests = keys %{{ %siginfo, %opt_val }};
eval 'use POSIX qw(SA_SIGINFO); SA_SIGINFO';
- skip("no SA_SIGINFO", 1) if $@;
- skip("SA_SIGINFO is broken on AIX 4.2", 1) if ($^O.$Config{osvers}) =~ m/^aix4\.2/;
- skip("SA_SIGINFO is broken on os390", 1) if ($^O.$Config{osvers}) =~ m/os390/;
+ skip("no SA_SIGINFO", $tests) if $@;
+ skip("SA_SIGINFO is broken on AIX 4.2", $tests) if ($^O.$Config{osvers}) =~ m/^aix4\.2/;
+ skip("SA_SIGINFO is broken on os390", $tests) if ($^O.$Config{osvers}) =~ m/os390/;
+ eval "use POSIX qw($opt_val{$_}); \$siginfo{$_} = $opt_val{$_}"
+ for keys %opt_val;
sub hiphup {
- is($_[1]->{signo}, SIGHUP, "SA_SIGINFO got right signal");
+ for my $field (sort keys %{{ %siginfo, %opt_val }}) {
+ SKIP: {
+ skip("siginfo_t has no $field field", 1)
+ unless %always{$field} or ($Config{"d_siginfo_si_$field"} || '') eq 'define';
+ skip("no constant defined for SA_SIGINFO $field value $opt_val{$field}", 1)
+ unless defined $siginfo{$field};
+ skip("SA_SIGINFO $field value is wrong on $^O: $skip{$field}{$^O}", 1)
+ if $skip{$field}{$^O};
+ is($_[1]->{$field}, $siginfo{$field}, "SA_SIGINFO got right $field")
+ }
+ }
}
my $act = POSIX::SigAction->new('hiphup', 0, SA_SIGINFO);
sigaction(SIGHUP, $act);
diff --git a/mg.c b/mg.c
index f8d8f33a3a..bb5cba104c 100644
--- a/mg.c
+++ b/mg.c
@@ -3340,13 +3340,27 @@ Perl_sighandler(int sig)
* 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));
+#ifdef HAS_SIGINFO_SI_ERRNO
+ (void)hv_stores(sih, "errno", newSViv(sip->si_errno));
+#endif
+#ifdef HAS_SIGINFO_SI_STATUS
+ (void)hv_stores(sih, "status", newSViv(sip->si_status));
+#endif
+#ifdef HAS_SIGINFO_SI_UID
+ {
+ SV *uid = newSV(0);
+ sv_setuid(uid, sip->si_uid);
+ (void)hv_stores(sih, "uid", uid);
+ }
+#endif
+#ifdef HAS_SIGINFO_SI_PID
+ (void)hv_stores(sih, "pid", newSViv(sip->si_pid));
+#endif
+#ifdef HAS_SIGINFO_SI_ADDR
+ (void)hv_stores(sih, "addr", newSVuv(PTR2UV(sip->si_addr)));
+#endif
+#ifdef HAS_SIGINFO_SI_BAND
+ (void)hv_stores(sih, "band", newSViv(sip->si_band));
#endif
EXTEND(SP, 2);
PUSHs(rv);
diff --git a/plan9/config_sh.sample b/plan9/config_sh.sample
index 66222934eb..e214d8951c 100644
--- a/plan9/config_sh.sample
+++ b/plan9/config_sh.sample
@@ -500,6 +500,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='define'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='define'
d_sigprocmask='define'
d_sigsetjmp='define'
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 4d09b82eeb..cacd83ef93 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -27,6 +27,13 @@ here, but most should go in the L</Performance Enhancements> section.
[ List each enhancement as a =head2 entry ]
+=head2 More fields provided to C<sigaction> callback with C<SA_SIGINFO>
+
+When passing the C<SA_SIGINFO> flag to L<sigaction|POSIX/sigaction>, the
+C<errno>, C<status>, C<uid>, C<pid>, C<addr> and C<band> fields are now
+included in the hash passed to the handler, if supported by the
+platform.
+
=head1 Security
XXX Any security-related notices go here. In particular, any security
diff --git a/symbian/config.sh b/symbian/config.sh
index c6466c99b5..64935b9928 100644
--- a/symbian/config.sh
+++ b/symbian/config.sh
@@ -446,6 +446,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='undef'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='undef'
d_sigprocmask='undef'
d_sigsetjmp='undef'
diff --git a/uconfig.h b/uconfig.h
index 079c73f724..c7bb73f9c1 100644
--- a/uconfig.h
+++ b/uconfig.h
@@ -2292,6 +2292,48 @@
*/
/*#define HAS_SIGACTION / **/
+/* HAS_SIGINFO_SI_ERRNO:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_errno member
+ */
+/*#define HAS_SIGINFO_SI_ERRNO / **/
+
+/* HAS_SIGINFO_SI_PID:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_pid member
+ */
+/*#define HAS_SIGINFO_SI_PID / **/
+
+/* HAS_SIGINFO_SI_UID:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_uid member
+ */
+/*#define HAS_SIGINFO_SI_UID / **/
+
+/* HAS_SIGINFO_SI_ADDR:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_addr member
+ */
+/*#define HAS_SIGINFO_SI_ADDR / **/
+
+/* HAS_SIGINFO_SI_STATUS:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_status member
+ */
+/*#define HAS_SIGINFO_SI_STATUS / **/
+
+/* HAS_SIGINFO_SI_BAND:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_band member
+ */
+/*#define HAS_SIGINFO_SI_BAND / **/
+
+/* HAS_SIGINFO_SI_VALUE:
+ * This symbol, if defined, indicates that siginfo_t has the
+ * si_value member
+ */
+/*#define HAS_SIGINFO_SI_VALUE / **/
+
/* HAS_SIGSETJMP:
* This variable indicates to the C program that the sigsetjmp()
* routine is available to save the calling process's registers
@@ -5182,6 +5224,6 @@
#endif
/* Generated from:
- * 056bddc3ae72075045127f87d3418b2caa44b81bdac54fa0a1a3cf11c8fbdd4a config_h.SH
- * a44240b1f83708d59d68e3c6d4d37d0c55ea9a2bab6e0413c17236c9000df18d uconfig.sh
+ * 0459b706f70bb18d7481b187553e0719406d2c7d5c354c3a309332dfd8e66197 config_h.SH
+ * 9382cd0e3b112993f14cfefe78ebe24b4b09df9d9dd199226ca7ba5e6b90f21a uconfig.sh
* ex: set ro: */
diff --git a/uconfig.sh b/uconfig.sh
index c70509038e..beecfe7aaf 100644
--- a/uconfig.sh
+++ b/uconfig.sh
@@ -439,6 +439,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='undef'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='undef'
d_sigprocmask='undef'
d_sigsetjmp='undef'
diff --git a/uconfig64.sh b/uconfig64.sh
index 8835d61d8c..3e58288ac5 100644
--- a/uconfig64.sh
+++ b/uconfig64.sh
@@ -440,6 +440,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='undef'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='undef'
d_sigprocmask='undef'
d_sigsetjmp='undef'
diff --git a/win32/config.ce b/win32/config.ce
index 2c978a5509..e18506fd9e 100644
--- a/win32/config.ce
+++ b/win32/config.ce
@@ -488,6 +488,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='undef'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='undef'
d_sigprocmask='undef'
d_sigsetjmp='undef'
diff --git a/win32/config.gc b/win32/config.gc
index 7b37e54224..390be9b4a5 100644
--- a/win32/config.gc
+++ b/win32/config.gc
@@ -488,6 +488,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='undef'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='undef'
d_sigprocmask='undef'
d_sigsetjmp='undef'
diff --git a/win32/config.vc b/win32/config.vc
index 8bf7fbadc2..aa79d2bbef 100644
--- a/win32/config.vc
+++ b/win32/config.vc
@@ -488,6 +488,13 @@ d_shmctl='undef'
d_shmdt='undef'
d_shmget='undef'
d_sigaction='undef'
+d_siginfo_si_addr='undef'
+d_siginfo_si_band='undef'
+d_siginfo_si_errno='undef'
+d_siginfo_si_pid='undef'
+d_siginfo_si_status='undef'
+d_siginfo_si_uid='undef'
+d_siginfo_si_value='undef'
d_signbit='undef'
d_sigprocmask='undef'
d_sigsetjmp='undef'