This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
add explicit 1-arg and 3-arg sig handler functions
authorDavid Mitchell <davem@iabyn.com>
Mon, 11 Nov 2019 15:49:58 +0000 (15:49 +0000)
committerDavid Mitchell <davem@iabyn.com>
Mon, 18 Nov 2019 09:34:40 +0000 (09:34 +0000)
Currently, whether the OS-level signal handler function is declared as
1-arg or 3-arg depends on the configuration. Add explicit versions of
these functions, principally so that POSIX.xs can call which version of
the handler it wants regardless of configuration: see next commit.

embed.fnc
embed.h
embedvar.h
intrpvar.h
iperlsys.h
mg.c
perl.c
perlapi.h
perlvars.h
proto.h
sv.c

index 1f3913e..900c124 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -1691,6 +1691,10 @@ ATp      |Signal_t |csighandler  |int sig|NULLOK Siginfo_t *info|NULLOK void *uap
 Tp     |Signal_t |sighandler   |int sig
 ATp    |Signal_t |csighandler  |int sig
 #endif
+Tp     |Signal_t |sighandler1  |int sig
+ATp    |Signal_t |csighandler1 |int sig
+Tp     |Signal_t |sighandler3  |int sig|NULLOK Siginfo_t *info|NULLOK void *uap
+ATp    |Signal_t |csighandler3 |int sig|NULLOK Siginfo_t *info|NULLOK void *uap
 ATp    |Signal_t |perly_sighandler     |int sig|NULLOK Siginfo_t *info|NULLOK void *uap|bool safe
 Ap     |SV**   |stack_grow     |NN SV** sp|NN SV** p|SSize_t n
 Ap     |I32    |start_subparse |I32 is_format|U32 flags
diff --git a/embed.h b/embed.h
index 8138141..5b10384 100644 (file)
--- a/embed.h
+++ b/embed.h
@@ -96,6 +96,8 @@
 #define croak_no_modify                Perl_croak_no_modify
 #define croak_sv(a)            Perl_croak_sv(aTHX_ a)
 #define croak_xs_usage         Perl_croak_xs_usage
+#define csighandler1           Perl_csighandler1
+#define csighandler3           Perl_csighandler3
 #ifndef NO_MATHOMS
 #define custom_op_desc(a)      Perl_custom_op_desc(aTHX_ a)
 #endif
 #define setfd_cloexec_or_inhexec_by_sysfdness(a)       Perl_setfd_cloexec_or_inhexec_by_sysfdness(aTHX_ a)
 #define setfd_inhexec          Perl_setfd_inhexec
 #define setfd_inhexec_for_sysfd(a)     Perl_setfd_inhexec_for_sysfd(aTHX_ a)
+#define sighandler1            Perl_sighandler1
+#define sighandler3            Perl_sighandler3
 #define sub_crush_depth(a)     Perl_sub_crush_depth(aTHX_ a)
 #define sv_2num(a)             Perl_sv_2num(aTHX_ a)
 #define sv_clean_all()         Perl_sv_clean_all(aTHX)
index d0d281c..2f96743 100644 (file)
 #define PL_setlocale_bufsize   (vTHX->Isetlocale_bufsize)
 #define PL_sharehook           (vTHX->Isharehook)
 #define PL_sig_pending         (vTHX->Isig_pending)
+#define PL_sighandler1p                (vTHX->Isighandler1p)
+#define PL_sighandler3p                (vTHX->Isighandler3p)
 #define PL_sighandlerp         (vTHX->Isighandlerp)
 #define PL_signalhook          (vTHX->Isignalhook)
 #define PL_signals             (vTHX->Isignals)
 #define PL_Gcheck              (my_vars->Gcheck)
 #define PL_check_mutex         (my_vars->Gcheck_mutex)
 #define PL_Gcheck_mutex                (my_vars->Gcheck_mutex)
+#define PL_csighandler1p       (my_vars->Gcsighandler1p)
+#define PL_Gcsighandler1p      (my_vars->Gcsighandler1p)
+#define PL_csighandler3p       (my_vars->Gcsighandler3p)
+#define PL_Gcsighandler3p      (my_vars->Gcsighandler3p)
 #define PL_csighandlerp                (my_vars->Gcsighandlerp)
 #define PL_Gcsighandlerp       (my_vars->Gcsighandlerp)
 #define PL_curinterp           (my_vars->Gcurinterp)
index 906a67a..cbbbadd 100644 (file)
@@ -611,7 +611,11 @@ PERLVAR(I, pidstatus,      HV *)           /* pid-to-status mappings for waitpid */
 #endif
 PERLVAR(I, osname,     char *)         /* operating system */
 
