I think it would be entirely reasonable to demand that POSIX resolve this. But I've always come down on the side of proscriptive standards rather than merely descriptive standards.
From one standpoint, I can see that would even be the desired behavior, because it gives the app the opportunity to deal with the error in some meaningful way, like to finish flushing. But since everybody else has long since decided that if you care you flush then close, being different is just aggravating. Although it sounds like flush then close will work everywhere.
If every implementation returned success when it had closed the descriptor and EINTR only when it hadn't, this would be easy.
For HP-UX, it's "close it again".
For AIX, it's apparently "everything is fine, don't close it again". Linux, too.
That could be OK, even when undocumented, IF we had a way to discover what had occurred. But we don't. close() isn't broken because it can behave in multiple ways that can't be predicted in advance, it's broken because there's no safe way to proceed.
And by the way, we do know something about the target when we're writing POSIX-compliant code. We know the target is POSIX-compliant. That's the whole point of POSIX.
I just have a difficult time with the rather strong terminology that the definition is broken: the definition is consistent, reasonable, and even somewhat workable... it is just not terribly useful, satisfying, or comforting; if anything, I'd say "incomplete".
(Although, given that it chose "unspecified" rather than "implementation-defined", one has to wonder whether some existing system actually did something horrific in this case and left non-deterministic behavior. I guess there could always be a constant for "you're screwed", though. ;P)
Yes, it sucks to resort to conditional compilation around "close", but it's already been explained why it's necessary. POSIX was not created in a vacuum as a theoretically ideal OS specification.
After continuing to research this issue (as I love looking at this kind of stuff: understanding more about the history and complexity of implementations excites me), I finally hit jackpot.
http://programming.itags.org/unix-linux-programming/79468/
HP-UX 11.22: """[EINTR] An attempt to close a slow device or connection or file with pending aio requests was interrupted by a signal. The file descriptor still points to an open device or connection or file."""
AIX 5.3: """If the close subroutine is interrupted by a signal that is caught, it returns a value of -1, the errno global variable is set to EINTR and the state of the FileDescriptor parameter is closed."""
So, here we have two Unix implementations--both of which predated POSIX--that have incompatible definitions of close(). I do not feel it is reasonable to demand POSIX solve this, and sure enough: it didn't.
Now, maybe that makes POSIX "useless" (if what you care about is being able to write code without knowing anything about the target), but I don't think it is fair to claim that the definition of close is "broken".
In distinction, it clearly states that the behavior is "unspecified", which is a bothersome yet practically acceptable tradeoff. Some things in life are simply unspecified. :(