Compare commits

...

4 commits

Author SHA1 Message Date
Philipp Stephani
202a61d09c Add a helper binary to create a basic Secure Computing filter.
The binary uses the 'seccomp' helper library.  The library isn't
needed to load the generated Secure Computing filter.

* configure.ac: Check for 'seccomp' header and library.

* lib-src/seccomp-filter.c: New helper binary to generate a generic
Secure Computing filter for GNU/Linux.

* lib-src/Makefile.in (DONT_INSTALL): Add 'seccomp-filter' helper
binary if possible.
(all): Add Secure Computing filter file if possible.
(seccomp-filter$(EXEEXT)): Compile helper binary.
(seccomp-filter.bpf seccomp-filter.pfc): Generate filter files.

* test/src/emacs-tests.el (emacs-tests/seccomp/allows-stdout)
(emacs-tests/seccomp/forbids-subprocess): New unit tests.

* test/Makefile.in (src/emacs-tests.log): Add dependency on the helper
binary.
2020-12-29 14:37:51 +01:00
Philipp Stephani
2334f9bfa3 Add support for --seccomp command-line option.
When passing this option on GNU/Linux, Emacs installs a Secure
Computing kernel system call filter.  See Bug#45198.

* configure.ac: Check for seccomp header.

* src/emacs.c (usage_message): Document --seccomp option.
(emacs_seccomp): New wrapper for 'seccomp' syscall.
(load_seccomp, maybe_load_seccomp): New helper functions.
(main): Potentially load seccomp filters during startup.
(standard_args): Add --seccomp option.

* lisp/startup.el (command-line): Detect and ignore --seccomp option.

* test/src/emacs-tests.el (emacs-tests/seccomp/absent-file)
(emacs-tests/seccomp/empty-file)
(emacs-tests/seccomp/file-too-large)
(emacs-tests/seccomp/invalid-file-size): New unit tests.
(emacs-tests--with-temp-file): New helper macro.

* etc/NEWS: Document new --seccomp option.
2020-12-29 14:37:51 +01:00
Philipp Stephani
a4eb3bd7d5 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.
2020-12-29 14:37:51 +01:00
Philipp Stephani
3fcd13c560 Update Gnulib.
All changes generated by running admin/merge-gnulib.
2020-12-29 14:37:51 +01:00
43 changed files with 2619 additions and 212 deletions

5
.gitignore vendored
View file

@ -187,6 +187,7 @@ lib-src/make-docfile
lib-src/make-fingerprint lib-src/make-fingerprint
lib-src/movemail lib-src/movemail
lib-src/profile lib-src/profile
lib-src/seccomp-filter
lib-src/test-distrib lib-src/test-distrib
lib-src/update-game-score lib-src/update-game-score
nextstep/Cocoa/Emacs.base/Contents/Info.plist nextstep/Cocoa/Emacs.base/Contents/Info.plist
@ -298,3 +299,7 @@ nt/emacs.rc
nt/emacsclient.rc nt/emacsclient.rc
src/gdb.ini src/gdb.ini
/var/ /var/
# Seccomp filter files.
lib-src/seccomp-filter.bpf
lib-src/seccomp-filter.pfc

View file

@ -40,7 +40,7 @@ GNULIB_MODULES='
ieee754-h ignore-value intprops largefile libgmp lstat ieee754-h ignore-value intprops largefile libgmp lstat
manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
pathmax pipe2 pselect pthread_sigmask 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 sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio
stpcpy strnlen strtoimax symlink sys_stat sys_time stpcpy strnlen strtoimax symlink sys_stat sys_time
tempname time time_r time_rz timegm timer-time timespec-add timespec-sub tempname time time_r time_rz timegm timer-time timespec-add timespec-sub

View file

@ -4184,6 +4184,13 @@ fi
AC_SUBST([BLESSMAIL_TARGET]) AC_SUBST([BLESSMAIL_TARGET])
AC_SUBST([LIBS_MAIL]) AC_SUBST([LIBS_MAIL])
AC_CHECK_HEADERS([linux/seccomp.h], [HAVE_SECCOMP=yes])
LIBSECCOMP=
AC_CHECK_HEADER([seccomp.h],
[AC_CHECK_LIB([seccomp], [seccomp_init], [LIBSECCOMP=-lseccomp])])
AC_SUBST([LIBSECCOMP])
OLD_LIBS=$LIBS OLD_LIBS=$LIBS
LIBS="$LIB_PTHREAD $LIB_MATH $LIBS" LIBS="$LIB_PTHREAD $LIB_MATH $LIBS"
AC_CHECK_FUNCS(accept4 fchdir gethostname \ AC_CHECK_FUNCS(accept4 fchdir gethostname \
@ -5659,7 +5666,7 @@ emacs_config_features=
for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG CAIRO IMAGEMAGICK SOUND GPM DBUS \ for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG CAIRO IMAGEMAGICK SOUND GPM DBUS \
GCONF GSETTINGS GLIB NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT \ GCONF GSETTINGS GLIB NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT \
LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS X_TOOLKIT OLDXMENU X11 XDBE XIM \ LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS X_TOOLKIT OLDXMENU X11 XDBE XIM \
NS MODULES THREADS XWIDGETS LIBSYSTEMD JSON PDUMPER UNEXEC LCMS2 GMP; do NS MODULES THREADS XWIDGETS LIBSYSTEMD JSON PDUMPER UNEXEC LCMS2 GMP SECCOMP; do
case $opt in case $opt in
PDUMPER) val=${with_pdumper} ;; PDUMPER) val=${with_pdumper} ;;

View file

@ -82,6 +82,16 @@ lacks the terminfo database, you can instruct Emacs to support 24-bit
true color by setting 'COLORTERM=truecolor' in the environment. This is true color by setting 'COLORTERM=truecolor' in the environment. This is
useful on systems such as FreeBSD which ships only with "etc/termcap". useful on systems such as FreeBSD which ships only with "etc/termcap".
** On GNU/Linux systems, Emacs now supports loading a Secure Computing
filter. To use this, you can pass a --seccomp=FILE command-line
option to Emacs. FILE must name a binary file containing an array of
'struct sock_filter' structures. Emacs will then install that list of
Secure Computing filters into its own process early during the startup
process. You can use this functionality to put an Emacs process in a
sandbox to avoid security issues when executing untrusted code. See
the manual page for 'seccomp' for details about Secure Computing
filters.
* Changes in Emacs 28.1 * Changes in Emacs 28.1

View file

@ -209,6 +209,12 @@ LIB_EACCESS=@LIB_EACCESS@
## empty or -lwsock2 for MinGW ## empty or -lwsock2 for MinGW
LIB_WSOCK32=@LIB_WSOCK32@ LIB_WSOCK32=@LIB_WSOCK32@
LIBSECCOMP=@LIBSECCOMP@
ifneq ($(LIBSECCOMP),)
DONT_INSTALL += seccomp-filter$(EXEEXT)
endif
## Extra libraries to use when linking movemail. ## Extra libraries to use when linking movemail.
LIBS_MOVE = $(LIBS_MAIL) $(KRB4LIB) $(DESLIB) $(KRB5LIB) $(CRYPTOLIB) \ LIBS_MOVE = $(LIBS_MAIL) $(KRB4LIB) $(DESLIB) $(KRB5LIB) $(CRYPTOLIB) \
$(COM_ERRLIB) $(LIBHESIOD) $(LIBRESOLV) $(LIB_WSOCK32) $(COM_ERRLIB) $(LIBHESIOD) $(LIBRESOLV) $(LIB_WSOCK32)
@ -238,6 +244,10 @@ config_h = ../src/config.h $(srcdir)/../src/conf_post.h
all: ${EXE_FILES} ${SCRIPTS} all: ${EXE_FILES} ${SCRIPTS}
ifneq ($(LIBSECCOMP),)
all: seccomp-filter.bpf
endif
.PHONY: all need-blessmail maybe-blessmail .PHONY: all need-blessmail maybe-blessmail
LOADLIBES = ../lib/libgnu.a $(LIBS_SYSTEM) LOADLIBES = ../lib/libgnu.a $(LIBS_SYSTEM)
@ -420,4 +430,13 @@ update-game-score${EXEEXT}: ${srcdir}/update-game-score.c $(NTLIB) $(config_h)
emacsclient.res: ../nt/emacsclient.rc $(NTINC)/../icons/emacs.ico emacsclient.res: ../nt/emacsclient.rc $(NTINC)/../icons/emacs.ico
$(AM_V_RC)$(WINDRES) -O coff --include-dir=$(NTINC)/.. -o $@ $< $(AM_V_RC)$(WINDRES) -O coff --include-dir=$(NTINC)/.. -o $@ $<
ifneq ($(LIBSECCOMP),)
seccomp-filter$(EXEEXT): $(srcdir)/seccomp-filter.c $(config_h)
$(AM_V_CCLD)$(CC) $(ALL_CFLAGS) $< $(LIBSECCOMP) -o $@
seccomp-filter.bpf seccomp-filter.pfc: seccomp-filter$(EXEEXT)
$(AM_V_GEN)./seccomp-filter$(EXEEXT) \
seccomp-filter.bpf seccomp-filter.pfc
endif
## Makefile ends here. ## Makefile ends here.

321
lib-src/seccomp-filter.c Normal file
View file

