Description
echo
may fail to write to stdout. When it does, it causes stdout
to be put into an error state (such that c_ferror(stdout)
is non-zero) but does not raise any exception. Then a future, possibly far-distant attempt to stdout.write
will fail with an exception. Having the error reported so far from when the failure happened is difficult to debug.
Example
I'm having trouble duplicating the setup that caused this (it involves spawning several subprocesses, some of which set stdout to nonblocking). I was seeing errno 35, resource busy.
Hopefully you can see that errors are ignored by looking at the code for echo. Lines 801, 803 and 804 are where failed writes might happen (note the discard
on each line).
Lines 797 to 804 in d15f63a
Suppose the following happens:
- Line 801
c_fwrite(...)
fails to write. - It sets
errno = 35
- It also sets the stdout error flag such that
c_ferror(stdout) == 1
c_ferror
is not checked withinecho
- More code runs, possibly code that causes
errno
to be set to something else. In my case it waserrno = 2
. - Finally, a call to
stdout.write(...)
is attempted - Because
stdout.write
checksc_ferror(stdout)
, it will see there's a problem and report the error using the now-invaliderrno == 2
.
Possible solutions
I don't know what the solution is. I can understand why it's desirable to have echo
rarely raise exceptions, especially as a debugging tool. I'm just now hesitant to use echo
for anything but debugging.
- Make
echo
raise an exception ifc_fwrite
fails - Make
echo
write a warning to stderr ifc_fwrite
fails (but don't raise an exception) - Add a warning to the
echo
docs, indicating that failures are swallowed - Possibly introduce an alternate version of
echo
(maybeEcho
?) if it's desirable to keepecho
the way it is
Additional Information
The reason my echo
was failing is specific to macOS, but I believe this issue applies to any POSIX system.
$ nim -v
Nim Compiler Version 1.4.0 [MacOSX: amd64]
Compiled at 2020-10-16
Copyright (c) 2006-2020 by Andreas Rumpf
git hash: 018ae963ba83934a68d815c3c1c44c06e8ec6178
active boot switches: -d:release