summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/m4sugar/m4sh.m478
-rw-r--r--tests/base.at73
-rw-r--r--tests/torture.at27
3 files changed, 152 insertions, 26 deletions
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index c9e86246..bd4d2b9e 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -300,6 +300,28 @@ dnl We shouldn't have to worry about any traps being active at this point.
exit 255])# _AS_REEXEC_WITH_SHELL
+# _AS_ENSURE_STANDARD_FDS
+# -----------------------
+# Ensure that file descriptors 0, 1, and 2 are open, as a defensive
+# measure against weird environments that run configure scripts
+# with these descriptors closed.
+# `exec m>&n` fails in POSIX sh when fd N is closed, but succeeds
+# regardless of whether fd N is open in some old shells, e.g. Solaris
+# /bin/sh. This is OK because those shells will be rejected by
+# _AS_DETECT_BETTER_SHELL anyway.
+# TODO post-2.70: use "backward" redirections when opening these fds,
+# so we preserve their unusable state. Needs downstream logic to
+# stop on the first failed attempt to write to fd 1 or 2, so we don't
+# run through an entire configure script spewing "write error"
+# messages when fd 1 is closed.
+m4_defun([_AS_ENSURE_STANDARD_FDS], [dnl
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
+])
+
+
# _AS_PREPARE
# -----------
# This macro has a very special status. Normal use of M4sh relies
@@ -456,18 +478,42 @@ m4_defun([_AS_SHELL_SANITIZE],
[m4_text_box([M4sh Initialization.])
AS_BOURNE_COMPATIBLE
-_AS_PATH_SEPARATOR_PREPARE
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
as_nl='
'
export as_nl
IFS=" "" $as_nl"
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+_AS_ENSURE_STANDARD_FDS
+_AS_PATH_SEPARATOR_PREPARE
+
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $[0] in @%:@((
@@ -486,26 +532,6 @@ if test ! -f "$as_myself"; then
AS_EXIT
fi
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test \${$as_var+y} \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
_m4_popdef([AS_EXIT])])# _AS_SHELL_SANITIZE
diff --git a/tests/base.at b/tests/base.at
index 4042a8aa..6894990a 100644
--- a/tests/base.at
+++ b/tests/base.at
@@ -846,3 +846,76 @@ FOO
]])
AT_CLEANUP
+
+## ----------------------------------- ##
+## configure with closed standard fds ##
+## ----------------------------------- ##
+
+AT_SETUP([configure with closed standard fds])
+AT_KEYWORDS([AS@&t@_INIT])
+
+# Create a configure script that runs a relatively complicated but
+# self-contained test. Run it.
+AT_CONFIGURE_AC([[AC_PROG_CC]])
+AT_CHECK_AUTOCONF
+AT_CHECK_AUTOHEADER
+AT_CHECK_CONFIGURE([], [], [stdout], [stderr])
+AT_CHECK_ENV
+
+mv stdout stdout-expected
+mv stderr stderr-expected
+mv state-env.after state-env-expected
+mv config.status config-status-expected
+mv config.h config-h-expected
+
+# Run it again with stdin (fd 0) closed.
+# There should be no change to the stdout or stderr output and thoe
+# result of configuration should be the same.
+
+AT_CHECK_CONFIGURE([ 0<&- ], [], [stdout], [stderr])
+AT_CHECK_ENV
+AT_CMP([stdout-expected], [stdout])
+AT_CMP([stderr-expected], [stderr])
+AT_CONFIG_CMP([state-env-expected], [state-env.after])
+
+mv stdout stdout-closed-0
+mv stderr stderr-closed-0
+mv state-env.after state-env-closed-0
+mv config.status config-status-closed-0
+mv config.h config-h-closed-0
+
+# Run it again with stdout (fd 1) closed.
+# There should be no change to the stderr output and the
+# result of configuration should be the same. (Any output
+# that would have gone to stdout, of course, is lost.)
+
+AT_CHECK_CONFIGURE([ 1>&- ], [], [stdout], [stderr])
+AT_CHECK_ENV
+AT_CHECK([test -f stdout && test ! -s stdout])
+AT_CMP([stderr-expected], [stderr])
+AT_CONFIG_CMP([state-env-expected], [state-env.after])
+
+mv stdout stdout-closed-1
+mv stderr stderr-closed-1
+mv state-env.after state-env-closed-1
+mv config.status config-status-closed-1
+mv config.h config-h-closed-1
+
+# Run it again with stderr (fd 2) closed.
+# There should be no change to the stdout output and the
+# result of configuration should be the same. (Any output
+# that would have gone to stderr, of course, is lost.)
+
+AT_CHECK_CONFIGURE([ 2>&- ], [], [stdout], [stderr])
+AT_CHECK_ENV
+AT_CMP([stdout-expected], [stdout])
+AT_CHECK([test -f stderr && test ! -s stderr])
+AT_CONFIG_CMP([state-env-expected], [state-env.after])
+
+mv stdout stdout-closed-2
+mv stderr stderr-closed-2
+mv state-env.after state-env-closed-2
+mv config.status config-status-closed-2
+mv config.h config-h-closed-2
+
+AT_CLEANUP
diff --git a/tests/torture.at b/tests/torture.at
index 616e051c..53859f6b 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -493,6 +493,33 @@ AT_CLEANUP
+## ---------------------- ##
+## --help and --version. ##
+## ---------------------- ##
+
+AT_SETUP([--help and --version in unwritable directory])
+
+AS_MKDIR_P([inner])
+AT_DATA([inner/configure.ac],
+[[AC_INIT
+AC_OUTPUT
+]])
+
+AT_CHECK_M4([(cd inner && autoconf --force)])
+AT_CHECK([test -s inner/configure])
+if test "$SHELL_N" != none; then
+ AT_CHECK_SHELL_SYNTAX([inner/configure])
+fi
+
+chmod a-w inner
+AT_CHECK([(cd inner && ./configure --help)], 0, [ignore], [ignore])
+AT_CHECK([(cd inner && ./configure --version)], 0, [ignore], [ignore])
+chmod u+w inner
+
+AT_CLEANUP
+
+
+
## -------------------------------------------- ##
## Check that `#define' templates are honored. ##
## -------------------------------------------- ##