@ -0,0 +1,321 @@
/* Generate a Secure Computing filter definition file.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs 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.
GNU Emacs 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 GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
/* This program creates a small Secure Computing filter usable for a
typical minimal Emacs sandbox. See the man page for `seccomp' for
details about Secure Computing filters. This program requires the
`libseccomp' library. However, the resulting filter file requires
only a Linux kernel supporting the Secure Computing extension.
Usage:
seccomp-filter out.bpf out.pfc
This writes the raw `struct sock_filter' array to out.bpf and a
human-readable representation to out.pfc. */
#include "config.h"
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/futex.h>
#include <fcntl.h>
#include <sched.h>
#include <seccomp.h>
#include <unistd.h>
#include "verify.h"
static ATTRIBUTE_FORMAT_PRINTF (2, 3) _Noreturn void
fail (int error, const char *format, ...)
{
va_list ap;
va_start (ap, format);
if (error == 0)
vfprintf (stderr, format, ap);
else
{
char buffer[1000];
vsnprintf (buffer, sizeof buffer, format, ap);
errno = error;
perror (buffer);
}
va_end (ap);
fflush (NULL);
exit (EXIT_FAILURE);
}
/* This binary is trivial, so we use a single global filter context
object that we release using `atexit'. */
static scmp_filter_ctx ctx;
static void
release_context (void)
{
seccomp_release (ctx);
}
/* Wrapper functions and macros for libseccomp functions. We exit
immediately upon any error to avoid error checking noise. */
static void
set_attribute (enum scmp_filter_attr attr, uint32_t value)
{
int status = seccomp_attr_set (ctx, attr, value);
if (status < 0)
fail (-status, "seccomp_attr_set (ctx, %u, %u)", attr, value);
}
/* Like `seccomp_rule_add (ACTION, SYSCALL, ...)', except that you
don't have to specify the number of comparator arguments, and any
failure will exit the process. */
#define RULE(action, syscall, ...) \
do \
{ \
const struct scmp_arg_cmp arg_array[] = {__VA_ARGS__}; \
enum { arg_cnt = sizeof arg_array / sizeof *arg_array }; \
int status = seccomp_rule_add_array (ctx, (action), (syscall), \
arg_cnt, arg_array); \
if (status < 0) \
fail (-status, "seccomp_rule_add_array (%s, %s, %d, {%s})", \
#action, #syscall, arg_cnt, #__VA_ARGS__); \
} \
while (false)
static void
export_filter (const char *file,
int (*function) (const scmp_filter_ctx, int),
const char *name)
{
int fd = TEMP_FAILURE_RETRY (
open (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC,
0644));
if (fd < 0)
fail (errno, "open %s", file);
int status = function (ctx, fd);
if (status < 0)
fail (-status, "%s", name);
if (close (fd) != 0)
fail (errno, "close");
}
#define EXPORT_FILTER(file, function) \
export_filter ((file), (function), #function)
int
main (int argc, char **argv)
{
if (argc != 3)
fail (0, "usage: %s out.bpf out.pfc", argv[0]);
/* Any unhandled syscall should abort the Emacs process. */
ctx = seccomp_init (SCMP_ACT_KILL_PROCESS);
if (ctx == NULL)
fail (0, "seccomp_init");
atexit (release_context);
/* We want to abort immediately if the architecture is unknown. */
set_attribute (SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_KILL_PROCESS);
set_attribute (SCMP_FLTATR_CTL_NNP, 1);
set_attribute (SCMP_FLTATR_CTL_TSYNC, 1);
set_attribute (SCMP_FLTATR_CTL_LOG, 0);
verify (CHAR_BIT == 8);
verify (sizeof (int) == 4 && INT_MIN == INT32_MIN
&& INT_MAX == INT32_MAX);
verify (sizeof (void *) == 8);
verify ((uintptr_t) NULL == 0);
/* Allow a clean exit. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit_group));
/* Allow `mmap' and friends. This is necessary for dynamic loading,
reading the portable dump file, and thread creation. We don't
allow pages to be both writable and executable. */
verify (MAP_PRIVATE != 0);
verify (MAP_SHARED != 0);
RULE (SCMP_ACT_ALLOW, SCMP_SYS (mmap),
SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
~(PROT_NONE | PROT_READ | PROT_WRITE)),
/* Only support known flags. MAP_DENYWRITE is ignored, but
some versions of the dynamic loader still use it. Also
allow allocating thread stacks. */
SCMP_A3_32 (SCMP_CMP_MASKED_EQ,
~(MAP_PRIVATE | MAP_FILE | MAP_ANONYMOUS
| MAP_FIXED | MAP_DENYWRITE | MAP_STACK
| MAP_NORESERVE),
0));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (mmap),
SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
~(PROT_NONE | PROT_READ | PROT_EXEC)),
/* Only support known flags. MAP_DENYWRITE is ignored, but
some versions of the dynamic loader still use it. */
SCMP_A3_32 (SCMP_CMP_MASKED_EQ,
~(MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED
| MAP_DENYWRITE),
0));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (munmap));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (mprotect),
/* Don't allow making pages executable. */
SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
~(PROT_NONE | PROT_READ | PROT_WRITE), 0));
/* Futexes are used everywhere. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (futex),
SCMP_A1_32 (SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
/* Allow basic dynamic memory management. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (brk));
/* Allow some status inquiries. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (uname));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getuid));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (geteuid));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpid));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpgrp));
/* Allow operations on open file descriptors. File descriptors are
capabilities, and operating on them shouldn't cause security
issues. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (read));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (write));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (close));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (lseek));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup2));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstat));
/* Allow read operations on the filesystem. If necessary, these
should be further restricted using mount namespaces. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (access));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (faccessat));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat64));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat64));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstatat64));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (newfstatat));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlink));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlinkat));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getcwd));
/* Allow opening files, assuming they are only opened for
reading. */
verify (O_WRONLY != 0);
verify (O_RDWR != 0);
verify (O_CREAT != 0);
RULE (SCMP_ACT_ALLOW, SCMP_SYS (open),
SCMP_A1_32 (SCMP_CMP_MASKED_EQ,
~(O_RDONLY | O_BINARY | O_CLOEXEC | O_PATH
| O_DIRECTORY),
0));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (openat),
SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
~(O_RDONLY | O_BINARY | O_CLOEXEC | O_PATH
| O_DIRECTORY),
0));
/* Allow `tcgetpgrp'. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (ioctl),
SCMP_A0_32 (SCMP_CMP_EQ, STDIN_FILENO),
SCMP_A1_32 (SCMP_CMP_EQ, TIOCGPGRP));
/* Allow reading (but not setting) file flags. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl),
SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl64),
SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL));
/* Allow reading random numbers from the kernel. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrandom));
/* Changing the umask is uncritical. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (umask));
/* Allow creation of pipes. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe2));
/* Allow reading (but not changing) resource limits. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrlimit));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (prlimit64),
SCMP_A0_32 (SCMP_CMP_EQ, 0) /* pid == 0 (current process) */,
SCMP_A2_64 (SCMP_CMP_EQ, 0) /* new_limit == NULL */);
/* Block changing resource limits, but don't crash. */
RULE (SCMP_ACT_ERRNO (EPERM), SCMP_SYS (prlimit64),
SCMP_A0_32 (SCMP_CMP_EQ, 0) /* pid == 0 (current process) */,
SCMP_A2_64 (SCMP_CMP_NE, 0) /* new_limit != NULL */);
/* Emacs installs signal handlers, which is harmless. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaction));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigaction));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigprocmask));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigprocmask));
/* Allow timer support. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (timer_create));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (timerfd_create));
/* Allow thread creation. See the NOTES section in the manual page
for the `clone' function. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (clone),
SCMP_A0_64 (SCMP_CMP_MASKED_EQ,
/* Flags needed to create threads. See
create_thread in libc. */
~(CLONE_VM | CLONE_FS | CLONE_FILES
| CLONE_SYSVSEM | CLONE_SIGHAND | CLONE_THREAD
| CLONE_SETTLS | CLONE_PARENT_SETTID
| CLONE_CHILD_CLEARTID),
0));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaltstack));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_robust_list));
/* Allow setting the process name for new threads. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (prctl),
SCMP_A0_32 (SCMP_CMP_EQ, PR_SET_NAME));
/* Allow some event handling functions used by glib. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd2));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (wait4));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (poll));
/* Don't allow creating sockets (network access would be extremely
dangerous), but also don't crash. */
RULE (SCMP_ACT_ERRNO (EACCES), SCMP_SYS (socket));
EXPORT_FILTER (argv[1], seccomp_export_bpf);
EXPORT_FILTER (argv[2], seccomp_export_pfc);
}

View file

@ -112,7 +112,7 @@ _GL_CXXALIASWARN (creat);
/* Assume creat is always declared. */ /* Assume creat is always declared. */
_GL_WARN_ON_USE (creat, "creat is not always POSIX compliant - " _GL_WARN_ON_USE (creat, "creat is not always POSIX compliant - "
"use gnulib module creat for portability"); "use gnulib module creat for portability");
#else #elif @GNULIB_MDA_CREAT@
/* On native Windows, map 'creat' to '_creat', so that -loldnames is not /* On native Windows, map 'creat' to '_creat', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::creat always. */ platforms by defining GNULIB_NAMESPACE::creat always. */
@ -186,7 +186,7 @@ _GL_CXXALIASWARN (open);
/* Assume open is always declared. */ /* Assume open is always declared. */
_GL_WARN_ON_USE (open, "open is not always POSIX compliant - " _GL_WARN_ON_USE (open, "open is not always POSIX compliant - "
"use gnulib module open for portability"); "use gnulib module open for portability");
#else #elif @GNULIB_MDA_OPEN@
/* On native Windows, map 'open' to '_open', so that -loldnames is not /* On native Windows, map 'open' to '_open', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::open always. */ platforms by defining GNULIB_NAMESPACE::open always. */

230
lib/fopen.c Normal file
View file

@ -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);
}

37
lib/ftell.c Normal file
View file

@ -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;
}
}

85
lib/ftello.c Normal file
View file

@ -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);
}

View file

