On 12/07/2011 05:58 PM, Stefano Lattarini wrote:
> Hi Paul, thanks for your quick reply.
> 
> On Monday 05 December 2011, Paul Eggert wrote:
>> On 12/05/11 11:26, Stefano Lattarini wrote:
>>> Ping?  There is still interest in this?
>>
>> There's interest, yes, but alas I don't have the time
>> to work on it.  It seems you've identified four issues
>> of which at least the first two should probably be
>> fixed before it's shipped with autoconf:
>>
>> http://lists.gnu.org/archive/html/autoconf-patches/2011-11/msg00004.html
>>
>> Can you come up with a patch that fixes the first two?
>>
> I will follow-up on this after the pending Automake release.
> 
I've re-worked the patch into a three-patches series that addresses points [1]
and [3].  I find that point [2] is not so pressing anymore, now that automatic
re-execution is enabled only for autoconf-generated configure scripts and not
for all m4sh-generated scripts.

The three-patches series is attached.  OK for master?

Regards,
  Stefano
>From c95615dae1f4427f7f38efed4db1ddea64491328 Mon Sep 17 00:00:00 2001
Message-Id: <c95615dae1f4427f7f38efed4db1ddea64491328.1324895396.git.stefano.lattar...@gmail.com>
From: Stefano Lattarini <[email protected]>
Date: Mon, 26 Dec 2011 10:06:18 +0100
Subject: [PATCH 1/3] m4sh: refactor _AS_DETECT_BETTER_SHELL, for future
 changes

* lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): Move code to
handle the re-execution of the shell ...
(_AS_REEXEC_WITH_SHELL): ... in this new macro.
---
 ChangeLog           |    7 +++++++
 lib/m4sugar/m4sh.m4 |   41 ++++++++++++++++++++++++++---------------
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0f67f89..1e9fdce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-12-26  Stefano Lattarini  <[email protected]>
+
+	m4sh: refactor _AS_DETECT_BETTER_SHELL, for future changes
+	* lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): Move code to
+	handle the re-execution of the shell ...
+	(_AS_REEXEC_WITH_SHELL): ... in this new macro.
+
 2011-12-07  Paul Eggert  <[email protected]>
 
 	AC_LANG_BOOL_COMPILE_TRY(C): port to g++ with warnings
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index 1ff1705..a0c9b1f 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -223,21 +223,8 @@ dnl Remove any tests from suggested that are also required
 	     [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+"$[@]"}])
+            [export CONFIG_SHELL
+             _AS_REEXEC_WITH_SHELL([$CONFIG_SHELL])])
 
 dnl Unfortunately, $as_me isn't available here.
     AS_IF([test x$as_have_required = xno],
@@ -263,6 +250,30 @@ CLICOLOR_FORCE= GREP_OPTIONS=
 unset CLICOLOR_FORCE GREP_OPTIONS
 _m4_popdef([AS_EXIT])])# _AS_DETECT_BETTER_SHELL
 
+# _AS_REEXEC_WITH_SHELL(SHELL)
+# ----------------------------
+# Re-execute the current script with the given shell, trying to preserve
+# portable settings (e.g., the `xtrace' and `verbose' shell flag).
+m4_defun([_AS_REEXEC_WITH_SHELL], [dnl
+# 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
+case $- in @%:@ ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $1 $as_opts "$as_myself" ${1+"$[@]"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+AS_ECHO(["$[]0: could not re-execute with $1"]) >&2
+AS_EXIT([255])])# _AS_REEXEC_WITH_SHELL
+
 
 # _AS_PREPARE
 # -----------
-- 
1.7.7.3

>From 1762e46e97c4842b2045fd10f4514649e44247bd Mon Sep 17 00:00:00 2001
Message-Id: <1762e46e97c4842b2045fd10f4514649e44247bd.1324895396.git.stefano.lattar...@gmail.com>
In-Reply-To: <c95615dae1f4427f7f38efed4db1ddea64491328.1324895396.git.stefano.lattar...@gmail.com>
References: <c95615dae1f4427f7f38efed4db1ddea64491328.1324895396.git.stefano.lattar...@gmail.com>
From: Stefano Lattarini <[email protected]>
Date: Mon, 26 Dec 2011 10:06:18 +0100
Subject: [PATCH 2/3] m4sh: allow forced re-execution with $CONFIG_SHELL, if
 it's set

* lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): If the m4sh client
has defined the macro, emit code to always re-execute  the current
script with $CONFIG_SHELL, if that's set.
* tests/m4sh.at: Add tests for the new and old semantics, in ...
(Re-exec with CONFIG_SHELL, Forced re-exec with CONFIG_SHELL): ...
these new test groups.
---
 ChangeLog           |   10 ++++++
 lib/m4sugar/m4sh.m4 |   22 +++++++++++++
 tests/m4sh.at       |   87 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1e9fdce..8e3b881 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2011-12-26  Stefano Lattarini  <[email protected]>
 
