Blame SOURCES/grep-3.6-gnulib-c-stack-fix.patch

a7991f
diff --git a/gnulib-tests/Makefile.in b/gnulib-tests/Makefile.in
a7991f
index aa979f4..194cc7d 100644
a7991f
--- a/gnulib-tests/Makefile.in
a7991f
+++ b/gnulib-tests/Makefile.in
a7991f
@@ -3100,7 +3100,7 @@ test_argmatch_LDADD = $(LDADD) @LIBINTL@ $(LIB_MBRTOWC)
a7991f
 test_bind_LDADD = $(LDADD) @LIBSOCKET@ $(INET_PTON_LIB)
a7991f
 test_btowc_LDADD = $(LDADD) $(LIB_SETLOCALE)
a7991f
 test_c_ctype_LDADD = $(LDADD) $(LIB_SETLOCALE)
a7991f
-test_c_stack_LDADD = $(LDADD) $(LIBCSTACK) @LIBINTL@
a7991f
+test_c_stack_LDADD = $(LDADD) -lsigsegv @LIBINTL@
a7991f
 test_c_strcasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE)
a7991f
 test_c_strncasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE)
a7991f
 test_connect_LDADD = $(LDADD) @LIBSOCKET@ $(INET_PTON_LIB)
a7991f
diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk
a7991f
index b1dc6f9..ba0594e 100644
a7991f
--- a/gnulib-tests/gnulib.mk
a7991f
+++ b/gnulib-tests/gnulib.mk
a7991f
@@ -209,7 +209,7 @@ EXTRA_DIST += test-c-ctype.c macros.h
a7991f
 TESTS += test-c-stack.sh test-c-stack2.sh
a7991f
 TESTS_ENVIRONMENT += LIBSIGSEGV='@LIBSIGSEGV@'
a7991f
 check_PROGRAMS += test-c-stack
a7991f
-test_c_stack_LDADD = $(LDADD) $(LIBCSTACK) @LIBINTL@
a7991f
+test_c_stack_LDADD = $(LDADD) -lsigsegv @LIBINTL@
a7991f
 MOSTLYCLEANFILES += t-c-stack.tmp t-c-stack2.tmp
a7991f
 EXTRA_DIST += test-c-stack.c test-c-stack.sh test-c-stack2.sh macros.h
a7991f
 
a7991f
diff --git a/lib/c-stack.c b/lib/c-stack.c
a7991f
index 3aea16a..b0e5cb1 100644
a7991f
--- a/lib/c-stack.c
a7991f
+++ b/lib/c-stack.c
a7991f
@@ -1,6 +1,6 @@
a7991f
 /* Stack overflow handling.
a7991f
 
a7991f
-   Copyright (C) 2002, 2004, 2006, 2008-2020 Free Software Foundation, Inc.
a7991f
+   Copyright (C) 2002, 2004, 2006, 2008-2021 Free Software Foundation, Inc.
a7991f
 
a7991f
    This program is free software: you can redistribute it and/or modify
a7991f
    it under the terms of the GNU General Public License as published by
a7991f
@@ -37,54 +37,28 @@
a7991f
 
a7991f
 #include "c-stack.h"
a7991f
 
a7991f
-#include "gettext.h"
a7991f
-#define _(msgid) gettext (msgid)
a7991f
-
a7991f
 #include <errno.h>
a7991f
 #include <inttypes.h>
a7991f
-
a7991f
 #include <signal.h>
a7991f
-#if ! HAVE_STACK_T && ! defined stack_t
a7991f
-typedef struct sigaltstack stack_t;
a7991f
-#endif
a7991f
-
a7991f
-#include <stdbool.h>
a7991f
 #include <stddef.h>
a7991f
 #include <stdlib.h>
a7991f
 #include <string.h>
a7991f
-
a7991f
-/* Pre-2008 POSIX declared ucontext_t in ucontext.h instead of signal.h.  */
a7991f
-#if HAVE_UCONTEXT_H
a7991f
-# include <ucontext.h>
a7991f
-#endif
a7991f
-
a7991f
 #include <unistd.h>
a7991f
 
a7991f
 #if DEBUG
a7991f
 # include <stdio.h>
a7991f
 #endif
a7991f
 
