(root)/
findutils-4.9.0/
gnulib-tests/
zerosize-ptr.h
       1  /* Return a pointer to a zero-size object in memory.
       2     Copyright (C) 2009-2022 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)
      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  }