@ -133,6 +133,7 @@
# pselect \ # pselect \
# pthread_sigmask \ # pthread_sigmask \
# qcopy-acl \ # qcopy-acl \
# read-file \
# readlink \ # readlink \
# readlinkat \ # readlinkat \
# regex \ # regex \
@ -362,10 +363,51 @@ GNULIB_MBSSPN = @GNULIB_MBSSPN@
GNULIB_MBSSTR = @GNULIB_MBSSTR@ GNULIB_MBSSTR = @GNULIB_MBSSTR@
GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@ GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
GNULIB_MBTOWC = @GNULIB_MBTOWC@ GNULIB_MBTOWC = @GNULIB_MBTOWC@
GNULIB_MDA_ACCESS = @GNULIB_MDA_ACCESS@
GNULIB_MDA_CHDIR = @GNULIB_MDA_CHDIR@
GNULIB_MDA_CHMOD = @GNULIB_MDA_CHMOD@
GNULIB_MDA_CLOSE = @GNULIB_MDA_CLOSE@
GNULIB_MDA_CREAT = @GNULIB_MDA_CREAT@
GNULIB_MDA_DUP = @GNULIB_MDA_DUP@
GNULIB_MDA_DUP2 = @GNULIB_MDA_DUP2@
GNULIB_MDA_ECVT = @GNULIB_MDA_ECVT@
GNULIB_MDA_EXECL = @GNULIB_MDA_EXECL@
GNULIB_MDA_EXECLE = @GNULIB_MDA_EXECLE@
GNULIB_MDA_EXECLP = @GNULIB_MDA_EXECLP@
GNULIB_MDA_EXECV = @GNULIB_MDA_EXECV@
GNULIB_MDA_EXECVE = @GNULIB_MDA_EXECVE@
GNULIB_MDA_EXECVP = @GNULIB_MDA_EXECVP@
GNULIB_MDA_EXECVPE = @GNULIB_MDA_EXECVPE@
GNULIB_MDA_FCLOSEALL = @GNULIB_MDA_FCLOSEALL@
GNULIB_MDA_FCVT = @GNULIB_MDA_FCVT@
GNULIB_MDA_FDOPEN = @GNULIB_MDA_FDOPEN@
GNULIB_MDA_FILENO = @GNULIB_MDA_FILENO@
GNULIB_MDA_GCVT = @GNULIB_MDA_GCVT@
GNULIB_MDA_GETCWD = @GNULIB_MDA_GETCWD@
GNULIB_MDA_GETPID = @GNULIB_MDA_GETPID@
GNULIB_MDA_GETW = @GNULIB_MDA_GETW@
GNULIB_MDA_ISATTY = @GNULIB_MDA_ISATTY@
GNULIB_MDA_LSEEK = @GNULIB_MDA_LSEEK@
GNULIB_MDA_MEMCCPY = @GNULIB_MDA_MEMCCPY@
GNULIB_MDA_MKDIR = @GNULIB_MDA_MKDIR@
GNULIB_MDA_MKTEMP = @GNULIB_MDA_MKTEMP@
GNULIB_MDA_OPEN = @GNULIB_MDA_OPEN@
GNULIB_MDA_PUTENV = @GNULIB_MDA_PUTENV@
GNULIB_MDA_PUTW = @GNULIB_MDA_PUTW@
GNULIB_MDA_READ = @GNULIB_MDA_READ@
GNULIB_MDA_RMDIR = @GNULIB_MDA_RMDIR@
GNULIB_MDA_STRDUP = @GNULIB_MDA_STRDUP@
GNULIB_MDA_SWAB = @GNULIB_MDA_SWAB@
GNULIB_MDA_TEMPNAM = @GNULIB_MDA_TEMPNAM@
GNULIB_MDA_TZSET = @GNULIB_MDA_TZSET@
GNULIB_MDA_UMASK = @GNULIB_MDA_UMASK@
GNULIB_MDA_UNLINK = @GNULIB_MDA_UNLINK@
GNULIB_MDA_WRITE = @GNULIB_MDA_WRITE@
GNULIB_MEMCHR = @GNULIB_MEMCHR@ GNULIB_MEMCHR = @GNULIB_MEMCHR@
GNULIB_MEMMEM = @GNULIB_MEMMEM@ GNULIB_MEMMEM = @GNULIB_MEMMEM@
GNULIB_MEMPCPY = @GNULIB_MEMPCPY@ GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
GNULIB_MEMRCHR = @GNULIB_MEMRCHR@ GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
GNULIB_MKDIR = @GNULIB_MKDIR@
GNULIB_MKDIRAT = @GNULIB_MKDIRAT@ GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
GNULIB_MKDTEMP = @GNULIB_MKDTEMP@ GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
GNULIB_MKFIFO = @GNULIB_MKFIFO@ GNULIB_MKFIFO = @GNULIB_MKFIFO@
@ -1111,11 +1153,11 @@ gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b = @gl_GNULIB_ENABLED_260941c0
gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@ gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@
gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c@ gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c@
gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec = @gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec@ gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec = @gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec@
gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c = @gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c@
gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1@ gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1@
gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@ gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@
gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@ gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@
gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@ gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@
gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955 = @gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955@
gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@ gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@
gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@
gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@
@ -1159,6 +1201,7 @@ pdfdir = @pdfdir@
prefix = @prefix@ prefix = @prefix@
program_transform_name = @program_transform_name@ program_transform_name = @program_transform_name@
psdir = @psdir@ psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@ srcdir = @srcdir@
@ -1680,6 +1723,8 @@ fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \ -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \
-e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \ -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \
-e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \ -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \
-e 's/@''GNULIB_MDA_CREAT''@/$(GNULIB_MDA_CREAT)/g' \
-e 's/@''GNULIB_MDA_OPEN''@/$(GNULIB_MDA_OPEN)/g' \
-e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \ -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
-e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \ -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \
-e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \ -e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \
@ -1748,6 +1793,28 @@ EXTRA_DIST += flexmember.h
endif endif
## end gnulib module flexmember ## 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 ## begin gnulib module fpending
ifeq (,$(OMIT_GNULIB_MODULE_fpending)) ifeq (,$(OMIT_GNULIB_MODULE_fpending))
@ -1803,6 +1870,28 @@ EXTRA_libgnu_a_SOURCES += fsync.c
endif endif
## end gnulib module fsync ## 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 ## begin gnulib module futimens
ifeq (,$(OMIT_GNULIB_MODULE_futimens)) ifeq (,$(OMIT_GNULIB_MODULE_futimens))
@ -2132,6 +2221,19 @@ EXTRA_DIST += limits.in.h
endif endif
## end gnulib module limits-h ## 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 ## begin gnulib module lstat
ifeq (,$(OMIT_GNULIB_MODULE_lstat)) ifeq (,$(OMIT_GNULIB_MODULE_lstat))
@ -2313,6 +2415,16 @@ EXTRA_libgnu_a_SOURCES += rawmemchr.c
endif endif
## end gnulib module rawmemchr ## 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 ## begin gnulib module readlink
ifeq (,$(OMIT_GNULIB_MODULE_readlink)) ifeq (,$(OMIT_GNULIB_MODULE_readlink))
@ -2335,6 +2447,17 @@ EXTRA_libgnu_a_SOURCES += at-func.c readlinkat.c
endif endif
## end gnulib module readlinkat ## 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 ## begin gnulib module regex
ifeq (,$(OMIT_GNULIB_MODULE_regex)) ifeq (,$(OMIT_GNULIB_MODULE_regex))
@ -2679,6 +2802,12 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \
-e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \
-e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \
-e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GNULIB_MDA_FCLOSEALL)/g' \
-e 's/@''GNULIB_MDA_FDOPEN''@/$(GNULIB_MDA_FDOPEN)/g' \
-e 's/@''GNULIB_MDA_FILENO''@/$(GNULIB_MDA_FILENO)/g' \
-e 's/@''GNULIB_MDA_GETW''@/$(GNULIB_MDA_GETW)/g' \
-e 's/@''GNULIB_MDA_PUTW''@/$(GNULIB_MDA_PUTW)/g' \
-e 's/@''GNULIB_MDA_TEMPNAM''@/$(GNULIB_MDA_TEMPNAM)/g' \
< $(srcdir)/stdio.in.h | \ < $(srcdir)/stdio.in.h | \
sed -e 's|@''HAVE_DECL_FCLOSEALL''@|$(HAVE_DECL_FCLOSEALL)|g' \ sed -e 's|@''HAVE_DECL_FCLOSEALL''@|$(HAVE_DECL_FCLOSEALL)|g' \
-e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \
@ -2796,6 +2925,11 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \
-e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \
-e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \
-e 's/@''GNULIB_MDA_ECVT''@/$(GNULIB_MDA_ECVT)/g' \
-e 's/@''GNULIB_MDA_FCVT''@/$(GNULIB_MDA_FCVT)/g' \
-e 's/@''GNULIB_MDA_GCVT''@/$(GNULIB_MDA_GCVT)/g' \
-e 's/@''GNULIB_MDA_MKTEMP''@/$(GNULIB_MDA_MKTEMP)/g' \
-e 's/@''GNULIB_MDA_PUTENV''@/$(GNULIB_MDA_PUTENV)/g' \
< $(srcdir)/stdlib.in.h | \ < $(srcdir)/stdlib.in.h | \
sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
-e 's|@''HAVE_ALIGNED_ALLOC''@|$(HAVE_ALIGNED_ALLOC)|g' \ -e 's|@''HAVE_ALIGNED_ALLOC''@|$(HAVE_ALIGNED_ALLOC)|g' \
@ -2941,6 +3075,8 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's/@''GNULIB_SIGDESCR_NP''@/$(GNULIB_SIGDESCR_NP)/g' \ -e 's/@''GNULIB_SIGDESCR_NP''@/$(GNULIB_SIGDESCR_NP)/g' \
-e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \
-e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
-e 's/@''GNULIB_MDA_MEMCCPY''@/$(GNULIB_MDA_MEMCCPY)/g' \
-e 's/@''GNULIB_MDA_STRDUP''@/$(GNULIB_MDA_STRDUP)/g' \
< $(srcdir)/string.in.h | \ < $(srcdir)/string.in.h | \
sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \ sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \
-e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \
@ -3136,6 +3272,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
-e 's/@''GNULIB_GETUMASK''@/$(GNULIB_GETUMASK)/g' \ -e 's/@''GNULIB_GETUMASK''@/$(GNULIB_GETUMASK)/g' \
-e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \ -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \
-e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \ -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \
-e 's/@''GNULIB_MKDIR''@/$(GNULIB_MKDIR)/g' \
-e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \ -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \
-e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \ -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \
-e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \ -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \
@ -3144,6 +3281,9 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
-e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \ -e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \
-e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \ -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \
-e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GNULIB_OVERRIDES_STRUCT_STAT)/g' \ -e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GNULIB_OVERRIDES_STRUCT_STAT)/g' \
-e 's/@''GNULIB_MDA_CHMOD''@/$(GNULIB_MDA_CHMOD)/g' \
-e 's/@''GNULIB_MDA_MKDIR''@/$(GNULIB_MDA_MKDIR)/g' \
-e 's/@''GNULIB_MDA_UMASK''@/$(GNULIB_MDA_UMASK)/g' \
-e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \ -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \
-e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \ -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \
-e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \ -e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \
@ -3279,6 +3419,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
-e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \ -e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \
-e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \ -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \
-e 's/@''GNULIB_MDA_TZSET''@/$(GNULIB_MDA_TZSET)/g' \
-e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \ -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \ -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
@ -3452,6 +3593,27 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \
-e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \
-e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \
-e 's/@''GNULIB_MDA_ACCESS''@/$(GNULIB_MDA_ACCESS)/g' \
-e 's/@''GNULIB_MDA_CHDIR''@/$(GNULIB_MDA_CHDIR)/g' \
-e 's/@''GNULIB_MDA_CLOSE''@/$(GNULIB_MDA_CLOSE)/g' \
-e 's/@''GNULIB_MDA_DUP''@/$(GNULIB_MDA_DUP)/g' \
-e 's/@''GNULIB_MDA_DUP2''@/$(GNULIB_MDA_DUP2)/g' \
-e 's/@''GNULIB_MDA_EXECL''@/$(GNULIB_MDA_EXECL)/g' \
-e 's/@''GNULIB_MDA_EXECLE''@/$(GNULIB_MDA_EXECLE)/g' \
-e 's/@''GNULIB_MDA_EXECLP''@/$(GNULIB_MDA_EXECLP)/g' \
-e 's/@''GNULIB_MDA_EXECV''@/$(GNULIB_MDA_EXECV)/g' \
-e 's/@''GNULIB_MDA_EXECVE''@/$(GNULIB_MDA_EXECVE)/g' \
-e 's/@''GNULIB_MDA_EXECVP''@/$(GNULIB_MDA_EXECVP)/g' \
-e 's/@''GNULIB_MDA_EXECVPE''@/$(GNULIB_MDA_EXECVPE)/g' \
-e 's/@''GNULIB_MDA_GETCWD''@/$(GNULIB_MDA_GETCWD)/g' \
-e 's/@''GNULIB_MDA_GETPID''@/$(GNULIB_MDA_GETPID)/g' \
-e 's/@''GNULIB_MDA_ISATTY''@/$(GNULIB_MDA_ISATTY)/g' \
-e 's/@''GNULIB_MDA_LSEEK''@/$(GNULIB_MDA_LSEEK)/g' \
-e 's/@''GNULIB_MDA_READ''@/$(GNULIB_MDA_READ)/g' \
-e 's/@''GNULIB_MDA_RMDIR''@/$(GNULIB_MDA_RMDIR)/g' \
-e 's/@''GNULIB_MDA_SWAB''@/$(GNULIB_MDA_SWAB)/g' \
-e 's/@''GNULIB_MDA_UNLINK''@/$(GNULIB_MDA_UNLINK)/g' \
-e 's/@''GNULIB_MDA_WRITE''@/$(GNULIB_MDA_WRITE)/g' \
< $(srcdir)/unistd.in.h | \ < $(srcdir)/unistd.in.h | \
sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \
-e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \ -e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \

View file

@ -1,19 +1,20 @@
/* A type for indices and sizes. /* A type for indices and sizes.
Copyright (C) 2020 Free Software Foundation, Inc. Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify The GNU C Library is free software; you can redistribute it and/or
it under the terms of the GNU General Public License as published by modify it under the terms of the GNU General Public
the Free Software Foundation; either version 3, or (at your option) License as published by the Free Software Foundation; either
any later version. version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
GNU General Public License for more details. General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public
along with this program; if not, see <https://www.gnu.org/licenses/>. */ License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef _IDX_H #ifndef _IDX_H
#define _IDX_H #define _IDX_H

71
lib/lseek.c Normal file
View file

@ -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
}

221
lib/read-file.c Normal file
View file

@ -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;
}

37
lib/read-file.h Normal file
View file

@ -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 */

79
lib/realloc.c Normal file
View file

@ -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;
}

View file

@ -229,27 +229,29 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - "
"use gnulib module fclose for portable POSIX compliance"); "use gnulib module fclose for portable POSIX compliance");
#endif #endif
#if @GNULIB_MDA_FCLOSEALL@
/* On native Windows, map 'fcloseall' to '_fcloseall', so that -loldnames is /* On native Windows, map 'fcloseall' to '_fcloseall', so that -loldnames is
not required. In C++ with GNULIB_NAMESPACE, avoid differences between not required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::fcloseall on all platforms that have platforms by defining GNULIB_NAMESPACE::fcloseall on all platforms that have
it. */ it. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef fcloseall # undef fcloseall
# define fcloseall _fcloseall # define fcloseall _fcloseall
# endif # endif
_GL_CXXALIAS_MDA (fcloseall, int, (void)); _GL_CXXALIAS_MDA (fcloseall, int, (void));
#else # else
# if @HAVE_DECL_FCLOSEALL@ # if @HAVE_DECL_FCLOSEALL@
# if defined __FreeBSD__ # if defined __FreeBSD__
_GL_CXXALIAS_SYS (fcloseall, void, (void)); _GL_CXXALIAS_SYS (fcloseall, void, (void));
# else # else
_GL_CXXALIAS_SYS (fcloseall, int, (void)); _GL_CXXALIAS_SYS (fcloseall, int, (void));
# endif
# endif # endif
# endif # endif
#endif # if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCLOSEALL@
#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCLOSEALL@
_GL_CXXALIASWARN (fcloseall); _GL_CXXALIASWARN (fcloseall);
# endif
#endif #endif
#if @GNULIB_FDOPEN@ #if @GNULIB_FDOPEN@
@ -276,7 +278,7 @@ _GL_CXXALIASWARN (fdopen);
/* Assume fdopen is always declared. */ /* Assume fdopen is always declared. */
_GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX compliant - " _GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX compliant - "
"use gnulib module fdopen for portability"); "use gnulib module fdopen for portability");
#else #elif @GNULIB_MDA_FDOPEN@
/* On native Windows, map 'fdopen' to '_fdopen', so that -loldnames is not /* On native Windows, map 'fdopen' to '_fdopen', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::fdopen always. */ platforms by defining GNULIB_NAMESPACE::fdopen always. */
@ -354,19 +356,21 @@ _GL_CXXALIASWARN (fgets);
# endif # endif
#endif #endif
#if @GNULIB_MDA_FILENO@
/* On native Windows, map 'fileno' to '_fileno', so that -loldnames is not /* On native Windows, map 'fileno' to '_fileno', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::fileno always. */ platforms by defining GNULIB_NAMESPACE::fileno always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef fileno # undef fileno
# define fileno _fileno # define fileno _fileno
# endif # endif
_GL_CXXALIAS_MDA (fileno, int, (FILE *restrict stream)); _GL_CXXALIAS_MDA (fileno, int, (FILE *restrict stream));
#else # else
_GL_CXXALIAS_SYS (fileno, int, (FILE *restrict stream)); _GL_CXXALIAS_SYS (fileno, int, (FILE *restrict stream));
#endif # endif
_GL_CXXALIASWARN (fileno); _GL_CXXALIASWARN (fileno);
#endif
#if @GNULIB_FOPEN@ #if @GNULIB_FOPEN@
# if @REPLACE_FOPEN@ # if @REPLACE_FOPEN@
@ -895,19 +899,21 @@ _GL_WARN_ON_USE (getline, "getline is unportable - "
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
#endif #endif
#if @GNULIB_MDA_GETW@
/* On native Windows, map 'getw' to '_getw', so that -loldnames is not /* On native Windows, map 'getw' to '_getw', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::getw always. */ platforms by defining GNULIB_NAMESPACE::getw always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef getw # undef getw
# define getw _getw # define getw _getw
# endif # endif
_GL_CXXALIAS_MDA (getw, int, (FILE *restrict stream)); _GL_CXXALIAS_MDA (getw, int, (FILE *restrict stream));
#else # else
_GL_CXXALIAS_SYS (getw, int, (FILE *restrict stream)); _GL_CXXALIAS_SYS (getw, int, (FILE *restrict stream));
#endif # endif
_GL_CXXALIASWARN (getw); _GL_CXXALIASWARN (getw);
#endif
#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
struct obstack; struct obstack;
@ -1122,19 +1128,21 @@ _GL_CXXALIASWARN (puts);
# endif # endif
#endif #endif
#if @GNULIB_MDA_PUTW@
/* On native Windows, map 'putw' to '_putw', so that -loldnames is not /* On native Windows, map 'putw' to '_putw', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::putw always. */ platforms by defining GNULIB_NAMESPACE::putw always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef putw # undef putw
# define putw _putw # define putw _putw
# endif # endif
_GL_CXXALIAS_MDA (putw, int, (int w, FILE *restrict stream)); _GL_CXXALIAS_MDA (putw, int, (int w, FILE *restrict stream));
#else # else
_GL_CXXALIAS_SYS (putw, int, (int w, FILE *restrict stream)); _GL_CXXALIAS_SYS (putw, int, (int w, FILE *restrict stream));
#endif # endif
_GL_CXXALIASWARN (putw); _GL_CXXALIASWARN (putw);
#endif
#if @GNULIB_REMOVE@ #if @GNULIB_REMOVE@
# if @REPLACE_REMOVE@ # if @REPLACE_REMOVE@
@ -1315,19 +1323,21 @@ _GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX compliant - "
"POSIX compliance"); "POSIX compliance");
#endif #endif
#if @GNULIB_MDA_TEMPNAM@
/* On native Windows, map 'tempnam' to '_tempnam', so that -loldnames is not /* On native Windows, map 'tempnam' to '_tempnam', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::tempnam always. */ platforms by defining GNULIB_NAMESPACE::tempnam always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef tempnam # undef tempnam
# define tempnam _tempnam # define tempnam _tempnam
# endif # endif
_GL_CXXALIAS_MDA (tempnam, char *, (const char *dir, const char *prefix)); _GL_CXXALIAS_MDA (tempnam, char *, (const char *dir, const char *prefix));
#else # else
_GL_CXXALIAS_SYS (tempnam, char *, (const char *dir, const char *prefix)); _GL_CXXALIAS_SYS (tempnam, char *, (const char *dir, const char *prefix));
#endif # endif
_GL_CXXALIASWARN (tempnam); _GL_CXXALIASWARN (tempnam);
#endif
#if @GNULIB_TMPFILE@ #if @GNULIB_TMPFILE@
# if @REPLACE_TMPFILE@ # if @REPLACE_TMPFILE@

