* doc/autoconf.texi (Shell Substitutions): Document the issue.
* lib/m4sugar/m4sh.m4 (AS_VAR_IF): New function.
* lib/autoconf/functions.m4 (AC_CHECK_FUNC): Use it in place of
"test AS_VAR_GET([...]) = yes"
* lib/autoconf/general.m4 (AC_CHECK_FILE, AC_CHECK_DECL): Likewise.
* lib/autoconf/headers.m4 (_AC_CHECK_HEADER_MONGREL): Likewise.
(_AC_CHECK_HEADER_NEW, _AC_CHECK_HEADER_OLD): Likewise.
(_AC_CHECK_HEADER_DIRENT): Likewise.
* lib/autoconf/libs.m4 (AC_CHECK_LIB): Likewise.
* lib/autoconf/types.m4 (_AC_CHECK_TYPE_NEW, AC_CHECK_MEMBER): Likewise.
* lib/autoconf/status.m4 (_AC_OUTPUT_FILES_PREPARE): Use
temporary variable to work around the issue.
* tests/foreign.at (Libtool): Quote result of command
substitution.
Signed-off-by: Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+2008-08-19 Jim Meyering <jim@meyering.net>
+ Eric Blake <ebb9@byu.net>
+ Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ Avoid shell parse errors after interrupt due to empty ``.
+ * doc/autoconf.texi (Shell Substitutions): Document the issue.
+ * lib/m4sugar/m4sh.m4 (AS_VAR_IF): New function.
+ * lib/autoconf/functions.m4 (AC_CHECK_FUNC): Use it in place of
+ "test AS_VAR_GET([...]) = yes"
+ * lib/autoconf/general.m4 (AC_CHECK_FILE, AC_CHECK_DECL): Likewise.
+ * lib/autoconf/headers.m4 (_AC_CHECK_HEADER_MONGREL): Likewise.
+ (_AC_CHECK_HEADER_NEW, _AC_CHECK_HEADER_OLD): Likewise.
+ (_AC_CHECK_HEADER_DIRENT): Likewise.
+ * lib/autoconf/libs.m4 (AC_CHECK_LIB): Likewise.
+ * lib/autoconf/types.m4 (_AC_CHECK_TYPE_NEW, AC_CHECK_MEMBER): Likewise.
+ * lib/autoconf/status.m4 (_AC_OUTPUT_FILES_PREPARE): Use
+ temporary variable to work around the issue.
+ * tests/foreign.at (Libtool): Quote result of command
+ substitution.
+
2008-08-18 Eric Blake <ebb9@byu.net>
Test m4_transform without tickling shell bugs.
- broken differ: char 4, line 1
@end example
+Upon interrupt or SIGTERM, some shells may abort a command substitution,
+replace it with a null string, and wrongly evaluate the enclosing
+command before entering the trap or ending the script. This can lead to
+spurious errors:
+
+@example
+$ @kbd{sh -c 'if test `sleep 5; echo hi` = hi; then echo yes; fi'}
+$ @kbd{^C}
+sh: test: hi: unexpected operator/operand
+@end example
+
+@noindent
+You can avoid this by assigning the command substitution to a temporary
+variable:
+
+@example
+$ @kbd{sh -c 'res=`sleep 5; echo hi`
+ if test "x$res" = xhi; then echo yes; fi'}
+$ @kbd{^C}
+@end example
@item $(@var{commands})
@cindex $(@var{commands})
[AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([$1])],
[AS_VAR_SET([ac_var], [yes])],
[AS_VAR_SET([ac_var], [no])])])
-AS_IF([test AS_VAR_GET([ac_var]) = yes], [$2], [$3])dnl
+AS_VAR_IF([ac_var], [yes], [$2], [$3])dnl
AS_VAR_POPDEF([ac_var])dnl
])# AC_CHECK_FUNC
else
AS_VAR_SET([ac_File], [no])
fi])
-AS_IF([test AS_VAR_GET([ac_File]) = yes], [$2], [$3])[]dnl
+AS_VAR_IF([ac_File], [yes], [$2], [$3])[]dnl
AS_VAR_POPDEF([ac_File])dnl
])# AC_CHECK_FILE
])],
[AS_VAR_SET([ac_Symbol], [yes])],
[AS_VAR_SET([ac_Symbol], [no])])])
-AS_IF([test AS_VAR_GET([ac_Symbol]) = yes], [$2], [$3])[]dnl
+AS_VAR_IF([ac_Symbol], [yes], [$2], [$3])[]dnl
AS_VAR_POPDEF([ac_Symbol])dnl
])# AC_CHECK_DECL
AC_CACHE_CHECK([for $1], [ac_Header],
[AS_VAR_SET([ac_Header], [$ac_header_preproc])])
])dnl ! set ac_HEADER
-AS_IF([test AS_VAR_GET([ac_Header]) = yes], [$2], [$3])[]dnl
+AS_VAR_IF([ac_Header], [yes], [$2], [$3])[]dnl
AS_VAR_POPDEF([ac_Header])dnl
])# _AC_CHECK_HEADER_MONGREL
@%:@include <$1>])],
[AS_VAR_SET([ac_Header], [yes])],
[AS_VAR_SET([ac_Header], [no])])])
-AS_IF([test AS_VAR_GET([ac_Header]) = yes], [$2], [$3])[]dnl
+AS_VAR_IF([ac_Header], [yes], [$2], [$3])[]dnl
AS_VAR_POPDEF([ac_Header])dnl
])# _AC_CHECK_HEADER_NEW
[AC_PREPROC_IFELSE([AC_LANG_SOURCE([@%:@include <$1>])],
[AS_VAR_SET([ac_Header], [yes])],
[AS_VAR_SET([ac_Header], [no])])])
-AS_IF([test AS_VAR_GET([ac_Header]) = yes], [$2], [$3])[]dnl
+AS_VAR_IF([ac_Header], [yes], [$2], [$3])[]dnl
AS_VAR_POPDEF([ac_Header])dnl
])# _AC_CHECK_HEADER_OLD
return 0;])],
[AS_VAR_SET([ac_Header], [yes])],
[AS_VAR_SET([ac_Header], [no])])])
-AS_IF([test AS_VAR_GET([ac_Header]) = yes], [$2], [$3])[]dnl
+AS_VAR_IF([ac_Header], [yes], [$2], [$3])[]dnl
AS_VAR_POPDEF([ac_Header])dnl
])# _AC_CHECK_HEADER_DIRENT
[AS_VAR_SET([ac_Lib], [yes])],
[AS_VAR_SET([ac_Lib], [no])])
LIBS=$ac_check_lib_save_LIBS])
-AS_IF([test AS_VAR_GET([ac_Lib]) = yes],
+AS_VAR_IF([ac_Lib], [yes],
[m4_default([$3], [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1))
LIBS="-l$1 $LIBS"
])],
AC_MSG_ERROR([could not make $CONFIG_STATUS])
dnl Do not use grep on conf$$subs.awk, since AIX grep has a line length limit.
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` = $ac_delim_num; then
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
break
elif $ac_last_try; then
AC_MSG_ERROR([could not make $CONFIG_STATUS])
return 0;])],
[],
[AS_VAR_SET([ac_Type], [yes])])])])
-AS_IF([test AS_VAR_GET([ac_Type]) = yes], [$2], [$3])[]dnl
+AS_VAR_IF([ac_Type], [yes], [$2], [$3])[]dnl
AS_VAR_POPDEF([ac_Type])dnl
])# _AC_CHECK_TYPE_NEW
return 0;])],
[AS_VAR_SET([ac_Member], [yes])],
[AS_VAR_SET([ac_Member], [no])])])])
-AS_IF([test AS_VAR_GET([ac_Member]) = yes], [$2], [$3])dnl
+AS_VAR_IF([ac_Member], [yes], [$2], [$3])dnl
AS_VAR_POPDEF([ac_Member])dnl
])# AC_CHECK_MEMBER
[AS_IF([AS_VAR_TEST_SET([$1])], [$2], [$3])])
+# AS_VAR_IF(VARIABLE, VALUE, IF-TRUE, IF-FALSE)
+# ---------------------------------------------
+# Implement a shell `if test $VARIABLE = VALUE; then-else'.
+# Polymorphic, and avoids sh expansion error upon interrupt or term signal.
+m4_define([AS_VAR_IF],
+[AS_LITERAL_IF([$1],
+ [AS_IF([test "x$$1" = x""$2], [$3], [$4])],
+ [as_val=AS_VAR_GET([$1])
+ AS_IF([test "x$as_val" = x""$2], [$3], [$4])])])
+
+
# AS_VAR_PUSHDEF and AS_VAR_POPDEF
# --------------------------------
#
touch install-sh
# Build the concatenation of libtool.m4 and configure.ac.
-cp `cat stdout` configure.in
+cp "`cat stdout`" configure.in
cat >>configure.in <<_EOF
AC_INIT
AC_CONFIG_AUX_DIR(.)