zsh-workers
 help / color / mirror / code / Atom feed
* [BUG] builtin echo doesn't check write error
@ 2021-06-09 14:09 Vincent Lefevre
  2021-06-09 14:17 ` Vincent Lefevre
  2021-06-09 16:13 ` Bart Schaefer
  0 siblings, 2 replies; 10+ messages in thread
From: Vincent Lefevre @ 2021-06-09 14:09 UTC (permalink / raw)
  To: zsh-workers

With zsh 5.8, the builtin echo doesn't check write error.

zira% zsh -c 'echo foo >&-; echo $?'
0

In strace output:

close(1)                                = 0
write(1, "foo\n", 4)                    = -1 EBADF (Bad file descriptor)

No issues with an external echo command:

zira% zsh -c '/bin/echo foo >&-; echo $?'
/bin/echo: write error: Bad file descriptor
1

And with other shells:

zira% sh -c 'echo foo >&-; echo $?'
sh: 1: echo: echo: I/O error
1
zira% bash -c 'echo foo >&-; echo $?'
bash: line 1: echo: write error: Bad file descriptor
1
zira% ksh -c 'echo foo >&-; echo $?'
1
zira% ksh93 -c 'echo foo >&-; echo $?'
1
zira% mksh -c 'echo foo >&-; echo $?'
1
zira% posh -c 'echo foo >&-; echo $?'
1
zira% yash -c 'echo foo >&-; echo $?'
echo: cannot print to the standard output: Bad file descriptor
1

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 14:09 [BUG] builtin echo doesn't check write error Vincent Lefevre
@ 2021-06-09 14:17 ` Vincent Lefevre
  2021-06-09 15:33   ` Stephane Chazelas
  2021-06-09 16:13 ` Bart Schaefer
  1 sibling, 1 reply; 10+ messages in thread
From: Vincent Lefevre @ 2021-06-09 14:17 UTC (permalink / raw)
  To: zsh-workers

On 2021-06-09 16:09:40 +0200, Vincent Lefevre wrote:
> With zsh 5.8, the builtin echo doesn't check write error.

And that's also the case for "print", "printf" and maybe others.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 14:17 ` Vincent Lefevre
@ 2021-06-09 15:33   ` Stephane Chazelas
  2021-06-09 15:40     ` Stephane Chazelas
  0 siblings, 1 reply; 10+ messages in thread
From: Stephane Chazelas @ 2021-06-09 15:33 UTC (permalink / raw)
  To: zsh-workers

2021-06-09 16:17:30 +0200, Vincent Lefevre:
> On 2021-06-09 16:09:40 +0200, Vincent Lefevre wrote:
> > With zsh 5.8, the builtin echo doesn't check write error.
> 
> And that's also the case for "print", "printf" and maybe others.
[...]

It looks as if EBADF is treated specially on purpose. Errors are
reported for ENOSPC for instance:

$ zsh -c 'echo asd >> mnt/a; echo $?'
zsh:echo:1: write error: no space left on device
1


For print and printf to fail with an error upon EBADF, you can do:

print -u1 -- Sstring
print -u1 -f "$format" -- ...