View file

@ -242,46 +242,50 @@ _GL_WARN_ON_USE (canonicalize_file_name,
# endif # endif
#endif #endif
#if @GNULIB_MDA_ECVT@
/* On native Windows, map 'ecvt' to '_ecvt', so that -loldnames is not /* On native Windows, map 'ecvt' to '_ecvt', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::ecvt on all platforms that have platforms by defining GNULIB_NAMESPACE::ecvt on all platforms that have
it. */ it. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef ecvt # undef ecvt
# define ecvt _ecvt # define ecvt _ecvt
# endif # endif
_GL_CXXALIAS_MDA (ecvt, char *, _GL_CXXALIAS_MDA (ecvt, char *,
(double number, int ndigits, int *decptp, int *signp)); (double number, int ndigits, int *decptp, int *signp));
#else # else
# if @HAVE_DECL_ECVT@ # if @HAVE_DECL_ECVT@
_GL_CXXALIAS_SYS (ecvt, char *, _GL_CXXALIAS_SYS (ecvt, char *,
(double number, int ndigits, int *decptp, int *signp)); (double number, int ndigits, int *decptp, int *signp));
# endif
# endif
# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_ECVT@
_GL_CXXALIASWARN (ecvt);
# endif # endif
#endif #endif
#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_ECVT@
_GL_CXXALIASWARN (ecvt);
#endif
#if @GNULIB_MDA_FCVT@
/* On native Windows, map 'fcvt' to '_fcvt', so that -loldnames is not /* On native Windows, map 'fcvt' to '_fcvt', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::fcvt on all platforms that have platforms by defining GNULIB_NAMESPACE::fcvt on all platforms that have
it. */ it. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef fcvt # undef fcvt
# define fcvt _fcvt # define fcvt _fcvt
# endif # endif
_GL_CXXALIAS_MDA (fcvt, char *, _GL_CXXALIAS_MDA (fcvt, char *,
(double number, int ndigits, int *decptp, int *signp)); (double number, int ndigits, int *decptp, int *signp));
#else # else
# if @HAVE_DECL_FCVT@ # if @HAVE_DECL_FCVT@
_GL_CXXALIAS_SYS (fcvt, char *, _GL_CXXALIAS_SYS (fcvt, char *,
(double number, int ndigits, int *decptp, int *signp)); (double number, int ndigits, int *decptp, int *signp));
# endif
# endif # endif
#endif # if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCVT@
#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCVT@
_GL_CXXALIASWARN (fcvt); _GL_CXXALIASWARN (fcvt);
# endif
#endif #endif
#if @GNULIB_FREE_POSIX@ #if @GNULIB_FREE_POSIX@
@ -305,23 +309,25 @@ _GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - "
"use gnulib module free for portability"); "use gnulib module free for portability");
#endif #endif
#if @GNULIB_MDA_GCVT@
/* On native Windows, map 'gcvt' to '_gcvt', so that -loldnames is not /* On native Windows, map 'gcvt' to '_gcvt', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::gcvt on all platforms that have platforms by defining GNULIB_NAMESPACE::gcvt on all platforms that have
it. */ it. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef gcvt # undef gcvt
# define gcvt _gcvt # define gcvt _gcvt
# endif # endif
_GL_CXXALIAS_MDA (gcvt, char *, (double number, int ndigits, char *buf)); _GL_CXXALIAS_MDA (gcvt, char *, (double number, int ndigits, char *buf));
#else # else
# if @HAVE_DECL_GCVT@ # if @HAVE_DECL_GCVT@
_GL_CXXALIAS_SYS (gcvt, char *, (double number, int ndigits, char *buf)); _GL_CXXALIAS_SYS (gcvt, char *, (double number, int ndigits, char *buf));
# endif
# endif # endif
#endif # if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_GCVT@
#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_GCVT@
_GL_CXXALIASWARN (gcvt); _GL_CXXALIASWARN (gcvt);
# endif
#endif #endif
#if @GNULIB_GETLOADAVG@ #if @GNULIB_GETLOADAVG@
@ -575,19 +581,21 @@ _GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - "
# endif # endif
#endif #endif
#if @GNULIB_MDA_MKTEMP@
/* On native Windows, map 'mktemp' to '_mktemp', so that -loldnames is not /* On native Windows, map 'mktemp' to '_mktemp', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::mktemp always. */ platforms by defining GNULIB_NAMESPACE::mktemp always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef mktemp # undef mktemp
# define mktemp _mktemp # define mktemp _mktemp
# endif # endif
_GL_CXXALIAS_MDA (mktemp, char *, (char * /*template*/)); _GL_CXXALIAS_MDA (mktemp, char *, (char * /*template*/));
#else # else
_GL_CXXALIAS_SYS (mktemp, char *, (char * /*template*/)); _GL_CXXALIAS_SYS (mktemp, char *, (char * /*template*/));
#endif # endif
_GL_CXXALIASWARN (mktemp); _GL_CXXALIASWARN (mktemp);
#endif
/* Allocate memory with indefinite extent and specified alignment. */ /* Allocate memory with indefinite extent and specified alignment. */
#if @GNULIB_POSIX_MEMALIGN@ #if @GNULIB_POSIX_MEMALIGN@
@ -706,7 +714,7 @@ _GL_CXXALIAS_MDA (putenv, int, (char *string));
_GL_CXXALIAS_SYS (putenv, int, (char *string)); _GL_CXXALIAS_SYS (putenv, int, (char *string));
# endif # endif
_GL_CXXALIASWARN (putenv); _GL_CXXALIASWARN (putenv);
#else #elif @GNULIB_MDA_PUTENV@
/* On native Windows, map 'putenv' to '_putenv', so that -loldnames is not /* On native Windows, map 'putenv' to '_putenv', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::putenv always. */ platforms by defining GNULIB_NAMESPACE::putenv always. */

View file

@ -123,21 +123,23 @@ _GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module");
#endif #endif
#if @GNULIB_MDA_MEMCCPY@
/* On native Windows, map 'memccpy' to '_memccpy', so that -loldnames is not /* On native Windows, map 'memccpy' to '_memccpy', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::memccpy always. */ platforms by defining GNULIB_NAMESPACE::memccpy always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef memccpy # undef memccpy
# define memccpy _memccpy # define memccpy _memccpy
# endif # endif
_GL_CXXALIAS_MDA (memccpy, void *, _GL_CXXALIAS_MDA (memccpy, void *,
(void *dest, const void *src, int c, size_t n)); (void *dest, const void *src, int c, size_t n));
#else # else
_GL_CXXALIAS_SYS (memccpy, void *, _GL_CXXALIAS_SYS (memccpy, void *,
(void *dest, const void *src, int c, size_t n)); (void *dest, const void *src, int c, size_t n));
#endif # endif
_GL_CXXALIASWARN (memccpy); _GL_CXXALIASWARN (memccpy);
#endif
/* Return the first instance of C within N bytes of S, or NULL. */ /* Return the first instance of C within N bytes of S, or NULL. */
@ -425,7 +427,7 @@ _GL_CXXALIASWARN (strdup);
_GL_WARN_ON_USE (strdup, "strdup is unportable - " _GL_WARN_ON_USE (strdup, "strdup is unportable - "
"use gnulib module strdup for portability"); "use gnulib module strdup for portability");
# endif # endif
#else #elif @GNULIB_MDA_STRDUP@
/* On native Windows, map 'creat' to '_creat', so that -loldnames is not /* On native Windows, map 'creat' to '_creat', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::creat always. */ platforms by defining GNULIB_NAMESPACE::creat always. */

View file

