Date:        Tue, 29 Jun 2021 09:49:40 +0100
    From:        "Geoff Clare via austin-group-l at The Open Group" 
<austin-group-l@opengroup.org>
    Message-ID:  <20210629084940.GA8391@localhost>

  | You are wrong when you say it "printed it".  It tried to print it but
  | failed to do so.

But how do you actually know?  In the full filesystem case you might,
but how do you really tell the difference between

        { sleep 1; pwd; } | :
and
        pwd | sleep 1

In neither case does the output get through the pipe.  If the sleep
wasn't there, and we just had

        pwd | :

then sometimes we might get one behaviour, and other times the other.

I assume you're not suggesting that it is the responsibility of the
application (pwd in this case) to verify that data sent to a pipe gets
received by some process at the other end?

And if not that, then what's the point - sometimes the output is lost,
and there's no error message, or non-zero exit status.   Other times you
apparently demand that there is.   Not very consistent is it?

  | > You might prefer that it "fflush(stdout); if (ferror(stdout)) ..." but
  | > there's nothing explicit in the standard that says that it has to do that.
  |
  | There's nothing in the standard that requires pwd to be written in C,
  | so any argument based on C functions has no merit.

There was no argument based upon C functions - the use of them was
just a shorthand to make a point.

pwd does write to stdout - it does (the equivalent of, in whatever
language it is written) printf("%s\n", directory);

Having done that it exits.   It is finished.

exit() as part of its processing flushes the stdio buffers.  Including stdout.
That's when the actual write from the process happens - but it is far too
late then for pwd to do anything about it, exit() never returns, no pwd
supplied code ever runs again (unless it set an atexit() - but it has no
need for that, and doesn't).   I see nothing in the standard allowing exit()
to terminate the process with any exit status other than the one handed to
it, do you?   What's more, it would be extremely unlikely for exit() to be
writing messages to stderr, which as you mentioned in a previous message is
a requirement if the exit code is not 0 (for most utilities).

Which returns to my point quoted above - I see nothing in the standard
that requires applications to manually flush file descriptors, and check
for errors, before they exit.  If there is something somewhere which
requires this, please point it out, and I'll file a defect report to
have that fixed.

  | The standard requires that pwd writes to stdout.

The question is just what that means in terms of the interfaces available.
pwd called printf, printf reported no error.   Stdout has been written to
as far as I'm concerned when that has happened.

  | It applies to every utility for which writing to stdout is something
  | the utility needs to do in order to be considered to have completed
  | successfully.

That's never going to fly, it is no surprise that Solaris didn't bother
to implement that (even if you can show where the standard actually
requires it).

  | No they wouldn't.  The only reason to set SIGPIPE to be ignored is
  | because you want EPIPE error conditions to be diagnosed instead of
  | causing the process to terminate. So fixing these bugs is exactly what
  | users want.

Two problems with that - first, why should there be a distinction between
what happens (as visible to the outside world) when SIGPIPE is ignored and
when it isn't?   In neither case does any output from pwd move through the
pipe, so you'd assume that in either both cases, or neither, should an error
message be written, and a non-zero exit status issued.

In the SIGPIPE case the exit status is (kind of) non-zero (kind of, because
it isn't, I assume, the kind of non-zero exit status that requires a disgnostic
message to be written to stderr, is it?) - but it is a process to
the left of a pipe, so aside from pipefail (which doesn't exist in any
published standard) that exit status gets ignored - shells don't even report
the process as having terminated abnormally, exiting due to SIGPIPE is
just a normal exit.

And second, don't go assuming "the only reason" - you have no idea why SIGPIPE
might have been ignored.   And EPIPE is just one of the errors that might
occur, but not be detected until exit() is running, the others have no SIGxxx
to fall back on as the "normal way of terminating where no message is
required".

  | >   | You are talking about pre-POSIX tradition.  The rules in POSIX.2 
should have
  | >   | put an end to that ancient dodgy behaviour when systems were updated 
to
  | >   | conform to POSIX.
  | > 
  | > Do you have some evidence that they did?
  |
  | I said "should have".  Obviously that didn't happen, at least for
  | some systems.

Do you have some evidence it happened for any?   For all (relevant)
utilities, not just pwd of course.

This is an example of why standards bodies (which in general are representative
of almost nothing) MUST NOT ever attempt to legislate behaviour.

The objective is to document the behaviour that has been agreed (as 
demonstrated by the implementations) so that later implementations know
what is required to offer the same service, and users know what to expect
when they use such a service (whatever it is, not just POSIX).

If some kind of mandatory change is required (for which the reasons usually
need to be very good) then the authority to do that needs to come from some
body that has the power (and the accountability) to actually make such a
decision.

Otherwise the response will just be (in this case) "screw POSIX", which
benefits no-one really.

No matter how certain that you are (in your own mind) that the implementations
are all (or mostly) wrong, and the world would be a better place if only
they did this particular thing the way you believe is right, rather than
the way they do it (regardless of why they do it the way they do), and then
make the standard say that they must do it your way to conform (to something
which would in that case, demonstrably not actually be a "standard" regardless
of what is written in some document).

If you are certain that your way is the right way, the onus is upon you to
convince the implementations of the merit of your argument, and have them
change the way they work.   Once you've convinced the implementors to fix
things, and that's actually been done (without issues causing the changes
to be reverted) then you can start to consider putting it in the standard,
as at that time, it will be standard behaviour.

kre

Reply via email to