+#if (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK \
+ && HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV
+
+/* Storage for the alternate signal stack. */
+static union
+{
+ char buffer[SIGSTKSZ];
+
+ /* These other members are for proper alignment. There's no
+ standard way to guarantee stack alignment, but this seems enough
+ in practice. */
+ long double ld;
+ long l;
+ void *p;
+} alternate_signal_stack;
+
+static void
+null_action (int signo __attribute__ ((unused)))
+{
+}
+
+#endif /* SIGALTSTACK || LIBSIGSEGV */
+
+/* Only use libsigsegv if we need it; platforms like Solaris can
+ detect stack overflow without the overhead of an external
+ library. */
+#if HAVE_LIBSIGSEGV && ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC
+
+/* Nonzero if general segv handler could not be installed. */
+static volatile int segv_handler_missing;
+
+/* Handle a segmentation violation and exit if it cannot be stack
+ overflow. This function is async-signal-safe. */
+
+static int segv_handler (void *address __attribute__ ((unused)),
+ int serious)
+{
+# if DEBUG
+ {
+ char buf[1024];
+ sprintf (buf, "segv_handler serious=%d\n", serious);
+ write (STDERR_FILENO, buf, strlen (buf));
+ }
+# endif
+
+ /* If this fault is not serious, return 0 to let the stack overflow
+ handler take a shot at it. */
+ if (!serious)
+ return 0;
+ die (SIGSEGV);
+}
+
+/* Handle a segmentation violation that is likely to be a stack
+ overflow and exit. This function is async-signal-safe. */
+
+static void overflow_handler (int, stackoverflow_context_t)
+ __attribute__ ((noreturn));
+static void
+overflow_handler (int emergency,
+ stackoverflow_context_t context __attribute__ ((unused)))
+{
+# if DEBUG
+ {
+ char buf[1024];
+ sprintf (buf, "overflow_handler emergency=%d segv_handler_missing=%d\n",
+ emergency, segv_handler_missing);
+ write (STDERR_FILENO, buf, strlen (buf));
+ }
+# endif
+
+ die ((!emergency || segv_handler_missing) ? 0 : SIGSEGV);
+}
+
+int
+c_stack_action (void (*action) (int))
+{
+ segv_action = action ? action : null_action;
+ program_error_message = _("program error");
+ stack_overflow_message = _("stack overflow");
+
+ /* Always install the overflow handler. */
+ if (stackoverflow_install_handler (overflow_handler,
+ alternate_signal_stack.buffer,
+ sizeof alternate_signal_stack.buffer))
+ {
+ errno = ENOTSUP;
+ return -1;
+ }
+ /* Try installing a general handler; if it fails, then treat all
+ segv as stack overflow. */
+ segv_handler_missing = sigsegv_install_handler (segv_handler);
+ return 0;
+}
+
+#elif HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING