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

Reply via email to