-- 
Stephane


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 15:33   ` Stephane Chazelas
@ 2021-06-09 15:40     ` Stephane Chazelas
  2021-06-09 15:59       ` Stephane Chazelas
  0 siblings, 1 reply; 10+ messages in thread
From: Stephane Chazelas @ 2021-06-09 15:40 UTC (permalink / raw)
  To: zsh-workers

2021-06-09 16:33:19 +0100, Stephane Chazelas:
> 2021-06-09 16:17:30 +0200, Vincent Lefevre:
> > On 2021-06-09 16:09:40 +0200, Vincent Lefevre wrote:
> > > With zsh 5.8, the builtin echo doesn't check write error.
> > 
> > And that's also the case for "print", "printf" and maybe others.
> [...]
> 
> It looks as if EBADF is treated specially on purpose.
[...]

See: https://www.zsh.org/mla/workers/2002/msg00158.html

A04redirect.ztst still has:

  print foo >&-
0:'>&-' redirection

  (exec >&-
  print foo)
0:'>&-' with attempt to use closed fd
*?\(eval\):2: write error:*

That is "print" with stdout explicitely closed meant to return
success and report no error message, but "print foo" without
explicit closing outputs an error (but exit status still 0).

So it seems to work as intended, though I'm not sure what the
rationale is for that intended behaviour.

-- 
Stephane


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 15:40     ` Stephane Chazelas
@ 2021-06-09 15:59       ` Stephane Chazelas
  0 siblings, 0 replies; 10+ messages in thread
From: Stephane Chazelas @ 2021-06-09 15:59 UTC (permalink / raw)
  To: zsh-workers

2021-06-09 16:40:50 +0100, Stephane Chazelas:
[...]
> A04redirect.ztst still has:
> 
>   print foo >&-
> 0:'>&-' redirection
[...]


That particular one has been there since that test framework was
added: https://www.zsh.org/mla/workers/1999/msg04158.html

>   (exec >&-
>   print foo)
> 0:'>&-' with attempt to use closed fd
> *?\(eval\):2: write error:*
[...]

But there has been some variations as to whether and what error
messages were displayed over the years.

See also:

https://www.zsh.org/mla/workers/2011/msg01272.html

-- 
Stephane


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 14:09 [BUG] builtin echo doesn't check write error Vincent Lefevre
  2021-06-09 14:17 ` Vincent Lefevre
@ 2021-06-09 16:13 ` Bart Schaefer
  2021-06-09 18:16   ` Stephane Chazelas
  1 sibling, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2021-06-09 16:13 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, Jun 9, 2021 at 7:10 AM Vincent Lefevre <vincent@vinc17.net> wrote:
>
> With zsh 5.8, the builtin echo doesn't check write error.

As others have noted, this is not specific to 5.8, it's been that way forever.

My (possibly poor) recollection is that this was made this way in part
for ports to environments that don't have a /dev/null device, but it
might just be this way because 1990s BSD csh behaves this way.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 16:13 ` Bart Schaefer
@ 2021-06-09 18:16   ` Stephane Chazelas
  2021-06-10  8:11     ` Vincent Lefevre
  2021-06-24  8:47     ` Vincent Lefevre
  0 siblings, 2 replies; 10+ messages in thread
From: Stephane Chazelas @ 2021-06-09 18:16 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh hackers list

2021-06-09 09:13:42 -0700, Bart Schaefer:
[...]
> My (possibly poor) recollection is that this was made this way in part
> for ports to environments that don't have a /dev/null device

While that sounds like a very plausible reason for the original
behaviour whereby "print" would not report any write error,
that doesn't really tie up with the current behaviour where
the error is supressed only when print/echo's stdout is
explicitly closed.

Why would one write print foo >&- in the first place, other than
to check whether print reports error or not (and in that regard,
the behaviour is very misleading)

From looking at the history, it looks more like:

1990 (1.0) echo ignores write failures (by design or not).
1999 workers/9129 Peter writes the "print foo >&-" succeeds, no
     error test case, just documenting the actual behaviour of
     print ignoring errors (here using >&- as the easiest way to
     trigger a write error).
2002 workers/16503 Clint adds some error messages upon write
     errors.
