[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Diagnose write errors in config.status
From: |
Ralf Wildenhues |
Subject: |
Diagnose write errors in config.status |
Date: |
Thu, 15 Nov 2007 22:37:20 +0100 |
User-agent: |
Mutt/1.5.13 (2006-08-11) |
Plowing my way through Bruno's bug reports and suggestions from:
<http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/11571/focus=11850>.
Let's make write errors fail config.status.
First off, writing a test that exercises all possible code paths is
rather difficult. I left it at a reasonably primitive addition to an
existing test, where most of the write errors will just trigger at the
`mkdir "$tmp"' near the beginning. And a couple of tests using
/dev/full which I guess is not portable; however, on systems without it,
the redirection will just fail, so we should at least degrade gracefully.
I just went through status.m4 once, searching for all failure spots.
I deliberately left out checking all the
cat >$CONFIG_STATUS <<...
for now, my (weak) rationale being that with a write error, the
config.status file will likely be completely unusable anyway (and my
other one being laziness for now). Do you think each one of them should
be checked as well? I can try fixing that then.
I believe to have found all other spots, but would of course appreciate
a second pair of eyes.
OK to apply?
Cheers,
Ralf
Diagnose write errors in config.status instantiations.
* lib/autoconf/status.m4 (_AC_OUTPUT_FILE)
(_AC_OUTPUT_HEADER, _AC_OUTPUT_MAIN_LOOP): Bail out
on write errors.
* tests/torture.at (AC_CONFIG_FILES, HEADERS, LINKS and COMMANDS):
Extend test to also check for some write error failures, using...
<AT_CHECK_CONFIG_CREATION_NOWRITE>: ...this new macro.
Report by Bruno Haible.
diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4
index 0d1d93e..4a617a6 100644
--- a/lib/autoconf/status.m4
+++ b/lib/autoconf/status.m4
@@ -636,7 +636,8 @@ m4_foreach([_AC_Var], [srcdir, abs_srcdir, top_srcdir,
abs_top_srcdir,
])dnl
m4_ifndef([AC_DATAROOTDIR_CHECKED], [$ac_datarootdir_hack
])dnl
-" $ac_file_inputs m4_defn([_AC_SUBST_CMDS]) >$tmp/out
+" $ac_file_inputs m4_defn([_AC_SUBST_CMDS]) >$tmp/out \
+ || AC_MSG_ERROR([could not create $ac_file])
m4_ifndef([AC_DATAROOTDIR_CHECKED],
[test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
@@ -648,9 +649,10 @@ which seems to be undefined. Please make sure it is
defined.])
rm -f "$tmp/stdin"
case $ac_file in
- -) cat "$tmp/out"; rm -f "$tmp/out";;
- *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
- esac
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" $ac_file;;
+ esac \
+ || AC_MSG_ERROR([could not create $ac_file])
dnl This would break Makefile dependencies:
dnl if diff $ac_file "$tmp/out" >/dev/null 2>&1; then
dnl echo "$ac_file is unchanged"
@@ -838,17 +840,22 @@ m4_define([_AC_OUTPUT_HEADER],
# CONFIG_HEADER
#
if test x"$ac_file" != x-; then
- AS_ECHO(["/* $configure_input */"]) >"$tmp/config.h"
- $AWK -f "$tmp/defines.awk" $ac_file_inputs >>"$tmp/config.h"
+ {
+ AS_ECHO(["/* $configure_input */"]) \
+ && $AWK -f "$tmp/defines.awk" $ac_file_inputs
+ } >"$tmp/config.h" \
+ || AC_MSG_ERROR([could not create $ac_file])
if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
AC_MSG_NOTICE([$ac_file is unchanged])
else
rm -f $ac_file
- mv "$tmp/config.h" $ac_file
+ mv "$tmp/config.h" $ac_file \
+ || AC_MSG_ERROR([could not create $ac_file])
fi
else
- AS_ECHO(["/* $configure_input */"])
- $AWK -f "$tmp/defines.awk" $ac_file_inputs
+ AS_ECHO(["/* $configure_input */"]) \
+ && $AWK -f "$tmp/defines.awk" $ac_file_inputs \
+ || AC_MSG_ERROR([could not create -])
fi
dnl If running for Automake, be ready to perform additional
dnl commands to set up the timestamp files.
@@ -1617,7 +1624,8 @@ do
fi
case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin";;
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || AC_MSG_ERROR([could not create $ac_file]) ;;
esac
;;
esac
diff --git a/tests/torture.at b/tests/torture.at
index 63d6ef9..a87a33b 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -193,6 +193,29 @@ AT_CHECK([grep OK var-$1], [], [OK
])# AT_CHECK_CONFIG_CREATION
+# AT_CHECK_CONFIG_CREATION_NOWRITE(THING = (header | link | file | command))
+# ------------------------------------------------------------------
+# Check that THING and var-THING (which uses variables in AC_CONFIG_THING)
+# are properly created, with the right content.
+# Use `grep OK' instead of a simple `cat' to avoid banners such as in
+# AC_CONFIG_HEADERS.
+m4_define([AT_CHECK_CONFIG_CREATION_NOWRITE],
+[AT_CHECK_CONFIGURE([what_to_test=$1])
+AT_CHECK([ls header var-header file var-file command var-command link var-link
2>/dev/null],
+ [ignore], [$1
+])
+AT_CHECK([grep OK $1], [], [OK
+])
+
+AT_CHECK_CONFIGURE([what_to_test=var-$1 --no-create])
+# config.status might be stupidly expecting data on stdin, if it's
+# really broken...
+chmod a-w .
+AT_CHECK([./config.status var-$1 </dev/null], [1], [ignore], [ignore])
+chmod u+w .
+])# AT_CHECK_CONFIG_CREATION_NOWRITE
+
+
# Create a file
AT_CHECK_CONFIG_CREATION(file)
@@ -205,6 +228,24 @@ AT_CHECK_CONFIG_CREATION(command)
# Create a link
AT_CHECK_CONFIG_CREATION(link)
+# Now check for write errors
+
+# Create a file
+AT_CHECK_CONFIG_CREATION_NOWRITE(file)
+AT_CHECK([./config.status --file=-:input </dev/null >/dev/full],
+ [1], [ignore], [ignore])
+
+# Create a header
+AT_CHECK_CONFIG_CREATION_NOWRITE(header)
+AT_CHECK([./config.status --header=-:input </dev/null >/dev/full],
+ [1], [ignore], [ignore])
+
+# Execute a command
+AT_CHECK_CONFIG_CREATION_NOWRITE(command)
+
+# Create a link
+AT_CHECK_CONFIG_CREATION_NOWRITE(link)
+
AT_CLEANUP
- Diagnose write errors in config.status,
Ralf Wildenhues <=
Re: Diagnose write errors in config.status, Bruno Haible, 2007/11/15