@ -391,20 +391,22 @@ struct stat
#endif #endif
#if @GNULIB_MDA_CHMOD@
/* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not /* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::chmod always. */ platforms by defining GNULIB_NAMESPACE::chmod always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef chmod # undef chmod
# define chmod _chmod # define chmod _chmod
# endif # endif
/* Need to cast, because in mingw the last argument is 'int mode'. */ /* Need to cast, because in mingw the last argument is 'int mode'. */
_GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode)); _GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode));
#else # else
_GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode)); _GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode));
#endif # endif
_GL_CXXALIASWARN (chmod); _GL_CXXALIASWARN (chmod);
#endif
#if @GNULIB_FCHMODAT@ #if @GNULIB_FCHMODAT@
@ -606,21 +608,20 @@ _GL_WARN_ON_USE (lstat, "lstat is unportable - "
#endif #endif
#if @REPLACE_MKDIR@ #if @GNULIB_MKDIR@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if @REPLACE_MKDIR@
# undef mkdir # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define mkdir rpl_mkdir # undef mkdir
# endif # define mkdir rpl_mkdir
# endif
_GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode) _GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode)
_GL_ARG_NONNULL ((1))); _GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode));
#else # elif defined _WIN32 && !defined __CYGWIN__
/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. /* mingw's _mkdir() function has 1 argument, but we pass 2 arguments.
Additionally, it declares _mkdir (and depending on compile flags, an Additionally, it declares _mkdir (and depending on compile flags, an
alias mkdir), only in the nonstandard includes <direct.h> and <io.h>, alias mkdir), only in the nonstandard includes <direct.h> and <io.h>,
which are included above. */ which are included above. */
# if defined _WIN32 && ! defined __CYGWIN__
# if !GNULIB_defined_rpl_mkdir # if !GNULIB_defined_rpl_mkdir
static int static int
rpl_mkdir (char const *name, mode_t mode) rpl_mkdir (char const *name, mode_t mode)
@ -629,16 +630,44 @@ rpl_mkdir (char const *name, mode_t mode)
} }
# define GNULIB_defined_rpl_mkdir 1 # define GNULIB_defined_rpl_mkdir 1
# endif # endif
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef mkdir
# define mkdir rpl_mkdir # define mkdir rpl_mkdir
# endif # endif
_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode));
# else # else
_GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); _GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode));
# endif # endif
#endif
_GL_CXXALIASWARN (mkdir); _GL_CXXALIASWARN (mkdir);
#elif defined GNULIB_POSIXCHECK
# undef mkdir
# if HAVE_RAW_DECL_MKDIR
_GL_WARN_ON_USE (mkdir, "mkdir does not always support two parameters - "
"use gnulib module mkdir for portability");
# endif
#elif @GNULIB_MDA_MKDIR@
/* On native Windows, map 'mkdir' to '_mkdir', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::mkdir always. */
# if defined _WIN32 && !defined __CYGWIN__
# if !GNULIB_defined_rpl_mkdir
static int
rpl_mkdir (char const *name, mode_t mode)
{
return _mkdir (name);
}
# define GNULIB_defined_rpl_mkdir 1
# endif
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef mkdir
# define mkdir rpl_mkdir
# endif
_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode));
# else
_GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode));
# endif
_GL_CXXALIASWARN (mkdir);
#endif
#if @GNULIB_MKDIRAT@ #if @GNULIB_MKDIRAT@
@ -818,20 +847,22 @@ _GL_WARN_ON_USE (stat, "stat is unportable - "
#endif #endif
#if @GNULIB_MDA_UMASK@
/* On native Windows, map 'umask' to '_umask', so that -loldnames is not /* On native Windows, map 'umask' to '_umask', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::umask always. */ platforms by defining GNULIB_NAMESPACE::umask always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef umask # undef umask
# define umask _umask # define umask _umask
# endif # endif
/* Need to cast, because in mingw the last argument is 'int mode'. */ /* Need to cast, because in mingw the last argument is 'int mode'. */
_GL_CXXALIAS_MDA_CAST (umask, mode_t, (mode_t mask)); _GL_CXXALIAS_MDA_CAST (umask, mode_t, (mode_t mask));
#else # else
_GL_CXXALIAS_SYS (umask, mode_t, (mode_t mask)); _GL_CXXALIAS_SYS (umask, mode_t, (mode_t mask));
#endif # endif
_GL_CXXALIASWARN (umask); _GL_CXXALIASWARN (umask);
#endif
#if @GNULIB_UTIMENSAT@ #if @GNULIB_UTIMENSAT@

View file

@ -145,7 +145,7 @@ _GL_CXXALIAS_MDA (tzset, void, (void));
_GL_CXXALIAS_SYS (tzset, void, (void)); _GL_CXXALIAS_SYS (tzset, void, (void));
# endif # endif
_GL_CXXALIASWARN (tzset); _GL_CXXALIASWARN (tzset);
# else # elif @GNULIB_MDA_TZSET@
/* On native Windows, map 'tzset' to '_tzset', so that -loldnames is not /* On native Windows, map 'tzset' to '_tzset', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::tzset always. */ platforms by defining GNULIB_NAMESPACE::tzset always. */

View file

@ -287,7 +287,7 @@ _GL_WARN_ON_USE (access, "access does not always support X_OK - "
"also, this function is a security risk - " "also, this function is a security risk - "
"use the gnulib module faccessat instead"); "use the gnulib module faccessat instead");
# endif # endif
#else #elif @GNULIB_MDA_ACCESS@
/* On native Windows, map 'access' to '_access', so that -loldnames is not /* On native Windows, map 'access' to '_access', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::access always. */ platforms by defining GNULIB_NAMESPACE::access always. */
@ -321,7 +321,7 @@ _GL_CXXALIASWARN (chdir);
_GL_WARN_ON_USE (chown, "chdir is not always in <unistd.h> - " _GL_WARN_ON_USE (chown, "chdir is not always in <unistd.h> - "
"use gnulib module chdir for portability"); "use gnulib module chdir for portability");
# endif # endif
#else #elif @GNULIB_MDA_CHDIR@
/* On native Windows, map 'chdir' to '_chdir', so that -loldnames is not /* On native Windows, map 'chdir' to '_chdir', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::chdir always. */ platforms by defining GNULIB_NAMESPACE::chdir always. */
@ -397,7 +397,7 @@ _GL_CXXALIASWARN (close);
/* Assume close is always declared. */ /* Assume close is always declared. */
_GL_WARN_ON_USE (close, "close does not portably work on sockets - " _GL_WARN_ON_USE (close, "close does not portably work on sockets - "
"use gnulib module close for portability"); "use gnulib module close for portability");
#else #elif @GNULIB_MDA_CLOSE@
/* On native Windows, map 'close' to '_close', so that -loldnames is not /* On native Windows, map 'close' to '_close', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::close always. */ platforms by defining GNULIB_NAMESPACE::close always. */
@ -456,7 +456,7 @@ _GL_CXXALIASWARN (dup);
_GL_WARN_ON_USE (dup, "dup is unportable - " _GL_WARN_ON_USE (dup, "dup is unportable - "
"use gnulib module dup for portability"); "use gnulib module dup for portability");
# endif # endif
#else #elif @GNULIB_MDA_DUP@
/* On native Windows, map 'dup' to '_dup', so that -loldnames is not /* On native Windows, map 'dup' to '_dup', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::dup always. */ platforms by defining GNULIB_NAMESPACE::dup always. */
@ -501,7 +501,7 @@ _GL_CXXALIASWARN (dup2);
_GL_WARN_ON_USE (dup2, "dup2 is unportable - " _GL_WARN_ON_USE (dup2, "dup2 is unportable - "
"use gnulib module dup2 for portability"); "use gnulib module dup2 for portability");
# endif # endif
#else #elif @GNULIB_MDA_DUP2@
/* On native Windows, map 'dup2' to '_dup2', so that -loldnames is not /* On native Windows, map 'dup2' to '_dup2', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::dup2 always. */ platforms by defining GNULIB_NAMESPACE::dup2 always. */
@ -615,116 +615,130 @@ _GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - "
#endif #endif
#if @GNULIB_MDA_EXECL@
/* On native Windows, map 'execl' to '_execl', so that -loldnames is not /* On native Windows, map 'execl' to '_execl', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::execl always. */ platforms by defining GNULIB_NAMESPACE::execl always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef execl # undef execl
# define execl _execl # define execl _execl
# endif # endif
_GL_CXXALIAS_MDA (execl, intptr_t, (const char *program, const char *arg, ...)); _GL_CXXALIAS_MDA (execl, intptr_t, (const char *program, const char *arg, ...));
#else # else
_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...)); _GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...));
#endif # endif
_GL_CXXALIASWARN (execl); _GL_CXXALIASWARN (execl);
#endif
#if @GNULIB_MDA_EXECLE@
/* On native Windows, map 'execle' to '_execle', so that -loldnames is not /* On native Windows, map 'execle' to '_execle', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::execle always. */ platforms by defining GNULIB_NAMESPACE::execle always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef execle # undef execle
# define execle _execle # define execle _execle
# endif # endif
_GL_CXXALIAS_MDA (execle, intptr_t, (const char *program, const char *arg, ...)); _GL_CXXALIAS_MDA (execle, intptr_t, (const char *program, const char *arg, ...));
#else # else
_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...)); _GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...));
#endif # endif
_GL_CXXALIASWARN (execle); _GL_CXXALIASWARN (execle);
#endif
#if @GNULIB_MDA_EXECLP@
/* On native Windows, map 'execlp' to '_execlp', so that -loldnames is not /* On native Windows, map 'execlp' to '_execlp', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::execlp always. */ platforms by defining GNULIB_NAMESPACE::execlp always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef execlp # undef execlp
# define execlp _execlp # define execlp _execlp
# endif # endif
_GL_CXXALIAS_MDA (execlp, intptr_t, (const char *program, const char *arg, ...)); _GL_CXXALIAS_MDA (execlp, intptr_t, (const char *program, const char *arg, ...));
#else # else
_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...)); _GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...));
#endif # endif
_GL_CXXALIASWARN (execlp); _GL_CXXALIASWARN (execlp);
#endif
#if @GNULIB_MDA_EXECV@
/* On native Windows, map 'execv' to '_execv', so that -loldnames is not /* On native Windows, map 'execv' to '_execv', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::execv always. */ platforms by defining GNULIB_NAMESPACE::execv always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef execv # undef execv
# define execv _execv # define execv _execv
# endif # endif
_GL_CXXALIAS_MDA (execv, intptr_t, _GL_CXXALIAS_MDA (execv, intptr_t,
(const char *program, const char * const *argv)); (const char *program, const char * const *argv));
#else # else
_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv)); _GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv));
#endif # endif
_GL_CXXALIASWARN (execv); _GL_CXXALIASWARN (execv);
#endif
#if @GNULIB_MDA_EXECVE@
/* On native Windows, map 'execve' to '_execve', so that -loldnames is not /* On native Windows, map 'execve' to '_execve', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::execve always. */ platforms by defining GNULIB_NAMESPACE::execve always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef execve # undef execve
# define execve _execve # define execve _execve
# endif # endif
_GL_CXXALIAS_MDA (execve, intptr_t, _GL_CXXALIAS_MDA (execve, intptr_t,
(const char *program, const char * const *argv, (const char *program, const char * const *argv,
const char * const *env)); const char * const *env));
#else # else
_GL_CXXALIAS_SYS (execve, int, _GL_CXXALIAS_SYS (execve, int,
(const char *program, char * const *argv, char * const *env)); (const char *program, char * const *argv, char * const *env));
#endif # endif
_GL_CXXALIASWARN (execve); _GL_CXXALIASWARN (execve);
#endif
#if @GNULIB_MDA_EXECVP@
/* On native Windows, map 'execvp' to '_execvp', so that -loldnames is not /* On native Windows, map 'execvp' to '_execvp', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::execvp always. */ platforms by defining GNULIB_NAMESPACE::execvp always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef execvp # undef execvp
# define execvp _execvp # define execvp _execvp
# endif # endif
_GL_CXXALIAS_MDA (execvp, intptr_t, _GL_CXXALIAS_MDA (execvp, intptr_t,
(const char *program, const char * const *argv)); (const char *program, const char * const *argv));
#else # else
_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv)); _GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv));
#endif # endif
_GL_CXXALIASWARN (execvp); _GL_CXXALIASWARN (execvp);
#endif
#if @GNULIB_MDA_EXECVPE@
/* On native Windows, map 'execvpe' to '_execvpe', so that -loldnames is not /* On native Windows, map 'execvpe' to '_execvpe', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::execvpe on all platforms that have platforms by defining GNULIB_NAMESPACE::execvpe on all platforms that have
it. */ it. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef execvpe # undef execvpe
# define execvpe _execvpe # define execvpe _execvpe
# endif # endif
_GL_CXXALIAS_MDA (execvpe, intptr_t, _GL_CXXALIAS_MDA (execvpe, intptr_t,
(const char *program, const char * const *argv, (const char *program, const char * const *argv,
const char * const *env)); const char * const *env));
#else # else
# if @HAVE_DECL_EXECVPE@ # if @HAVE_DECL_EXECVPE@
_GL_CXXALIAS_SYS (execvpe, int, _GL_CXXALIAS_SYS (execvpe, int,
(const char *program, char * const *argv, char * const *env)); (const char *program, char * const *argv, char * const *env));
# endif
# endif # endif
#endif # if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_EXECVPE@
#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_EXECVPE@
_GL_CXXALIASWARN (execvpe); _GL_CXXALIASWARN (execvpe);
# endif
#endif #endif
@ -921,7 +935,7 @@ _GL_CXXALIASWARN (getcwd);
_GL_WARN_ON_USE (getcwd, "getcwd is unportable - " _GL_WARN_ON_USE (getcwd, "getcwd is unportable - "
"use gnulib module getcwd for portability"); "use gnulib module getcwd for portability");
# endif # endif
#else #elif @GNULIB_MDA_GETCWD@
/* On native Windows, map 'getcwd' to '_getcwd', so that -loldnames is not /* On native Windows, map 'getcwd' to '_getcwd', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::getcwd always. */ platforms by defining GNULIB_NAMESPACE::getcwd always. */
@ -1271,19 +1285,21 @@ _GL_WARN_ON_USE (getpass, "getpass is unportable - "
#endif #endif
#if @GNULIB_MDA_GETPID@
/* On native Windows, map 'getpid' to '_getpid', so that -loldnames is not /* On native Windows, map 'getpid' to '_getpid', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::getpid always. */ platforms by defining GNULIB_NAMESPACE::getpid always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef getpid # undef getpid
# define getpid _getpid # define getpid _getpid
# endif # endif
_GL_CXXALIAS_MDA (getpid, int, (void)); _GL_CXXALIAS_MDA (getpid, int, (void));
#else # else
_GL_CXXALIAS_SYS (getpid, pid_t, (void)); _GL_CXXALIAS_SYS (getpid, pid_t, (void));
#endif # endif
_GL_CXXALIASWARN (getpid); _GL_CXXALIASWARN (getpid);
#endif
#if @GNULIB_GETUSERSHELL@ #if @GNULIB_GETUSERSHELL@
@ -1374,7 +1390,7 @@ _GL_CXXALIASWARN (isatty);
_GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - " _GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - "
"use gnulib module isatty for portability"); "use gnulib module isatty for portability");
# endif # endif
#else #elif @GNULIB_MDA_ISATTY@
/* On native Windows, map 'isatty' to '_isatty', so that -loldnames is not /* On native Windows, map 'isatty' to '_isatty', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::isatty always. */ platforms by defining GNULIB_NAMESPACE::isatty always. */
@ -1515,7 +1531,7 @@ _GL_CXXALIASWARN (lseek);
_GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some " _GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some "
"systems - use gnulib module lseek for portability"); "systems - use gnulib module lseek for portability");
# endif # endif
#else #elif @GNULIB_MDA_LSEEK@
/* On native Windows, map 'lseek' to '_lseek', so that -loldnames is not /* On native Windows, map 'lseek' to '_lseek', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::lseek always. */ platforms by defining GNULIB_NAMESPACE::lseek always. */
@ -1671,7 +1687,7 @@ _GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, size_t count));
_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count)); _GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count));
# endif # endif
_GL_CXXALIASWARN (read); _GL_CXXALIASWARN (read);
#else #elif @GNULIB_MDA_READ@
/* On native Windows, map 'read' to '_read', so that -loldnames is not /* On native Windows, map 'read' to '_read', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::read always. */ platforms by defining GNULIB_NAMESPACE::read always. */
@ -1787,7 +1803,7 @@ _GL_CXXALIASWARN (rmdir);
_GL_WARN_ON_USE (rmdir, "rmdir is unportable - " _GL_WARN_ON_USE (rmdir, "rmdir is unportable - "
"use gnulib module rmdir for portability"); "use gnulib module rmdir for portability");
# endif # endif
#else #elif @GNULIB_MDA_RMDIR@
/* On native Windows, map 'rmdir' to '_rmdir', so that -loldnames is not /* On native Windows, map 'rmdir' to '_rmdir', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::rmdir always. */ platforms by defining GNULIB_NAMESPACE::rmdir always. */
@ -1859,19 +1875,21 @@ _GL_WARN_ON_USE (sleep, "sleep is unportable - "
#endif #endif
#if @GNULIB_MDA_SWAB@
/* On native Windows, map 'swab' to '_swab', so that -loldnames is not /* On native Windows, map 'swab' to '_swab', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::creat always. */ platforms by defining GNULIB_NAMESPACE::creat always. */
#if defined _WIN32 && !defined __CYGWIN__ # if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef swab # undef swab
# define swab _swab # define swab _swab
# endif # endif
_GL_CXXALIAS_MDA (swab, void, (char *from, char *to, int n)); _GL_CXXALIAS_MDA (swab, void, (char *from, char *to, int n));
#else # else
_GL_CXXALIAS_SYS (swab, void, (const void *from, void *to, ssize_t n)); _GL_CXXALIAS_SYS (swab, void, (const void *from, void *to, ssize_t n));
#endif # endif
_GL_CXXALIASWARN (swab); _GL_CXXALIASWARN (swab);
#endif
#if @GNULIB_SYMLINK@ #if @GNULIB_SYMLINK@
@ -2014,7 +2032,7 @@ _GL_CXXALIASWARN (unlink);
_GL_WARN_ON_USE (unlink, "unlink is not portable - " _GL_WARN_ON_USE (unlink, "unlink is not portable - "
"use gnulib module unlink for portability"); "use gnulib module unlink for portability");
# endif # endif
#else #elif @GNULIB_MDA_UNLINK@
/* On native Windows, map 'unlink' to '_unlink', so that -loldnames is not /* On native Windows, map 'unlink' to '_unlink', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::unlink always. */ platforms by defining GNULIB_NAMESPACE::unlink always. */
@ -2109,7 +2127,7 @@ _GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, size_t count));
_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count)); _GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count));
# endif # endif
_GL_CXXALIASWARN (write); _GL_CXXALIASWARN (write);
#else #elif @GNULIB_MDA_WRITE@
/* On native Windows, map 'write' to '_write', so that -loldnames is not /* On native Windows, map 'write' to '_write', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::write always. */ platforms by defining GNULIB_NAMESPACE::write always. */

