From: Philipp Stephani Date: Sat, 26 Dec 2020 14:45:11 +0000 (+0100) Subject: Add Gnulib module 'read-file'. X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a4eb3bd7d5c4ae63efebfd77120c64e993cb872e;p=emacs.git 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. --- diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 880dc5eef53..901862af6b6 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 00000000000..252785019b7 --- /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 . */ + +/* Written by Bruno Haible , 2007. */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_fopen doesn't recurse to + rpl_fopen. */ +#define _GL_ALREADY_INCLUDING_STDIO_H +#include + +/* Get the original definition of fopen. It might be defined as a macro. */ +#include +#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 , otherwise OSF/1 5.1 DTK cc eliminates + this include because of the preliminary #include above. */ +#include "stdio.h" + +#include +#include +#include +#include +#include +#include +#include + +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 . 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 + : + "A pathname that contains at least one non- character and that + ends with one or more trailing characters shall not be resolved + successfully unless the last pathname component before the trailing + 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 + + 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 00000000000..234c1931ba2 --- /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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +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 00000000000..43d4a4d49af --- /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 . */ + +#include + +/* Specification. */ +#include + +/* Get lseek. */ +#include + +#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 372ddd64274..da07727247f 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 00000000000..aaf9f32c8e7 --- /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 . */ + +#include + +/* Specification. */ +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Windows platforms. */ +/* Get GetFileType. */ +# include +/* Get _get_osfhandle. */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif +#else +# include +#endif +#include + +#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 00000000000..08b22a7a25b --- /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 . */ + +#include + +#include "read-file.h" + +/* Get fstat. */ +#include + +/* Get ftello. */ +#include + +/* Get PTRDIFF_MAX. */ +#include + +/* Get malloc, realloc, free. */ +#include + +/* Get explicit_bzero, memcpy. */ +#include + +/* Get errno. */ +#include + +/* 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 00000000000..58192f1e8b2 --- /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 . */ + +#ifndef READ_FILE_H +#define READ_FILE_H + +/* Get size_t. */ +#include + +/* Get FILE. */ +#include + +/* 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 00000000000..a24054de93d --- /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 . */ + +/* written by Jim Meyering and Bruno Haible */ + +#define _GL_USE_STDLIB_ALLOC 1 +#include + +/* 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 + +#include + +/* 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 00000000000..a5d687ab9eb --- /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 +#include +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 +#include +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 +#include +#include +]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 00000000000..a64e6406595 --- /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 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 +]], [[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 ]], +[[#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 +# 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 00000000000..22055d4f683 --- /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 00000000000..4c629c06aed --- /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 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 ]], + [[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 +#include +#include +#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 0971636c33d..6d73146df1d 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 00000000000..472a1cbba08 --- /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 /* for off_t */ +#include /* for SEEK_CUR */ +#if HAVE_UNISTD_H +# include +#else /* on Windows with MSVC */ +# include +#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 00000000000..3823566d950 --- /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 + ]], + [[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 00000000000..4638c7e1d97 --- /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 00000000000..53967f4ef13 --- /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 + ]], + [[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 +])