a7991f
-/* Use libsigsegv only if needed; kernels like Solaris can detect
a7991f
-   stack overflow without the overhead of an external library.  */
a7991f
-#define USE_LIBSIGSEGV (!HAVE_XSI_STACK_OVERFLOW_HEURISTIC && HAVE_LIBSIGSEGV)
a7991f
-
a7991f
-#if USE_LIBSIGSEGV
a7991f
-# include <sigsegv.h>
a7991f
-#endif
a7991f
+#include <sigsegv.h>
a7991f
 
a7991f
 #include "exitfail.h"
a7991f
-#include "ignore-value.h"
a7991f
-#include "intprops.h"
a7991f
 #include "getprogname.h"
a7991f
+#include "ignore-value.h"
a7991f
 
a7991f
-#if defined SA_ONSTACK && defined SA_SIGINFO
a7991f
-# define SIGINFO_WORKS 1
a7991f
-#else
a7991f
-# define SIGINFO_WORKS 0
a7991f
-# ifndef SA_ONSTACK
a7991f
-#  define SA_ONSTACK 0
a7991f
-# endif
a7991f
-#endif
a7991f
+#include "gettext.h"
a7991f
+#define _(msgid) gettext (msgid)
a7991f
+
a7991f
+#if HAVE_STACK_OVERFLOW_RECOVERY
a7991f
 
a7991f
 /* Storage for the alternate signal stack.
a7991f
    64 KiB is not too large for Gnulib-using apps, and is large enough
a7991f
@@ -106,9 +80,6 @@ static _GL_ASYNC_SAFE void (* volatile segv_action) (int);
a7991f
 static char const * volatile program_error_message;
a7991f
 static char const * volatile stack_overflow_message;
a7991f
 
a7991f
-#if (USE_LIBSIGSEGV                                           \
a7991f
-     || (HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING))
a7991f
-
a7991f
 /* Output an error message, then exit with status EXIT_FAILURE if it
a7991f
    appears to have been a stack overflow, or with a core dump
a7991f
    otherwise.  This function is async-signal-safe.  */
a7991f
@@ -118,12 +89,6 @@ static char const * volatile progname;
a7991f
 static _GL_ASYNC_SAFE _Noreturn void
a7991f
 die (int signo)
a7991f
 {
a7991f
-# if !SIGINFO_WORKS && !USE_LIBSIGSEGV
a7991f
-  /* We can't easily determine whether it is a stack overflow; so
a7991f
-     assume that the rest of our program is perfect (!) and that
a7991f
-     this segmentation violation is a stack overflow.  */
a7991f
-  signo = 0;
a7991f
-# endif
a7991f
   segv_action (signo);
a7991f
   char const *message = signo ? program_error_message : stack_overflow_message;
a7991f
 
a7991f
@@ -164,12 +129,8 @@ null_action (int signo _GL_UNUSED)
a7991f
 {
a7991f
 }
a7991f
 
a7991f
-#endif /* SIGALTSTACK || LIBSIGSEGV */
a7991f
-
a7991f
-#if USE_LIBSIGSEGV
a7991f
-
a7991f
 /* Pacify GCC 9.3.1, which otherwise would complain about segv_handler.  */
a7991f
-# if __GNUC_PREREQ (4, 6)
a7991f
+# if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
a7991f
 #  pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
a7991f
 # endif
a7991f
 
a7991f
@@ -240,132 +201,7 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
a7991f
   return 0;
a7991f
 }
a7991f
 
