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