-PERLVAR(I, sighandlerp,        Sighandler_t)
+PERLVAR(I, sighandlerp,         Sighandler_t)
+/* these two are provided only to solve library linkage issues; they
+ * should not be hooked by user code */
+PERLVAR(I, sighandler1p, Sighandler1_t)
+PERLVAR(I, sighandler3p, Sighandler3_t)
 
 PERLVARA(I, body_roots,        PERL_ARENA_ROOTS_SIZE, void*) /* array of body roots */
 
index de2dad6..d4ecb73 100644 (file)
 */
 #include "perlio.h"
 
+typedef Signal_t (*Sighandler1_t) (int);
+typedef Signal_t (*Sighandler3_t) (int, Siginfo_t*, void*);
+
 #ifndef Sighandler_t
 #  ifdef PERL_USE_3ARG_SIGHANDLER
-typedef Signal_t (*Sighandler_t) (int, Siginfo_t*, void*);
+typedef Sighandler3_t Sighandler_t;
 #  else
-typedef Signal_t (*Sighandler_t) (int);
+typedef Sighandler1_t Sighandler_t;
 #  endif
 #endif
 
diff --git a/mg.c b/mg.c
index 7b96dce..9424698 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -62,6 +62,7 @@ tie.
 #  include <sys/prctl.h>
 #endif
 
+
 #ifdef PERL_USE_3ARG_SIGHANDLER
 Signal_t Perl_csighandler(int sig, Siginfo_t *, void *);
 #else
@@ -1486,12 +1487,37 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
     return sv_unmagic(sv, mg->mg_type);
 }
 
-Signal_t
+
 #ifdef PERL_USE_3ARG_SIGHANDLER
-Perl_csighandler(int sig, Siginfo_t *sip PERL_UNUSED_DECL, void *uap PERL_UNUSED_DECL)
+Signal_t
+Perl_csighandler(int sig, Siginfo_t *sip, void *uap)
+{
+    Perl_csighandler3(sig, sip, uap);
+}
 #else
+Signal_t
 Perl_csighandler(int sig)
+{
+    Perl_csighandler3(sig, NULL, NULL);
+}
 #endif
+
+Signal_t
+Perl_csighandler1(int sig)
+{
+    Perl_csighandler3(sig, NULL, NULL);
+}
+
+/* Handler intended to directly handle signal calls from the kernel.
+ * (Depending on configuration, the kernel may actually call one of the
+ * wrappers csighandler() or csighandler1() instead.)
+ * It either queues up the signal or dispatches it immediately depending
+ * on whether safe signals are enabled and whether the signal is capable
+ * of being deferred (e.g. SEGV isn't).
+ */
+
+Signal_t
+Perl_csighandler3(int sig, Siginfo_t *sip PERL_UNUSED_DECL, void *uap PERL_UNUSED_DECL)
 {
 #ifdef PERL_GET_SIG_CONTEXT
     dTHXa(PERL_GET_SIG_CONTEXT);
@@ -3336,6 +3362,20 @@ Perl_whichsig_pvn(pTHX_ const char *sig, STRLEN len)
     return -1;
 }
 
+
+/* Perl_sighandler(), Perl_sighandler1(), Perl_sighandler3():
+ * these three function are intended to be called by the OS as 'C' level
+ * signal handler functions in the case where unsafe signals are being
+ * used - i.e. they immediately invoke Perl_perly_sighandler() to call the
+ * perl-level sighandler, rather than deferring.
+ * In fact, the core itself will normally use Perl_csighandler as the
+ * OS-level handler; that function will then decide whether to queue the
+ * signal or call Perl_sighandler / Perl_perly_sighandler itself. So these
+ * functions are more useful for e.g. POSIX.xs when it wants explicit
+ * control of what's happening.
+ */
+
+
 #ifdef PERL_USE_3ARG_SIGHANDLER
 
 Signal_t
@@ -3354,6 +3394,19 @@ Perl_sighandler(int sig)
 
 #endif
 
