[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] m4sh: always re-exec with $CONFIG_SHELL, if it's set
From: |
Stefano Lattarini |
Subject: |
[PATCH] m4sh: always re-exec with $CONFIG_SHELL, if it's set |
Date: |
Tue, 1 Nov 2011 13:12:11 +0100 |
* lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): Always re-execute
the current script with $CONFIG_SHELL, if that's set.
* tests/m4sh.at: Add tests for the new semantics, in ...
(Re-exec with CONFIG_SHELL): ... this new section.
* doc/autoconf.texi (config.status Invocation): Update.
* doc/install.texi (Defining Variables): Likewise.
* NEWS: Likewise.
---
ChangeLog | 11 ++++++
doc/autoconf.texi | 11 ++----
doc/install.texi | 6 ++--
lib/m4sugar/m4sh.m4 | 90 +++++++++++++++++++++++++++++++++-----------------
tests/m4sh.at | 68 ++++++++++++++++++++++++++++++++++++++
5 files changed, 145 insertions(+), 41 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e51f7d7..188c394 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-11-01 Stefano Lattarini <address@hidden>
+
+ m4sh: always re-exec with $CONFIG_SHELL, if it's set
+ * lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): Always re-execute
+ the current script with $CONFIG_SHELL, if that's set.
+ * tests/m4sh.at: Add tests for the new semantics, in ...
+ (Re-exec with CONFIG_SHELL): ... this new section.
+ * doc/autoconf.texi (config.status Invocation): Update.
+ * doc/install.texi (Defining Variables): Likewise.
+ * NEWS: Likewise.
+
2011-10-21 Stefano Lattarini <address@hidden>
fortran: define $GFC to "yes" if $FC is a GNU compiler
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index b6dc67b..5735200 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -22616,13 +22616,10 @@ can alter its behavior:
@anchor{CONFIG_SHELL}
@defvar CONFIG_SHELL
@evindex CONFIG_SHELL
-The shell with which to run @command{configure} for the @option{--recheck}
-option. It must be Bourne-compatible. The default is a shell that
-supports @code{LINENO} if available, and @file{/bin/sh} otherwise.
-Invoking @command{configure} by hand bypasses this setting, so you may
-need to use a command like @samp{CONFIG_SHELL=/bin/bash /bin/bash ./configure}
-to insure that the same shell is used everywhere. The absolute name of the
-shell should be passed.
+The shell with which to run @command{configure}. It must be
+Bourne-compatible, and the absolute name of the shell should be passed.
+The default is a shell that supports @code{LINENO} if available, and
address@hidden/bin/sh} otherwise.
@end defvar
@defvar CONFIG_STATUS
diff --git a/doc/install.texi b/doc/install.texi
index d397b8a..c6a8bdf 100644
--- a/doc/install.texi
+++ b/doc/install.texi
@@ -364,11 +364,11 @@ overridden in the site shell script).
@noindent
Unfortunately, this technique does not work for @env{CONFIG_SHELL} due
-to an Autoconf bug. Until the bug is fixed you can use this
-workaround:
+to an Autoconf limitation. Until the limitation is lifted, you can use
+this workaround:
@example
-CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
@end example
@node configure Invocation
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index 1ff1705..043a2c6 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -178,8 +178,9 @@ m4_define([_AS_DETECT_SUGGESTED_PRUNE],
# _AS_DETECT_BETTER_SHELL
# -----------------------
-# The real workhorse for detecting a shell with the correct
-# features.
+# The real workhorse for detecting a shell with the correct features.
+# FIXME: this should be split into two macros, one to detect a better
+# shell, and one to re-execute with it.
#
# In previous versions, we prepended /usr/posix/bin to the path, but that
# caused a regression on OpenServer 6.0.0
@@ -220,42 +221,69 @@ dnl Remove any tests from suggested that are also required
esac],
[AS_IF([{ test -f "$SHELL" || test -f "$SHELL.exe"; } &&
_AS_RUN(["$as_required"], ["$SHELL"])],
- [CONFIG_SHELL=$SHELL as_have_required=yes])])
-
- AS_IF([test "x$CONFIG_SHELL" != x],
- [# We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in @%:@ ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"address@hidden"}])
-
-dnl Unfortunately, $as_me isn't available here.
- AS_IF([test x$as_have_required = xno],
- [AS_ECHO(["$[]0: This script requires a shell more modern than all"])
- AS_ECHO(["$[]0: the shells that I found on your system."])
- if test x${ZSH_VERSION+set} = xset ; then
- AS_ECHO(["$[]0: In particular, zsh $ZSH_VERSION has bugs and should"])
- AS_ECHO(["$[]0: be upgraded to zsh 4.3.4 or later."])
+ [CONFIG_SHELL=$SHELL as_have_required=yes])])])
+
+ if test "x$CONFIG_SHELL" != x; then
+ : We have found a good-enough or better shell, we will re-execute
+ : ourselves with it soon.
+ elif test x$as_have_required = xyes; then
+ : The current shell is good enough.
else
- AS_ECHO("m4_text_wrap([Please tell ]_m4_defn([m4_PACKAGE_BUGREPORT])
+ : Just give up.
+ # Unfortunately, $as_me isn't available here, so we just use $0.
+ AS_ECHO(["$[]0: This script requires a shell more modern than all"])
+ AS_ECHO(["$[]0: the shells that I found on your system."])
+ if test x${ZSH_VERSION+set} = xset ; then
+ AS_ECHO(["$[]0: In particular, zsh $ZSH_VERSION has bugs and should"])
+ AS_ECHO(["$[]0: be upgraded to zsh 4.3.4 or later."])
+ else
+ AS_ECHO("m4_text_wrap([Please tell ]_m4_defn([m4_PACKAGE_BUGREPORT])
m4_ifset([AC_PACKAGE_BUGREPORT], [m4_if(_m4_defn([m4_PACKAGE_BUGREPORT]),
_m4_defn([AC_PACKAGE_BUGREPORT]), [], [and _m4_defn([AC_PACKAGE_BUGREPORT])])])
[about your system, including any error possibly output before this message.
Then install a modern shell, or manually run the script under such a
shell if you do have one.], [$[]0: ], [], [62])")
- fi
- AS_EXIT])])
+ fi
+ AS_EXIT
+ fi # No good-enough shell found.
+
+fi # $CONFIG_SHELL not pre-set by the user.
+
+# We might have to re-execute the current script, either because the
+# current shell is not good enough, or a better shell has been found,
+# or the user has pre-set $CONFIG_SHELL in the environment.
+# Use a proper internal environment variable to ensure we don't fall
+# into an infinite loop, continuously re-executing ourselves.
+if test x"${_ac_no_reexec}" = x && test "x$CONFIG_SHELL" != x; then
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ # Preserve -v and -x to the replacement shell.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ case $- in @%:@ ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+ esac
+ _ac_no_reexec=yes; export _ac_no_reexec;
+ exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"address@hidden"}
+ # In case the user has done a typo in the setting of $CONFIG_SHELL.
+ # Admittedly, this is quite paranoid, since all the known shells bail
+ # out after a failed `exec'.
+ AS_ECHO(["$[]0: could not re-execute with $CONFIG_SHELL"]) >&2
+ AS_EXIT([255])
fi
+# We don't want this to propagate to other subprocesses.
+dnl This might be especially important in case an m4sh-generated script
+dnl is used to later execute other m4sh-generated scripts. This happens
+dnl for example in autoconf's own testsuite (and happens *a lot* there,
+dnl in fact).
+AS_UNSET([_ac_no_reexec])
+
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
diff --git a/tests/m4sh.at b/tests/m4sh.at
index a5ef905..4fa26d1 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -17,6 +17,74 @@ AT_BANNER([M4sh.])
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+## --------------------------- ##
+## Re-exec with CONFIG_SHELL. ##
+## --------------------------- ##
+
+AT_SETUP([Re-exec with CONFIG_SHELL])
+AT_KEYWORDS([CONFIG_SHELL])
+
+AT_DATA_M4SH([script.as],
+[[AS_INIT
+echo foo > sentinel
+]])
+AT_CHECK_M4SH
+
+AT_DATA([fake-shell],
+[[#!/bin/sh
+echo 'Fake shell executed.'
+shift # fake shell
+echo "nargs = @S|@#"
+for i
+do
+ printf ' :%s:\n' "$i"
+done
+]])
+chmod a+x fake-shell
+
+AT_CHECK([CONFIG_SHELL=./fake-shell ./script 1 2 4 8], [0],
+[Fake shell executed.
+nargs = 4
+ :1:
+ :2:
+ :4:
+ :8:
+], [])
+AT_CHECK([test ! -f sentinel], [0])
+test ! -f sentinel || rm -f sentinel # Cleanup for next test.
+
+AT_CHECK(
+[CONFIG_SHELL=`pwd`/fake-shell sh script a 'b c' ' d e '],
+[0],
+[Fake shell executed.
+nargs = 3
+ :a:
+ :b c:
+ : d e :
+], [])
+AT_CHECK([test ! -f sentinel], [0])
+test ! -f sentinel || rm -f sentinel # Cleanup for next test.
+
+AT_CHECK([(PATH=`pwd`:$PATH; export PATH;
+CONFIG_SHELL=fake-shell script '' '&' '!;*' '<(address@hidden:@)>,' 'x
+y z
+1 2 3')], [0],
+[Fake shell executed.
+nargs = 5
+ ::
+ :&:
+ :!;*:
+ :<(address@hidden:@)>,:
+ :x
+y z
+1 2 3:
+], [])
+AT_CHECK([test ! -f sentinel], [0])
+test ! -f sentinel || rm -f sentinel # Cleanup for next test.
+
+AT_CLEANUP
+
+
## ------------------- ##
## AS_WARN, AS_ERROR. ##
## ------------------- ##
--
1.7.2.3
- [PATCH] m4sh: always re-exec with $CONFIG_SHELL, if it's set,
Stefano Lattarini <=