On Sun, Aug 19, 2018 at 02:32:49PM +0200, Carsten Kunze wrote: > Many system calls (e.g. close(2), > http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html) > return 0 on success and -1 on error and set errno. > > My understanding is that errno is only reliably set when the system > call returns -1, not for < -1 nor for > 0, so I do only check the > error condition with "if (close(fd) == -1)" ignoring all other values. > Some are testing for "< 0" but would it not be consequent for them to > check for "!= 0"? So when can I rely on errno to be set, for -1, for > "< 0" or for "!= 0"?
These kinds of system calls only ever return 0 or -1, so it doesn't much matter which way you do the test. It depends which way you read the implicit gap in the specification; it explicitly enumerates all the possible return values, but what would any other return value mean if it could happen? Writing "== -1" implies a reading that any other value would indicate success; writing "!= 0" implies a reading that any other value would indicate an error; writing "< 0" implies a reading that it depends on the sign of the hypothetical not-zero-or-minus-one return value. You could perhaps argue that you ought to explicitly test for some value other than 0 or -1 and raise some kind of generic error that doesn't make use of errno in that case; but in practice people don't want to scatter all this untestable error handling code all over their programs for a condition that's already specified not to happen, and possibly printing a stale errno value in a hypothetical situation is a good trade-off for writing less code (and thus, statistically, fewer bugs). The "< 0" idiom probably arises from system calls such as read(2), which return either zero for end-of-file, a positive value for the number of bytes read on success, or -1 on error. In that case "< 0" covers all the return values that aren't defined to be successful. As a result, my habit is to use that form for everything that returns -1 on error unless I have a good reason not to (e.g. if -2 were defined to mean something else then I'd explicitly test for -1). In short, you're asking for a specification for unspecified behaviour, and you aren't going to get one unless the POSIX committee chooses to clarify it. But POSIX also says that the other return values you're concerned about simply don't happen, so I'd suggest just picking whatever syntax you prefer for testing for the cases that do happen and moving on. -- Colin Watson [cjwat...@debian.org]