a7991f
-#elif HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING
a7991f
-
a7991f
-# if SIGINFO_WORKS
a7991f
-
a7991f
-static size_t volatile page_size;
a7991f
-
a7991f
-/* Handle a segmentation violation and exit.  This function is
a7991f
-   async-signal-safe.  */
a7991f
-
a7991f
-static _GL_ASYNC_SAFE _Noreturn void
a7991f
-segv_handler (int signo, siginfo_t *info, void *context _GL_UNUSED)
a7991f
-{
a7991f
-  /* Clear SIGNO if it seems to have been a stack overflow.  */
a7991f
-
a7991f
-  /* If si_code is nonpositive, something like raise (SIGSEGV) occurred
a7991f
-     so it cannot be a stack overflow.  */
a7991f
-  bool cannot_be_stack_overflow = info->si_code <= 0;
a7991f
-
a7991f
-  /* An unaligned address cannot be a stack overflow.  */
a7991f
-#  if FAULT_YIELDS_SIGBUS
a7991f
-  cannot_be_stack_overflow |= signo == SIGBUS && info->si_code == BUS_ADRALN;
a7991f
-#  endif
a7991f
-
a7991f
-  /* If we can't easily determine that it is not a stack overflow,
a7991f
-     assume that the rest of our program is perfect (!) and that
a7991f
-     this segmentation violation is a stack overflow.
a7991f
-
a7991f
-     Note that although both Linux and Solaris provide
a7991f
-     sigaltstack, SA_ONSTACK, and SA_SIGINFO, currently only
a7991f
-     Solaris satisfies the XSI heuristic.  This is because
a7991f
-     Solaris populates uc_stack with the details of the
a7991f
-     interrupted stack, while Linux populates it with the details
a7991f
-     of the current stack.  */
a7991f
-  if (!cannot_be_stack_overflow)
a7991f
-    {
a7991f
-      /* If the faulting address is within the stack, or within one
a7991f
-         page of the stack, assume that it is a stack overflow.  */
a7991f
-      uintptr_t faulting_address = (uintptr_t) info->si_addr;
a7991f
-
a7991f
-      /* On all platforms we know of, the first page is not in the
a7991f
-         stack to catch null pointer dereferening.  However, all other
a7991f
-         pages might be in the stack.  */
a7991f
-      void *stack_base = (void *) (uintptr_t) page_size;
a7991f
-      uintptr_t stack_size = 0; stack_size -= page_size;
a7991f
-#  if HAVE_XSI_STACK_OVERFLOW_HEURISTIC
a7991f
-      /* Tighten the stack bounds via the XSI heuristic.  */
a7991f
-      ucontext_t const *user_context = context;
a7991f
-      stack_base = user_context->uc_stack.ss_sp;
a7991f
-      stack_size = user_context->uc_stack.ss_size;
a7991f
-#  endif
a7991f
-      uintptr_t base = (uintptr_t) stack_base,
a7991f
-        lo = (INT_SUBTRACT_WRAPV (base, page_size, &lo) || lo < page_size
a7991f
-              ? page_size : lo),
a7991f
-        hi = ((INT_ADD_WRAPV (base, stack_size, &hi)
a7991f
-               || INT_ADD_WRAPV (hi, page_size - 1, &hi))
a7991f
-              ? UINTPTR_MAX : hi);
a7991f
-      if (lo <= faulting_address && faulting_address <= hi)
a7991f
-        signo = 0;
a7991f
-
a7991f
-#   if DEBUG
a7991f
-      {
a7991f
-        char buf[1024];
a7991f
-        ignore_value (write (STDERR_FILENO, buf,
a7991f
-                             sprintf (buf,
a7991f
-                                      ("segv_handler code=%d fault=%p base=%p"
a7991f
-                                       " size=0x%zx page=0x%zx signo=%d\n"),
a7991f
-                                      info->si_code, info->si_addr, stack_base,
a7991f
-                                      stack_size, page_size, signo)));
a7991f
-      }
a7991f
-#  endif
a7991f
-    }
a7991f
-
a7991f
-  die (signo);
a7991f
-}
a7991f
-# endif
a7991f
-
a7991f
-int
a7991f
-c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
a7991f
-{
a7991f
-  stack_t st;
a7991f
-  st.ss_flags = 0;
a7991f
-  st.ss_sp = alternate_signal_stack;
a7991f
-  st.ss_size = sizeof alternate_signal_stack;
a7991f
-# if SIGALTSTACK_SS_REVERSED
a7991f
-  /* Irix mistakenly treats ss_sp as the upper bound, rather than
a7991f
-     lower bound, of the alternate stack.  */
a7991f
-  st.ss_size -= sizeof (void *);
a7991f
-  char *ss_sp = st.ss_sp;
a7991f
-  st.ss_sp = ss_sp + st.ss_size;
a7991f
-# endif
a7991f
-  int r = sigaltstack (&st, NULL);
a7991f
-  if (r != 0)
a7991f
-    return r;
a7991f
-
a7991f
-  segv_action = action ? action : null_action;
a7991f
-  program_error_message = _("program error");
a7991f
-  stack_overflow_message = _("stack overflow");
a7991f
-  progname = getprogname ();
a7991f
-
a7991f
-# if SIGINFO_WORKS
a7991f
-  page_size = sysconf (_SC_PAGESIZE);
a7991f
-# endif
a7991f
-
a7991f
-  struct sigaction act;
a7991f
-  sigemptyset (&act.sa_mask);
a7991f
-
a7991f
-# if SIGINFO_WORKS
a7991f
-  /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but
a7991f
-     this is not true on Solaris 8 at least.  It doesn't hurt to use
a7991f
-     SA_NODEFER here, so leave it in.  */
a7991f
-  act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
a7991f
-  act.sa_sigaction = segv_handler;
a7991f
-# else
a7991f
-  act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
a7991f
-  act.sa_handler = die;
a7991f
-# endif
a7991f
-
a7991f
-# if FAULT_YIELDS_SIGBUS
a7991f
-  if (sigaction (SIGBUS, &act, NULL) < 0)
a7991f
-    return -1;
a7991f
-# endif
a7991f
-  return sigaction (SIGSEGV, &act, NULL);
a7991f
-}
a7991f
-
a7991f
-#else /* ! (USE_LIBSIGSEGV
a7991f
-            || (HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING)) */
a7991f
+#else /* !HAVE_STACK_OVERFLOW_RECOVERY */
a7991f
 
