4 ms·
Looks like Plan 9 and FreeBSD are the only ones to correctly handle write errors. The others just silently ignore them. I guess the moral is "Don't rely on echo
by jws 12y ago
Looks like Plan 9 and FreeBSD are the only ones to correctly handle write errors. The others just silently ignore them. I guess the moral is "Don't rely on echo to save important data."
Also, the comment…
/* This utility may NOT do getopt(3) option parsing. */
… which appears in two of them certainly cries out for an explanation. Was it true in NetBSD? Is it still true? Will people call us names if we do?
Update: bash does not handle errors. zsh might, it checks the result of fclose() or if stdout, fflush(). I'm not sure that is sufficient after ignoring all the fwrite() and fputc() errors. Plus it's in an 850 line function and my monitor is only 20" tall, so I'm not following all of it.
Update2: asveikau is correct. The only ones to attempt error handling miss short reads. FreeBSD also misses EAGAIN/EINTR handling. Plan9 doesn't need that, but its man page explicitly states that short writes should be considered errors by the caller.
I guess it's official. The unix read/write system calls are too complicated to be used by experts in the operating system. (I've rather thought that for some time now.)
- asveikau 12y ago> Looks like Plan 9 and FreeBSD are the only ones to correctly handle write errors. Both only check for negative return codes. If stdout were piped/redirected to something where write(2) may return a short byte count (let's say a socket) neither of them will detect it. > /* This utility may NOT do getopt(3) option parsing. */ I noticed this too. My guess, totally not backed up by anything but by instinct, is getopt(3) tried to do too much which doesn't make sense for echo. For example if it tried to parse "echo -foobar" as anything other than "you spit out the string '-foobar'" I could see it being problematic.
- johnny22 12y agoas mentioned above, it's a POSIX thing.
- tedunangst 12y agohttp://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html http://pubs.opengroup.org/onlinepubs/009604599/utilities/ech...
- jws 12y agoSo POSIX allows no options to the command, but if the first operand is "-n" then the result is undefined. that compromise between the BSD and SysV behavior just have taken some time to work out.
- anon1385 12y agoThere was actually a project for the GNU Coreutils to make sure that write errors were being reported[1]. It looks like echo is using the "atexit (close_stdout);" method described in that talk to close the stream and detect errors. You can see what close_stdout actually does here: http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/closeout.c http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/closeou... Arguably GNU echo is the only one to actually get this correct. Which is kinda amusing given how the comments on github are all about how ugly and bloated it is and how elegant the Plan9 and UnixV ones are. The talk is worth a watch if you care about these things. It kind of re-enforces your point about read/write being to complicated to use correctly. Meyering found these kinds of bugs in lots of other programs like perl, python, rsync and emacs. [1] http://www.irill.org/events/ghm-gnu-hackers-meeting/videos/jim-meyering-goodbye-world-the-perils-of-relying-on-output-streams-in-c http://www.irill.org/events/ghm-gnu-hackers-meeting/videos/j... (slides: http://www.gnu.org/ghm/2011/paris/slides/jim-meyering-goodbye-world.pdf http://www.gnu.org/ghm/2011/paris/slides/jim-meyering-goodby... )