Date: Mon, 5 Jul 2021 10:51:04 +0100 From: "Geoff Clare via austin-group-l at The Open Group" <austin-group-l@opengroup.org> Message-ID: <20210705095104.GA23845@localhost>
| As I said before, there is nothing in the standard that requires pwd | to be written in C. No issue with that, | Nor is there anything that requires it to use the | interfaces described in XSH (or their equivalent in another language). Same there. But surely there is nothing that prohibits either of those is there? It is permitted to write pwd in C, and permitted to use the interfaces in XSH, is it not? And if using the XSH interfaces is permitted, then, when that option is taken: | Nothing in XSH is relevant to XCU cannot be correct, can it? That is, XCU would be broken if it were impossible to achieve using the XSH interfaces (except in those rare cases where something is simply omitted from XSH because it isn't suitable to standardise, (eg: ioctl) but is needed, which is not the case here). | unless there is a reference to it | (direct or indirect, e.g. via a definition) from normative text in XCU. Which one could say applies to "standard output", as, as was pointed out, that's better defined in XSH than anywhere else. | The above definition of "file descriptor" (from XCU 2.7 Redirection) is | of course the one I was using when I said "file descriptor 1". As the brief exchange with Harald concluded, this is really irrelevant. For the current purpose, no-one cares what the file descriptor value is, nor whether there even actually is one (in the traditional sense). The output goes to standard output - the question isn't where that is (or not currently, all versions of pwd I have ever seen send the output to the correct place) but what it means when that output fails for some reason. | If my argument is dependent on pwd being executed from a shell instead | of from something else, I don't think that weakens my argument one jot. | No implementor in their right mind is going to have (a non-shell-builtin) | pwd detect whether it is executed from a shell and behave differently in | that case. I have no idea why that needed mentioning, but no, no-one is suggesting that it makes a difference (to the requirements) whether the pwd in question is a shell built-in or a standalone utility, nor where it is executed from. | > Implementor of what? | Of pwd. Who has no idea whether or not buffering is being used. Or at least should not, that's an implementation detail of a lower layer. | No, I'm saying it is the pwd implementor's responsibility, if they choose | to make use of some kind of buffering facility, Again, that implementor isn't deciding to do that, that was decided by someone else. Like the standard, which requires it, in certain circumstances (when the XSH interfaces are being used, which I hope you will have agreed, is permitted). | to ensure that any | buffered data is successfully flushed to fd 1 before choosing whether to | exit with a status that indicates successful completion. Now, if we're talking just about pwd for a minute (and not the general issue for standard utilities in general, which I had mostly been concentrating upon), there's another issue that we need to deal with. pwd is explicitly prohibited from writing anything to standard output and exiting with a non-zero status - it is only allowed to write at all if the exit status will be 0 (aka, if no error has occurred). (Once again,line numbers from 202x-D2) 104925 CONSEQUENCES OF ERRORS 104926 If an error is detected, output shall not be written to standard output, a diagnostic message shall 104927 be written to standard error, and the exit status is not zero. The RATIONALE (lines 104935...) explains more about why, and (the relevant part) ends with: 104940 therefore, the CONSEQUENCES OF ERRORS section specifically disallows any 104941 partial output being written to standard output. It is hard to see how one can treat a write error on the standard output from pwd as an "error [that] is detected", when the error is required to be detected (as not having happened) before the write is permitted to be performed. As soon as we do (any form of) write system call directed at standard output (or file descriptor 1 if you prefer), it is possible that there will be output to standard output - once that happens, there must not be an error. Now this only applies to pwd, as a special case (or only to pwd that I'm aware of) so isn't useful as an argument about the general case, but for pwd, it seems to me more like a fairly explicit requirement that anything that goes wrong there, cannot be reported (or if you like, there cannot be output on both standard output and standard error from pwd, and we all agree, that if there is standard error output, the exit status cannot be 0, and vice versa - that part of the standard is clear). | That's a separate requirement that arises if the exit status indicates | an error occurred. My main argument is about how pwd decides what its | exit status should be. And it appears that it must make that decision before writing to standard output, and unless it can somehow guarantee that the write can only totally succeed, or totally fail (no idea how it would do that) that means not attempting to write before deciding upon the exit status. | Yes, every implementation of pwd must ensure that it only exits with | status 0 if it has successfully written to "standard output" (fd 1) in | order to conform to the standard. That wasn't what I asked. You're telling me what you believe is required. I asked what the actual implementations do. And particularly the standalone ones. And leaving side the "consequences of errors" argument above for a minute, I still don't see anywhere where the standard actually explicitly says what you believe it says - and you have failed, despite my asking for it repeatedly, to quote any text from the standard to support your position. It seems more likely to me that your argument is more "it just must be" which isn't something I ever accept - that is, you cannot believe that anything else is possible, even though there is nothing which actually says that it must be that way. | We are not discussing C applications, which are written to meet their | author's requirements, but implementations of POSIX standard utilities, | which must be written to meet the requirements stated in the standard. Of course. | A shell application whose author has high requirements for error detection | must be able to rely on standard utilities reporting errors so that it | can detect and handle those errors. That would be nice - but what in the standard actually promises that to be true? | If the primary purpose of a utility is to write some data to standard | output, it really must exit with a status that indicates an error | occurred if it failed to write the data to fd 1. That sounds like a goal, perhaps even a worthy one, but I don't see it as a requirement. Even that is leaving aside how one decides what is the "primary purpose" of most utilities. | Any system which has implementations of those utilities that do not | do this is a poor quality implementation, That might be true. | does not conform to POSIX, but that I have seen no evidence to support. | and its users would be well advised to switch to an implementation | that handles write errors properly. Perhaps - if they can find one. But in practice, the users don't care, as write errors to standard output, other than those deliberately induced for testing purposes, as in the examples which started this whole thing, simply don't happen in practice unless the system is failing in ways that make the exit status of info reporting commands (ones that do nothing important beyond writing to standard output) is almost certainly going to be irrelevant when compared to other things which will also be failing. eg: if your "pwd > file" fails because the filesystem is full, then it is very likely that all kinds of other things are also failing, and the failed output from pwd will be the least of anyone's concerns. And even here, the standard seems to make it clear, that while sub-optimal perhaps, testing whether the standard output from pwd is empty (which cannot happen if a directory name can be found) is an alternative way to testing the error status (though that one, as above, is something of a special case). kre