a7991f
 int
a7991f
 c_stack_action (_GL_ASYNC_SAFE void (*action) (int)  _GL_UNUSED)
a7991f
diff --git a/m4/c-stack.m4 b/m4/c-stack.m4
a7991f
index 85107f4..7cccb06 100644
a7991f
--- a/m4/c-stack.m4
a7991f
+++ b/m4/c-stack.m4
a7991f
@@ -1,376 +1,21 @@
a7991f
 # Check prerequisites for compiling lib/c-stack.c.
a7991f
 
a7991f
-# Copyright (C) 2002-2004, 2008-2020 Free Software Foundation, Inc.
a7991f
+# Copyright (C) 2002-2004, 2008-2021 Free Software Foundation, Inc.
a7991f
 # This file is free software; the Free Software Foundation
a7991f
 # gives unlimited permission to copy and/or distribute it,
a7991f
 # with or without modifications, as long as this notice is preserved.
a7991f
 
a7991f
 # Written by Paul Eggert.
a7991f
 
a7991f
-# serial 20
a7991f
-
a7991f
-AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
a7991f
-  [
a7991f
-   AC_REQUIRE([AC_CANONICAL_HOST])
a7991f
-   AC_CHECK_FUNCS_ONCE([setrlimit])
a7991f
-   AC_CHECK_HEADERS_ONCE([ucontext.h])
a7991f
-
a7991f
-   dnl List of signals that are sent when an invalid virtual memory address
a7991f
-   dnl is accessed, or when the stack overflows.
a7991f
-   dnl Either { SIGSEGV } or { SIGSEGV, SIGBUS }.
a7991f
-   case "$host_os" in
a7991f
-     sunos4* | freebsd* | dragonfly* | openbsd* | mirbsd* | netbsd* | kfreebsd* | knetbsd*) # BSD systems
a7991f
-       FAULT_YIELDS_SIGBUS=1 ;;
a7991f
-     hpux*) # HP-UX
a7991f
-       FAULT_YIELDS_SIGBUS=1 ;;
a7991f
-     macos* | darwin*) # Mac OS X
a7991f
-       FAULT_YIELDS_SIGBUS=1 ;;
a7991f
-     gnu*) # Hurd
a7991f
-       FAULT_YIELDS_SIGBUS=1 ;;
a7991f
-     *)
a7991f
-       FAULT_YIELDS_SIGBUS=0 ;;
a7991f
-   esac
a7991f
-   AC_DEFINE_UNQUOTED([FAULT_YIELDS_SIGBUS], [$FAULT_YIELDS_SIGBUS],
a7991f
-     [Define to 1 if an invalid memory address access may yield a SIGBUS.])
a7991f
-
a7991f
-   AC_CACHE_CHECK([for working C stack overflow detection],
a7991f
-     [gl_cv_sys_stack_overflow_works],
a7991f
-     [AC_RUN_IFELSE([AC_LANG_SOURCE(
a7991f
-           [[
a7991f
-            #include <unistd.h>
a7991f
-            #include <signal.h>
a7991f
-            #if HAVE_SETRLIMIT
a7991f
-            # include <sys/types.h>
a7991f
-            # include <sys/time.h>
a7991f
-            # include <sys/resource.h>
a7991f
-            #endif
a7991f
-            #ifndef SIGSTKSZ
a7991f
-            # define SIGSTKSZ 16384
a7991f
-            #endif
a7991f
-
a7991f
-            static union
a7991f
-            {
a7991f
-              char buffer[2 * SIGSTKSZ];
a7991f
-              long double ld;
a7991f
-              long u;
a7991f
-              void *p;
a7991f
-            } alternate_signal_stack;
a7991f
-
a7991f
-            static void
a7991f
-            segv_handler (int signo)
a7991f
-            {
a7991f
-              _exit (0);
a7991f
-            }
a7991f
-
a7991f
-            static int
a7991f
-            c_stack_action ()
a7991f
-            {
a7991f
-              stack_t st;
a7991f
-              struct sigaction act;
a7991f
-              int r;
a7991f
-
a7991f
-              st.ss_flags = 0;
a7991f
-              /* Use the midpoint to avoid Irix sigaltstack bug.  */
a7991f
-              st.ss_sp = alternate_signal_stack.buffer + SIGSTKSZ;
a7991f
-              st.ss_size = SIGSTKSZ;
a7991f
-              r = sigaltstack (&st, 0);
a7991f
-              if (r != 0)
a7991f
-                return 1;
a7991f
-
a7991f
-              sigemptyset (&act.sa_mask);
a7991f
-              act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
a7991f
-              act.sa_handler = segv_handler;
a7991f
-              #if FAULT_YIELDS_SIGBUS
a7991f
-              if (sigaction (SIGBUS, &act, 0) < 0)
a7991f
-                return 2;
a7991f
-              #endif
a7991f
-              if (sigaction (SIGSEGV, &act, 0) < 0)
a7991f
-                return 3;
a7991f
-              return 0;
a7991f
-            }
a7991f
-            static volatile int *
a7991f
-            recurse_1 (volatile int n, volatile int *p)
a7991f
-            {
a7991f
-              if (n >= 0)
a7991f
-                *recurse_1 (n + 1, p) += n;
a7991f
-              return p;
a7991f
-            }
a7991f
-            static int
a7991f
-            recurse (volatile int n)
a7991f
-            {
a7991f
-              int sum = 0;
a7991f
-              return *recurse_1 (n, &sum);
a7991f
-            }
a7991f
-            int
a7991f
-            main ()
a7991f
-            {
a7991f
-              int result;
a7991f
-              #if HAVE_SETRLIMIT && defined RLIMIT_STACK
a7991f
-              /* Before starting the endless recursion, try to be friendly
a7991f
-                 to the user's machine.  On some Linux 2.2.x systems, there
a7991f
-                 is no stack limit for user processes at all.  We don't want
a7991f
-                 to kill such systems.  */
a7991f
-              struct rlimit rl;
a7991f
-              rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
a7991f
-              setrlimit (RLIMIT_STACK, &rl);
a7991f
-              #endif
a7991f
-
a7991f
-              result = c_stack_action ();
a7991f
-              if (result != 0)
a7991f
-                return result;
a7991f
-              return recurse (0);
a7991f
-            }
a7991f
-           ]])],
a7991f
-        [gl_cv_sys_stack_overflow_works=yes],
a7991f
-        [gl_cv_sys_stack_overflow_works=no],
a7991f
-        [case "$host_os" in
a7991f
-                   # Guess no on native Windows.
a7991f
-           mingw*) gl_cv_sys_stack_overflow_works="guessing no" ;;
a7991f
-           *)      gl_cv_sys_stack_overflow_works=cross-compiling ;;
a7991f
-         esac
a7991f
-        ])
a7991f
-     ])
a7991f
-
a7991f
-  if test "$gl_cv_sys_stack_overflow_works" = yes; then
a7991f
-   AC_DEFINE([HAVE_STACK_OVERFLOW_HANDLING], [1],
a7991f
-     [Define to 1 if extending the stack slightly past the limit causes
a7991f
-      a SIGSEGV which can be handled on an alternate stack established
a7991f
-      with sigaltstack.])
a7991f
-
a7991f
-    dnl The ss_sp field of a stack_t is, according to POSIX, the lowest address
a7991f
-    dnl of the memory block designated as an alternate stack. But IRIX 5.3
a7991f
-    dnl interprets it as the highest address!
a7991f
-    AC_CACHE_CHECK([for correct stack_t interpretation],
a7991f
-      [gl_cv_sigaltstack_low_base], [
a7991f
-      AC_RUN_IFELSE([
a7991f
-        AC_LANG_SOURCE([[
a7991f
-#include <stdlib.h>
a7991f
-#include <signal.h>
a7991f
-#if HAVE_SYS_SIGNAL_H
a7991f
-# include <sys/signal.h>
a7991f
-#endif
a7991f
-#ifndef SIGSTKSZ
a7991f
-# define SIGSTKSZ 16384
a7991f
-#endif
a7991f
-volatile char *stack_lower_bound;
a7991f
-volatile char *stack_upper_bound;
a7991f
-static void check_stack_location (volatile char *addr)
a7991f
-{
a7991f
-  if (addr >= stack_lower_bound && addr <= stack_upper_bound)
a7991f
-    exit (0);
a7991f
-  else
a7991f
-    exit (1);
a7991f
-}
a7991f
-static void stackoverflow_handler (int sig)
a7991f
-{
a7991f
-  char dummy;
a7991f
-  check_stack_location (&dummy);
a7991f
-}
a7991f
-int main ()
a7991f
-{
a7991f
-  char mystack[2 * SIGSTKSZ];
a7991f
-  stack_t altstack;
a7991f
-  struct sigaction action;
a7991f
-  /* Install the alternate stack.  */
a7991f
-  altstack.ss_sp = mystack + SIGSTKSZ;
a7991f
-  altstack.ss_size = SIGSTKSZ;
a7991f
-  stack_lower_bound = (char *) altstack.ss_sp;
a7991f
-  stack_upper_bound = (char *) altstack.ss_sp + altstack.ss_size - 1;
a7991f
-  altstack.ss_flags = 0; /* no SS_DISABLE */
a7991f
-  if (sigaltstack (&altstack, NULL) < 0)
a7991f
-    exit (2);
a7991f
-  /* Install the SIGSEGV handler.  */
a7991f
-  sigemptyset (&action.sa_mask);
a7991f
-  action.sa_handler = &stackoverflow_handler;
a7991f
-  action.sa_flags = SA_ONSTACK;
a7991f
-  if (sigaction (SIGSEGV, &action, (struct sigaction *) NULL) < 0)
a7991f
-    exit(3);
a7991f
-  /* Provoke a SIGSEGV.  */
a7991f
-  raise (SIGSEGV);
a7991f
-  exit (4);
a7991f
-}]])],
a7991f
-      [gl_cv_sigaltstack_low_base=yes],
a7991f
-      [gl_cv_sigaltstack_low_base=no],
a7991f
-      [gl_cv_sigaltstack_low_base=cross-compiling])])
a7991f
-   if test "$gl_cv_sigaltstack_low_base" = no; then
a7991f
-      AC_DEFINE([SIGALTSTACK_SS_REVERSED], [1],
a7991f
-        [Define if sigaltstack() interprets the stack_t.ss_sp field
a7991f
-         incorrectly, as the highest address of the alternate stack range
a7991f
-         rather than as the lowest address.])
a7991f
-    fi
a7991f
-
a7991f
-   AC_CACHE_CHECK([for precise C stack overflow detection],
a7991f
-     [gl_cv_sys_xsi_stack_overflow_heuristic],
a7991f
-     [dnl On Linux/sparc64 (both in 32-bit and 64-bit mode), it would be wrong
a7991f
-      dnl to set HAVE_XSI_STACK_OVERFLOW_HEURISTIC to 1, because the third
a7991f
-      dnl argument passed to the segv_handler is a 'struct sigcontext *', not
a7991f
-      dnl an 'ucontext_t *'.  It would lead to a failure of test-c-stack2.sh.
a7991f
-      case "${host_os}--${host_cpu}" in
a7991f
-        linux*--sparc*)
a7991f
-          gl_cv_sys_xsi_stack_overflow_heuristic=no
a7991f
-          ;;
a7991f
-        *)
a7991f
-          AC_RUN_IFELSE(
a7991f
-            [AC_LANG_SOURCE(
a7991f
-               [[
a7991f
-                #include <unistd.h>
a7991f
-                #include <signal.h>
a7991f
-                #if HAVE_UCONTEXT_H
a7991f
-                # include <ucontext.h>
a7991f
-                #endif
a7991f
-                #if HAVE_SETRLIMIT
a7991f
-                # include <sys/types.h>
a7991f
-                # include <sys/time.h>
a7991f
-                # include <sys/resource.h>
a7991f
-                #endif
a7991f
-                #ifndef SIGSTKSZ
a7991f
-                # define SIGSTKSZ 16384
a7991f
-                #endif
a7991f
-
a7991f
-                static union
a7991f
-                {
a7991f
-                  char buffer[2 * SIGSTKSZ];
a7991f
-                  long double ld;
a7991f
-                  long u;
a7991f
-                  void *p;
a7991f
-                } alternate_signal_stack;
a7991f
-
a7991f
-                #if STACK_DIRECTION
a7991f
-                # define find_stack_direction(ptr) STACK_DIRECTION
a7991f
-                #else
a7991f
-                static int
a7991f
-                find_stack_direction (char const *addr)
a7991f
-                {
a7991f
-                  char dummy;
a7991f
-                  return (! addr ? find_stack_direction (&dummy)
a7991f
-                          : addr < &dummy ? 1 : -1);
a7991f
-                }
a7991f
-                #endif
a7991f
-
a7991f
-                static void
a7991f
-                segv_handler (int signo, siginfo_t *info, void *context)
a7991f
-                {
a7991f
-                  if (0 < info->si_code)
a7991f
-                    {
a7991f
-                      /* For XSI heuristics to work, we need uc_stack to
a7991f
-                         describe the interrupted stack (as on Solaris), and
a7991f
-                         not the currently executing stack (as on Linux).  */
a7991f
-                      ucontext_t const *user_context = context;
a7991f
-                      char const *stack_min = user_context->uc_stack.ss_sp;
a7991f
-                      size_t stack_size = user_context->uc_stack.ss_size;
a7991f
-                      char const *faulting_address = info->si_addr;
a7991f
-                      size_t s = faulting_address - stack_min;
a7991f
-                      size_t page_size = sysconf (_SC_PAGESIZE);
a7991f
-                      if (find_stack_direction (0) < 0)
a7991f
-                        s += page_size;
a7991f
-                      if (s < stack_size + page_size)
a7991f
-                        _exit (0);
a7991f
-                      _exit (4);
a7991f
-                    }
a7991f
-                  _exit (5);
a7991f
-                }
a7991f
-
a7991f
-                static int
a7991f
-                c_stack_action ()
a7991f
-                {
a7991f
-                  stack_t st;
a7991f
-                  struct sigaction act;
a7991f
-                  int r;
a7991f
-
a7991f
-                  st.ss_flags = 0;
a7991f
-                  /* Use the midpoint to avoid Irix sigaltstack bug.  */
a7991f
-                  st.ss_sp = alternate_signal_stack.buffer + SIGSTKSZ;
a7991f
-                  st.ss_size = SIGSTKSZ;
a7991f
-                  r = sigaltstack (&st, 0);
a7991f
-                  if (r != 0)
a7991f
-                    return 1;
a7991f
-
a7991f
-                  sigemptyset (&act.sa_mask);
a7991f
-                  act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
a7991f
-                  act.sa_sigaction = segv_handler;
a7991f
-                  #if FAULT_YIELDS_SIGBUS
a7991f
-                  if (sigaction (SIGBUS, &act, 0) < 0)
a7991f
-                    return 2;
a7991f
-                  #endif
a7991f
-                  if (sigaction (SIGSEGV, &act, 0) < 0)
a7991f
-                    return 3;
a7991f
-                  return 0;
a7991f
-                }
a7991f
-                static volatile int *
a7991f
-                recurse_1 (volatile int n, volatile int *p)
a7991f
-                {
a7991f
-                  if (n >= 0)
a7991f
-                    *recurse_1 (n + 1, p) += n;
a7991f
-                  return p;
a7991f
-                }
a7991f
-                static int
a7991f
-                recurse (volatile int n)
a7991f
-                {
a7991f
-                  int sum = 0;
a7991f
-                  return *recurse_1 (n, &sum);
a7991f
-                }
a7991f
-                int
a7991f
-                main ()
a7991f
-                {
a7991f
-                  int result;
a7991f
-                  #if HAVE_SETRLIMIT && defined RLIMIT_STACK
a7991f
-                  /* Before starting the endless recursion, try to be friendly
a7991f
-                     to the user's machine.  On some Linux 2.2.x systems, there
a7991f
-                     is no stack limit for user processes at all.  We don't want
a7991f
-                     to kill such systems.  */
a7991f
-                  struct rlimit rl;
a7991f
-                  rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
a7991f
-                  setrlimit (RLIMIT_STACK, &rl);
a7991f
-                  #endif
a7991f
-
a7991f
-                  result = c_stack_action ();
a7991f
-                  if (result != 0)
a7991f
-                    return result;
a7991f
-                  return recurse (0);
a7991f
-                }
a7991f
-               ]])],
a7991f
-            [gl_cv_sys_xsi_stack_overflow_heuristic=yes],
a7991f
-            [gl_cv_sys_xsi_stack_overflow_heuristic=no],
a7991f
-            [gl_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])
a7991f
-          ;;
a7991f
-      esac
a7991f
-     ])
a7991f
-
a7991f
-   if test "$gl_cv_sys_xsi_stack_overflow_heuristic" = yes; then
a7991f
-     AC_DEFINE([HAVE_XSI_STACK_OVERFLOW_HEURISTIC], [1],
a7991f
-       [Define to 1 if extending the stack slightly past the limit causes
a7991f
-        a SIGSEGV, and an alternate stack can be established with sigaltstack,
a7991f
-        and the signal handler is passed a context that specifies the
a7991f
-        run time stack.  This behavior is defined by POSIX 1003.1-2001
a7991f
-        with the X/Open System Interface (XSI) option
a7991f
-        and is a standardized way to implement a SEGV-based stack
a7991f
-        overflow detection heuristic.])
a7991f
-   fi
a7991f
-  fi])
a7991f
-
a7991f
-
a7991f
-AC_DEFUN([gl_PREREQ_C_STACK],
a7991f
-  [AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC])
a7991f
-
a7991f
-   AC_CHECK_FUNCS_ONCE([sigaltstack])
a7991f
-   AC_CHECK_DECLS([sigaltstack], , , [[#include <signal.h>]])
a7991f
-
a7991f
-   AC_CHECK_HEADERS_ONCE([ucontext.h])
a7991f
-
a7991f
-   AC_CHECK_TYPES([stack_t], , , [[#include <signal.h>]])
a7991f
-
a7991f
-   dnl c-stack does not need -lsigsegv if the system has XSI heuristics.
a7991f
-   if test "$gl_cv_sys_xsi_stack_overflow_heuristic" != yes; then
a7991f
-     gl_LIBSIGSEGV
a7991f
-     if test "$gl_cv_lib_sigsegv" = yes; then
a7991f
-       AC_SUBST([LIBCSTACK], [$LIBSIGSEGV])
a7991f
-       AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV])
a7991f
-     fi
a7991f
-   fi
a7991f
-])
a7991f
+# serial 23
a7991f
 
a7991f
 AC_DEFUN([gl_C_STACK],
a7991f
 [
a7991f
-  dnl Prerequisites of lib/c-stack.c.
a7991f
-  gl_PREREQ_C_STACK
a7991f
+  dnl 'c-stack' needs -lsigsegv if and only if the 'sigsegv' module needs it.
a7991f
+  if test "$with_libsigsegv" = yes; then
a7991f
+    if test "$gl_cv_lib_sigsegv" = yes; then
a7991f
+      AC_SUBST([LIBCSTACK], [$LIBSIGSEGV])
a7991f
+      AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV])
a7991f
+    fi
a7991f
+  fi
a7991f
 ])
