[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: `cat` vs. read
From: |
Eric Blake |
Subject: |
Re: `cat` vs. read |
Date: |
Mon, 27 Oct 2008 22:11:38 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Ralf Wildenhues <Ralf.Wildenhues <at> gmx.de> writes:
> > $ foo=; printf 'abc' > file; read foo < file; echo $? $foo
> > 1 abc
> >
> > Does anyone know of a shell where this patch would fail (either because the
> > shell spits out an error message, or because foo is unpopulated due to the
> > nonzero status)?
>
> Solaris 2.10 dtksh will print
> 1 ab
>
> Tru64/OSF1 dtksh will print
> 0
Thanks for the research. Do either of these two shells pass the required shell
function tests?
But now that you've forced me to think about the issue, I have a workaround
that should do just fine, even on the case of mingw where `cat` was not
stripping the \r. We still can't change conftest.c to output \n when it
creates conftest.val (because fopen("conftest.val","wb") is not necessarily
portable, and fopen("conftest.val","w") might result in \r\n on mingw with a
shell that doesn't strip \r during read), but we CAN use 'echo >>
conftest.val'. If the shell's echo uses a plain \n, then there is no issue.
And if it uses \r\n, then it is also safe to assume that the shell's read
ignores \r. Thus, by using the same tool to both generate and strip the end-of-
line, we have taken care of the problem that was plaguing mingw, while avoiding
the portability problem of using read on a non-text file.
Here's the modified patch that I plan on committing later today, if I don't get
any further feedback. I've tested it on a cross-compile with cygwin build and
mingw host, which was one of the configurations where I had reproduced the bug
that led to commit 78dc34d.
From: Eric Blake <address@hidden>
Date: Mon, 27 Oct 2008 10:36:59 -0600
Subject: [PATCH] Use read, rather than `cat`, for safe one-line files.
* lib/autotest/general.m4 (AT_CLEANUP): Avoid a fork, since it is
known that the file has only one line and no \.
* lib/autoconf/general.m4 (_AC_COMPUTE_INT_RUN): Likewise.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 7 +++++++
lib/autoconf/general.m4 | 7 +++++--
lib/autotest/general.m4 | 2 +-
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index eab5a93..313124b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-10-27 Eric Blake <address@hidden>
+
+ Use read, rather than `cat`, for safe one-line files.
+ * lib/autotest/general.m4 (AT_CLEANUP): Avoid a fork, since it is
+ known that the file has only one line and no \.
+ * lib/autoconf/general.m4 (_AC_COMPUTE_INT_RUN): Likewise.
+
2008-10-27 Paolo Bonzini <address@hidden>
* lib/autoconf/general.m4 (_AC_COMPUTE_INT_COMPILE,
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 8b84245..000f705 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -2908,9 +2908,12 @@ esac[]dnl
# [IF-FAILURE])
# -----------------------------------------------------------------
# Store the evaluation of the integer EXPRESSION in VARIABLE.
+#
+# AC_LANG_INT_SAVE intentionally does not end the file in a newline, so
+# we must add one to make it a text file before passing it to read.
m4_define([_AC_COMPUTE_INT_RUN],
[_AC_RUN_IFELSE([AC_LANG_INT_SAVE([$3], [$1])],
- [AS_VAR_SET([$2], [`cat conftest.val`]); $4], [$5])
+ [echo >>conftest.val; read $2 <conftest.val; $4], [$5])
rm -f conftest.val
])# _AC_COMPUTE_INT_RUN
diff --git a/lib/autotest/general.m4 b/lib/autotest/general.m4
index 149fff1..00817b1 100644
--- a/lib/autotest/general.m4
+++ b/lib/autotest/general.m4
@@ -1674,7 +1674,7 @@ m4_undivert([TEST_SCRIPT])dnl Insert the code here
$at_traceoff
$at_times_p && times >"$at_times_file"
) AS_MESSAGE_LOG_FD>&1 2>&1 | eval $at_tee_pipe
-at_status=`cat "$at_status_file"`
+read at_status <"$at_status_file"
[#AT_STOP_]AT_ordinal
m4_divert_pop([TEST_GROUPS])dnl Back to KILL.
])# AT_CLEANUP
--
1.6.0.2