emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/seccomp a4eb3bd 2/4: Add Gnulib module 'read-file'.


From: Philipp Stephani
Subject: scratch/seccomp a4eb3bd 2/4: Add Gnulib module 'read-file'.
Date: Tue, 29 Dec 2020 08:50:00 -0500 (EST)

branch: scratch/seccomp
commit a4eb3bd7d5c4ae63efebfd77120c64e993cb872e
Author: Philipp Stephani <phst@google.com>
Commit: Philipp Stephani <phst@google.com>

    Add Gnulib module 'read-file'.
    
    All changes are autogenerated by running admin/merge-gnulib, except
    for the change to merge-gnulib itself.
    
    * admin/merge-gnulib (GNULIB_MODULES): Add 'read-file' module.
---
 admin/merge-gnulib |   2 +-
 lib/fopen.c        | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/ftell.c        |  37 +++++++++
 lib/ftello.c       |  85 ++++++++++++++++++++
 lib/gnulib.mk.in   |  79 ++++++++++++++++++
 lib/lseek.c        |  71 +++++++++++++++++
 lib/read-file.c    | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/read-file.h    |  37 +++++++++
 lib/realloc.c      |  79 ++++++++++++++++++
 m4/fopen.m4        | 148 ++++++++++++++++++++++++++++++++++
 m4/fseeko.m4       |  77 ++++++++++++++++++
 m4/ftell.m4        |  15 ++++
 m4/ftello.m4       | 142 +++++++++++++++++++++++++++++++++
 m4/gnulib-comp.m4  |  71 +++++++++++++++++
 m4/lseek.m4        |  72 +++++++++++++++++
 m4/malloc.m4       |  98 +++++++++++++++++++++++
 m4/read-file.m4    |   8 ++
 m4/realloc.m4      |  76 ++++++++++++++++++
 18 files changed, 1547 insertions(+), 1 deletion(-)

diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 880dc5e..901862a 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -40,7 +40,7 @@ GNULIB_MODULES='
   ieee754-h ignore-value intprops largefile libgmp lstat
   manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
   pathmax pipe2 pselect pthread_sigmask
-  qcopy-acl readlink readlinkat regex
+  qcopy-acl read-file readlink readlinkat regex
   sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio
   stpcpy strnlen strtoimax symlink sys_stat sys_time
   tempname time time_r time_rz timegm timer-time timespec-add timespec-sub