View file

@ -1094,7 +1094,7 @@ please check its value")
("--no-x-resources") ("--debug-init") ("--no-x-resources") ("--debug-init")
("--user") ("--iconic") ("--icon-type") ("--quick") ("--user") ("--iconic") ("--icon-type") ("--quick")
("--no-blinking-cursor") ("--basic-display") ("--no-blinking-cursor") ("--basic-display")
("--dump-file") ("--temacs"))) ("--dump-file") ("--temacs") ("--seccomp")))
(argi (pop args)) (argi (pop args))
(orig-argi argi) (orig-argi argi)
argval) argval)
@ -1146,7 +1146,8 @@ please check its value")
(push '(visibility . icon) initial-frame-alist)) (push '(visibility . icon) initial-frame-alist))
((member argi '("-nbc" "-no-blinking-cursor")) ((member argi '("-nbc" "-no-blinking-cursor"))
(setq no-blinking-cursor t)) (setq no-blinking-cursor t))
((member argi '("-dump-file" "-temacs")) ; Handled in C ((member argi '("-dump-file" "-temacs" "-seccomp"))
;; Handled in C
(or argval (pop args)) (or argval (pop args))
(setq argval nil)) (setq argval nil))
;; Push the popped arg back on the list of arguments. ;; Push the popped arg back on the list of arguments.

View file

@ -1,4 +1,4 @@
# serial 16 # serial 17
# Configure fcntl.h. # Configure fcntl.h.
dnl Copyright (C) 2006-2007, 2009-2020 Free Software Foundation, Inc. dnl Copyright (C) 2006-2007, 2009-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
@ -42,6 +42,9 @@ AC_DEFUN([gl_FCNTL_H_DEFAULTS],
GNULIB_NONBLOCKING=0; AC_SUBST([GNULIB_NONBLOCKING]) GNULIB_NONBLOCKING=0; AC_SUBST([GNULIB_NONBLOCKING])
GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN]) GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN])
GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT]) GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT])
dnl Support Microsoft deprecated alias function names by default.
GNULIB_MDA_CREAT=1; AC_SUBST([GNULIB_MDA_CREAT])
GNULIB_MDA_OPEN=1; AC_SUBST([GNULIB_MDA_OPEN])
dnl Assume proper GNU behavior unless another module says otherwise. dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL]) HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL])
HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT]) HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT])

148
m4/fopen.m4 Normal file
View file

@ -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], [:])

77
m4/fseeko.m4 Normal file
View file

@ -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
])

15
m4/ftell.m4 Normal file
View file

@ -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
])

142
m4/ftello.m4 Normal file
View file

@ -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])
])

View file

@ -92,6 +92,8 @@ AC_DEFUN([gl_EARLY],
# Code from module filename: # Code from module filename:
# Code from module filevercmp: # Code from module filevercmp:
# Code from module flexmember: # Code from module flexmember:
# Code from module fopen:
# Code from module fopen-gnu:
# Code from module fpending: # Code from module fpending:
# Code from module fpieee: # Code from module fpieee:
AC_REQUIRE([gl_FP_IEEE]) AC_REQUIRE([gl_FP_IEEE])
@ -99,6 +101,9 @@ AC_DEFUN([gl_EARLY],
# Code from module fstatat: # Code from module fstatat:
# Code from module fsusage: # Code from module fsusage:
# Code from module fsync: # 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 futimens:
# Code from module getdtablesize: # Code from module getdtablesize:
# Code from module getgroups: # Code from module getgroups:
@ -123,6 +128,7 @@ AC_DEFUN([gl_EARLY],
# Code from module libc-config: # Code from module libc-config:
# Code from module libgmp: # Code from module libgmp:
# Code from module limits-h: # Code from module limits-h:
# Code from module lseek:
# Code from module lstat: # Code from module lstat:
# Code from module manywarnings: # Code from module manywarnings:
# Code from module memmem-simple: # Code from module memmem-simple:
@ -143,8 +149,10 @@ AC_DEFUN([gl_EARLY],
# Code from module pthread_sigmask: # Code from module pthread_sigmask:
# Code from module qcopy-acl: # Code from module qcopy-acl:
# Code from module rawmemchr: # Code from module rawmemchr:
# Code from module read-file:
# Code from module readlink: # Code from module readlink:
# Code from module readlinkat: # Code from module readlinkat:
# Code from module realloc-posix:
# Code from module regex: # Code from module regex:
# Code from module root-uid: # Code from module root-uid:
# Code from module scratch_buffer: # Code from module scratch_buffer:
@ -288,6 +296,18 @@ AC_DEFUN([gl_INIT],
gl_MODULE_INDICATOR([fdopendir]) gl_MODULE_INDICATOR([fdopendir])
gl_FILEMODE gl_FILEMODE
AC_C_FLEXIBLE_ARRAY_MEMBER 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 gl_FUNC_FPENDING
if test $gl_cv_func___fpending = no; then if test $gl_cv_func___fpending = no; then
AC_LIBOBJ([fpending]) AC_LIBOBJ([fpending])
@ -314,6 +334,17 @@ AC_DEFUN([gl_INIT],
gl_PREREQ_FSYNC gl_PREREQ_FSYNC
fi fi
gl_UNISTD_MODULE_INDICATOR([fsync]) 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 gl_FUNC_FUTIMENS
if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
AC_LIBOBJ([futimens]) AC_LIBOBJ([futimens])
@ -414,6 +445,7 @@ AC_DEFUN([gl_INIT],
gl_PREREQ_PTHREAD_SIGMASK gl_PREREQ_PTHREAD_SIGMASK
fi fi
gl_SIGNAL_MODULE_INDICATOR([pthread_sigmask]) gl_SIGNAL_MODULE_INDICATOR([pthread_sigmask])
gl_PREREQ_READ_FILE
gl_FUNC_READLINK gl_FUNC_READLINK
if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
AC_LIBOBJ([readlink]) AC_LIBOBJ([readlink])
@ -425,6 +457,11 @@ AC_DEFUN([gl_INIT],
AC_LIBOBJ([readlinkat]) AC_LIBOBJ([readlinkat])
fi fi
gl_UNISTD_MODULE_INDICATOR([readlinkat]) 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 gl_REGEX
if test $ac_use_included_regex = yes; then if test $ac_use_included_regex = yes; then
AC_LIBOBJ([regex]) AC_LIBOBJ([regex])
@ -525,6 +562,7 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false
gl_gnulib_enabled_idx=false gl_gnulib_enabled_idx=false
gl_gnulib_enabled_lchmod=false gl_gnulib_enabled_lchmod=false
gl_gnulib_enabled_lseek=false
gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false
gl_gnulib_enabled_open=false gl_gnulib_enabled_open=false
gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false
@ -653,6 +691,17 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_lchmod=true gl_gnulib_enabled_lchmod=true
fi 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 () func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31 ()
{ {
if ! $gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31; then if ! $gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31; then
@ -773,12 +822,18 @@ AC_DEFUN([gl_INIT],
if test $HAVE_FDOPENDIR = 0; then if test $HAVE_FDOPENDIR = 0; then
func_gl_gnulib_m4code_dirfd func_gl_gnulib_m4code_dirfd
fi fi
if test $REPLACE_FOPEN = 1; then
func_gl_gnulib_m4code_open
fi
if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
fi fi
if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7 func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
fi 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 if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
func_gl_gnulib_m4code_utimens func_gl_gnulib_m4code_utimens
fi fi
@ -827,6 +882,7 @@ AC_DEFUN([gl_INIT],
AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], [$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1]) 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_idx], [$gl_gnulib_enabled_idx])
AM_CONDITIONAL([gl_GNULIB_ENABLED_lchmod], [$gl_gnulib_enabled_lchmod]) 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_5264294aa0a5557541b53c8c741f7f31], [$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31])
AM_CONDITIONAL([gl_GNULIB_ENABLED_open], [$gl_gnulib_enabled_open]) AM_CONDITIONAL([gl_GNULIB_ENABLED_open], [$gl_gnulib_enabled_open])
AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7]) AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7])
@ -1038,6 +1094,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/filevercmp.c lib/filevercmp.c
lib/filevercmp.h lib/filevercmp.h
lib/flexmember.h lib/flexmember.h
lib/fopen.c
lib/fpending.c lib/fpending.c
lib/fpending.h lib/fpending.h
lib/free.c lib/free.c
@ -1045,6 +1102,8 @@ AC_DEFUN([gl_FILE_LIST], [
lib/fsusage.c lib/fsusage.c
lib/fsusage.h lib/fsusage.h
lib/fsync.c lib/fsync.c
lib/ftell.c
lib/ftello.c
lib/ftoastr.c lib/ftoastr.c
lib/ftoastr.h lib/ftoastr.h
lib/futimens.c lib/futimens.c
@ -1075,6 +1134,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/lchmod.c lib/lchmod.c
lib/libc-config.h lib/libc-config.h
lib/limits.in.h lib/limits.in.h
lib/lseek.c
lib/lstat.c lib/lstat.c
lib/malloc/scratch_buffer.h lib/malloc/scratch_buffer.h
lib/malloc/scratch_buffer_grow.c lib/malloc/scratch_buffer_grow.c
@ -1104,8 +1164,11 @@ AC_DEFUN([gl_FILE_LIST], [
lib/qcopy-acl.c lib/qcopy-acl.c
lib/rawmemchr.c lib/rawmemchr.c
lib/rawmemchr.valgrind lib/rawmemchr.valgrind
lib/read-file.c
lib/read-file.h
lib/readlink.c lib/readlink.c
lib/readlinkat.c lib/readlinkat.c
lib/realloc.c
lib/regcomp.c lib/regcomp.c
lib/regex.c lib/regex.c
lib/regex.h lib/regex.h
@ -1201,12 +1264,16 @@ AC_DEFUN([gl_FILE_LIST], [
m4/fdopendir.m4 m4/fdopendir.m4
m4/filemode.m4 m4/filemode.m4
m4/flexmember.m4 m4/flexmember.m4
m4/fopen.m4
m4/fpending.m4 m4/fpending.m4
m4/fpieee.m4 m4/fpieee.m4
m4/free.m4 m4/free.m4
m4/fseeko.m4
m4/fstatat.m4 m4/fstatat.m4
m4/fsusage.m4 m4/fsusage.m4
m4/fsync.m4 m4/fsync.m4
m4/ftell.m4
m4/ftello.m4
m4/futimens.m4 m4/futimens.m4
m4/getdtablesize.m4 m4/getdtablesize.m4
m4/getgroups.m4 m4/getgroups.m4
@ -1226,7 +1293,9 @@ AC_DEFUN([gl_FILE_LIST], [
m4/lchmod.m4 m4/lchmod.m4
m4/libgmp.m4 m4/libgmp.m4
m4/limits-h.m4 m4/limits-h.m4
m4/lseek.m4
m4/lstat.m4 m4/lstat.m4
m4/malloc.m4
m4/manywarnings-c++.m4 m4/manywarnings-c++.m4
m4/manywarnings.m4 m4/manywarnings.m4
m4/mbstate_t.m4 m4/mbstate_t.m4
@ -1251,8 +1320,10 @@ AC_DEFUN([gl_FILE_LIST], [
m4/pselect.m4 m4/pselect.m4
m4/pthread_sigmask.m4 m4/pthread_sigmask.m4
m4/rawmemchr.m4 m4/rawmemchr.m4
m4/read-file.m4
m4/readlink.m4 m4/readlink.m4
m4/readlinkat.m4 m4/readlinkat.m4
m4/realloc.m4
m4/regex.m4 m4/regex.m4
m4/sha1.m4 m4/sha1.m4
m4/sha256.m4 m4/sha256.m4

72
m4/lseek.m4 Normal file
View file

@ -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
])

98
m4/malloc.m4 Normal file
View file

@ -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])
])
])

8
m4/read-file.m4 Normal file
View file

@ -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], [:])

76
m4/realloc.m4 Normal file
View file

@ -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
])

