SA_SIGINFO-style signals were part of the POSIX.1-2006 optional Real Time Signals (XSI RTS) feature. Haiku does not implement it (yet) and goes so far as to not define SA_SIGINFO to indicate lack thereof.
In POSIX.1-2008 they're no longer optional. Define SA_SIGINFO for Haiku, to avoid a forest of #ifdefs in Mono code. As long as Haiku doesn't support it, all sa_flags checks for SA_SIGINFO will evaluate to false, leading to the right code path taken. In console-unix, don't assume SA_SIGINFO signal handler parameters or chained SA_SIGINFO signal handlers. To cope with SA_SIGINFO chaining, request SA_SIGINFO semantics if available. Handle both types of chained signal handlers. Fixes build on Haiku. Cc: Miguel de Icaza <[email protected]> Cc: Paolo Molaro <[email protected]> Cc: Ingo Weinhold <[email protected]> v4 -> v5: * Add support for chained BeOS-style signal handlers. * Drop mini changes, define SA_SIGINFO in configure instead. * Decouple local MONO_ARCH_USE_SIGACTION from SA_SIGINFO (FIXME). v3 -> v4: * Replace macro with inline function, requested by Miguel de Icaza. * Don't assume SA_SIGINFO, request it explicitly, if possible. v2 -> v3: * Rework signature macros to match mini. v1 -> v2: * Introduce helper macros, suggested by Paolo Molaro. This commit is licensed under the MIT X11 license. --- ChangeLog | 6 +++ configure.in | 2 + mono/metadata/ChangeLog | 9 +++++ mono/metadata/console-unix.c | 83 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 90 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb8ef4b..c97f411 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2010-04-04 Andreas Färber <[email protected]> + * configure.in: Define SA_SIGINFO for Haiku. + + Contributed under MIT/X11 license. + +2010-04-04 Andreas Färber <[email protected]> + * configure.in: Fix typo. Set default for with_moonlight to fix "Moon Profile:" output. diff --git a/configure.in b/configure.in index bc9e755..5e34fc4 100644 --- a/configure.in +++ b/configure.in @@ -266,6 +266,8 @@ case "$host" in *-*-haiku*) host_win32=no CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_THREAD_SAFE" + # SA_SIGINFO is currently commented out in Haiku's headers + CPPFLAGS="$CPPFLAGS -DSA_SIGINFO=0x40" libmono_cflags="-D_REENTRANT -D_THREAD_SAFE" libdl= LIBS="$LIBS -lnetwork" diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 2d076da..0aaf44c 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,12 @@ +2010-04-04 Andreas Färber <[email protected]> + + * console-unix.c (sigcont_handler, sigwinch_handler): Don't assume + SA_SIGINFO-style signals. Fixes the build on platforms without (Haiku). + (console_set_signal_handlers): Distinguish between SA_SIGINFO and + default signal handlers to match our signal handlers' expectations. + + Code is contributed under MIT/X11 license. + 2010-04-04 Mark Probst <[email protected]> * sgen-gc.c: Remove superfluous scanning of alloc-pinned objects. diff --git a/mono/metadata/console-unix.c b/mono/metadata/console-unix.c index 0845c64..01e7742 100644 --- a/mono/metadata/console-unix.c +++ b/mono/metadata/console-unix.c @@ -246,6 +246,65 @@ do_console_cancel_event (void) mono_thread_pool_add ((MonoObject *) load_value, msg, NULL, NULL); } + +#define SIGHANDLER_SIGNATURE_SIGACTION int signo, void *the_siginfo, void *data +#define SIGHANDLER_PARAMS_SIGACTION signo, the_siginfo, data +#if defined(__HAIKU__) +#define SIGHANDLER_SIGNATURE_HANDLER int signo, char *userData, vregs regs +#define SIGHANDLER_PARAMS_HANDLER signo, userData, regs +#else +#define SIGHANDLER_SIGNATURE_HANDLER int signo +#define SIGHANDLER_PARAMS_HANDLER signo +#endif + +/* FIXME: move MONO_ARCH_USE_SIGACTION to central header? */ +#if !defined(__HAIKU__) +#define MONO_ARCH_USE_SIGACTION +#endif + +/* SIG_HANDLER_SIGNATURE and SIG_HANDLER_PARAMS synchronized with mini */ +#ifdef MONO_ARCH_USE_SIGACTION +#define SIGHANDLER_SIGNATURE SIGHANDLER_SIGNATURE_SIGACTION +#define SIG_HANDLER_PARAMS SIGHANDLER_PARAMS_SIGACTION +#else +#define SIGHANDLER_SIGNATURE SIGHANDLER_SIGNATURE_HANDLER +#define SIG_HANDLER_PARAMS SIGHANDLER_PARAMS_HANDLER +#endif +#define SIG_HANDLER_SIGNATURE(ftn) ftn (SIGHANDLER_SIGNATURE) + +static inline gboolean +is_sighandler_valid (void *sigh) +{ + return sigh != NULL && + sigh != (void *)SIG_DFL && + sigh != (void *)SIG_IGN; +} + +static inline void +invoke_sighandler_if_valid (struct sigaction *siga, SIGHANDLER_SIGNATURE) +{ + if (siga->sa_flags & SA_SIGINFO) { +#ifdef MONO_ARCH_USE_SIGACTION + if (is_sighandler_valid (siga->sa_sigaction)) + (*siga->sa_sigaction) (SIGHANDLER_PARAMS_SIGACTION); +#endif + } else { + if (is_sighandler_valid (siga->sa_handler)) +#if (defined(__HAIKU__)) && defined(MONO_ARCH_USE_SIGACTION) + (*siga->sa_handler) (signo, NULL/*XXX*/, + *((ucontext_t *)data)->uc_mcontext/*XXX*/); +#elif defined(__HAIKU__) + (*(void (*) (int, char *, vregs))siga->sa_handler) (SIGHANDLER_PARAMS_HANDLER); +#else + (*siga->sa_handler) (SIGHANDLER_PARAMS_HANDLER); +#endif + } +} + +#define INVOKE_SIGHANDLER_IF_VALID(siga) \ + invoke_sighandler_if_valid (&(siga), SIG_HANDLER_PARAMS) + + static gboolean in_sigint; static void sigint_handler (int signo) @@ -263,7 +322,7 @@ sigint_handler (int signo) static struct sigaction save_sigcont, save_sigint, save_sigwinch; static void -sigcont_handler (int signo, void *the_siginfo, void *data) +SIG_HANDLER_SIGNATURE (sigcont_handler) { // Ignore error, there is not much we can do in the sigcont handler. tcsetattr (STDIN_FILENO, TCSANOW, &mono_attr); @@ -272,24 +331,18 @@ sigcont_handler (int signo, void *the_siginfo, void *data) write (STDOUT_FILENO, keypad_xmit_str, strlen (keypad_xmit_str)); // Call previous handler - if (save_sigcont.sa_sigaction != NULL && - save_sigcont.sa_sigaction != (void *)SIG_DFL && - save_sigcont.sa_sigaction != (void *)SIG_IGN) - (*save_sigcont.sa_sigaction) (signo, the_siginfo, data); + INVOKE_SIGHANDLER_IF_VALID (save_sigcont); } static void -sigwinch_handler (int signo, void *the_siginfo, void *data) +SIG_HANDLER_SIGNATURE (sigwinch_handler) { int dims = terminal_get_dimensions (); if (dims != -1) cols_and_lines = dims; // Call previous handler - if (save_sigwinch.sa_sigaction != NULL && - save_sigwinch.sa_sigaction != (void *)SIG_DFL && - save_sigwinch.sa_sigaction != (void *)SIG_IGN) - (*save_sigwinch.sa_sigaction) (signo, the_siginfo, data); + INVOKE_SIGHANDLER_IF_VALID (save_sigwinch); } void @@ -302,8 +355,13 @@ console_set_signal_handlers () memset (&sigwinch, 0, sizeof (struct sigaction)); // Continuing +#ifdef MONO_ARCH_USE_SIGACTION + sigcont.sa_sigaction = (void *) sigcont_handler; + sigcont.sa_flags = SA_SIGINFO; +#else sigcont.sa_handler = (void *) sigcont_handler; sigcont.sa_flags = 0; +#endif sigemptyset (&sigcont.sa_mask); sigaction (SIGCONT, &sigcont, &save_sigcont); @@ -314,8 +372,13 @@ console_set_signal_handlers () sigaction (SIGINT, &sigint, &save_sigint); // Window size changed +#ifdef MONO_ARCH_USE_SIGACTION + sigwinch.sa_sigaction = (void *) sigwinch_handler; + sigwinch.sa_flags = SA_SIGINFO; +#else sigwinch.sa_handler = (void *) sigwinch_handler; sigwinch.sa_flags = 0; +#endif sigemptyset (&sigwinch.sa_mask); sigaction (SIGWINCH, &sigwinch, &save_sigwinch); } -- 1.7.0.4.297.g6555b1
_______________________________________________ Mono-devel-list mailing list [email protected] http://lists.ximian.com/mailman/listinfo/mono-devel-list
