memchr.m4 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # memchr.m4 serial 12
  2. dnl Copyright (C) 2002-2004, 2009-2017 Free Software Foundation, Inc.
  3. dnl This file is free software; the Free Software Foundation
  4. dnl gives unlimited permission to copy and/or distribute it,
  5. dnl with or without modifications, as long as this notice is preserved.
  6. AC_DEFUN_ONCE([gl_FUNC_MEMCHR],
  7. [
  8. dnl Check for prerequisites for memory fence checks.
  9. gl_FUNC_MMAP_ANON
  10. AC_CHECK_HEADERS_ONCE([sys/mman.h])
  11. AC_CHECK_FUNCS_ONCE([mprotect])
  12. AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
  13. m4_ifdef([gl_FUNC_MEMCHR_OBSOLETE], [
  14. dnl These days, we assume memchr is present. But if support for old
  15. dnl platforms is desired:
  16. AC_CHECK_FUNCS_ONCE([memchr])
  17. if test $ac_cv_func_memchr = no; then
  18. HAVE_MEMCHR=0
  19. fi
  20. ])
  21. if test $HAVE_MEMCHR = 1; then
  22. # Detect platform-specific bugs in some versions of glibc:
  23. # memchr should not dereference anything with length 0
  24. # http://bugzilla.redhat.com/499689
  25. # memchr should not dereference overestimated length after a match
  26. # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737
  27. # http://sourceware.org/bugzilla/show_bug.cgi?id=10162
  28. # Assume that memchr works on platforms that lack mprotect.
  29. AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works],
  30. [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
  31. #include <string.h>
  32. #if HAVE_SYS_MMAN_H
  33. # include <fcntl.h>
  34. # include <unistd.h>
  35. # include <sys/types.h>
  36. # include <sys/mman.h>
  37. # ifndef MAP_FILE
  38. # define MAP_FILE 0
  39. # endif
  40. #endif
  41. ]], [[
  42. int result = 0;
  43. char *fence = NULL;
  44. #if HAVE_SYS_MMAN_H && HAVE_MPROTECT
  45. # if HAVE_MAP_ANONYMOUS
  46. const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
  47. const int fd = -1;
  48. # else /* !HAVE_MAP_ANONYMOUS */
  49. const int flags = MAP_FILE | MAP_PRIVATE;
  50. int fd = open ("/dev/zero", O_RDONLY, 0666);
  51. if (fd >= 0)
  52. # endif
  53. {
  54. int pagesize = getpagesize ();
  55. char *two_pages =
  56. (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
  57. flags, fd, 0);
  58. if (two_pages != (char *)(-1)
  59. && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
  60. fence = two_pages + pagesize;
  61. }
  62. #endif
  63. if (fence)
  64. {
  65. if (memchr (fence, 0, 0))
  66. result |= 1;
  67. strcpy (fence - 9, "12345678");
  68. if (memchr (fence - 9, 0, 79) != fence - 1)
  69. result |= 2;
  70. if (memchr (fence - 1, 0, 3) != fence - 1)
  71. result |= 4;
  72. }
  73. return result;
  74. ]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no],
  75. [dnl Be pessimistic for now.
  76. gl_cv_func_memchr_works="guessing no"])])
  77. if test "$gl_cv_func_memchr_works" != yes; then
  78. REPLACE_MEMCHR=1
  79. fi
  80. fi
  81. ])
  82. # Prerequisites of lib/memchr.c.
  83. AC_DEFUN([gl_PREREQ_MEMCHR], [
  84. AC_CHECK_HEADERS([bp-sym.h])
  85. ])