View file

@ -1,4 +1,4 @@
# stdio_h.m4 serial 51 # stdio_h.m4 serial 52
dnl Copyright (C) 2007-2020 Free Software Foundation, Inc. dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -180,6 +180,13 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS],
GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX]) GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX])
GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF]) GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF])
GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX])
dnl Support Microsoft deprecated alias function names by default.
GNULIB_MDA_FCLOSEALL=1; AC_SUBST([GNULIB_MDA_FCLOSEALL])
GNULIB_MDA_FDOPEN=1; AC_SUBST([GNULIB_MDA_FDOPEN])
GNULIB_MDA_FILENO=1; AC_SUBST([GNULIB_MDA_FILENO])
GNULIB_MDA_GETW=1; AC_SUBST([GNULIB_MDA_GETW])
GNULIB_MDA_PUTW=1; AC_SUBST([GNULIB_MDA_PUTW])
GNULIB_MDA_TEMPNAM=1; AC_SUBST([GNULIB_MDA_TEMPNAM])
dnl Assume proper GNU behavior unless another module says otherwise. dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DECL_FCLOSEALL=1; AC_SUBST([HAVE_DECL_FCLOSEALL]) HAVE_DECL_FCLOSEALL=1; AC_SUBST([HAVE_DECL_FCLOSEALL])
HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE]) HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE])

View file

@ -1,4 +1,4 @@
# stdlib_h.m4 serial 54 # stdlib_h.m4 serial 55
dnl Copyright (C) 2007-2020 Free Software Foundation, Inc. dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -95,6 +95,12 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT]) GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT])
GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV]) GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV])
GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB]) GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB])
dnl Support Microsoft deprecated alias function names by default.
GNULIB_MDA_ECVT=1; AC_SUBST([GNULIB_MDA_ECVT])
GNULIB_MDA_FCVT=1; AC_SUBST([GNULIB_MDA_FCVT])
GNULIB_MDA_GCVT=1; AC_SUBST([GNULIB_MDA_GCVT])
GNULIB_MDA_MKTEMP=1; AC_SUBST([GNULIB_MDA_MKTEMP])
GNULIB_MDA_PUTENV=1; AC_SUBST([GNULIB_MDA_PUTENV])
dnl Assume proper GNU behavior unless another module says otherwise. dnl Assume proper GNU behavior unless another module says otherwise.
HAVE__EXIT=1; AC_SUBST([HAVE__EXIT]) HAVE__EXIT=1; AC_SUBST([HAVE__EXIT])
HAVE_ALIGNED_ALLOC=1; AC_SUBST([HAVE_ALIGNED_ALLOC]) HAVE_ALIGNED_ALLOC=1; AC_SUBST([HAVE_ALIGNED_ALLOC])

View file

@ -5,7 +5,7 @@
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved. # with or without modifications, as long as this notice is preserved.
# serial 27 # serial 28
# Written by Paul Eggert. # Written by Paul Eggert.
@ -86,6 +86,9 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL])
GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP])
HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN])
dnl Support Microsoft deprecated alias function names by default.
GNULIB_MDA_MEMCCPY=1; AC_SUBST([GNULIB_MDA_MEMCCPY])
GNULIB_MDA_STRDUP=1; AC_SUBST([GNULIB_MDA_STRDUP])
dnl Assume proper GNU behavior unless another module says otherwise. dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO]) HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO])
HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) HAVE_FFSL=1; AC_SUBST([HAVE_FFSL])

View file

@ -1,4 +1,4 @@
# sys_stat_h.m4 serial 34 -*- Autoconf -*- # sys_stat_h.m4 serial 36 -*- Autoconf -*-
dnl Copyright (C) 2006-2020 Free Software Foundation, Inc. dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -71,6 +71,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
GNULIB_GETUMASK=0; AC_SUBST([GNULIB_GETUMASK]) GNULIB_GETUMASK=0; AC_SUBST([GNULIB_GETUMASK])
GNULIB_LCHMOD=0; AC_SUBST([GNULIB_LCHMOD]) GNULIB_LCHMOD=0; AC_SUBST([GNULIB_LCHMOD])
GNULIB_LSTAT=0; AC_SUBST([GNULIB_LSTAT]) GNULIB_LSTAT=0; AC_SUBST([GNULIB_LSTAT])
GNULIB_MKDIR=0; AC_SUBST([GNULIB_MKDIR])
GNULIB_MKDIRAT=0; AC_SUBST([GNULIB_MKDIRAT]) GNULIB_MKDIRAT=0; AC_SUBST([GNULIB_MKDIRAT])
GNULIB_MKFIFO=0; AC_SUBST([GNULIB_MKFIFO]) GNULIB_MKFIFO=0; AC_SUBST([GNULIB_MKFIFO])
GNULIB_MKFIFOAT=0; AC_SUBST([GNULIB_MKFIFOAT]) GNULIB_MKFIFOAT=0; AC_SUBST([GNULIB_MKFIFOAT])
@ -79,6 +80,10 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
GNULIB_STAT=0; AC_SUBST([GNULIB_STAT]) GNULIB_STAT=0; AC_SUBST([GNULIB_STAT])
GNULIB_UTIMENSAT=0; AC_SUBST([GNULIB_UTIMENSAT]) GNULIB_UTIMENSAT=0; AC_SUBST([GNULIB_UTIMENSAT])
GNULIB_OVERRIDES_STRUCT_STAT=0; AC_SUBST([GNULIB_OVERRIDES_STRUCT_STAT]) GNULIB_OVERRIDES_STRUCT_STAT=0; AC_SUBST([GNULIB_OVERRIDES_STRUCT_STAT])
dnl Support Microsoft deprecated alias function names by default.
GNULIB_MDA_CHMOD=1; AC_SUBST([GNULIB_MDA_CHMOD])
GNULIB_MDA_MKDIR=1; AC_SUBST([GNULIB_MDA_MKDIR])
GNULIB_MDA_UMASK=1; AC_SUBST([GNULIB_MDA_UMASK])
dnl Assume proper GNU behavior unless another module says otherwise. dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT]) HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT])
HAVE_FSTATAT=1; AC_SUBST([HAVE_FSTATAT]) HAVE_FSTATAT=1; AC_SUBST([HAVE_FSTATAT])

View file

@ -2,7 +2,7 @@
# Copyright (C) 2000-2001, 2003-2007, 2009-2020 Free Software Foundation, Inc. # Copyright (C) 2000-2001, 2003-2007, 2009-2020 Free Software Foundation, Inc.
# serial 12 # serial 13
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -116,6 +116,8 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS],
GNULIB_TIME_R=0; AC_SUBST([GNULIB_TIME_R]) GNULIB_TIME_R=0; AC_SUBST([GNULIB_TIME_R])
GNULIB_TIME_RZ=0; AC_SUBST([GNULIB_TIME_RZ]) GNULIB_TIME_RZ=0; AC_SUBST([GNULIB_TIME_RZ])
GNULIB_TZSET=0; AC_SUBST([GNULIB_TZSET]) GNULIB_TZSET=0; AC_SUBST([GNULIB_TZSET])
dnl Support Microsoft deprecated alias function names by default.
GNULIB_MDA_TZSET=1; AC_SUBST([GNULIB_MDA_TZSET])
dnl Assume proper GNU behavior unless another module says otherwise. dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DECL_LOCALTIME_R=1; AC_SUBST([HAVE_DECL_LOCALTIME_R]) HAVE_DECL_LOCALTIME_R=1; AC_SUBST([HAVE_DECL_LOCALTIME_R])
HAVE_NANOSLEEP=1; AC_SUBST([HAVE_NANOSLEEP]) HAVE_NANOSLEEP=1; AC_SUBST([HAVE_NANOSLEEP])

View file

@ -1,4 +1,4 @@
# unistd_h.m4 serial 83 # unistd_h.m4 serial 84
dnl Copyright (C) 2006-2020 Free Software Foundation, Inc. dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -123,6 +123,28 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT]) GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT])
GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP]) GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP])
GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE])
dnl Support Microsoft deprecated alias function names by default.
GNULIB_MDA_ACCESS=1; AC_SUBST([GNULIB_MDA_ACCESS])
GNULIB_MDA_CHDIR=1; AC_SUBST([GNULIB_MDA_CHDIR])
GNULIB_MDA_CLOSE=1; AC_SUBST([GNULIB_MDA_CLOSE])
GNULIB_MDA_DUP=1; AC_SUBST([GNULIB_MDA_DUP])
GNULIB_MDA_DUP2=1; AC_SUBST([GNULIB_MDA_DUP2])
GNULIB_MDA_EXECL=1; AC_SUBST([GNULIB_MDA_EXECL])
GNULIB_MDA_EXECLE=1; AC_SUBST([GNULIB_MDA_EXECLE])
GNULIB_MDA_EXECLP=1; AC_SUBST([GNULIB_MDA_EXECLP])
GNULIB_MDA_EXECV=1; AC_SUBST([GNULIB_MDA_EXECV])
GNULIB_MDA_EXECVE=1; AC_SUBST([GNULIB_MDA_EXECVE])
GNULIB_MDA_EXECVP=1; AC_SUBST([GNULIB_MDA_EXECVP])
GNULIB_MDA_EXECVPE=1; AC_SUBST([GNULIB_MDA_EXECVPE])
GNULIB_MDA_GETCWD=1; AC_SUBST([GNULIB_MDA_GETCWD])
GNULIB_MDA_GETPID=1; AC_SUBST([GNULIB_MDA_GETPID])
GNULIB_MDA_ISATTY=1; AC_SUBST([GNULIB_MDA_ISATTY])
GNULIB_MDA_LSEEK=1; AC_SUBST([GNULIB_MDA_LSEEK])
GNULIB_MDA_READ=1; AC_SUBST([GNULIB_MDA_READ])
GNULIB_MDA_RMDIR=1; AC_SUBST([GNULIB_MDA_RMDIR])
GNULIB_MDA_SWAB=1; AC_SUBST([GNULIB_MDA_SWAB])
GNULIB_MDA_UNLINK=1; AC_SUBST([GNULIB_MDA_UNLINK])
GNULIB_MDA_WRITE=1; AC_SUBST([GNULIB_MDA_WRITE])
dnl Assume proper GNU behavior unless another module says otherwise. dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN])
HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE]) HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE])