diff --git a/lib/fopen.c b/lib/fopen.c
new file mode 100644
index 0000000..2527850
--- /dev/null
+++ b/lib/fopen.c
@@ -0,0 +1,230 @@
+/* Open a stream to a file.
+   Copyright (C) 2007-2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
+
+/* If the user's config.h happens to include <stdio.h>, let it include only
+   the system's <stdio.h> here, so that orig_fopen doesn't recurse to
+   rpl_fopen.  */
+#define _GL_ALREADY_INCLUDING_STDIO_H
+#include <config.h>
+
+/* Get the original definition of fopen.  It might be defined as a macro.  */
+#include <stdio.h>
+#undef _GL_ALREADY_INCLUDING_STDIO_H
+
+static FILE *
+orig_fopen (const char *filename, const char *mode)
+{
+  return fopen (filename, mode);
+}
+
+/* Specification.  */
+/* Write "stdio.h" here, not <stdio.h>, otherwise OSF/1 5.1 DTK cc eliminates
+   this include because of the preliminary #include <stdio.h> above.  */
+#include "stdio.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+FILE *
+rpl_fopen (const char *filename, const char *mode)
+{
+  int open_direction;
+  int open_flags;
+#if GNULIB_FOPEN_GNU
+  bool open_flags_gnu;
+# define BUF_SIZE 80
+  char fdopen_mode_buf[BUF_SIZE + 1];
+#endif
+
+#if defined _WIN32 && ! defined __CYGWIN__
+  if (strcmp (filename, "/dev/null") == 0)
+    filename = "NUL";
+#endif
+
+  /* Parse the mode.  */
+  open_direction = 0;
+  open_flags = 0;
+#if GNULIB_FOPEN_GNU
+  open_flags_gnu = false;
+#endif
+  {
+    const char *p = mode;
+#if GNULIB_FOPEN_GNU
+    char *q = fdopen_mode_buf;
+#endif
+
+    for (; *p != '\0'; p++)
+      {
+        switch (*p)
+          {
+          case 'r':
+            open_direction = O_RDONLY;
+#if GNULIB_FOPEN_GNU
+            if (q < fdopen_mode_buf + BUF_SIZE)
+              *q++ = *p;
+#endif
+            continue;
+          case 'w':
+            open_direction = O_WRONLY;
+            open_flags |= O_CREAT | O_TRUNC;
+#if GNULIB_FOPEN_GNU
+            if (q < fdopen_mode_buf + BUF_SIZE)
+              *q++ = *p;
+#endif
+            continue;
+          case 'a':
+            open_direction = O_WRONLY;
+            open_flags |= O_CREAT | O_APPEND;
+#if GNULIB_FOPEN_GNU
+            if (q < fdopen_mode_buf + BUF_SIZE)
+              *q++ = *p;
+#endif
+            continue;
+          case 'b':
+            /* While it is non-standard, O_BINARY is guaranteed by
+               gnulib <fcntl.h>.  We can also assume that orig_fopen
+               supports the 'b' flag.  */
+            open_flags |= O_BINARY;
+#if GNULIB_FOPEN_GNU
+            if (q < fdopen_mode_buf + BUF_SIZE)
+              *q++ = *p;
+#endif
+            continue;
+          case '+':
+            open_direction = O_RDWR;
+#if GNULIB_FOPEN_GNU
+            if (q < fdopen_mode_buf + BUF_SIZE)
+              *q++ = *p;
+#endif
+            continue;
+#if GNULIB_FOPEN_GNU
+          case 'x':
+            open_flags |= O_EXCL;
+            open_flags_gnu = true;
+            continue;
+          case 'e':
+            open_flags |= O_CLOEXEC;
+            open_flags_gnu = true;
+            continue;
+#endif
+          default:
+            break;
+          }
+#if GNULIB_FOPEN_GNU
+        /* The rest of the mode string can be a platform-dependent extension.
+           Copy it unmodified.  */
+        {
+          size_t len = strlen (p);
+          if (len > fdopen_mode_buf + BUF_SIZE - q)
+            len = fdopen_mode_buf + BUF_SIZE - q;
+          memcpy (q, p, len);
+          q += len;
+        }
+#endif
+        break;
+      }
+#if GNULIB_FOPEN_GNU
+    *q = '\0';
+#endif
+  }
+
+#if FOPEN_TRAILING_SLASH_BUG
+  /* Fail if the mode requires write access and the filename ends in a slash,
+     as POSIX says such a filename must name a directory
+     
<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>:
+       "A pathname that contains at least one non-<slash> character and that
+        ends with one or more trailing <slash> characters shall not be resolved
+        successfully unless the last pathname component before the trailing
+        <slash> characters names an existing directory"
+     If the named file already exists as a directory, then if a mode that
+     requires write access is specified, fopen() must fail because POSIX
+     <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html>
+     says that it fails with errno = EISDIR in this case.
+     If the named file does not exist or does not name a directory, then
+     fopen() must fail since the file does not contain a '.' directory.  */
+  {
+    size_t len = strlen (filename);
+    if (len > 0 && filename[len - 1] == '/')
+      {
+        int fd;
+        struct stat statbuf;
+        FILE *fp;
+
+        if (open_direction != O_RDONLY)
+          {
+            errno = EISDIR;
+            return NULL;
+          }
+
+        fd = open (filename, open_direction | open_flags,
+                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+        if (fd < 0)
+          return NULL;
+
+        if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
+          {
+            close (fd);
+            errno = ENOTDIR;
+            return NULL;
+          }
+
+# if GNULIB_FOPEN_GNU
+        fp = fdopen (fd, fdopen_mode_buf);
+# else
+        fp = fdopen (fd, mode);
+# endif
+        if (fp == NULL)
+          {
+            int saved_errno = errno;
+            close (fd);
+            errno = saved_errno;
+          }
+        return fp;
+      }
+  }
+#endif
+
+#if GNULIB_FOPEN_GNU
+  if (open_flags_gnu)
+    {
+      int fd;
+      FILE *fp;
+
+      fd = open (filename, open_direction | open_flags,
+                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+      if (fd < 0)
+        return NULL;
+
+      fp = fdopen (fd, fdopen_mode_buf);
+      if (fp == NULL)
+        {
+          int saved_errno = errno;
+          close (fd);
+          errno = saved_errno;
+        }
+      return fp;
+    }
+#endif
+
+  return orig_fopen (filename, mode);
+}
diff --git a/lib/ftell.c b/lib/ftell.c
new file mode 100644
index 0000000..234c193
--- /dev/null
+++ b/lib/ftell.c
@@ -0,0 +1,37 @@
+/* An ftell() function that works around platform bugs.
+   Copyright (C) 2007-2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdio.h>
+
+#include <errno.h>
+#include <limits.h>
+
+long
+ftell (FILE *fp)
+{
+  /* Use the replacement ftello function with all its workarounds.  */
+  off_t offset = ftello (fp);
+  if (LONG_MIN <= offset && offset <= LONG_MAX)
+    return /* (long) */ offset;
+  else
+    {
+      errno = EOVERFLOW;
+      return -1;
+    }
+}
diff --git a/lib/ftello.c b/lib/ftello.c
new file mode 100644
index 0000000..43d4a4d
--- /dev/null
+++ b/lib/ftello.c
@@ -0,0 +1,85 @@
+/* An ftello() function that works around platform bugs.
+   Copyright (C) 2007, 2009-2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdio.h>
+
+/* Get lseek.  */
+#include <unistd.h>
+
+#include "stdio-impl.h"
+
+off_t
+ftello (FILE *fp)
+#undef ftello
+#if !HAVE_FTELLO
+# undef ftell
+# define ftello ftell
+#endif
+#if _GL_WINDOWS_64_BIT_OFF_T
+# undef ftello
+# if HAVE__FTELLI64 /* msvc, mingw64 */
+#  define ftello _ftelli64
+# else /* mingw */
+#  define ftello ftello64
+# endif
+#endif
+{
+#if LSEEK_PIPE_BROKEN
+  /* mingw gives bogus answers rather than failure on non-seekable files.  */
+  if (lseek (fileno (fp), 0, SEEK_CUR) == -1)
+    return -1;
+#endif
+
+#if FTELLO_BROKEN_AFTER_SWITCHING_FROM_READ_TO_WRITE /* Solaris */
+  /* The Solaris stdio leaves the _IOREAD flag set after reading from a file
+     reaches EOF and the program then starts writing to the file.  ftello
+     gets confused by this.  */
+  if (fp_->_flag & _IOWRT)
+    {
+      off_t pos;
+
+      /* Call ftello nevertheless, for the side effects that it does on fp.  */
+      ftello (fp);
+
+      /* Compute the file position ourselves.  */
+      pos = lseek (fileno (fp), (off_t) 0, SEEK_CUR);
+      if (pos >= 0)
+        {
+          if ((fp_->_flag & _IONBF) == 0 && fp_->_base != NULL)
+            pos += fp_->_ptr - fp_->_base;
+        }
+      return pos;
+    }
+#endif
+
+#if defined __SL64 && defined __SCLE /* Cygwin */
+  if ((fp->_flags & __SL64) == 0)
+    {
+      /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit
+         mode; but has an ftello that requires 64-bit mode.  */
+      FILE *tmp = fopen ("/dev/null", "r");
+      if (!tmp)
+        return -1;
+      fp->_flags |= __SL64;
+      fp->_seek64 = tmp->_seek64;
+      fclose (tmp);
+    }
+#endif
+  return ftello (fp);
+}
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 372ddd6..da07727 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -133,6 +133,7 @@
 #  pselect \
 #  pthread_sigmask \
 #  qcopy-acl \
+#  read-file \
 #  readlink \
 #  readlinkat \
 #  regex \
@@ -1792,6 +1793,28 @@ EXTRA_DIST += flexmember.h
 endif
 ## end   gnulib module flexmember
 
+## begin gnulib module fopen
+ifeq (,$(OMIT_GNULIB_MODULE_fopen))
+
+
+EXTRA_DIST += fopen.c
+
+EXTRA_libgnu_a_SOURCES += fopen.c
+
+endif
+## end   gnulib module fopen
+
+## begin gnulib module fopen-gnu
+ifeq (,$(OMIT_GNULIB_MODULE_fopen-gnu))
+
+
+EXTRA_DIST += fopen.c
+
+EXTRA_libgnu_a_SOURCES += fopen.c
+
+endif
+## end   gnulib module fopen-gnu
+
 ## begin gnulib module fpending
 ifeq (,$(OMIT_GNULIB_MODULE_fpending))
 
@@ -1847,6 +1870,28 @@ EXTRA_libgnu_a_SOURCES += fsync.c
 endif
 ## end   gnulib module fsync
 
+## begin gnulib module ftell
+ifeq (,$(OMIT_GNULIB_MODULE_ftell))
+
+
+EXTRA_DIST += ftell.c
+
+EXTRA_libgnu_a_SOURCES += ftell.c
+
+endif
+## end   gnulib module ftell
+
+## begin gnulib module ftello
+ifeq (,$(OMIT_GNULIB_MODULE_ftello))
+
+
+EXTRA_DIST += ftello.c stdio-impl.h
+
+EXTRA_libgnu_a_SOURCES += ftello.c
+
+endif
+## end   gnulib module ftello
+
 ## begin gnulib module futimens
 ifeq (,$(OMIT_GNULIB_MODULE_futimens))
 
@@ -2176,6 +2221,19 @@ EXTRA_DIST += limits.in.h
 endif
 ## end   gnulib module limits-h
 
+## begin gnulib module lseek
+ifeq (,$(OMIT_GNULIB_MODULE_lseek))
+
+ifneq (,$(gl_GNULIB_ENABLED_lseek))
+
+endif
+EXTRA_DIST += lseek.c
+
+EXTRA_libgnu_a_SOURCES += lseek.c
+
+endif
+## end   gnulib module lseek
+
 ## begin gnulib module lstat
 ifeq (,$(OMIT_GNULIB_MODULE_lstat))
 
@@ -2357,6 +2415,16 @@ EXTRA_libgnu_a_SOURCES += rawmemchr.c
 endif
 ## end   gnulib module rawmemchr
 
+## begin gnulib module read-file
+ifeq (,$(OMIT_GNULIB_MODULE_read-file))
+
+libgnu_a_SOURCES += read-file.c
+
+EXTRA_DIST += read-file.h
+
+endif
+## end   gnulib module read-file
+
 ## begin gnulib module readlink
 ifeq (,$(OMIT_GNULIB_MODULE_readlink))
 
@@ -2379,6 +2447,17 @@ EXTRA_libgnu_a_SOURCES += at-func.c readlinkat.c
 endif
 ## end   gnulib module readlinkat
 
+## begin gnulib module realloc-posix
+ifeq (,$(OMIT_GNULIB_MODULE_realloc-posix))
+
+
+EXTRA_DIST += realloc.c
+
+EXTRA_libgnu_a_SOURCES += realloc.c
+
+endif
+## end   gnulib module realloc-posix
+
 ## begin gnulib module regex
 ifeq (,$(OMIT_GNULIB_MODULE_regex))
 
diff --git a/lib/lseek.c b/lib/lseek.c
new file mode 100644
index 0000000..aaf9f32
--- /dev/null
+++ b/lib/lseek.c
@@ -0,0 +1,71 @@
+/* An lseek() function that detects pipes.
+   Copyright (C) 2007, 2009-2020 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#if defined _WIN32 && ! defined __CYGWIN__
+/* Windows platforms.  */
+/* Get GetFileType.  */
+# include <windows.h>
+/* Get _get_osfhandle.  */
+# if GNULIB_MSVC_NOTHROW
+#  include "msvc-nothrow.h"
+# else
+#  include <io.h>
+# endif
+#else
+# include <sys/stat.h>
+#endif
+#include <errno.h>
+
+#undef lseek
+
+off_t
+rpl_lseek (int fd, off_t offset, int whence)
+{
+#if defined _WIN32 && ! defined __CYGWIN__
+  /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals.  */
+  HANDLE h = (HANDLE) _get_osfhandle (fd);
+  if (h == INVALID_HANDLE_VALUE)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  if (GetFileType (h) != FILE_TYPE_DISK)
+    {
+      errno = ESPIPE;
+      return -1;
+    }
+#else
+  /* BeOS lseek mistakenly succeeds on pipes...  */
+  struct stat statbuf;
+  if (fstat (fd, &statbuf) < 0)
+    return -1;
+  if (!S_ISREG (statbuf.st_mode))
+    {
+      errno = ESPIPE;
+      return -1;
+    }
+#endif
+#if _GL_WINDOWS_64_BIT_OFF_T || (defined __MINGW32__ && defined 
_FILE_OFFSET_BITS && (_FILE_OFFSET_BITS == 64))
+  return _lseeki64 (fd, offset, whence);
+#else
+  return lseek (fd, offset, whence);
+#endif
+}
diff --git a/lib/read-file.c b/lib/read-file.c
new file mode 100644
index 0000000..08b22a7
--- /dev/null
+++ b/lib/read-file.c
@@ -0,0 +1,221 @@
+/* read-file.c -- read file contents into a string
+   Copyright (C) 2006, 2009-2020 Free Software Foundation, Inc.
+   Written by Simon Josefsson and Bruno Haible.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include "read-file.h"
+
+/* Get fstat.  */
+#include <sys/stat.h>
+
+/* Get ftello.  */
+#include <stdio.h>
+
+/* Get PTRDIFF_MAX.  */
+#include <stdint.h>
+
+/* Get malloc, realloc, free. */
+#include <stdlib.h>
+
+/* Get explicit_bzero, memcpy. */
+#include <string.h>
+
+/* Get errno. */
+#include <errno.h>
+
+/* Read a STREAM and return a newly allocated string with the content,
+   and set *LENGTH to the length of the string.  The string is
+   zero-terminated, but the terminating zero byte is not counted in
+   *LENGTH.  On errors, *LENGTH is undefined, errno preserves the
+   values set by system functions (if any), and NULL is returned.
+
+   If the RF_SENSITIVE flag is set in FLAGS:
+     - You should control the buffering of STREAM using 'setvbuf'.  Either
+       clear the buffer of STREAM after closing it, or disable buffering of
+       STREAM before calling this function.
+     - The memory buffer internally allocated will be cleared upon failure.  */
+char *
+fread_file (FILE *stream, int flags, size_t *length)
+{
+  char *buf = NULL;
+  size_t alloc = BUFSIZ;
+
+  /* For a regular file, allocate a buffer that has exactly the right
+     size.  This avoids the need to do dynamic reallocations later.  */
+  {
+    struct stat st;
+
+    if (fstat (fileno (stream), &st) >= 0 && S_ISREG (st.st_mode))
+      {
+        off_t pos = ftello (stream);
+
+        if (pos >= 0 && pos < st.st_size)
+          {
+            off_t alloc_off = st.st_size - pos;
+
+            /* '1' below, accounts for the trailing NUL.  */
+            if (PTRDIFF_MAX - 1 < alloc_off)
+              {
+                errno = ENOMEM;
+                return NULL;
+              }
+
+            alloc = alloc_off + 1;
+          }
+      }
+  }
+
+  if (!(buf = malloc (alloc)))
+    return NULL; /* errno is ENOMEM.  */
+
+  {
+    size_t size = 0; /* number of bytes read so far */
+    int save_errno;
+
+    for (;;)
+      {
+        /* This reads 1 more than the size of a regular file
+           so that we get eof immediately.  */
+        size_t requested = alloc - size;
+        size_t count = fread (buf + size, 1, requested, stream);
+        size += count;
+
+        if (count != requested)
+          {
+            save_errno = errno;
+            if (ferror (stream))
+              break;
+
+            /* Shrink the allocated memory if possible.  */
+            if (size < alloc - 1)
+              {
+                if (flags & RF_SENSITIVE)
+                  {
+                    char *smaller_buf = malloc (size + 1);
+                    if (smaller_buf == NULL)
+                      explicit_bzero (buf + size, alloc - size);
+                    else
+                      {
+                        memcpy (smaller_buf, buf, size);
+                        explicit_bzero (buf, alloc);
+                        free (buf);
+                        buf = smaller_buf;
+                      }
+                  }
+                else
+                  {
+                    char *smaller_buf = realloc (buf, size + 1);
+                    if (smaller_buf != NULL)
+                      buf = smaller_buf;
+                  }
+              }
+
+            buf[size] = '\0';
+            *length = size;
+            return buf;
+          }
+
+        {
+          char *new_buf;
+          size_t save_alloc = alloc;
+
+          if (alloc == PTRDIFF_MAX)
+            {
+              save_errno = ENOMEM;
+              break;
+            }
+
+          if (alloc < PTRDIFF_MAX - alloc / 2)
+            alloc = alloc + alloc / 2;
+          else
+            alloc = PTRDIFF_MAX;
+
+          if (flags & RF_SENSITIVE)
+            {
+              new_buf = malloc (alloc);
+              if (!new_buf)
+                {
+                  /* BUF should be cleared below after the loop.  */
+                  save_errno = errno;
+                  break;
+                }
+              memcpy (new_buf, buf, save_alloc);
+              explicit_bzero (buf, save_alloc);
+              free (buf);
+            }
+          else if (!(new_buf = realloc (buf, alloc)))
+            {
+              save_errno = errno;
+              break;
+            }
+
+          buf = new_buf;
+        }
+      }
+
+    if (flags & RF_SENSITIVE)
+      explicit_bzero (buf, alloc);
+
+    free (buf);
+    errno = save_errno;
+    return NULL;
+  }
+}
+
+/* Open and read the contents of FILENAME, and return a newly
+   allocated string with the content, and set *LENGTH to the length of
+   the string.  The string is zero-terminated, but the terminating
+   zero byte is not counted in *LENGTH.  On errors, *LENGTH is
+   undefined, errno preserves the values set by system functions (if
+   any), and NULL is returned.
+
+   If the RF_BINARY flag is set in FLAGS, the file is opened in binary
+   mode.  If the RF_SENSITIVE flag is set in FLAGS, the memory buffer
+   internally allocated will be cleared upon failure.  */
+char *
+read_file (const char *filename, int flags, size_t *length)
+{
+  const char *mode = (flags & RF_BINARY) ? "rbe" : "re";
+  FILE *stream = fopen (filename, mode);
+  char *out;
+  int save_errno;
+
+  if (!stream)
+    return NULL;
+
+  if (flags & RF_SENSITIVE)
+    setvbuf (stream, NULL, _IONBF, 0);
+
+  out = fread_file (stream, flags, length);
+
+  save_errno = errno;
+
+  if (fclose (stream) != 0)
+    {
+      if (out)
+        {
+          save_errno = errno;
+          if (flags & RF_SENSITIVE)
+            explicit_bzero (out, *length);
+          free (out);
+        }
+      errno = save_errno;
+      return NULL;
+    }
+
+  return out;
+}
diff --git a/lib/read-file.h b/lib/read-file.h
new file mode 100644
index 0000000..58192f1
--- /dev/null
+++ b/lib/read-file.h
@@ -0,0 +1,37 @@
+/* read-file.h -- read file contents into a string
+   Copyright (C) 2006, 2009-2020 Free Software Foundation, Inc.
+   Written by Simon Josefsson.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef READ_FILE_H
+#define READ_FILE_H
+
+/* Get size_t.  */
+#include <stddef.h>
+
+/* Get FILE.  */
+#include <stdio.h>
+
+/* Indicate that the file is treated as binary.  */
+#define RF_BINARY 0x1
+
+/* Indicate that the file content contains sensitive information.  */
+#define RF_SENSITIVE 0x2
+
+extern char *fread_file (FILE * stream, int flags, size_t * length);
+
+extern char *read_file (const char *filename, int flags, size_t * length);
+
+#endif /* READ_FILE_H */
diff --git a/lib/realloc.c b/lib/realloc.c
new file mode 100644
index 0000000..a24054d
--- /dev/null
+++ b/lib/realloc.c
@@ -0,0 +1,79 @@
+/* realloc() function that is glibc compatible.
+
+   Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2020 Free Software
+   Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* written by Jim Meyering and Bruno Haible */
+
+#define _GL_USE_STDLIB_ALLOC 1
+#include <config.h>
+
+/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h.  */
+#ifdef realloc
+# define NEED_REALLOC_GNU 1
+/* Whereas the gnulib module 'realloc-gnu' defines HAVE_REALLOC_GNU.  */
+#elif GNULIB_REALLOC_GNU && !HAVE_REALLOC_GNU
+# define NEED_REALLOC_GNU 1
+#endif
+
+/* Infer the properties of the system's malloc function.
+   The gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU.  */
+#if GNULIB_MALLOC_GNU && HAVE_MALLOC_GNU
+# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1
+#endif
+
+#include <stdlib.h>
+
+#include <errno.h>
+
+/* Change the size of an allocated block of memory P to N bytes,
+   with error checking.  If N is zero, change it to 1.  If P is NULL,
+   use malloc.  */
+
+void *
+rpl_realloc (void *p, size_t n)
+{
+  void *result;
+
+#if NEED_REALLOC_GNU
+  if (n == 0)
+    {
+      n = 1;
+
+      /* In theory realloc might fail, so don't rely on it to free.  */
+      free (p);
+      p = NULL;
+    }
+#endif
+
+  if (p == NULL)
+    {
+#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE
+      if (n == 0)
+        n = 1;
+#endif
+      result = malloc (n);
+    }
+  else
+    result = realloc (p, n);
+
+#if !HAVE_REALLOC_POSIX
+  if (result == NULL)
+    errno = ENOMEM;
+#endif
+
+  return result;
+}
diff --git a/m4/fopen.m4 b/m4/fopen.m4
new file mode 100644
index 0000000..a5d687a
--- /dev/null
+++ b/m4/fopen.m4
@@ -0,0 +1,148 @@
+# fopen.m4 serial 12
+dnl Copyright (C) 2007-2020 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([gl_FUNC_FOPEN],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  case "$host_os" in
+    mingw* | pw*)
+      dnl Replace fopen, for handling of "/dev/null".
+      REPLACE_FOPEN=1
+      dnl fopen on mingw also has the trailing slash bug.
+      gl_cv_func_fopen_slash="guessing no"
+      ;;
+    *)
+      dnl fopen("foo/", "w") should not create a file when the file name has a
+      dnl trailing slash.
+      AC_CACHE_CHECK([whether fopen recognizes a trailing slash],
+        [gl_cv_func_fopen_slash],
+        [
+          AC_RUN_IFELSE(
+            [AC_LANG_SOURCE([[
+#include <stddef.h>
+#include <stdio.h>
+int main ()
+{
+  FILE *fp = fopen ("conftest.sl/", "w");
+  int result = (fp != NULL);
+  if (fp != NULL)
+    fclose (fp);
+  return result;
+}]])],
+            [gl_cv_func_fopen_slash=yes],
+            [gl_cv_func_fopen_slash=no],
+            [
+changequote(,)dnl
+             case "$host_os" in
+               aix* | hpux* | solaris2.[0-9] | solaris2.[0-9].*)
+                 gl_cv_func_fopen_slash="guessing no" ;;
+               *)
+                 gl_cv_func_fopen_slash="guessing yes" ;;
+             esac
+changequote([,])dnl
+            ])
+          rm -f conftest.sl
+        ])
+      ;;
+  esac
+  case "$gl_cv_func_fopen_slash" in
+    *no)
+      AC_DEFINE([FOPEN_TRAILING_SLASH_BUG], [1],
+        [Define to 1 if fopen() fails to recognize a trailing slash.])
+      REPLACE_FOPEN=1
+      ;;
+  esac
+])
+
+AC_DEFUN([gl_FUNC_FOPEN_GNU],
+[
+  AC_REQUIRE([gl_FUNC_FOPEN])
+  AC_CACHE_CHECK([whether fopen supports the mode character 'x'],
+    [gl_cv_func_fopen_mode_x],
+    [rm -f conftest.x
+     AC_RUN_IFELSE(
+       [AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <errno.h>
+int main ()
+{
+  FILE *fp;
+  fp = fopen ("conftest.x", "w");
+  fclose (fp);
+  fp = fopen ("conftest.x", "wx");
+  if (fp != NULL)
+    /* 'x' ignored */
+    return 1;
+  else if (errno == EEXIST)
+    return 0;
+  else
+    /* 'x' rejected */
+    return 2;
+}]])],
+       [gl_cv_func_fopen_mode_x=yes],
+       [gl_cv_func_fopen_mode_x=no],
+       [case "$host_os" in
+          # Guess yes on glibc and musl systems.
+          linux*-gnu* | gnu* | kfreebsd*-gnu | *-musl*)
+            gl_cv_func_fopen_mode_x="guessing yes" ;;
+          # If we don't know, obey --enable-cross-guesses.
+          *)
+            gl_cv_func_fopen_mode_x="$gl_cross_guess_normal" ;;
+        esac
+       ])
+     rm -f conftest.x
+    ])
+  AC_CACHE_CHECK([whether fopen supports the mode character 'e'],
+    [gl_cv_func_fopen_mode_e],
+    [echo foo > conftest.x
+     AC_RUN_IFELSE(
+       [AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+]GL_MDA_DEFINES[
+int main ()
+{
+  FILE *fp = fopen ("conftest.x", "re");
+  if (fp != NULL)
+    {
+      if (fcntl (fileno (fp), F_GETFD) & FD_CLOEXEC)
+        return 0;
+      else
+        /* 'e' ignored */
+        return 1;
+    }
+  else
+    /* 'e' rejected */
+    return 2;
+}]])],
+       [gl_cv_func_fopen_mode_e=yes],
+       [gl_cv_func_fopen_mode_e=no],
+       [case "$host_os" in
+          # Guess yes on glibc and musl systems.
+          linux*-gnu* | gnu* | kfreebsd*-gnu | *-musl*)
+            gl_cv_func_fopen_mode_e="guessing yes" ;;
+          # Guess no on native Windows.
+          mingw*)
+            gl_cv_func_fopen_mode_e="guessing no" ;;
+          # If we don't know, obey --enable-cross-guesses.
+          *)
+            gl_cv_func_fopen_mode_e="$gl_cross_guess_normal" ;;
+        esac
+       ])
+     rm -f conftest.x
+    ])
+  case "$gl_cv_func_fopen_mode_x" in
+    *no) REPLACE_FOPEN=1 ;;
+  esac
+  case "$gl_cv_func_fopen_mode_e" in
+    *no) REPLACE_FOPEN=1 ;;
+  esac
+])
+
+# Prerequisites of lib/fopen.c.
+AC_DEFUN([gl_PREREQ_FOPEN], [:])
diff --git a/m4/fseeko.m4 b/m4/fseeko.m4
new file mode 100644
index 0000000..a64e640
--- /dev/null
+++ b/m4/fseeko.m4
@@ -0,0 +1,77 @@
+# fseeko.m4 serial 20
+dnl Copyright (C) 2007-2020 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([gl_FUNC_FSEEKO],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_REQUIRE([gl_STDIN_LARGE_OFFSET])
+  AC_REQUIRE([gl_SYS_TYPES_H])
+  AC_REQUIRE([AC_PROG_CC])
+
+  dnl Persuade glibc <stdio.h> to declare fseeko().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko],
+    [
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
+]], [[fseeko (stdin, 0, 0);]])],
+        [gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no])
+    ])
+
+  AC_CHECK_DECLS_ONCE([fseeko])
+  if test $ac_cv_have_decl_fseeko = no; then
+    HAVE_DECL_FSEEKO=0
+  fi
+
+  if test $gl_cv_func_fseeko = no; then
+    HAVE_FSEEKO=0
+  else
+    if test $WINDOWS_64_BIT_OFF_T = 1; then
+      REPLACE_FSEEKO=1
+    fi
+    if test $gl_cv_var_stdin_large_offset = no; then
+      REPLACE_FSEEKO=1
+    fi
+    m4_ifdef([gl_FUNC_FFLUSH_STDIN], [
+      gl_FUNC_FFLUSH_STDIN
+      case "$gl_cv_func_fflush_stdin" in
+        *yes) ;;
+        *) REPLACE_FSEEKO=1 ;;
+      esac
+    ])
+  fi
+])
+
+dnl Code shared by fseeko and ftello.  Determine if large files are supported,
+dnl but stdin does not start as a large file by default.
+AC_DEFUN([gl_STDIN_LARGE_OFFSET],
+  [
+    AC_CACHE_CHECK([whether stdin defaults to large file offsets],
+      [gl_cv_var_stdin_large_offset],
+      [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]],
+[[#if defined __SL64 && defined __SCLE /* cygwin */
+  /* Cygwin 1.5.24 and earlier fail to put stdin in 64-bit mode, making
+     fseeko/ftello needlessly fail.  This bug was fixed in 1.5.25, and
+     it is easier to do a version check than building a runtime test.  */
+# include <cygwin/version.h>
+# if CYGWIN_VERSION_DLL_COMBINED < CYGWIN_VERSION_DLL_MAKE_COMBINED (1005, 25)
+  choke me
+# endif
+#endif]])],
+        [gl_cv_var_stdin_large_offset=yes],
+        [gl_cv_var_stdin_large_offset=no])])
+])
+
+# Prerequisites of lib/fseeko.c.
+AC_DEFUN([gl_PREREQ_FSEEKO],
+[
+  dnl Native Windows has the function _fseeki64. mingw hides it in some
+  dnl circumstances, but mingw64 makes it usable again.
+  AC_CHECK_FUNCS([_fseeki64])
+  if test $ac_cv_func__fseeki64 = yes; then
+    AC_CHECK_DECLS([_fseeki64])
+  fi
+])
diff --git a/m4/ftell.m4 b/m4/ftell.m4
new file mode 100644
index 0000000..22055d4
--- /dev/null
+++ b/m4/ftell.m4
@@ -0,0 +1,15 @@
+# ftell.m4 serial 3
+dnl Copyright (C) 2007, 2009-2020 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([gl_FUNC_FTELL],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_REQUIRE([gl_FUNC_FTELLO])
+  dnl When ftello needs fixes, ftell needs them too.
+  if test $HAVE_FTELLO = 0 || test $REPLACE_FTELLO = 1; then
+    REPLACE_FTELL=1
+  fi
+])
diff --git a/m4/ftello.m4 b/m4/ftello.m4
new file mode 100644
index 0000000..4c629c0
--- /dev/null
+++ b/m4/ftello.m4
@@ -0,0 +1,142 @@
+# ftello.m4 serial 13
+dnl Copyright (C) 2007-2020 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([gl_FUNC_FTELLO],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gl_STDIN_LARGE_OFFSET])
+  AC_REQUIRE([gl_SYS_TYPES_H])
+
+  dnl Persuade glibc <stdio.h> to declare ftello().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CHECK_DECLS_ONCE([ftello])
+  if test $ac_cv_have_decl_ftello = no; then
+    HAVE_DECL_FTELLO=0
+  fi
+
+  AC_CACHE_CHECK([for ftello], [gl_cv_func_ftello],
+    [
+      AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[#include <stdio.h>]],
+           [[ftello (stdin);]])],
+        [gl_cv_func_ftello=yes],
+        [gl_cv_func_ftello=no])
+    ])
+  if test $gl_cv_func_ftello = no; then
+    HAVE_FTELLO=0
+  else
+    if test $WINDOWS_64_BIT_OFF_T = 1; then
+      REPLACE_FTELLO=1
+    fi
+    if test $gl_cv_var_stdin_large_offset = no; then
+      REPLACE_FTELLO=1
+    fi
+    if test $REPLACE_FTELLO = 0; then
+      dnl Detect bug on Solaris.
+      dnl ftell and ftello produce incorrect results after putc that followed a
+      dnl getc call that reached EOF on Solaris. This is because the _IOREAD
+      dnl flag does not get cleared in this case, even though _IOWRT gets set,
+      dnl and ftell and ftello look whether the _IOREAD flag is set.
+      AC_REQUIRE([AC_CANONICAL_HOST])
+      AC_CACHE_CHECK([whether ftello works],
+        [gl_cv_func_ftello_works],
+        [
+          dnl Initial guess, used when cross-compiling or when /dev/tty cannot
+          dnl be opened.
+changequote(,)dnl
+          case "$host_os" in
+                      # Guess no on Solaris.
+            solaris*) gl_cv_func_ftello_works="guessing no" ;;
+                      # Guess yes on native Windows.
+            mingw*)   gl_cv_func_ftello_works="guessing yes" ;;
+                      # Guess yes otherwise.
+            *)        gl_cv_func_ftello_works="guessing yes" ;;
+          esac
+changequote([,])dnl
+          AC_RUN_IFELSE(
+            [AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define TESTFILE "conftest.tmp"
+int
+main (void)
+{
+  FILE *fp;
+
+  /* Create a file with some contents.  */
+  fp = fopen (TESTFILE, "w");
+  if (fp == NULL)
+    return 70;
+  if (fwrite ("foogarsh", 1, 8, fp) < 8)
+    { fclose (fp); return 71; }
+  if (fclose (fp))
+    return 72;
+
+  /* The file's contents is now "foogarsh".  */
+
+  /* Try writing after reading to EOF.  */
+  fp = fopen (TESTFILE, "r+");
+  if (fp == NULL)
+    return 73;
+  if (fseek (fp, -1, SEEK_END))
+    { fclose (fp); return 74; }
+  if (!(getc (fp) == 'h'))
+    { fclose (fp); return 1; }
+  if (!(getc (fp) == EOF))
+    { fclose (fp); return 2; }
+  if (!(ftell (fp) == 8))
+    { fclose (fp); return 3; }
+  if (!(ftell (fp) == 8))
+    { fclose (fp); return 4; }
+  if (!(putc ('!', fp) == '!'))
+    { fclose (fp); return 5; }
+  if (!(ftell (fp) == 9))
+    { fclose (fp); return 6; }
+  if (!(fclose (fp) == 0))
+    return 7;
+  fp = fopen (TESTFILE, "r");
+  if (fp == NULL)
+    return 75;
+  {
+    char buf[10];
+    if (!(fread (buf, 1, 10, fp) == 9))
+      { fclose (fp); return 10; }
+    if (!(memcmp (buf, "foogarsh!", 9) == 0))
+      { fclose (fp); return 11; }
+  }
+  if (!(fclose (fp) == 0))
+    return 12;
+
+  /* The file's contents is now "foogarsh!".  */
+
+  return 0;
+}]])],
+            [gl_cv_func_ftello_works=yes],
+            [gl_cv_func_ftello_works=no], [:])
+        ])
+      case "$gl_cv_func_ftello_works" in
+        *yes) ;;
+        *)
+          REPLACE_FTELLO=1
+          AC_DEFINE([FTELLO_BROKEN_AFTER_SWITCHING_FROM_READ_TO_WRITE], [1],
+            [Define to 1 if the system's ftello function has the Solaris bug.])
+          ;;
+      esac
+    fi
+  fi
+])
+
+# Prerequisites of lib/ftello.c.
+AC_DEFUN([gl_PREREQ_FTELLO],
+[
+  dnl Native Windows has the function _ftelli64. mingw hides it, but mingw64
+  dnl makes it usable again.
+  AC_CHECK_FUNCS([_ftelli64])
+])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 0971636..6d73146 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -92,6 +92,8 @@ AC_DEFUN([gl_EARLY],
   # Code from module filename:
   # Code from module filevercmp:
   # Code from module flexmember:
+  # Code from module fopen:
+  # Code from module fopen-gnu:
   # Code from module fpending:
   # Code from module fpieee:
   AC_REQUIRE([gl_FP_IEEE])
@@ -99,6 +101,9 @@ AC_DEFUN([gl_EARLY],
   # Code from module fstatat:
   # Code from module fsusage:
   # Code from module fsync:
+  # Code from module ftell:
+  # Code from module ftello:
+  AC_REQUIRE([gl_SET_LARGEFILE_SOURCE])
   # Code from module futimens:
   # Code from module getdtablesize:
   # Code from module getgroups:
@@ -123,6 +128,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module libc-config:
   # Code from module libgmp:
   # Code from module limits-h:
+  # Code from module lseek:
   # Code from module lstat:
   # Code from module manywarnings:
   # Code from module memmem-simple:
@@ -143,8 +149,10 @@ AC_DEFUN([gl_EARLY],
   # Code from module pthread_sigmask:
   # Code from module qcopy-acl:
   # Code from module rawmemchr:
+  # Code from module read-file:
   # Code from module readlink:
   # Code from module readlinkat:
+  # Code from module realloc-posix:
   # Code from module regex:
   # Code from module root-uid:
   # Code from module scratch_buffer:
@@ -288,6 +296,18 @@ AC_DEFUN([gl_INIT],
   gl_MODULE_INDICATOR([fdopendir])
   gl_FILEMODE
   AC_C_FLEXIBLE_ARRAY_MEMBER
+  gl_FUNC_FOPEN
+  if test $REPLACE_FOPEN = 1; then
+    AC_LIBOBJ([fopen])
+    gl_PREREQ_FOPEN
+  fi
+  gl_STDIO_MODULE_INDICATOR([fopen])
+  gl_FUNC_FOPEN_GNU
+  if test $REPLACE_FOPEN = 1; then
+    AC_LIBOBJ([fopen])
+    gl_PREREQ_FOPEN
+  fi
+  gl_MODULE_INDICATOR([fopen-gnu])
   gl_FUNC_FPENDING
   if test $gl_cv_func___fpending = no; then
     AC_LIBOBJ([fpending])
@@ -314,6 +334,17 @@ AC_DEFUN([gl_INIT],
     gl_PREREQ_FSYNC
   fi
   gl_UNISTD_MODULE_INDICATOR([fsync])
+  gl_FUNC_FTELL
+  if test $REPLACE_FTELL = 1; then
+    AC_LIBOBJ([ftell])
+  fi
+  gl_STDIO_MODULE_INDICATOR([ftell])
+  gl_FUNC_FTELLO
+  if test $HAVE_FTELLO = 0 || test $REPLACE_FTELLO = 1; then
+    AC_LIBOBJ([ftello])
+    gl_PREREQ_FTELLO
+  fi
+  gl_STDIO_MODULE_INDICATOR([ftello])
   gl_FUNC_FUTIMENS
   if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
     AC_LIBOBJ([futimens])
@@ -414,6 +445,7 @@ AC_DEFUN([gl_INIT],
     gl_PREREQ_PTHREAD_SIGMASK
   fi
   gl_SIGNAL_MODULE_INDICATOR([pthread_sigmask])
+  gl_PREREQ_READ_FILE
   gl_FUNC_READLINK
   if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
     AC_LIBOBJ([readlink])
@@ -425,6 +457,11 @@ AC_DEFUN([gl_INIT],
     AC_LIBOBJ([readlinkat])
   fi
   gl_UNISTD_MODULE_INDICATOR([readlinkat])
+  gl_FUNC_REALLOC_POSIX
+  if test $REPLACE_REALLOC = 1; then
+    AC_LIBOBJ([realloc])
+  fi
+  gl_STDLIB_MODULE_INDICATOR([realloc-posix])
   gl_REGEX
   if test $ac_use_included_regex = yes; then
     AC_LIBOBJ([regex])
@@ -525,6 +562,7 @@ AC_DEFUN([gl_INIT],
   gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false
   gl_gnulib_enabled_idx=false
   gl_gnulib_enabled_lchmod=false
+  gl_gnulib_enabled_lseek=false
   gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false
   gl_gnulib_enabled_open=false
   gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false
@@ -653,6 +691,17 @@ AC_DEFUN([gl_INIT],
       gl_gnulib_enabled_lchmod=true
     fi
   }
+  func_gl_gnulib_m4code_lseek ()
+  {
+    if ! $gl_gnulib_enabled_lseek; then
+      gl_FUNC_LSEEK
+      if test $REPLACE_LSEEK = 1; then
+        AC_LIBOBJ([lseek])
+      fi
+      gl_UNISTD_MODULE_INDICATOR([lseek])
+      gl_gnulib_enabled_lseek=true
+    fi
+  }
   func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31 ()
   {
     if ! $gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31; then
@@ -773,12 +822,18 @@ AC_DEFUN([gl_INIT],
   if test $HAVE_FDOPENDIR = 0; then
     func_gl_gnulib_m4code_dirfd
   fi
+  if test $REPLACE_FOPEN = 1; then
+    func_gl_gnulib_m4code_open
+  fi
   if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
     func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
   fi
   if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
     func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
   fi
+  if test $HAVE_FTELLO = 0 || test $REPLACE_FTELLO = 1; then
+    func_gl_gnulib_m4code_lseek
+  fi
   if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
     func_gl_gnulib_m4code_utimens
   fi
@@ -827,6 +882,7 @@ AC_DEFUN([gl_INIT],
   AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], 
[$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_idx], [$gl_gnulib_enabled_idx])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_lchmod], [$gl_gnulib_enabled_lchmod])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_lseek], [$gl_gnulib_enabled_lseek])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31], 
[$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_open], [$gl_gnulib_enabled_open])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], 
[$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7])
@@ -1038,6 +1094,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/filevercmp.c
   lib/filevercmp.h
   lib/flexmember.h
+  lib/fopen.c
   lib/fpending.c
   lib/fpending.h
   lib/free.c
@@ -1045,6 +1102,8 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/fsusage.c
   lib/fsusage.h
   lib/fsync.c
+  lib/ftell.c
+  lib/ftello.c
   lib/ftoastr.c
   lib/ftoastr.h
   lib/futimens.c
@@ -1075,6 +1134,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/lchmod.c
   lib/libc-config.h
   lib/limits.in.h
+  lib/lseek.c
   lib/lstat.c
   lib/malloc/scratch_buffer.h
   lib/malloc/scratch_buffer_grow.c
@@ -1104,8 +1164,11 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/qcopy-acl.c
   lib/rawmemchr.c
   lib/rawmemchr.valgrind
+  lib/read-file.c
+  lib/read-file.h
   lib/readlink.c
   lib/readlinkat.c
+  lib/realloc.c
   lib/regcomp.c
   lib/regex.c
   lib/regex.h
@@ -1201,12 +1264,16 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/fdopendir.m4
   m4/filemode.m4
   m4/flexmember.m4
+  m4/fopen.m4
   m4/fpending.m4
   m4/fpieee.m4
   m4/free.m4
+  m4/fseeko.m4
   m4/fstatat.m4
   m4/fsusage.m4
   m4/fsync.m4
+  m4/ftell.m4
+  m4/ftello.m4
   m4/futimens.m4
   m4/getdtablesize.m4
   m4/getgroups.m4
@@ -1226,7 +1293,9 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/lchmod.m4
   m4/libgmp.m4
   m4/limits-h.m4
+  m4/lseek.m4
   m4/lstat.m4
+  m4/malloc.m4
   m4/manywarnings-c++.m4
   m4/manywarnings.m4
   m4/mbstate_t.m4
@@ -1251,8 +1320,10 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/pselect.m4
   m4/pthread_sigmask.m4
   m4/rawmemchr.m4
+  m4/read-file.m4
   m4/readlink.m4
   m4/readlinkat.m4
+  m4/realloc.m4
   m4/regex.m4
   m4/sha1.m4
   m4/sha256.m4
diff --git a/m4/lseek.m4 b/m4/lseek.m4
new file mode 100644
index 0000000..472a1cb
--- /dev/null
+++ b/m4/lseek.m4
@@ -0,0 +1,72 @@
+# lseek.m4 serial 11
+dnl Copyright (C) 2007, 2009-2020 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([gl_FUNC_LSEEK],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_CHECK_HEADERS_ONCE([unistd.h])
+  AC_CACHE_CHECK([whether lseek detects pipes], [gl_cv_func_lseek_pipe],
+    [case "$host_os" in
+       mingw*)
+         dnl Native Windows.
+         dnl The result of lseek (fd, (off_t)0, SEEK_CUR) or
+         dnl SetFilePointer(handle, 0, NULL, FILE_CURRENT)
+         dnl for a pipe depends on the environment: In a Cygwin 1.5
+         dnl environment it succeeds (wrong); in a Cygwin 1.7 environment
+         dnl it fails with a wrong errno value.
+         gl_cv_func_lseek_pipe=no
+         ;;
+       *)
+         if test $cross_compiling = no; then
+           AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h> /* for off_t */
+#include <stdio.h> /* for SEEK_CUR */
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#else /* on Windows with MSVC */
+# include <io.h>
+#endif
+]GL_MDA_DEFINES],
+[[
+  /* Exit with success only if stdin is seekable.  */
+  return lseek (0, (off_t)0, SEEK_CUR) < 0;
+]])],
+             [if test -s conftest$ac_exeext \
+                 && ./conftest$ac_exeext < conftest.$ac_ext \
+                 && test 1 = "`echo hi \
+                   | { ./conftest$ac_exeext; echo $?; cat >/dev/null; }`"; then
+                gl_cv_func_lseek_pipe=yes
+              else
+                gl_cv_func_lseek_pipe=no
+              fi
+             ],
+             [gl_cv_func_lseek_pipe=no])
+         else
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE([[
+#if defined __BEOS__
+/* BeOS mistakenly return 0 when trying to seek on pipes.  */
+  Choke me.
+#endif]])],
+             [gl_cv_func_lseek_pipe=yes], [gl_cv_func_lseek_pipe=no])
+         fi
+         ;;
+     esac
+    ])
+  if test $gl_cv_func_lseek_pipe = no; then
+    REPLACE_LSEEK=1
+    AC_DEFINE([LSEEK_PIPE_BROKEN], [1],
+      [Define to 1 if lseek does not detect pipes.])
+  fi
+
+  AC_REQUIRE([gl_SYS_TYPES_H])
+  if test $WINDOWS_64_BIT_OFF_T = 1; then
+    REPLACE_LSEEK=1
+  fi
+])
diff --git a/m4/malloc.m4 b/m4/malloc.m4
new file mode 100644
index 0000000..3823566
--- /dev/null
+++ b/m4/malloc.m4
@@ -0,0 +1,98 @@
+# malloc.m4 serial 21
+dnl Copyright (C) 2007, 2009-2020 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.
+
+# This is adapted with modifications from upstream Autoconf here:
+# 
https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=04be2b7a29d65d9a08e64e8e56e594c91749598c
+AC_DEFUN([_AC_FUNC_MALLOC_IF],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+  AC_CACHE_CHECK([for GNU libc compatible malloc],
+    [ac_cv_func_malloc_0_nonnull],
+    [AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <stdlib.h>
+          ]],
+          [[char *p = malloc (0);
+            int result = !p;
+            free (p);
+            return result;]])
+       ],
+       [ac_cv_func_malloc_0_nonnull=yes],
+       [ac_cv_func_malloc_0_nonnull=no],
+       [case "$host_os" in
+          # Guess yes on platforms where we know the result.
+          *-gnu* | gnu* | *-musl* | freebsd* | netbsd* | openbsd* \
+          | hpux* | solaris* | cygwin* | mingw*)
+            ac_cv_func_malloc_0_nonnull="guessing yes" ;;
+          # If we don't know, obey --enable-cross-guesses.
+          *) ac_cv_func_malloc_0_nonnull="$gl_cross_guess_normal" ;;
+        esac
+       ])
+    ])
+  case "$ac_cv_func_malloc_0_nonnull" in
+    *yes)
+      $1
+      ;;
+    *)
+      $2
+      ;;
+  esac
+])# _AC_FUNC_MALLOC_IF
+
+# gl_FUNC_MALLOC_GNU
+# ------------------
+# Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if
+# it is not.
+AC_DEFUN([gl_FUNC_MALLOC_GNU],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  dnl _AC_FUNC_MALLOC_IF is defined in Autoconf.
+  _AC_FUNC_MALLOC_IF(
+    [AC_DEFINE([HAVE_MALLOC_GNU], [1],
+               [Define to 1 if your system has a GNU libc compatible 'malloc'
+                function, and to 0 otherwise.])],
+    [AC_DEFINE([HAVE_MALLOC_GNU], [0])
+     REPLACE_MALLOC=1
+    ])
+])
+
+# gl_FUNC_MALLOC_POSIX
+# --------------------
+# Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it
+# fails), and replace malloc if it is not.
+AC_DEFUN([gl_FUNC_MALLOC_POSIX],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([gl_CHECK_MALLOC_POSIX])
+  if test $gl_cv_func_malloc_posix = yes; then
+    AC_DEFINE([HAVE_MALLOC_POSIX], [1],
+      [Define if the 'malloc' function is POSIX compliant.])
+  else
+    REPLACE_MALLOC=1
+  fi
+])
+
+# Test whether malloc, realloc, calloc are POSIX compliant,
+# Set gl_cv_func_malloc_posix to yes or no accordingly.
+AC_DEFUN([gl_CHECK_MALLOC_POSIX],
+[
+  AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant],
+    [gl_cv_func_malloc_posix],
+    [
+      dnl It is too dangerous to try to allocate a large amount of memory:
+      dnl some systems go to their knees when you do that. So assume that
+      dnl all Unix implementations of the function are POSIX compliant.
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[]],
+           [[#if defined _WIN32 && ! defined __CYGWIN__
+             choke me
+             #endif
+            ]])],
+        [gl_cv_func_malloc_posix=yes],
+        [gl_cv_func_malloc_posix=no])
+    ])
+])
diff --git a/m4/read-file.m4 b/m4/read-file.m4
new file mode 100644
index 0000000..4638c7e
--- /dev/null
+++ b/m4/read-file.m4
@@ -0,0 +1,8 @@
+# read-file.m4 serial 3
+dnl Copyright (C) 2002-2006, 2009-2020 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.
+
+# Prerequisites of lib/read-file.c.
+AC_DEFUN([gl_PREREQ_READ_FILE], [:])
diff --git a/m4/realloc.m4 b/m4/realloc.m4
new file mode 100644
index 0000000..53967f4
--- /dev/null
+++ b/m4/realloc.m4
@@ -0,0 +1,76 @@
+# realloc.m4 serial 19
+dnl Copyright (C) 2007, 2009-2020 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.
+
+# This is adapted with modifications from upstream Autoconf here:
+# 
https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=04be2b7a29d65d9a08e64e8e56e594c91749598c
+AC_DEFUN([_AC_FUNC_REALLOC_IF],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+  AC_CACHE_CHECK([for GNU libc compatible realloc],
+    [ac_cv_func_realloc_0_nonnull],
+    [AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <stdlib.h>
+          ]],
+          [[char *p = realloc (0, 0);
+            int result = !p;
+            free (p);
+            return result;]])
+       ],
+       [ac_cv_func_realloc_0_nonnull=yes],
+       [ac_cv_func_realloc_0_nonnull=no],
+       [case "$host_os" in
+          # Guess yes on platforms where we know the result.
+          *-gnu* | gnu* | *-musl* | freebsd* | netbsd* | openbsd* \
+          | hpux* | solaris* | cygwin* | mingw*)
+            ac_cv_func_realloc_0_nonnull="guessing yes" ;;
+          # If we don't know, obey --enable-cross-guesses.
+          *) ac_cv_func_realloc_0_nonnull="$gl_cross_guess_normal" ;;
+        esac
+       ])
+    ])
+  case "$ac_cv_func_realloc_0_nonnull" in
+    *yes)
+      $1
+      ;;
+    *)
+      $2
+      ;;
+  esac
+])# AC_FUNC_REALLOC
+
+# gl_FUNC_REALLOC_GNU
+# -------------------
+# Test whether 'realloc (0, 0)' is handled like in GNU libc, and replace
+# realloc if it is not.
+AC_DEFUN([gl_FUNC_REALLOC_GNU],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  dnl _AC_FUNC_REALLOC_IF is defined in Autoconf.
+  _AC_FUNC_REALLOC_IF(
+    [AC_DEFINE([HAVE_REALLOC_GNU], [1],
+               [Define to 1 if your system has a GNU libc compatible 'realloc'
+                function, and to 0 otherwise.])],
+    [AC_DEFINE([HAVE_REALLOC_GNU], [0])
+     REPLACE_REALLOC=1
+    ])
+])# gl_FUNC_REALLOC_GNU
+
+# gl_FUNC_REALLOC_POSIX
+# ---------------------
+# Test whether 'realloc' is POSIX compliant (sets errno to ENOMEM when it
+# fails), and replace realloc if it is not.
+AC_DEFUN([gl_FUNC_REALLOC_POSIX],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([gl_CHECK_MALLOC_POSIX])
+  if test $gl_cv_func_malloc_posix = yes; then
+    AC_DEFINE([HAVE_REALLOC_POSIX], [1],
+      [Define if the 'realloc' function is POSIX compliant.])
+  else
+    REPLACE_REALLOC=1
+  fi
+])



reply via email to

[Prev in Thread] Current Thread [Next in Thread]