Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh/bltin Fix a bug in the built-in echo in /bin/sh repor...



details:   https://anonhg.NetBSD.org/src/rev/5e915ef21067
branches:  trunk
changeset: 379201:5e915ef21067
user:      kre <kre%NetBSD.org@localhost>
date:      Tue May 18 21:39:06 2021 +0000

description:
Fix a bug in the built-in echo in /bin/sh reported in private mail by
Oguz <oguzismailuysal%gmail.com@localhost>

If echo detects an I/O error, it does exit(1) (that's fine) but then
the next echo also does exit(1) even without any errors of its own,
and every following echo writing to stdout does the same thing.

eg:

echo foo >&- ; echo $?; echo $?; ( echo $( echo $?; echo $?) ; echo $? )
1
1
1 1
1

The first echo writes nothing (stdout is closed) but does exit(1).
The second echo writes "1" (correct, the exit status of the previous
echo) and should exit(0) - but doesn't.  This pattern continues...

While here, conform to the POSIX requirement on echo (and many other
standard utilities, but definitely not all) that when the utility
does exit(>0) a message must be written to stderr (and vice versa
in many cases).   Our echo (as shown above) did the exit(1) part
when it detected the I/O error, but no message is sent to stderr.
Fix that while we're here.

Similar changes are required for /bin/echo (coming soon), and
/usr/bin/printf (which is also the sh builtin printf) - except
currently that one kind of conforms, as it ignores errors writing
to stdout (as do large numbers of other utilities).  For many
programs that's kind of acceptable, but where the sole purpose of
the program is to write to stdout, it really isn't.   Also to be
fixed soon.

diffstat:

 bin/sh/bltin/bltin.h |   4 +++-
 bin/sh/bltin/echo.c  |  12 ++++++++----
 2 files changed, 11 insertions(+), 5 deletions(-)

diffs (64 lines):

diff -r 42f6d619be1a -r 5e915ef21067 bin/sh/bltin/bltin.h
--- a/bin/sh/bltin/bltin.h      Tue May 18 21:37:56 2021 +0000
+++ b/bin/sh/bltin/bltin.h      Tue May 18 21:39:06 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bltin.h,v 1.15 2017/06/26 22:09:16 kre Exp $   */
+/*     $NetBSD: bltin.h,v 1.16 2021/05/18 21:39:06 kre Exp $   */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -58,6 +58,7 @@
 #undef putchar
 #undef fileno
 #undef ferror
+#undef clearerr
 #define FILE struct output
 #define stdout out1
 #define stderr out2
@@ -74,6 +75,7 @@
 #define fflush(f)      _RETURN_INT(flushout(f))
 #define fileno(f) ((f)->fd)
 #define ferror(f) ((f)->flags & OUTPUT_ERR)
+#define clearerr(f) ((f)->flags &= ~OUTPUT_ERR)
 #define INITARGS(argv)
 #define        err sh_err
 #define        verr sh_verr
diff -r 42f6d619be1a -r 5e915ef21067 bin/sh/bltin/echo.c
--- a/bin/sh/bltin/echo.c       Tue May 18 21:37:56 2021 +0000
+++ b/bin/sh/bltin/echo.c       Tue May 18 21:39:06 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: echo.c,v 1.14 2008/10/12 01:40:37 dholland Exp $       */
+/*     $NetBSD: echo.c,v 1.15 2021/05/18 21:39:06 kre Exp $    */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: echo.c,v 1.14 2008/10/12 01:40:37 dholland Exp $");
+__RCSID("$NetBSD: echo.c,v 1.15 2021/05/18 21:39:06 kre Exp $");
 
 #define main echocmd
 
@@ -68,6 +68,8 @@ main(int argc, char **argv)
        int nflag = 0;
        int eflag = 0;
 
+       clearerr(stdout);
+
        ap = argv;
        if (argc)
                ap++;
@@ -116,7 +118,9 @@ main(int argc, char **argv)
        if (! nflag)
                putchar('\n');
        fflush(stdout);
-       if (ferror(stdout))
-               return 1;
+       if (ferror(stdout)) {
+               clearerr(stdout);
+               err(1, "write error");
+       }
        return 0;
 }



Home | Main Index | Thread Index | Old Index