View file

@ -33,6 +33,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "lisp.h" #include "lisp.h"
#include "sysstdio.h" #include "sysstdio.h"
#include <read-file.h>
#ifdef WINDOWSNT #ifdef WINDOWSNT
#include <fcntl.h> #include <fcntl.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -61,6 +63,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
# include <sys/socket.h> # include <sys/socket.h>
#endif #endif
#ifdef HAVE_LINUX_SECCOMP_H
# include <linux/seccomp.h>
# include <linux/filter.h>
# include <sys/prctl.h>
# include <sys/syscall.h>
#endif
#ifdef HAVE_WINDOW_SYSTEM #ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER #include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */ #endif /* HAVE_WINDOW_SYSTEM */
@ -239,6 +248,11 @@ Initialization options:\n\
"\ "\
--dump-file FILE read dumped state from FILE\n\ --dump-file FILE read dumped state from FILE\n\
", ",
#endif
#ifdef HAVE_LINUX_SECCOMP_H
"\
--sandbox=FILE read Seccomp BPF filter from FILE\n\
"
#endif #endif
"\ "\
--no-build-details do not add build details such as time stamps\n\ --no-build-details do not add build details such as time stamps\n\
@ -937,6 +951,100 @@ load_pdump (int argc, char **argv)
} }
#endif /* HAVE_PDUMPER */ #endif /* HAVE_PDUMPER */
#ifdef HAVE_LINUX_SECCOMP_H
/* Wrapper function for the `seccomp' system call on GNU/Linux. This
system call usually doesn't have a wrapper function. See the
manual page of `seccomp' for the signature. */
static int
emacs_seccomp (unsigned int operation, unsigned int flags, void *args)
{
#ifdef SYS_seccomp
return syscall (SYS_seccomp, operation, flags, args);
#else
errno = ENOSYS;
return -1;
#endif
}
/* Attempt to load Secure Computing filters from FILE. Return false
if that doesn't work for some reason. */
static bool
load_seccomp (const char *file)
{
bool success = false;
struct sock_fprog program = {0, NULL};
size_t size;
program.filter
= (struct sock_filter *) read_file (file, RF_BINARY, &size);
if (program.filter == NULL)
{
emacs_perror ("read_file");
goto out;
}
if (size == 0 || size % sizeof *program.filter != 0)
{
fprintf (stderr, "seccomp filter %s has invalid size %zu\n",
file, size);
goto out;
}
size_t count = size / sizeof *program.filter;
eassert (0 < size && 0 < count);
if (USHRT_MAX < count)
{
fprintf (stderr, "seccomp filter %s is too big\n", file);
goto out;
}
program.len = count;
/* See man page of `seccomp' why this is necessary. Note that we
intentionally don't check the return value: a parent process
might have made this call before, in which case it would fail;
or, if enabling privilege-restricting mode fails, the `seccomp'
syscall will fail anyway. */
prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
/* Install the filter. Make sure that potential other threads can't
escape it. */
if (emacs_seccomp (SECCOMP_SET_MODE_FILTER,
SECCOMP_FILTER_FLAG_TSYNC, &program)
!= 0)
{
emacs_perror ("seccomp");
goto out;
}
success = true;
out:
free (program.filter);
return success;
}
/* Load Secure Computing filter from file specified with the --seccomp
option. Exit if that fails. */
static void
maybe_load_seccomp (int argc, char **argv)
{
int skip_args = 0;
char *file = NULL;
while (skip_args < argc - 1)
{
if (argmatch (argv, argc, "-seccomp", "--seccomp", 9, &file,
&skip_args)
|| argmatch (argv, argc, "--", NULL, 2, NULL, &skip_args))
break;
++skip_args;
}
if (file == NULL)
return;
if (!load_seccomp (file))
fatal ("cannot enable seccomp filter from %s", file);
}
#endif /* HAVE_LINUX_SECCOMP_H */
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -944,6 +1052,13 @@ main (int argc, char **argv)
for pointers. */ for pointers. */
void *stack_bottom_variable; void *stack_bottom_variable;
/* First, check whether we should apply a seccomp filter. This
should come at the very beginning to allow the filter to protect
the initialization phase. */
#ifdef HAVE_LINUX_SECCOMP_H
maybe_load_seccomp (argc, argv);
#endif
bool no_loadup = false; bool no_loadup = false;
char *junk = 0; char *junk = 0;
char *dname_arg = 0; char *dname_arg = 0;
@ -2137,12 +2252,15 @@ static const struct standard_args standard_args[] =
{ "-color", "--color", 5, 0}, { "-color", "--color", 5, 0},
{ "-no-splash", "--no-splash", 3, 0 }, { "-no-splash", "--no-splash", 3, 0 },
{ "-no-desktop", "--no-desktop", 3, 0 }, { "-no-desktop", "--no-desktop", 3, 0 },
/* The following two must be just above the file-name args, to get /* The following three must be just above the file-name args, to get
them out of our way, but without mixing them with file names. */ them out of our way, but without mixing them with file names. */
{ "-temacs", "--temacs", 1, 1 }, { "-temacs", "--temacs", 1, 1 },
#ifdef HAVE_PDUMPER #ifdef HAVE_PDUMPER
{ "-dump-file", "--dump-file", 1, 1 }, { "-dump-file", "--dump-file", 1, 1 },
#endif #endif
#ifdef HAVE_LINUX_SECCOMP_H
{ "-seccomp", "--seccomp", 1, 1 },
#endif
#ifdef HAVE_NS #ifdef HAVE_NS
{ "-NSAutoLaunch", 0, 5, 1 }, { "-NSAutoLaunch", 0, 5, 1 },
{ "-NXAutoLaunch", 0, 5, 1 }, { "-NXAutoLaunch", 0, 5, 1 },

View file

@ -272,6 +272,8 @@ $(test_module): $(test_module:${SO}=.c) ../src/emacs-module.h
$(srcdir)/../lib/timespec.c $(srcdir)/../lib/gettime.c $(srcdir)/../lib/timespec.c $(srcdir)/../lib/gettime.c
endif endif
src/emacs-tests.log: ../lib-src/seccomp-filter.c
## Check that there is no 'automated' subdirectory, which would ## Check that there is no 'automated' subdirectory, which would
## indicate an incomplete merge from an older version of Emacs where ## indicate an incomplete merge from an older version of Emacs where
## the tests were arranged differently. ## the tests were arranged differently.

View file

@ -0,0 +1 @@
../../../lib-src/seccomp-filter.bpf

176
test/src/emacs-tests.el Normal file
View file

@ -0,0 +1,176 @@
;;; emacs-tests.el --- unit tests for emacs.c -*- lexical-binding: t; -*-
;; Copyright (C) 2020 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs 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.
;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Unit tests for src/emacs.c.
;;; Code:
(require 'cl-lib)
(require 'ert)
(require 'ert-x)
(require 'rx)
(require 'subr-x)
(ert-deftest emacs-tests/seccomp/absent-file ()
(skip-unless (string-match-p (rx bow "SECCOMP" eow)
system-configuration-features))
(let ((emacs
(expand-file-name invocation-name invocation-directory))
(process-environment nil))
(skip-unless (file-executable-p emacs))
(should-not (file-exists-p "/does-not-exist.bpf"))
(should-not
(eql (call-process emacs nil nil nil
"--quick" "--batch"
"--seccomp=/does-not-exist.bpf")
0))))
(cl-defmacro emacs-tests--with-temp-file
(var (prefix &optional suffix text) &rest body)
"Evaluate BODY while a new temporary file exists.
Bind VAR to the name of the file. Pass PREFIX, SUFFIX, and TEXT
to `make-temp-file', which see."
(declare (indent 2) (debug (symbolp (form form form) body)))
(cl-check-type var symbol)
;; Use an uninterned symbol so that the code still works if BODY
;; changes VAR.
(let ((filename (make-symbol "filename")))
`(let ((,filename (make-temp-file ,prefix nil ,suffix ,text)))
(unwind-protect
(let ((,var ,filename))
,@body)
(delete-file ,filename)))))
(ert-deftest emacs-tests/seccomp/empty-file ()
(skip-unless (string-match-p (rx bow "SECCOMP" eow)
system-configuration-features))
(let ((emacs
(expand-file-name invocation-name invocation-directory))
(process-environment nil))
(skip-unless (file-executable-p emacs))
(emacs-tests--with-temp-file filter ("seccomp-invalid-" ".bpf")
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't
;; work.
(should-not (file-remote-p filter))
(cl-callf file-name-unquote filter)
;; According to the Seccomp man page, a filter must have at
;; least one element, so Emacs should reject an empty file.
(should-not
(eql (call-process emacs nil nil nil
"--quick" "--batch"
(concat "--seccomp=" filter))
0)))))
(ert-deftest emacs-tests/seccomp/file-too-large ()
(skip-unless (string-match-p (rx bow "SECCOMP" eow)
system-configuration-features))
(let ((emacs
(expand-file-name invocation-name invocation-directory))
(process-environment nil)
;; This value should be correct on all supported systems.
(ushort-max #xFFFF)
;; Either 8 or 16, but 16 should be large enough in all cases.
(filter-size 16))
(skip-unless (file-executable-p emacs))
(emacs-tests--with-temp-file
filter ("seccomp-too-large-" ".bpf"
(make-string (* (1+ ushort-max) filter-size) ?a))
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't
;; work.
(should-not (file-remote-p filter))
(cl-callf file-name-unquote filter)
;; The filter count must fit into an `unsigned short'. A bigger
;; file should be rejected.
(should-not
(eql (call-process emacs nil nil nil
"--quick" "--batch"
(concat "--seccomp=" filter))
0)))))
(ert-deftest emacs-tests/seccomp/invalid-file-size ()
(skip-unless (string-match-p (rx bow "SECCOMP" eow)
system-configuration-features))
(let ((emacs
(expand-file-name invocation-name invocation-directory))
(process-environment nil))
(skip-unless (file-executable-p emacs))
(emacs-tests--with-temp-file filter ("seccomp-invalid-" ".bpf"
"123456")
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't
;; work.
(should-not (file-remote-p filter))
(cl-callf file-name-unquote filter)
;; The Seccomp filter file must have a file size that's a
;; multiple of the size of struct sock_filter, which is 8 or 16,
;; but never 6.
(should-not
(eql (call-process emacs nil nil nil
"--quick" "--batch"
(concat "--seccomp=" filter))
0)))))
(ert-deftest emacs-tests/seccomp/allows-stdout ()
(let ((emacs
(expand-file-name invocation-name invocation-directory))
(filter (ert-resource-file "seccomp-filter.bpf"))
(process-environment nil))
(skip-unless (file-executable-p emacs))
(skip-unless (file-readable-p filter))
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't work.
(should-not (file-remote-p filter))
(cl-callf file-name-unquote filter)
(with-temp-buffer
(let ((status (call-process
emacs nil t nil
"--quick" "--batch"
(concat "--seccomp=" filter)
(format "--eval=%S" '(message "Hi")))))
(ert-info ((format "Process output: %s" (buffer-string)))
(should (eql status 0)))
(should (equal (string-trim (buffer-string)) "Hi"))))))
(ert-deftest emacs-tests/seccomp/forbids-subprocess ()
(let ((emacs
(expand-file-name invocation-name invocation-directory))
(filter (ert-resource-file "seccomp-filter.bpf"))
(process-environment nil))
(skip-unless (file-executable-p emacs))
(skip-unless (file-readable-p filter))
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't work.
(should-not (file-remote-p filter))
(cl-callf file-name-unquote filter)
(with-temp-buffer
(let ((status
(call-process
emacs nil t nil
"--quick" "--batch"
(concat "--seccomp=" filter)
(format "--eval=%S" `(call-process ,emacs nil nil nil
"--version")))))
(ert-info ((format "Process output: %s" (buffer-string)))
(should-not (eql status 0)))))))
;;; emacs-tests.el ends here