diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0e16e2455..0980aa17c 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -21,7 +21,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=tools --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files argmatch argp error isatty mkstemp mkstemps progname stpcpy strverscmp sys_wait
+# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=tools --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files argmatch argp closeout closestdout error isatty mkstemp mkstemps progname secure_getenv stpcpy strverscmp sys_wait
AUTOMAKE_OPTIONS = 1.9.6 gnits
@@ -128,6 +128,22 @@ EXTRA_DIST += c-strcaseeq.h
## end gnulib module c-strcaseeq
+## begin gnulib module close-stream
+
+libgnu_la_SOURCES += close-stream.c
+
+EXTRA_DIST += close-stream.h
+
+## end gnulib module close-stream
+
+## begin gnulib module closeout
+
+libgnu_la_SOURCES += closeout.c
+
+EXTRA_DIST += closeout.h
+
+## end gnulib module closeout
+
## begin gnulib module configmake
# Listed in the same order as the GNU makefile conventions, and
@@ -312,6 +328,15 @@ EXTRA_libgnu_la_SOURCES += float.c itold.c
## end gnulib module float
+## begin gnulib module fpending
+
+
+EXTRA_DIST += fpending.c fpending.h stdio-impl.h
+
+EXTRA_libgnu_la_SOURCES += fpending.c
+
+## end gnulib module fpending
+
## begin gnulib module getopt-posix
BUILT_SOURCES += $(GETOPT_H) $(GETOPT_CDEFS_H)
@@ -654,6 +679,15 @@ EXTRA_libgnu_la_SOURCES += rawmemchr.c
## end gnulib module rawmemchr
+## begin gnulib module secure_getenv
+
+
+EXTRA_DIST += secure_getenv.c
+
+EXTRA_libgnu_la_SOURCES += secure_getenv.c
+
+## end gnulib module secure_getenv
+
## begin gnulib module size_max
libgnu_la_SOURCES += size_max.h
diff --git a/lib/close-stream.c b/lib/close-stream.c
new file mode 100644
index 000000000..3d5a52ebd
--- /dev/null
+++ b/lib/close-stream.c
@@ -0,0 +1,78 @@
+/* Close a stream, with nicer error checking than fclose's.
+
+ Copyright (C) 1998-2002, 2004, 2006-2018 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+
+#include "close-stream.h"
+
+#include
+#include
+
+#include "fpending.h"
+
+#if USE_UNLOCKED_IO
+# include "unlocked-io.h"
+#endif
+
+/* Close STREAM. Return 0 if successful, EOF (setting errno)
+ otherwise. A failure might set errno to 0 if the error number
+ cannot be determined.
+
+ A failure with errno set to EPIPE may or may not indicate an error
+ situation worth signaling to the user. See the documentation of the
+ close_stdout_set_ignore_EPIPE function for details.
+
+ If a program writes *anything* to STREAM, that program should close
+ STREAM and make sure that it succeeds before exiting. Otherwise,
+ suppose that you go to the extreme of checking the return status
+ of every function that does an explicit write to STREAM. The last
+ printf can succeed in writing to the internal stream buffer, and yet
+ the fclose(STREAM) could still fail (due e.g., to a disk full error)
+ when it tries to write out that buffered data. Thus, you would be
+ left with an incomplete output file and the offending program would
+ exit successfully. Even calling fflush is not always sufficient,
+ since some file systems (NFS and CODA) buffer written/flushed data
+ until an actual close call.
+
+ Besides, it's wasteful to check the return value from every call
+ that writes to STREAM -- just let the internal stream state record
+ the failure. That's what the ferror test is checking below. */
+
+int
+close_stream (FILE *stream)
+{
+ const bool some_pending = (__fpending (stream) != 0);
+ const bool prev_fail = (ferror (stream) != 0);
+ const bool fclose_fail = (fclose (stream) != 0);
+
+ /* Return an error indication if there was a previous failure or if
+ fclose failed, with one exception: ignore an fclose failure if
+ there was no previous error, no data remains to be flushed, and
+ fclose failed with EBADF. That can happen when a program like cp
+ is invoked like this 'cp a b >&-' (i.e., with standard output
+ closed) and doesn't generate any output (hence no previous error
+ and nothing to be flushed). */
+
+ if (prev_fail || (fclose_fail && (some_pending || errno != EBADF)))
+ {
+ if (! fclose_fail)
+ errno = 0;
+ return EOF;
+ }
+
+ return 0;
+}
diff --git a/lib/close-stream.h b/lib/close-stream.h
new file mode 100644
index 000000000..be3d4196b
--- /dev/null
+++ b/lib/close-stream.h
@@ -0,0 +1,2 @@
+#include
+int close_stream (FILE *stream);
diff --git a/lib/closeout.c b/lib/closeout.c
new file mode 100644
index 000000000..0672732b6
--- /dev/null
+++ b/lib/closeout.c
@@ -0,0 +1,136 @@
+/* Close standard output and standard error, exiting with a diagnostic on error.
+
+ Copyright (C) 1998-2002, 2004, 2006, 2008-2018 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+
+#include "closeout.h"
+
+#include
+#include
+#include
+#include
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+#include "close-stream.h"
+#include "error.h"
+#include "exitfail.h"
+#include "quotearg.h"
+
+#ifndef __has_feature
+# define __has_feature(a) false
+#endif
+
+#if defined __SANITIZE_ADDRESS__ || __has_feature (address_sanitizer)
+enum { SANITIZE_ADDRESS = true };
+#else
+enum { SANITIZE_ADDRESS = false };
+#endif
+
+static const char *file_name;
+
+/* Set the file name to be reported in the event an error is detected
+ by close_stdout. */
+void
+close_stdout_set_file_name (const char *file)
+{
+ file_name = file;
+}
+
+static bool ignore_EPIPE /* = false */;
+
+/* Specify the reaction to an EPIPE error during the closing of stdout:
+ - If ignore = true, it shall be ignored.
+ - If ignore = false, it shall evoke a diagnostic, along with a nonzero
+ exit status.
+ The default is ignore = false.
+
+ This setting matters only if the SIGPIPE signal is ignored (i.e. its
+ handler set to SIG_IGN) or blocked. Only particular programs need to
+ temporarily ignore SIGPIPE. If SIGPIPE is ignored or blocked because
+ it was ignored or blocked in the parent process when it created the
+ child process, it usually is a bug in the parent process: It is bad
+ practice to have SIGPIPE ignored or blocked while creating a child
+ process.
+
+ EPIPE occurs when writing to a pipe or socket that has no readers now,
+ when SIGPIPE is ignored or blocked.
+
+ The ignore = false setting is suitable for a scenario where it is normally
+ guaranteed that the pipe writer terminates before the pipe reader. In
+ this case, an EPIPE is an indication of a premature termination of the
+ pipe reader and should lead to a diagnostic and a nonzero exit status.
+
+ The ignore = true setting is suitable for a scenario where you don't know
+ ahead of time whether the pipe writer or the pipe reader will terminate
+ first. In this case, an EPIPE is an indication that the pipe writer can
+ stop doing useless write() calls; this is what close_stdout does anyway.
+ EPIPE is part of the normal pipe/socket shutdown protocol in this case,
+ and should not lead to a diagnostic message. */
+
+void
+close_stdout_set_ignore_EPIPE (bool ignore)
+{
+ ignore_EPIPE = ignore;
+}
+
+/* Close standard output. On error, issue a diagnostic and _exit
+ with status 'exit_failure'.
+
+ Also close standard error. On error, _exit with status 'exit_failure'.
+
+ Since close_stdout is commonly registered via 'atexit', POSIX
+ and the C standard both say that it should not call 'exit',
+ because the behavior is undefined if 'exit' is called more than
+ once. So it calls '_exit' instead of 'exit'. If close_stdout
+ is registered via atexit before other functions are registered,
+ the other functions can act before this _exit is invoked.
+
+ Applications that use close_stdout should flush any streams
+ other than stdout and stderr before exiting, since the call to
+ _exit will bypass other buffer flushing. Applications should
+ be flushing and closing other streams anyway, to check for I/O
+ errors. Also, applications should not use tmpfile, since _exit
+ can bypass the removal of these files.
+
+ It's important to detect such failures and exit nonzero because many
+ tools (most notably 'make' and other build-management systems) depend
+ on being able to detect failure in other tools via their exit status. */
+
+void
+close_stdout (void)
+{
+ if (close_stream (stdout) != 0
+ && !(ignore_EPIPE && errno == EPIPE))
+ {
+ char const *write_error = _("write error");
+ if (file_name)
+ error (0, errno, "%s: %s", quotearg_colon (file_name),
+ write_error);
+ else
+ error (0, errno, "%s", write_error);
+
+ _exit (exit_failure);
+ }
+
+ /* Close stderr only if not sanitizing, as sanitizers may report to
+ stderr after this function returns. */
+ if (!SANITIZE_ADDRESS && close_stream (stderr) != 0)
+ _exit (exit_failure);
+}
diff --git a/lib/closeout.h b/lib/closeout.h
new file mode 100644
index 000000000..6629d4993
--- /dev/null
+++ b/lib/closeout.h
@@ -0,0 +1,36 @@
+/* Close standard output and standard error.
+
+ Copyright (C) 1998, 2000, 2003-2004, 2006, 2008-2018 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 . */
+
+#ifndef CLOSEOUT_H
+# define CLOSEOUT_H 1
+
+# include
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+void close_stdout_set_file_name (const char *file);
+void close_stdout_set_ignore_EPIPE (bool ignore);
+void close_stdout (void);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
diff --git a/lib/fpending.c b/lib/fpending.c
new file mode 100644
index 000000000..de370d4b1
--- /dev/null
+++ b/lib/fpending.c
@@ -0,0 +1,62 @@
+/* fpending.c -- return the number of pending output bytes on a stream
+ Copyright (C) 2000, 2004, 2006-2007, 2009-2018 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* Written by Jim Meyering. */
+
+#include
+
+/* Specification. */
+#include "fpending.h"
+
+#include "stdio-impl.h"
+
+/* This file is not used on systems that already have the __fpending function,
+ namely glibc >= 2.2, Solaris >= 7, Android API >= 23. */
+
+/* Return the number of pending (aka buffered, unflushed)
+ bytes on the stream, FP, that is open for writing. */
+size_t
+__fpending (FILE *fp)
+{
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ , because they need it for implementing getc() and putc() as
+ fast macros. */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+ /* GNU libc, BeOS, Haiku, Linux libc5 */
+ return fp->_IO_write_ptr - fp->_IO_write_base;
+#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
+ return fp->_p - fp->_bf._base;
+#elif defined __EMX__ /* emx+gcc */
+ return fp->_ptr - fp->_buffer;
+#elif defined __minix /* Minix */
+ return fp_->_ptr - fp_->_buf;
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel, OpenVMS */
+ return (fp_->_ptr ? fp_->_ptr - fp_->_base : 0);
+#elif defined __UCLIBC__ /* uClibc */
+ return (fp->__modeflags & __FLAG_WRITING ? fp->__bufpos - fp->__bufstart : 0);
+#elif defined __QNX__ /* QNX */
+ return (fp->_Mode & 0x2000 /*_MWRITE*/ ? fp->_Next - fp->_Buf : 0);
+#elif defined __MINT__ /* Atari FreeMiNT */
+ return fp->__bufp - fp->__buffer;
+#elif defined EPLAN9 /* Plan9 */
+ return fp->wp - fp->buf;
+#else
+# error "Please port gnulib fpending.c to your platform!"
+ return 1;
+#endif
+}
diff --git a/lib/fpending.h b/lib/fpending.h
new file mode 100644
index 000000000..2ff26bc6a
--- /dev/null
+++ b/lib/fpending.h
@@ -0,0 +1,29 @@
+/* Declare __fpending.
+
+ Copyright (C) 2000, 2003, 2005-2006, 2009-2018 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ Written by Jim Meyering. */
+
+#include
+#include
+#if HAVE_STDIO_EXT_H
+# include
+#endif
+
+#if !HAVE_DECL___FPENDING
+size_t __fpending (FILE *) _GL_ATTRIBUTE_PURE;
+#endif
diff --git a/lib/secure_getenv.c b/lib/secure_getenv.c
new file mode 100644
index 000000000..ebe98dbfd
--- /dev/null
+++ b/lib/secure_getenv.c
@@ -0,0 +1,54 @@
+/* Look up an environment variable, returning NULL in insecure situations.
+
+ Copyright 2013-2018 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+
+#include
+
+#if !HAVE___SECURE_GETENV
+# if HAVE_ISSETUGID || (HAVE_GETUID && HAVE_GETEUID && HAVE_GETGID && HAVE_GETEGID)
+# include
+# endif
+#endif
+
+char *
+secure_getenv (char const *name)
+{
+#if HAVE___SECURE_GETENV /* glibc */
+ return __secure_getenv (name);
+#elif HAVE_ISSETUGID /* OS X, FreeBSD, NetBSD, OpenBSD */
+ if (issetugid ())
+ return NULL;
+ return getenv (name);
+#elif HAVE_GETUID && HAVE_GETEUID && HAVE_GETGID && HAVE_GETEGID /* other Unix */
+ if (geteuid () != getuid () || getegid () != getgid ())
+ return NULL;
+ return getenv (name);
+#elif defined _WIN32 && ! defined __CYGWIN__ /* native Windows */
+ /* On native Windows, there is no such concept as setuid or setgid binaries.
+ - Programs launched as system services have high privileges, but they don't
+ inherit environment variables from a user.
+ - Programs launched by a user with "Run as Administrator" have high
+ privileges and use the environment variables, but the user has been asked
+ whether he agrees.
+ - Programs launched by a user without "Run as Administrator" cannot gain
+ high privileges, therefore there is no risk. */
+ return getenv (name);
+#else
+ return NULL;
+#endif
+}
diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h
new file mode 100644
index 000000000..393ef0cf5
--- /dev/null
+++ b/lib/stdio-impl.h
@@ -0,0 +1,202 @@
+/* Implementation details of FILE streams.
+ Copyright (C) 2007-2008, 2010-2018 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 . */
+
+/* Many stdio implementations have the same logic and therefore can share
+ the same implementation of stdio extension API, except that some fields
+ have different naming conventions, or their access requires some casts. */
+
+/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this
+ problem by defining it ourselves. FIXME: Do not rely on glibc
+ internals. */
+#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
+# define _IO_IN_BACKUP 0x100
+#endif
+
+/* BSD stdio derived implementations. */
+
+#if defined __NetBSD__ /* NetBSD */
+/* Get __NetBSD_Version__. */
+# include
+#endif
+
+#include /* For detecting Plan9. */
+
+#if defined __sferror || defined __DragonFly__ || defined __ANDROID__
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
+
+# if defined __DragonFly__ /* DragonFly */
+ /* See . */
+# define fp_ ((struct { struct __FILE_public pub; \
+ struct { unsigned char *_base; int _size; } _bf; \
+ void *cookie; \
+ void *_close; \
+ void *_read; \
+ void *_seek; \
+ void *_write; \
+ struct { unsigned char *_base; int _size; } _ub; \
+ int _ur; \
+ unsigned char _ubuf[3]; \
+ unsigned char _nbuf[1]; \
+ struct { unsigned char *_base; int _size; } _lb; \
+ int _blksize; \
+ fpos_t _offset; \
+ /* More fields, not relevant here. */ \
+ } *) fp)
+ /* See . */
+# define _p pub._p
+# define _flags pub._flags
+# define _r pub._r
+# define _w pub._w
+# elif defined __ANDROID__ /* Android */
+ /* Up to this commit from 2015-10-12
+
+ the innards of FILE were public, and fp_ub could be defined like for OpenBSD,
+ see
+ and .
+ After this commit, the innards of FILE are hidden. */
+# define fp_ ((struct { unsigned char *_p; \
+ int _r; \
+ int _w; \
+ int _flags; \
+ int _file; \
+ struct { unsigned char *_base; size_t _size; } _bf; \
+ int _lbfsize; \
+ void *_cookie; \
+ void *_close; \
+ void *_read; \
+ void *_seek; \
+ void *_write; \
+ struct { unsigned char *_base; size_t _size; } _ext; \
+ unsigned char *_up; \
+ int _ur; \
+ unsigned char _ubuf[3]; \
+ unsigned char _nbuf[1]; \
+ struct { unsigned char *_base; size_t _size; } _lb; \
+ int _blksize; \
+ fpos_t _offset; \
+ /* More fields, not relevant here. */ \
+ } *) fp)
+# else
+# define fp_ fp
+# endif
+
+# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __minix /* NetBSD >= 1.5ZA, OpenBSD, Minix 3 */
+ /* See
+ and
+ and */
+ struct __sfileext
+ {
+ struct __sbuf _ub; /* ungetc buffer */
+ /* More fields, not relevant here. */
+ };
+# define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub
+# elif defined __ANDROID__ /* Android */
+ struct __sfileext
+ {
+ struct { unsigned char *_base; size_t _size; } _ub; /* ungetc buffer */
+ /* More fields, not relevant here. */
+ };
+# define fp_ub ((struct __sfileext *) fp_->_ext._base)->_ub
+# else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, Mac OS X, Cygwin */
+# define fp_ub fp_->_ub
+# endif
+
+# define HASUB(fp) (fp_ub._base != NULL)
+
+# if defined __ANDROID__ /* Android */
+ /* Needed after this commit from 2016-01-25
+ */
+# ifndef __SEOF
+# define __SLBF 1
+# define __SNBF 2
+# define __SRD 4
+# define __SWR 8
+# define __SRW 0x10
+# define __SEOF 0x20
+# define __SERR 0x40
+# endif
+# ifndef __SOFF
+# define __SOFF 0x1000
+# endif
+# endif
+
+#endif
+
+
+/* SystemV derived implementations. */
+
+#ifdef __TANDEM /* NonStop Kernel */
+# ifndef _IOERR
+/* These values were determined by the program 'stdioext-flags' at
+ . */
+# define _IOERR 0x40
+# define _IOREAD 0x80
+# define _IOWRT 0x4
+# define _IORW 0x100
+# endif
+#endif
+
+#if defined _IOERR
+
+# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
+# define fp_ ((struct { unsigned char *_ptr; \
+ unsigned char *_base; \
+ unsigned char *_end; \
+ long _cnt; \
+ int _file; \
+ unsigned int _flag; \
+ } *) fp)
+# elif defined __VMS /* OpenVMS */
+# define fp_ ((struct _iobuf *) fp)
+# else
+# define fp_ fp
+# endif
+
+# if defined _SCO_DS /* OpenServer */
+# define _cnt __cnt
+# define _ptr __ptr
+# define _base __base
+# define _flag __flag
+# endif
+
+#elif defined _WIN32 && ! defined __CYGWIN__ /* newer Windows with MSVC */
+
+/* does not define the innards of FILE any more. */
+# define WINDOWS_OPAQUE_FILE
+
+struct _gl_real_FILE
+{
+ /* Note: Compared to older Windows and to mingw, it has the fields
+ _base and _cnt swapped. */
+ unsigned char *_ptr;
+ unsigned char *_base;
+ int _cnt;
+ int _flag;
+ int _file;
+ int _charbuf;
+ int _bufsiz;
+};
+# define fp_ ((struct _gl_real_FILE *) fp)
+
+/* These values were determined by a program similar to the one at
+ . */
+# define _IOREAD 0x1
+# define _IOWRT 0x2
+# define _IORW 0x4
+# define _IOEOF 0x8
+# define _IOERR 0x10
+
+#endif
diff --git a/m4/close-stream.m4 b/m4/close-stream.m4
new file mode 100644
index 000000000..c9bf62e95
--- /dev/null
+++ b/m4/close-stream.m4
@@ -0,0 +1,11 @@
+#serial 4
+dnl Copyright (C) 2006-2007, 2009-2018 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.
+
+dnl Prerequisites of lib/close-stream.c.
+AC_DEFUN([gl_CLOSE_STREAM],
+[
+ :
+])
diff --git a/m4/closeout.m4 b/m4/closeout.m4
new file mode 100644
index 000000000..6442406ca
--- /dev/null
+++ b/m4/closeout.m4
@@ -0,0 +1,12 @@
+# closeout.m4 serial 6
+dnl Copyright (C) 2002-2003, 2005-2006, 2009-2018 Free Software Foundation,
+dnl 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.
+
+dnl Prerequisites of lib/closeout.c.
+AC_DEFUN([gl_CLOSEOUT],
+[
+ :
+])
diff --git a/m4/fpending.m4 b/m4/fpending.m4
new file mode 100644
index 000000000..c897073de
--- /dev/null
+++ b/m4/fpending.m4
@@ -0,0 +1,36 @@
+# serial 22
+
+# Copyright (C) 2000-2001, 2004-2018 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+dnl From Jim Meyering
+dnl Using code from emacs, based on suggestions from Paul Eggert
+dnl and Ulrich Drepper.
+
+dnl Find out how to determine the number of pending output bytes on a stream.
+dnl glibc (2.1.93 and newer) and Solaris provide __fpending. On other systems,
+dnl we have to grub around in the (possibly opaque) FILE struct.
+
+AC_DEFUN([gl_FUNC_FPENDING],
+[
+ AC_CHECK_HEADERS_ONCE([stdio_ext.h])
+ fp_headers='
+ #include
+ #if HAVE_STDIO_EXT_H
+ # include
+ #endif
+ '
+ AC_CACHE_CHECK([for __fpending], [gl_cv_func___fpending],
+ [
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([$fp_headers],
+ [[return ! __fpending (stdin);]])],
+ [gl_cv_func___fpending=yes],
+ [gl_cv_func___fpending=no])
+ ])
+ if test $gl_cv_func___fpending = yes; then
+ AC_CHECK_DECLS([__fpending], [], [], [$fp_headers])
+ fi
+])
diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4
index 1193f6d99..3671db505 100644
--- a/m4/gnulib-cache.m4
+++ b/m4/gnulib-cache.m4
@@ -27,18 +27,20 @@
# Specification in the form of a command-line invocation:
-# gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=tools --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files argmatch argp error isatty mkstemp mkstemps progname stpcpy strverscmp sys_wait
+# gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=tools --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files argmatch argp closeout error isatty mkstemp mkstemps progname secure_getenv stpcpy strverscmp sys_wait
# Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([])
gl_MODULES([
argmatch
argp
+ closeout
error
isatty
mkstemp
mkstemps
progname
+ secure_getenv
stpcpy
strverscmp
sys_wait
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 35e964e33..2a8efa8be 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -50,6 +50,8 @@ AC_DEFUN([gl_EARLY],
# Code from module c-ctype:
# Code from module c-strcase:
# Code from module c-strcaseeq:
+ # Code from module close-stream:
+ # Code from module closeout:
# Code from module configmake:
# Code from module dirname-lgpl:
# Code from module dosname:
@@ -62,6 +64,7 @@ AC_DEFUN([gl_EARLY],
# Code from module fcntl-h:
# Code from module filename:
# Code from module float:
+ # Code from module fpending:
# Code from module getopt-gnu:
# Code from module getopt-posix:
# Code from module getprogname:
@@ -97,6 +100,7 @@ AC_DEFUN([gl_EARLY],
# Code from module quotearg:
# Code from module quotearg-simple:
# Code from module rawmemchr:
+ # Code from module secure_getenv:
# Code from module size_max:
# Code from module sleep:
# Code from module snippet/_Noreturn:
@@ -165,6 +169,9 @@ AC_SUBST([LTALLOCA])
m4_ifdef([AM_XGETTEXT_OPTION],
[AM_][XGETTEXT_OPTION([--flag=argp_error:2:c-format])
AM_][XGETTEXT_OPTION([--flag=argp_failure:4:c-format])])
+ gl_CLOSE_STREAM
+ gl_MODULE_INDICATOR([close-stream])
+ gl_CLOSEOUT
gl_CONFIGMAKE_PREP
gl_DIRNAME_LGPL
gl_DOUBLE_SLASH_ROOT
@@ -186,6 +193,10 @@ AC_SUBST([LTALLOCA])
if test $REPLACE_ITOLD = 1; then
AC_LIBOBJ([itold])
fi
+ gl_FUNC_FPENDING
+ if test $gl_cv_func___fpending = no; then
+ AC_LIBOBJ([fpending])
+ fi
gl_FUNC_GETOPT_GNU
dnl Because of the way gl_FUNC_GETOPT_GNU is implemented (the gl_getopt_required
dnl mechanism), there is no need to do any AC_LIBOBJ or AC_SUBST here; they are
@@ -296,6 +307,12 @@ AC_SUBST([LTALLOCA])
gl_PREREQ_RAWMEMCHR
fi
gl_STRING_MODULE_INDICATOR([rawmemchr])
+ gl_FUNC_SECURE_GETENV
+ if test $HAVE_SECURE_GETENV = 0; then
+ AC_LIBOBJ([secure_getenv])
+ gl_PREREQ_SECURE_GETENV
+ fi
+ gl_STDLIB_MODULE_INDICATOR([secure_getenv])
gl_SIZE_MAX
gl_FUNC_SLEEP
if test $HAVE_SLEEP = 0 || test $REPLACE_SLEEP = 1; then
@@ -557,6 +574,10 @@ AC_DEFUN([gl_FILE_LIST], [
lib/c-strcasecmp.c
lib/c-strcaseeq.h
lib/c-strncasecmp.c
+ lib/close-stream.c
+ lib/close-stream.h
+ lib/closeout.c
+ lib/closeout.h
lib/config.charset
lib/dirname-lgpl.c
lib/dirname.h
@@ -571,6 +592,8 @@ AC_DEFUN([gl_FILE_LIST], [
lib/float+.h
lib/float.c
lib/float.in.h
+ lib/fpending.c
+ lib/fpending.h
lib/getopt-cdefs.in.h
lib/getopt-core.h
lib/getopt-ext.h
@@ -624,6 +647,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/rawmemchr.valgrind
lib/ref-add.sin
lib/ref-del.sin
+ lib/secure_getenv.c
lib/size_max.h
lib/sleep.c
lib/stat-time.c
@@ -635,6 +659,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/stdbool.in.h
lib/stddef.in.h
lib/stdint.in.h
+ lib/stdio-impl.h
lib/stdio.in.h
lib/stdlib.in.h
lib/stpcpy.c
@@ -680,6 +705,8 @@ AC_DEFUN([gl_FILE_LIST], [
m4/absolute-header.m4
m4/alloca.m4
m4/argp.m4
+ m4/close-stream.m4
+ m4/closeout.m4
m4/codeset.m4
m4/configmake.m4
m4/dirname.m4
@@ -693,6 +720,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/fcntl-o.m4
m4/fcntl_h.m4
m4/float_h.m4
+ m4/fpending.m4
m4/getopt.m4
m4/getprogname.m4
m4/gettimeofday.m4
@@ -734,6 +762,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/quote.m4
m4/quotearg.m4
m4/rawmemchr.m4
+ m4/secure_getenv.m4
m4/size_max.m4
m4/sleep.m4
m4/ssize_t.m4
diff --git a/m4/secure_getenv.m4 b/m4/secure_getenv.m4
new file mode 100644
index 000000000..ad78eb180
--- /dev/null
+++ b/m4/secure_getenv.m4
@@ -0,0 +1,26 @@
+# Look up an environment variable more securely.
+dnl Copyright 2013-2018 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_SECURE_GETENV],
+[
+ dnl Persuade glibc to declare secure_getenv().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_CHECK_FUNCS_ONCE([secure_getenv])
+ if test $ac_cv_func_secure_getenv = no; then
+ HAVE_SECURE_GETENV=0
+ fi
+])
+
+# Prerequisites of lib/secure_getenv.c.
+AC_DEFUN([gl_PREREQ_SECURE_GETENV], [
+ AC_CHECK_FUNCS([__secure_getenv])
+ if test $ac_cv_func___secure_getenv = no; then
+ AC_CHECK_FUNCS([issetugid])
+ fi
+ AC_CHECK_FUNCS_ONCE([getuid geteuid getgid getegid])
+])