# strncat.m4 # serial 9 dnl Copyright (C) 2002-2004, 2009-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN_ONCE([gl_FUNC_STRNCAT], [ AC_REQUIRE([gl_STRING_H_DEFAULTS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles dnl Check for prerequisites for memory fence checks. gl_FUNC_MMAP_ANON AC_CHECK_HEADERS_ONCE([sys/mman.h]) AC_CHECK_FUNCS_ONCE([mprotect]) dnl Detect bug in Solaris 8..11.4 on SPARC and Solaris 11.0 on x86: dnl strncat should not dereference more than n bytes, but always dereferences dnl n+1 bytes if the first n bytes don't contain a NUL byte. dnl Assume that strncat works on platforms that lack mprotect. AC_CACHE_CHECK([whether strncat works], [gl_cv_func_strncat_works], [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include #if HAVE_SYS_MMAN_H # include # include # include # include # ifndef MAP_FILE # define MAP_FILE 0 # endif #endif ]GL_MDA_DEFINES], [[ char *fence = NULL; #if HAVE_SYS_MMAN_H && HAVE_MPROTECT # if HAVE_MAP_ANONYMOUS const int flags = MAP_ANONYMOUS | MAP_PRIVATE; const int fd = -1; # else /* !HAVE_MAP_ANONYMOUS */ const int flags = MAP_FILE | MAP_PRIVATE; int fd = open ("/dev/zero", O_RDONLY, 0666); if (fd >= 0) # endif { long int pagesize = sysconf (_SC_PAGESIZE); char *two_pages = (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, flags, fd, 0); if (two_pages != (char *)(-1) && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0) fence = two_pages + pagesize; } #endif if (fence) { char dest[8]; dest[0] = '*'; dest[1] = 'a'; dest[2] = '\0'; dest[3] = 'w'; dest[4] = 'x'; dest[5] = 'y'; dest[6] = 'z'; *(fence - 3) = '7'; *(fence - 2) = '2'; *(fence - 1) = '9'; if (strncat (dest + 1, fence - 3, 3) != dest + 1) return 1; if (dest[0] != '*') return 2; if (dest[1] != 'a' || dest[2] != '7' || dest[3] != '2' || dest[4] != '9' || dest[5] != '\0') return 3; if (dest[6] != 'z') return 4; } return 0; ]])], [gl_cv_func_strncat_works=yes], [gl_cv_func_strncat_works=no], [ case "$host_os" in # Guess no on Solaris. solaris*) gl_cv_func_strncat_works="guessing no" ;; # Guess yes on native Windows. mingw* | windows*) gl_cv_func_strncat_works="guessing yes" ;; # Guess yes otherwise. *) gl_cv_func_strncat_works="guessing yes" ;; esac ]) ]) case "$gl_cv_func_strncat_works" in *yes) ;; *) REPLACE_STRNCAT=1 ;; esac ]) # Prerequisites of lib/strncat.c. AC_DEFUN([gl_PREREQ_STRNCAT], [ : ])