autoconf-patches
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]