a7991f
diff --git a/src/Makefile.am b/src/Makefile.am
a7991f
index 1aebcf7..055ee17 100644
a7991f
--- a/src/Makefile.am
a7991f
+++ b/src/Makefile.am
a7991f
@@ -45,7 +45,7 @@ LDADD = \
a7991f
   ../lib/libgreputils.a $(LIBINTL) ../lib/libgreputils.a $(LIBICONV) \
a7991f
   $(LIBTHREAD)
a7991f
 
a7991f
-grep_LDADD = $(LDADD) $(PCRE_LIBS) $(LIBCSTACK)
a7991f
+grep_LDADD = $(LDADD) $(PCRE_LIBS) -lsigsegv
a7991f
 localedir = $(datadir)/locale
a7991f
 AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
a7991f
 
a7991f
diff --git a/src/Makefile.in b/src/Makefile.in
a7991f
index 20c43b5..a276db8 100644
a7991f
--- a/src/Makefile.in
a7991f
+++ b/src/Makefile.in
a7991f
@@ -1541,7 +1541,7 @@ LDADD = \
a7991f
   ../lib/libgreputils.a $(LIBINTL) ../lib/libgreputils.a $(LIBICONV) \
a7991f
   $(LIBTHREAD)
a7991f
 
a7991f
-grep_LDADD = $(LDADD) $(PCRE_LIBS) $(LIBCSTACK)
a7991f
+grep_LDADD = $(LDADD) $(PCRE_LIBS) -lsigsegv
a7991f
 AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
a7991f
 EXTRA_DIST = egrep.sh
a7991f
 CLEANFILES = egrep fgrep *-t