+Signal_t
+Perl_sighandler1(int sig)
+{
+    Perl_perly_sighandler(sig, NULL, NULL, 0);
+}
+
+Signal_t
+Perl_sighandler3(int sig, Siginfo_t *sip PERL_UNUSED_DECL, void *uap PERL_UNUSED_DECL)
+{
+    Perl_perly_sighandler(sig, sip, uap, 0);
+}
+
+
 /* Invoke the perl-level signal handler. This function is called either
  * directly from one of the C-level signals handlers (Perl_sighandler or
  * Perl_csighandler), or for safe signals, later from
diff --git a/perl.c b/perl.c
index 43f6f9b..e6fe14f 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -262,7 +262,10 @@ perl_construct(pTHXx)
     SvREADONLY_on(&PL_sv_placeholder);
     SvREFCNT(&PL_sv_placeholder) = SvREFCNT_IMMORTAL;
 
-    PL_sighandlerp = (Sighandler_t) Perl_sighandler;
+    PL_sighandlerp  = Perl_sighandler;
+    PL_sighandler1p = Perl_sighandler1;
+    PL_sighandler3p = Perl_sighandler3;
+
 #ifdef PERL_USES_PL_PIDSTATUS
     PL_pidstatus = newHV();
 #endif
index 2cf7ce2..8b74919 100644 (file)
--- a/perlapi.h
+++ b/perlapi.h
@@ -139,6 +139,10 @@ END_EXTERN_C
 #define PL_check               (*Perl_Gcheck_ptr(NULL))
 #undef  PL_check_mutex
 #define PL_check_mutex         (*Perl_Gcheck_mutex_ptr(NULL))
+#undef  PL_csighandler1p
+#define PL_csighandler1p       (*Perl_Gcsighandler1p_ptr(NULL))
+#undef  PL_csighandler3p
+#define PL_csighandler3p       (*Perl_Gcsighandler3p_ptr(NULL))
 #undef  PL_csighandlerp
 #define PL_csighandlerp                (*Perl_Gcsighandlerp_ptr(NULL))
 #undef  PL_curinterp
index b9ba540..976649a 100644 (file)
@@ -73,8 +73,13 @@ PERLVARI(G, sig_trapped, int,        0)
 /* If Perl has to ignore SIGPFE, this is its saved state.
  * See perl.h macros PERL_FPU_INIT and PERL_FPU_{PRE,POST}_EXEC. */
 PERLVAR(G, sigfpe_saved, Sighandler_t)
-PERLVARI(G, csighandlerp, Sighandler_t, Perl_csighandler)
-                                       /* Pointer to C-level sighandler */
+
+/* these ptrs to functions are to avoid linkage problems; see
+ * perl-5.8.0-2193-g5c1546dc48
+ */
+PERLVARI(G, csighandlerp,  Sighandler_t,  Perl_csighandler)
+PERLVARI(G, csighandler1p, Sighandler1_t, Perl_csighandler1)
+PERLVARI(G, csighandler3p, Sighandler3_t, Perl_csighandler3)
 #endif
 
 /* This is constant on most architectures, a global on OS/2 */
diff --git a/proto.h b/proto.h
index 7adae3c..009a966 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -701,6 +701,10 @@ PERL_CALLCONV_NO_RET void  Perl_croak_xs_usage(const CV *const cv, const char *co
 #define PERL_ARGS_ASSERT_CROAK_XS_USAGE        \
        assert(cv); assert(params)
 
+PERL_CALLCONV Signal_t Perl_csighandler1(int sig);
+#define PERL_ARGS_ASSERT_CSIGHANDLER1
+PERL_CALLCONV Signal_t Perl_csighandler3(int sig, Siginfo_t *info, void *uap);
+#define PERL_ARGS_ASSERT_CSIGHANDLER3
 PERL_CALLCONV regexp_engine const *    Perl_current_re_engine(pTHX);
 #define PERL_ARGS_ASSERT_CURRENT_RE_ENGINE
 #ifndef NO_MATHOMS
@@ -3116,6 +3120,10 @@ PERL_CALLCONV void       Perl_setfd_inhexec_for_sysfd(pTHX_ int fd);
 PERL_CALLCONV HEK*     Perl_share_hek(pTHX_ const char* str, SSize_t len, U32 hash);
 #define PERL_ARGS_ASSERT_SHARE_HEK     \
        assert(str)
+PERL_CALLCONV Signal_t Perl_sighandler1(int sig);
+#define PERL_ARGS_ASSERT_SIGHANDLER1
+PERL_CALLCONV Signal_t Perl_sighandler3(int sig, Siginfo_t *info, void *uap);
+#define PERL_ARGS_ASSERT_SIGHANDLER3
 PERL_CALLCONV char*    Perl_skipspace_flags(pTHX_ char *s, U32 flags)
                        __attribute__warn_unused_result__;
 #define PERL_ARGS_ASSERT_SKIPSPACE_FLAGS       \
diff --git a/sv.c b/sv.c
index 485755b..2fb9750 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -15317,6 +15317,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_origalen                = proto_perl->Iorigalen;
 
     PL_sighandlerp     = proto_perl->Isighandlerp;
+    PL_sighandler1p    = proto_perl->Isighandler1p;
+    PL_sighandler3p    = proto_perl->Isighandler3p;
 
     PL_runops          = proto_perl->Irunops;