+	m4sh: allow forced re-execution with $CONFIG_SHELL, if it's set
+	* lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): If the m4sh client
+	has defined the macro, emit code to always re-execute  the current
+	script with $CONFIG_SHELL, if that's set.
+	* tests/m4sh.at: Add tests for the new and old semantics, in ...
+	(Re-exec with CONFIG_SHELL, Forced re-exec with CONFIG_SHELL): ...
+	these new test groups.
+
+2011-12-26  Stefano Lattarini  <[email protected]>
+
 	m4sh: refactor _AS_DETECT_BETTER_SHELL, for future changes
 	* lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): Move code to
 	handle the re-execution of the shell ...
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index a0c9b1f..9518a52 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -192,6 +192,28 @@ m4_define([_AS_DETECT_SUGGESTED_PRUNE],
 #
 # This code is run outside any trap 0 context, hence we can simplify AS_EXIT.
 m4_defun([_AS_DETECT_BETTER_SHELL],
+dnl
+dnl By default, do not force re-execution of the script just because
+dnl the user has pre-set $CONFIG_SHELL; do so only if the m4sh client has
+dnl defined the internal variable `_AS_FORCE_REEXEC_WITH_CONFIG_SHELL' to
+dnl "yes".
+dnl FIXME: This interface is acceptable for the moment, as a private,
+dnl FIXME: internal one; but if we want to make the "always re-execute"
+dnl FIXME: feature public, we should find a better interface!
+[m4_if(_AS_FORCE_REEXEC_WITH_CONFIG_SHELL, [yes],
+  [# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    _AS_REEXEC_WITH_SHELL([$CONFIG_SHELL])
+  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([_as_can_reexec])
+])]dnl
 dnl Remove any tests from suggested that are also required
 [m4_set_map([_AS_DETECT_SUGGESTED_BODY], [_AS_DETECT_SUGGESTED_PRUNE])]dnl
 [m4_pushdef([AS_EXIT], [exit m4_default(]m4_dquote([$][1])[, 1)])]dnl
diff --git a/tests/m4sh.at b/tests/m4sh.at
index a5ef905..cdd0e7e 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -17,6 +17,93 @@ 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([No extra re-exec with CONFIG_SHELL])
+AT_KEYWORDS([CONFIG_SHELL])
+AT_DATA_M4SH([script.as],
+[[
+dnl We have to muck with internal details to goad the script into
+dnl thinking that the default shell is always good enough.
+m4_define([_AS_DETECT_REQUIRED_BODY], [])dnl
+m4_define([_AS_DETECT_SUGGESTED_BODY], [])dnl
+AS_INIT
+echo foo > ok
+]])
+AT_CHECK_M4SH
+AT_CHECK([CONFIG_SHELL=/bin/false ./script], [0], [], [])
+AT_CHECK([test -f ok], [0])
+rm -f ok
+
+AT_CLEANUP
+
+AT_SETUP([Forced re-exec with CONFIG_SHELL])
+AT_KEYWORDS([CONFIG_SHELL])
+
+AT_DATA_M4SH([script.as],
+[[m4_define([_AS_FORCE_REEXEC_WITH_CONFIG_SHELL], [yes])
+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 '' '&' '!;*' '<($[]@%:@)>,' 'x
+y  z
+1 2 3')], [0],
+[Fake shell executed.
+nargs = 5
+ ::
+ :&:
+ :!;*:
+ :<($[]@%:@)>,:
+ :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.7.3

>From 53317371d1e44d816c8793ee1f97c5bb41525edb Mon Sep 17 00:00:00 2001
Message-Id: <53317371d1e44d816c8793ee1f97c5bb41525edb.1324895396.git.stefano.lattar...@gmail.com>
In-Reply-To: <c95615dae1f4427f7f38efed4db1ddea64491328.1324895396.git.stefano.lattar...@gmail.com>
References: <c95615dae1f4427f7f38efed4db1ddea64491328.1324895396.git.stefano.lattar...@gmail.com>
From: Stefano Lattarini <[email protected]>
Date: Mon, 26 Dec 2011 10:27:51 +0100
Subject: [PATCH 3/3] configure: will re-execute with $CONFIG_SHELL, if it's
 set

* lib/m4sugar/general.m4 (_AS_DETECT_BETTER_SHELL): Define the
macro `' to `yes', so that the code in _AS_DETECT_BETTER_SHELL
will cause autoconf-generated configure scripts to always
re-execute themselves with $CONFIG_SHELL, if it's set in the
environment.
* doc/autoconf.texi (config.status Invocation): Update.
* doc/install.texi (Defining Variables): Likewise.
* NEWS: Likewise.
* tests/m4sh.at: Add tests for the new semantics in ...
(Configure re-execs self with CONFIG_SHELL): ... this new
test group.
---
 ChangeLog               |   15 +++++++++++++++
 NEWS                    |    3 +++
 doc/autoconf.texi       |   11 ++++-------
 doc/install.texi        |    6 +++---
 lib/autoconf/general.m4 |    3 +++
 tests/m4sh.at           |   27 +++++++++++++++++++++++++++
 6 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8e3b881..16b55f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2011-12-26  Stefano Lattarini  <[email protected]>
 
+	configure: will re-execute with $CONFIG_SHELL, if it's set
+	* lib/m4sugar/general.m4 (_AS_DETECT_BETTER_SHELL): Define the
+	macro `' to `yes', so that the code in _AS_DETECT_BETTER_SHELL
+	will cause autoconf-generated configure scripts to always
+	re-execute themselves with $CONFIG_SHELL, if it's set in the
+	environment.
+	* doc/autoconf.texi (config.status Invocation): Update.
+	* doc/install.texi (Defining Variables): Likewise.
+	* NEWS: Likewise.
+	* tests/m4sh.at: Add tests for the new semantics in ...
+	(Configure re-execs self with CONFIG_SHELL): ... this new
+	test group.
+
+2011-12-26  Stefano Lattarini  <[email protected]>
+
 	m4sh: allow forced re-execution with $CONFIG_SHELL, if it's set
 	* lib/m4sugar/m4sh.m4 (_AS_DETECT_BETTER_SHELL): If the m4sh client
 	has defined the macro, emit code to always re-execute  the current
diff --git a/NEWS b/NEWS
index 858601a..aff0fbb 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ GNU Autoconf NEWS - User visible changes.
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Autoconf-generated configure scripts now unconditionally re-execute
+   themselves with $CONFIG_SHELL, if that's set in the environment.
+
 ** The texinfo documentation no longer specifies "front-cover" or
    "back-cover" texts, so that it may now be included in Debian's
    "main" section.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index d7d2231..5360572 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -22633,13 +22633,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
+@file{/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/autoconf/general.m4 b/lib/autoconf/general.m4
index dd20e71..b2a7d94 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -1386,6 +1386,9 @@ m4_pattern_forbid([^LIBOBJS$],
 		  [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
 # Actually reserved by M4sh.
 m4_pattern_allow([^AS_FLAGS$])
+# So that the autoconf-generated scripts will always re-execute
+# themselves with $CONFIG_SHELL, if that's set in the environment.
+m4_define([_AS_FORCE_REEXEC_WITH_CONFIG_SHELL], [yes])
 AS_INIT[]dnl
 AS_PREPARE[]dnl
 m4_divert_push([KILL])
diff --git a/tests/m4sh.at b/tests/m4sh.at
index cdd0e7e..ba8991a 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -103,6 +103,33 @@ test ! -f sentinel || rm -f sentinel # Cleanup for next test.
 
 AT_CLEANUP
 
+AT_SETUP([Configure re-execs self with CONFIG_SHELL])
+
+AT_DATA([configure.ac],
+[[AC_INIT
+echo foobar >> quux
+]])
+
+AT_CHECK_AUTOCONF
+
+AT_DATA([cfg-sh],
+[[#!/bin/sh
+: > cfg-sh-has-run
+exec sh "@S|@@"
+]])
+chmod a+x cfg-sh
+
+AT_CAPTURE_FILE([config.log])
+AT_CHECK([env CONFIG_SHELL=./cfg-sh ./configure], [0], [], [])
+# ./configure re-executed itself.
+AT_CHECK([test -f cfg-sh-has-run], [0])
+# And did that not to cause extra execution of later commands.
+AT_CHECK([cat quux], [0], [foobar
+], [])
+
+rm -f quux cfg-sh*
+AT_CLEANUP
+
 
 ## ------------------- ##
 ## AS_WARN, AS_ERROR.  ##
-- 
1.7.7.3

Reply via email to