| # sigaltstack.m4 | |
| # serial 17 | |
| dnl Copyright (C) 2002-2026 Free Software Foundation, Inc. | |
| dnl This file is free software, distributed under the terms of the GNU | |
| dnl General Public License as published by the Free Software Foundation; | |
| dnl either version 2 of the License, or (at your option) any later version. | |
| dnl As a special exception to the GNU General Public License, this file | |
| dnl may be distributed as part of a program that contains a configuration | |
| dnl script generated by Autoconf, under the same distribution terms as | |
| dnl the rest of that program. | |
| dnl Written by Bruno Haible and Eric Blake. | |
| AC_DEFUN([SV_SIGALTSTACK], | |
| [ | |
| AC_REQUIRE([AC_PROG_CC]) | |
| AC_REQUIRE([AC_CANONICAL_HOST]) | |
| AC_CHECK_FUNCS_ONCE([sigaltstack setrlimit]) | |
| if test "$ac_cv_func_sigaltstack" = yes; then | |
| AC_CHECK_TYPE([stack_t], , | |
| [AC_DEFINE(stack_t, [struct sigaltstack], | |
| [Define to 'struct sigaltstack' if that's the type of the argument to sigaltstack]) | |
| ], | |
| [ | |
| #include <signal.h> | |
| #if HAVE_SYS_SIGNAL_H | |
| # include <sys/signal.h> | |
| #endif | |
| ]) | |
| fi | |
| AC_CACHE_CHECK([for working sigaltstack], [sv_cv_sigaltstack], [ | |
| if test "$ac_cv_func_sigaltstack" = yes; then | |
| case "$host_os" in | |
| macos* | darwin[[6-9]]* | darwin[[1-9]][[0-9]]*) | |
| # On MacOS X 10.2 or newer, just assume that if it compiles, it will | |
| # work. If we were to perform the real test, 1 Crash Report dialog | |
| # window would pop up. | |
| AC_LINK_IFELSE([ | |
| AC_LANG_PROGRAM([[#include <signal.h>]], | |
| [[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])], | |
| [sv_cv_sigaltstack="guessing yes"], | |
| [sv_cv_sigaltstack=no]) | |
| ;; | |
| *) | |
| AC_RUN_IFELSE([ | |
| AC_LANG_SOURCE([[ | |
| #include <stdlib.h> | |
| #include <signal.h> | |
| #if HAVE_SYS_SIGNAL_H | |
| # include <sys/signal.h> | |
| #endif | |
| #if HAVE_SETRLIMIT | |
| # include <sys/types.h> | |
| # include <sys/time.h> | |
| # include <sys/resource.h> | |
| #endif | |
| void stackoverflow_handler (int sig) | |
| { | |
| /* If we get here, the stack overflow was caught. */ | |
| exit (0); | |
| } | |
| volatile int * recurse_1 (volatile int n, volatile int *p) | |
| { | |
| if (n >= 0) | |
| *recurse_1 (n + 1, p) += n; | |
| return p; | |
| } | |
| int recurse (volatile int n) | |
| { | |
| int sum = 0; | |
| return *recurse_1 (n, &sum); | |
| } | |
| char mystack[2 * (1 << 24)]; | |
| int main () | |
| { | |
| stack_t altstack; | |
| struct sigaction action; | |
| #if defined HAVE_SETRLIMIT && defined RLIMIT_STACK | |
| /* Before starting the endless recursion, try to be friendly to the user's | |
| machine. On some Linux 2.2.x systems, there is no stack limit for user | |
| processes at all. We don't want to kill such systems. */ | |
| struct rlimit rl; | |
| rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */ | |
| setrlimit (RLIMIT_STACK, &rl); | |
| #endif | |
| /* Install the alternate stack. */ | |
| #ifdef SIGSTKSZ | |
| if (sizeof mystack < SIGSTKSZ) | |
| exit (3); | |
| #endif | |
| altstack.ss_sp = mystack; | |
| altstack.ss_size = sizeof mystack; | |
| altstack.ss_flags = 0; /* no SS_DISABLE */ | |
| if (sigaltstack (&altstack, NULL) < 0) | |
| exit (1); | |
| /* Install the SIGSEGV handler. */ | |
| sigemptyset (&action.sa_mask); | |
| action.sa_handler = &stackoverflow_handler; | |
| action.sa_flags = SA_ONSTACK; | |
| sigaction (SIGSEGV, &action, (struct sigaction *) NULL); | |
| sigaction (SIGBUS, &action, (struct sigaction *) NULL); | |
| /* Provoke a stack overflow. */ | |
| recurse (0); | |
| exit (2); | |
| }]])], | |
| [sv_cv_sigaltstack=yes], | |
| [sv_cv_sigaltstack=no], | |
| [ | |
| dnl FIXME: Put in some more known values here. | |
| case "$host_os" in | |
| *) | |
| AC_LINK_IFELSE([ | |
| AC_LANG_PROGRAM([[#include <signal.h>]], | |
| [[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])], | |
| [sv_cv_sigaltstack="guessing yes"], | |
| [sv_cv_sigaltstack=no]) | |
| ;; | |
| esac | |
| ]) | |
| ;; | |
| esac | |
| else | |
| sv_cv_sigaltstack=no | |
| fi | |
| ]) | |
| if test "$sv_cv_sigaltstack" != no; then | |
| AC_DEFINE([HAVE_WORKING_SIGALTSTACK], [1], | |
| [Define if you have the sigaltstack() function and it works.]) | |
| fi | |
| ]) |