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