doc: Improve usability of generated PDF.
[gnulib.git] / m4 / strncat.m4
blob2b597bd0a0bedd477310b68d485586174d818481
1 # strncat.m4
2 # serial 9
3 dnl Copyright (C) 2002-2004, 2009-2024 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
7 dnl This file is offered as-is, without any warranty.
9 AC_DEFUN_ONCE([gl_FUNC_STRNCAT],
11   AC_REQUIRE([gl_STRING_H_DEFAULTS])
12   AC_REQUIRE([AC_PROG_CC])
13   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
15   dnl Check for prerequisites for memory fence checks.
16   gl_FUNC_MMAP_ANON
17   AC_CHECK_HEADERS_ONCE([sys/mman.h])
18   AC_CHECK_FUNCS_ONCE([mprotect])
20   dnl Detect bug in Solaris 8..11.4 on SPARC and Solaris 11.0 on x86:
21   dnl strncat should not dereference more than n bytes, but always dereferences
22   dnl n+1 bytes if the first n bytes don't contain a NUL byte.
23   dnl Assume that strncat works on platforms that lack mprotect.
24   AC_CACHE_CHECK([whether strncat works], [gl_cv_func_strncat_works],
25     [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
26 #include <string.h>
27 #if HAVE_SYS_MMAN_H
28 # include <fcntl.h>
29 # include <unistd.h>
30 # include <sys/types.h>
31 # include <sys/mman.h>
32 # ifndef MAP_FILE
33 #  define MAP_FILE 0
34 # endif
35 #endif
36 ]GL_MDA_DEFINES],
38   char *fence = NULL;
39 #if HAVE_SYS_MMAN_H && HAVE_MPROTECT
40 # if HAVE_MAP_ANONYMOUS
41   const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
42   const int fd = -1;
43 # else /* !HAVE_MAP_ANONYMOUS */
44   const int flags = MAP_FILE | MAP_PRIVATE;
45   int fd = open ("/dev/zero", O_RDONLY, 0666);
46   if (fd >= 0)
47 # endif
48     {
49       long int pagesize = sysconf (_SC_PAGESIZE);
50       char *two_pages =
51         (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
52                        flags, fd, 0);
53       if (two_pages != (char *)(-1)
54           && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
55         fence = two_pages + pagesize;
56     }
57 #endif
58   if (fence)
59     {
60       char dest[8];
62       dest[0] = '*';
63       dest[1] = 'a';
64       dest[2] = '\0';
65       dest[3] = 'w';
66       dest[4] = 'x';
67       dest[5] = 'y';
68       dest[6] = 'z';
70       *(fence - 3) = '7';
71       *(fence - 2) = '2';
72       *(fence - 1) = '9';
74       if (strncat (dest + 1, fence - 3, 3) != dest + 1)
75         return 1;
76       if (dest[0] != '*')
77         return 2;
78       if (dest[1] != 'a'
79           || dest[2] != '7' || dest[3] != '2' || dest[4] != '9'
80           || dest[5] != '\0')
81         return 3;
82       if (dest[6] != 'z')
83         return 4;
84     }
85   return 0;
86 ]])], [gl_cv_func_strncat_works=yes], [gl_cv_func_strncat_works=no],
87        [
88         case "$host_os" in
89                              # Guess no on Solaris.
90           solaris*)          gl_cv_func_strncat_works="guessing no" ;;
91                              # Guess yes on native Windows.
92           mingw* | windows*) gl_cv_func_strncat_works="guessing yes" ;;
93                              # Guess yes otherwise.
94           *)                 gl_cv_func_strncat_works="guessing yes" ;;
95         esac
96        ])
97     ])
98   case "$gl_cv_func_strncat_works" in
99     *yes) ;;
100     *) REPLACE_STRNCAT=1 ;;
101   esac
104 # Prerequisites of lib/strncat.c.
105 AC_DEFUN([gl_PREREQ_STRNCAT], [
106   :