On 2021-06-30 00:46:00 +0000, mirabilos via austin-group-l at The Open Group
wrote:
> Using the same shorthand, I changed mksh tonight to do pretty much
> what you described, in a second patch:
>
> @@ pseudo @@
> int
> call_builtin(func_t builtinfunc, int argc, char *argv[])
> {
> int exitstatus;
>
> stdout = fdopen(1, "w");
> exitstatus = (*builtinfunc)(argc, argv, environ);
> fflush(stdout);
> + if (ferror(stdout)) {
> + fprintf(stderr, "%s: write: %s\n", argv[0], strerror(errno));
> + if (exitstatus == 0)
> + exitstatus = 1;
> + }
> return (exitstatus);
> }
>
> This handles pwd and (if compiled in) printf; I also added the same
> error message to the echo/print builtin for where it detects errors
> as it uses the write(2) syscall, not the stdio replacement, internally.
Thanks, I think that this is OK.
> We’ll see whether that breaks anything. Incidentally, if true encounters
> an error on stdout during operation now, it can return false — except it
> never accesses stdout, thus this cannot happen.
>
> Vincent will probably see whether this solves his problem; he’s got to
> notify me if there are any other builtins to take care of.
There are "ulimit", "alias" and "type". But I don't know whether they
are also handled by call_builtin...
> Ugh. This is a “magic fix”… I don’t like this, but it’ll do, I think.
> If the builtin encountered other errors and already exited nōn-zero,
> that will be that, but otherwise, it runs on until the buffers are
> flushed as write errors may not be recognised before that. If that’s
> not enough, I don’t know. In that case I’d question the standard harder.
It seems that Coreutils has the same logic: the check is done only
at the end (except that it closes the stream instead of just flushing
it... which is OK because these are external commands).
--
Vincent Lefèvre <[email protected]> - 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)