immutable: Add tests.
[gnulib.git] / m4 / mprotect.m4
blob13e27e2fd24c794be237568b6e42eaa987826786
1 # mprotect.m4 serial 1
2 dnl Copyright (C) 1993-2021 Free Software Foundation, Inc.
3 dnl This file is free software, distributed under the terms of the GNU
4 dnl General Public License as published by the Free Software Foundation;
5 dnl either version 2 of the License, or (at your option) any later version.
6 dnl As a special exception to the GNU General Public License, this file
7 dnl may be distributed as part of a program that contains a configuration
8 dnl script generated by Autoconf, under the same distribution terms as
9 dnl the rest of that program.
11 dnl Test whether mprotect() works.
12 dnl Sets gl_cv_func_mprotect_works and defines HAVE_WORKING_MPROTECT.
14 AC_DEFUN([gl_FUNC_MPROTECT_WORKS],
16   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
17   AC_REQUIRE([gl_FUNC_MMAP_ANON])
19   AC_CHECK_FUNCS([mprotect])
20   if test $ac_cv_func_mprotect = yes; then
21     AC_CACHE_CHECK([for working mprotect], [gl_cv_func_mprotect_works],
22       [if test $cross_compiling = no; then
23          mprotect_prog='
24            #include <sys/types.h>
25            /* Declare malloc().  */
26            #include <stdlib.h>
27            /* Declare getpagesize().  */
28            #if HAVE_UNISTD_H
29             #include <unistd.h>
30            #endif
31            #ifdef __hpux
32             extern
33             #ifdef __cplusplus
34             "C"
35             #endif
36             int getpagesize (void);
37            #endif
38            /* Declare mprotect().  */
39            #include <sys/mman.h>
40            char foo;
41            int main ()
42            {
43              unsigned long pagesize = getpagesize ();
44            #define page_align(address)  (char*)((unsigned long)(address) & -pagesize)
45          '
46          no_mprotect=
47          AC_RUN_IFELSE(
48            [AC_LANG_SOURCE([
49               [$mprotect_prog
50                  if ((pagesize - 1) & pagesize)
51                    return 1;
52                  return 0;
53                }
54               ]])
55            ],
56            [],
57            [no_mprotect=1],
58            [:])
59          mprotect_prog="$mprotect_prog"'
60            char* area = (char*) malloc (6 * pagesize);
61            char* fault_address = area + pagesize*7/2;
62          '
63          if test -z "$no_mprotect"; then
64            AC_RUN_IFELSE(
65              [AC_LANG_SOURCE([
66                 GL_NOCRASH
67                 [$mprotect_prog
68                    nocrash_init();
69                    if (mprotect (page_align (fault_address), pagesize, PROT_NONE) < 0)
70                      return 0;
71                    foo = *fault_address; /* this should cause an exception or signal */
72                    return 0;
73                  }
74                 ]])
75              ],
76              [no_mprotect=1],
77              [],
78              [:])
79          fi
80          if test -z "$no_mprotect"; then
81            AC_RUN_IFELSE(
82              [AC_LANG_SOURCE([
83                 GL_NOCRASH
84                 [$mprotect_prog
85                    nocrash_init();
86                    if (mprotect (page_align (fault_address), pagesize, PROT_NONE) < 0)
87                      return 0;
88                    *fault_address = 'z'; /* this should cause an exception or signal */
89                    return 0;
90                  }
91                 ]])
92              ],
93              [no_mprotect=1],
94              [],
95              [:])
96          fi
97          if test -z "$no_mprotect"; then
98            AC_RUN_IFELSE(
99              [AC_LANG_SOURCE([
100                 GL_NOCRASH
101                 [$mprotect_prog
102                    nocrash_init();
103                    if (mprotect (page_align (fault_address), pagesize, PROT_READ) < 0)
104                      return 0;
105                    *fault_address = 'z'; /* this should cause an exception or signal */
106                    return 0;
107                  }
108                 ]])
109              ],
110              [no_mprotect=1],
111              [],
112              [:])
113          fi
114          if test -z "$no_mprotect"; then
115            AC_RUN_IFELSE(
116              [AC_LANG_SOURCE([
117                 GL_NOCRASH
118                 [$mprotect_prog
119                    nocrash_init();
120                    if (mprotect (page_align (fault_address), pagesize, PROT_READ) < 0)
121                      return 1;
122                    if (mprotect (page_align (fault_address), pagesize, PROT_READ | PROT_WRITE) < 0)
123                      return 1;
124                    *fault_address = 'z'; /* this should not cause an exception or signal */
125                    return 0;
126                  }
127                 ]])
128              ],
129              [],
130              [no_mprotect=1],
131              [:])
132          fi
133          if test -z "$no_mprotect"; then
134            gl_cv_func_mprotect_works=yes
135          else
136            gl_cv_func_mprotect_works=no
137          fi
138        else
139          dnl When cross-compiling, assume the known behaviour.
140          case "$host_os" in
141            dnl Guess yes on Linux systems, glibc systems,
142            dnl macOS, BSD systems, AIX, HP-UX, IRIX, Solaris, Cygwin.
143            linux-* | linux | *-gnu* | gnu* | \
144            darwin* | freebsd* | dragonfly* | netbsd* | openbsd* | \
145            aix* | hpux* | irix* | solaris* | cygwin*)
146              gl_cv_func_mprotect_works="guessing yes" ;;
147            mingw*)
148              gl_cv_func_mprotect_works="guessing no" ;;
149            *)
150              dnl If we don't know, obey --enable-cross-guesses.
151              gl_cv_func_mprotect_works="$gl_cross_guess_normal" ;;
152          esac
153        fi
154       ])
155     case "$gl_cv_func_mprotect_works" in
156       *yes)
157         AC_DEFINE([HAVE_WORKING_MPROTECT], [1],
158           [have a working mprotect() function])
159         ;;
160     esac
161   fi