root/maint/gnulib/tests/zerosize-ptr.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. zerosize_ptr

   1 /* Return a pointer to a zero-size object in memory.
   2    Copyright (C) 2009-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* ISO C 99 does not allow memcmp(), memchr() etc. to be invoked with a NULL
  18    argument.  Therefore this file produces a non-NULL pointer which cannot
  19    be dereferenced, if possible.  */
  20 
  21 /* On Android, when targeting Android 4.4 or older with a GCC toolchain,
  22    prevent a compilation error
  23      "error: call to 'mmap' declared with attribute error: mmap is not
  24       available with _FILE_OFFSET_BITS=64 when using GCC until android-21.
  25       Either raise your minSdkVersion, disable _FILE_OFFSET_BITS=64, or
  26       switch to Clang."
  27    The files that we access in this compilation unit are less than 2 GB
  28    large.  */
  29 #if defined __ANDROID__
  30 # undef _FILE_OFFSET_BITS
  31 # undef __USE_FILE_OFFSET64
  32 #endif
  33 
  34 #include <stdlib.h>
  35 
  36 /* Test whether mmap() and mprotect() are available.
  37    We don't use HAVE_MMAP, because AC_FUNC_MMAP would not define it on HP-UX.
  38    HAVE_MPROTECT is not enough, because mingw does not have mmap() but has an
  39    mprotect() function in libgcc.a.
  40    And OS/2 kLIBC has <sys/mman.h> and mprotect(), but not mmap().  */
  41 #if HAVE_SYS_MMAN_H && HAVE_MPROTECT && !defined __KLIBC__
  42 # include <fcntl.h>
  43 # include <unistd.h>
  44 # include <sys/types.h>
  45 # include <sys/mman.h>
  46 /* Define MAP_FILE when it isn't otherwise.  */
  47 # ifndef MAP_FILE
  48 #  define MAP_FILE 0
  49 # endif
  50 #endif
  51 
  52 /* Return a pointer to a zero-size object in memory (that is, actually, a
  53    pointer to a page boundary where the previous page is readable and writable
  54    and the next page is neither readable not writable), if possible.
  55    Return NULL otherwise.  */
  56 
  57 static void *
  58 zerosize_ptr (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60 /* Use mmap and mprotect when they exist.  Don't test HAVE_MMAP, because it is
  61    not defined on HP-UX 11 (since it does not support MAP_FIXED).  */
  62 #if HAVE_SYS_MMAN_H && HAVE_MPROTECT && !defined __KLIBC__
  63 # if HAVE_MAP_ANONYMOUS
  64   const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
  65   const int fd = -1;
  66 # else /* !HAVE_MAP_ANONYMOUS */
  67   const int flags = MAP_FILE | MAP_PRIVATE;
  68   int fd = open ("/dev/zero", O_RDONLY, 0666);
  69   if (fd >= 0)
  70 # endif
  71     {
  72       int pagesize = getpagesize ();
  73       char *two_pages =
  74         (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
  75                        flags, fd, 0);
  76       if (two_pages != (char *)(-1)
  77           && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
  78         return two_pages + pagesize;
  79     }
  80 #endif
  81   return NULL;
  82 }

/* [previous][next][first][last][top][bottom][index][help] */