2002 workers/16556 we realise it breaks the test case above, so
     Bart removes the error message on EBADF for that test case
     to pass again. The fact that there's still an error message
     in (print)>&- looks like an oversight. The error in that
     case is output by execcmd_exec after print has returned as
     it tries to fflush stdout again,, not bin_print (you'll
     notice the error message doesn't mention "print").
2011 workers/29845 Peter notices the error is displayed in
     (exec >&-; print) and adds a test case for it, but I'm not
     sure he correctly identified why.

It very much looks like an (multiple) accident of
implementation.

POSIX does say that printf/echo should return with a non-zero
exit status upon error, and stderr be used for diagnostix
errors as usual. It's not clear to me if implementations are at
liberty to decide whether a write() error is considered an error
or not.

In any case, it would be useful from an error point of view to
be able to detect when writing fails.

-- 
Stephane


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 18:16   ` Stephane Chazelas
@ 2021-06-10  8:11     ` Vincent Lefevre
  2021-06-24  8:47     ` Vincent Lefevre
  1 sibling, 0 replies; 10+ messages in thread
From: Vincent Lefevre @ 2021-06-10  8:11 UTC (permalink / raw)
  To: zsh-workers; +Cc: Bart Schaefer

On 2021-06-09 19:16:17 +0100, Stephane Chazelas wrote:
> 2011 workers/29845 Peter notices the error is displayed in
>      (exec >&-; print) and adds a test case for it, but I'm not
>      sure he correctly identified why.

I also find this disturbing:

zira% (exec >&-; echo)
zsh: write error: bad file descriptor
zira% (exec >&-; echo >&-)
zira% 

(or with "print" instad of "echo").

> POSIX does say that printf/echo should return with a non-zero
> exit status upon error, and stderr be used for diagnostix
> errors as usual. It's not clear to me if implementations are at
> liberty to decide whether a write() error is considered an error
> or not.

Well, in almost all cases, e.g. when the close is not in the same
command, and when this is not fd 1 (stdout), but other fd, such as
in "echo foo 3>&- >&3", one gets an error. So this is already very
inconsistent.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-09 18:16   ` Stephane Chazelas
  2021-06-10  8:11     ` Vincent Lefevre
@ 2021-06-24  8:47     ` Vincent Lefevre
  2021-06-24  9:07       ` Vincent Lefevre
  1 sibling, 1 reply; 10+ messages in thread
From: Vincent Lefevre @ 2021-06-24  8:47 UTC (permalink / raw)
  To: zsh-workers; +Cc: Bart Schaefer

Since this message from Stephane got truncated in the archives
before a line starting with "From "

  https://www.zsh.org/mla/workers/2021/msg01272.html

I'm including it entirely below, quoted to avoid this issue.
I've just posted a message

  https://www.zsh.org/mla/workers/2021/msg01334.html
  archived messages with "From " get truncated

about this truncation issue.

Note also about the bug in echo/print/etc., this actually seems
to affect *all* builtins. For instance:

zira% (exec >&-; echo)
zsh: write error: bad file descriptor
zira% (exec >&-; echo >&-)
zira% (exec >&-; print)
zsh: write error: bad file descriptor
zira% (exec >&-; print >&-)
zira% (exec >&-; printf "\n")
zsh: write error: bad file descriptor
zira% (exec >&-; printf "\n" >&-)
zira% (exec >&-; pwd)
zsh: write error: bad file descriptor
zira% (exec >&-; pwd >&-)
zira% (exec >&-; history)
zsh: write error: bad file descriptor
zira% (exec >&-; history >&-)
zira% 

On 2021-06-09 19:16:17 +0100, Stephane Chazelas wrote:
> 2021-06-09 09:13:42 -0700, Bart Schaefer:
> [...]
> > My (possibly poor) recollection is that this was made this way in part
> > for ports to environments that don't have a /dev/null device
> 
> While that sounds like a very plausible reason for the original
> behaviour whereby "print" would not report any write error,
> that doesn't really tie up with the current behaviour where
> the error is supressed only when print/echo's stdout is
> explicitly closed.
> 
> Why would one write print foo >&- in the first place, other than
> to check whether print reports error or not (and in that regard,
> the behaviour is very misleading)
> 
> From looking at the history, it looks more like:
> 
> 1990 (1.0) echo ignores write failures (by design or not).
> 1999 workers/9129 Peter writes the "print foo >&-" succeeds, no
>      error test case, just documenting the actual behaviour of
>      print ignoring errors (here using >&- as the easiest way to
>      trigger a write error).
> 2002 workers/16503 Clint adds some error messages upon write
>      errors.
> 2002 workers/16556 we realise it breaks the test case above, so
>      Bart removes the error message on EBADF for that test case
>      to pass again. The fact that there's still an error message
>      in (print)>&- looks like an oversight. The error in that
>      case is output by execcmd_exec after print has returned as
>      it tries to fflush stdout again,, not bin_print (you'll
>      notice the error message doesn't mention "print").
> 2011 workers/29845 Peter notices the error is displayed in
>      (exec >&-; print) and adds a test case for it, but I'm not
>      sure he correctly identified why.
> 
> It very much looks like an (multiple) accident of
> implementation.
> 
> POSIX does say that printf/echo should return with a non-zero
> exit status upon error, and stderr be used for diagnostix
> errors as usual. It's not clear to me if implementations are at
> liberty to decide whether a write() error is considered an error
> or not.
> 
> In any case, it would be useful from an error point of view to
> be able to detect when writing fails.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] builtin echo doesn't check write error
  2021-06-24  8:47     ` Vincent Lefevre
@ 2021-06-24  9:07       ` Vincent Lefevre
  0 siblings, 0 replies; 10+ messages in thread
From: Vincent Lefevre @ 2021-06-24  9:07 UTC (permalink / raw)
  To: zsh-workers; +Cc: Bart Schaefer

On 2021-06-24 10:47:39 +0200, Vincent Lefevre wrote:
> Note also about the bug in echo/print/etc., this actually seems
> to affect *all* builtins. For instance:
> 
> zira% (exec >&-; echo)
> zsh: write error: bad file descriptor
> zira% (exec >&-; echo >&-)
> zira% (exec >&-; print)
> zsh: write error: bad file descriptor
> zira% (exec >&-; print >&-)
> zira% (exec >&-; printf "\n")
> zsh: write error: bad file descriptor
> zira% (exec >&-; printf "\n" >&-)
> zira% (exec >&-; pwd)
> zsh: write error: bad file descriptor
> zira% (exec >&-; pwd >&-)
> zira% (exec >&-; history)
> zsh: write error: bad file descriptor
> zira% (exec >&-; history >&-)
> zira% 

That was about the error messages. But in all cases, the exit status
is 0:

zira% (exec >&-; echo; echo $? >&2)
zsh: write error: bad file descriptor
0
zira% (exec >&-; echo >&-; echo $? >&2)
0
zira% (exec >&-; print; echo $? >&2)
zsh: write error: bad file descriptor
0
zira% (exec >&-; print >&-; echo $? >&2)
0
zira% (exec >&-; pwd; echo $? >&2)
zsh: write error: bad file descriptor
0
zira% (exec >&-; pwd >&-; echo $? >&2)
0
zira% (exec >&-; history; echo $? >&2)
zsh: write error: bad file descriptor
0
zira% (exec >&-; history >&-; echo $? >&2)
0

The other shells differ, but for ksh, posh and busybox sh, in an
inconsistent way (I assume that this is a bug in these shells):

$ zsh -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
zsh:1: write error: bad file descriptor
0
zsh:1: write error: bad file descriptor
0

$ sh -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
sh: 1: echo: echo: I/O error
1
sh: 1: pwd: pwd: I/O error
1

$ bash -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
bash: line 1: echo: write error: Bad file descriptor
1
bash: line 1: pwd: write error: Bad file descriptor
1

$ yash -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
echo: cannot print to the standard output: Bad file descriptor
1
pwd: cannot print to the standard output: Bad file descriptor
1

$ busybox sh -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
sh: write error: Bad file descriptor
1
1

(for busybox sh, the inconsistency is on the presence of the
error message).

$ ksh93 -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
1
0

$ mksh -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
1
0

$ posh -c 'exec >&-; echo; echo $? >&2; pwd; echo $? >&2'
1
0

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-06-24  9:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-09 14:09 [BUG] builtin echo doesn't check write error Vincent Lefevre
2021-06-09 14:17 ` Vincent Lefevre
2021-06-09 15:33   ` Stephane Chazelas
2021-06-09 15:40     ` Stephane Chazelas
2021-06-09 15:59       ` Stephane Chazelas
2021-06-09 16:13 ` Bart Schaefer
2021-06-09 18:16   ` Stephane Chazelas
2021-06-10  8:11     ` Vincent Lefevre
2021-06-24  8:47     ` Vincent Lefevre
2021-06-24  9:07       ` Vincent Lefevre

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).