Blame gnulib-tests/zerosize-ptr.h

Packit Service 2723c6
/* Return a pointer to a zero-size object in memory.
Packit Service 2723c6
   Copyright (C) 2009-2018 Free Software Foundation, Inc.
Packit Service 2723c6
Packit Service 2723c6
   This program is free software: you can redistribute it and/or modify
Packit Service 2723c6
   it under the terms of the GNU General Public License as published by
Packit Service 2723c6
   the Free Software Foundation; either version 3 of the License, or
Packit Service 2723c6
   (at your option) any later version.
Packit Service 2723c6
Packit Service 2723c6
   This program is distributed in the hope that it will be useful,
Packit Service 2723c6
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 2723c6
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 2723c6
   GNU General Public License for more details.
Packit Service 2723c6
Packit Service 2723c6
   You should have received a copy of the GNU General Public License
Packit Service 2723c6
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service 2723c6
Packit Service 2723c6
/* ISO C 99 does not allow memcmp(), memchr() etc. to be invoked with a NULL
Packit Service 2723c6
   argument.  Therefore this file produces a non-NULL pointer which cannot
Packit Service 2723c6
   be dereferenced, if possible.  */
Packit Service 2723c6
Packit Service 2723c6
/* On Android, when targeting Android 4.4 or older with a GCC toolchain,
Packit Service 2723c6
   prevent a compilation error
Packit Service 2723c6
     "error: call to 'mmap' declared with attribute error: mmap is not
Packit Service 2723c6
      available with _FILE_OFFSET_BITS=64 when using GCC until android-21.
Packit Service 2723c6
      Either raise your minSdkVersion, disable _FILE_OFFSET_BITS=64, or
Packit Service 2723c6
      switch to Clang."
Packit Service 2723c6
   The files that we access in this compilation unit are less than 2 GB
Packit Service 2723c6
   large.  */
Packit Service 2723c6
#if defined __ANDROID__
Packit Service 2723c6
# undef _FILE_OFFSET_BITS
Packit Service 2723c6
# undef __USE_FILE_OFFSET64
Packit Service 2723c6
#endif
Packit Service 2723c6
Packit Service 2723c6
#include <stdlib.h>
Packit Service 2723c6
Packit Service 2723c6
/* Test whether mmap() and mprotect() are available.
Packit Service 2723c6
   We don't use HAVE_MMAP, because AC_FUNC_MMAP would not define it on HP-UX.
Packit Service 2723c6
   HAVE_MPROTECT is not enough, because mingw does not have mmap() but has an
Packit Service 2723c6
   mprotect() function in libgcc.a.  */
Packit Service 2723c6
#if HAVE_SYS_MMAN_H && HAVE_MPROTECT
Packit Service 2723c6
# include <fcntl.h>
Packit Service 2723c6
# include <unistd.h>
Packit Service 2723c6
# include <sys/types.h>
Packit Service 2723c6
# include <sys/mman.h>
Packit Service 2723c6
/* Define MAP_FILE when it isn't otherwise.  */
Packit Service 2723c6
# ifndef MAP_FILE
Packit Service 2723c6
#  define MAP_FILE 0
Packit Service 2723c6
# endif
Packit Service 2723c6
#endif
Packit Service 2723c6
Packit Service 2723c6
/* Return a pointer to a zero-size object in memory (that is, actually, a
Packit Service 2723c6
   pointer to a page boundary where the previous page is readable and writable
Packit Service 2723c6
   and the next page is neither readable not writable), if possible.
Packit Service 2723c6
   Return NULL otherwise.  */
Packit Service 2723c6
Packit Service 2723c6
static void *
Packit Service 2723c6
zerosize_ptr (void)
Packit Service 2723c6
{
Packit Service 2723c6
/* Use mmap and mprotect when they exist.  Don't test HAVE_MMAP, because it is
Packit Service 2723c6
   not defined on HP-UX 11 (since it does not support MAP_FIXED).  */
Packit Service 2723c6
#if HAVE_SYS_MMAN_H && HAVE_MPROTECT
Packit Service 2723c6
# if HAVE_MAP_ANONYMOUS
Packit Service 2723c6
  const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
Packit Service 2723c6
  const int fd = -1;
Packit Service 2723c6
# else /* !HAVE_MAP_ANONYMOUS */
Packit Service 2723c6
  const int flags = MAP_FILE | MAP_PRIVATE;
Packit Service 2723c6
  int fd = open ("/dev/zero", O_RDONLY, 0666);
Packit Service 2723c6
  if (fd >= 0)
Packit Service 2723c6
# endif
Packit Service 2723c6
    {
Packit Service 2723c6
      int pagesize = getpagesize ();
Packit Service 2723c6
      char *two_pages =
Packit Service 2723c6
        (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
Packit Service 2723c6
                       flags, fd, 0);
Packit Service 2723c6
      if (two_pages != (char *)(-1)
Packit Service 2723c6
          && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
Packit Service 2723c6
        return two_pages + pagesize;
Packit Service 2723c6
    }
Packit Service 2723c6
#endif
Packit Service 2723c6
  return NULL;
Packit Service 2723c6
}