Standards state a contract or implication: *if* you, the developer follow
_these_ rules, *then* the standardized item will follow _these_other_
rules (if compliant). If you violate the implication, then the standard
no longer applies and you have lost the guarantees of the standard.
_If_ you build an electrical plug with prongs of a certain composition,
shape, size, and distance apart and nothing projecting out of a described
volume, _then_ it will fit into this standard plug with sufficient contact
to carry a particular current and resist physical force to move/remove it
of some size. If you go make the prongs of the wrong shape or size, then
the rules are off and it might fail in many different ways: wrong shape or
size? Might not make contact enough to carry the standard current, or
might not resist being removed sufficiently. Too close together? Might
not fit at all or might break when inserted. etc.
In the case of POSIX, there's a long intro which (tries to) set out the
rules that you have to follow. Some of these are effectively compile-time
restrictions (e.g., you MUST NOT define macros, variables, or functions
with various names) and others which are effectively run-time restrictions
(e.g., for many functions, particular arguments MUST be valid C strings).
If you go outside those then, again, the rules are off. If you put
"#define struct union" before "#include <time.h>", or pass a NULL pointer
as the first argument to gettimeofday(2) then you've violated the
application side of the POSIX contract and the system is not required to
do anything in particular.
Yes, standards can be written to require graceful degradation, effectively
saying "if you don't follow _all_ the rules but did follow at least this
shorter list, then the standardized item must still keep up part of its
side." This is common in security/safety standards. In POSIX this shows
up in some interfaces being required to return EINVAL or similar in
certain cases...but POSIX DOES NOT specify every possible error case and
explicitly leaves many such cases undefined, leaving it to applications to
do whatever meets their goal, be it speed, simplicity, debugability, etc.
So, background having been set:
On Sat, 2 Dec 2017, Scott Cheloha wrote:
> TL;DR: POSIX.1-2008 says gettimeofday(2) can't return anything but 0,
> but we return -1 on invalid input. We claim that our gettimeofday(2)
> conforms to POSIX.1-2008. Is something off here?
Nope. What POSIX says is that *if you follow the POSIX rules*, then
gettimeofday() will only return zero. It's perfectly acceptable for a
particular implementation to document its own behavior above and beyond
what the standard requires. We happen to document that if you pass a
bogus pointer to gettimeofday(2), something not permitted by POSIX, then
it'll fail with error EFAULT.
EFAULT is kinda interesting in that POSIX documents its existence but does
not require it to ever be returned. Here's what POSIX says normatively:
[EFAULT]
Bad address. The system detected an invalid address in attempting to
use an argument of a call. The reliable detection of this error
cannot be guaranteed, and when not detected may result in the
generation of a signal, indicating an address volation, which is
sent to the process.
_Informatively_ (no compliance requirement!) it says this in the
rationale:
POSIX.1 requires (in the ERRORS sections of function descriptions)
certain error values to be set in certain conditions because many
existing applications depend on them. Some error numbers, such
as [EFAULT], are entirely implementation-defined and are noted
as such in their description in the ERRORS section. This section
otherwise allows wide latitude to the implementation in handling
error reporting.
...
[EFAULT] Most historical implementations do not catch an error
and set errno when an invalid address is given to the
functions wait(), time(), or times(). Some implementations
cannot reliably detect an invalid address. And most
systems that detect invalid addresses will do so only
for a system call, not for a library routine.
...
> Does this make our implementation non-conforming and does something
> in the manpage need to change?
>
> I do note that gettimeofday(2) predates [3] POSIX (and me :p), so
> perhaps this is just an ancient compromise between BSD and the
> standards committees?
It's not so much a compromise as the standards committee making a decision
about where to draw the line of covered-vs-not. In theory, a standard
could be written that exactly described all the error cases...but it would
take forever to write and resolve the ambiguities in the description and
no implementation would ever comply with all the details. And what would
the benefit be? We don't _want_ application authors to use those corners!
So, since it doesn't seem to be useful to specify the behavior of
gettimeofday() when you pass NULL, POSIX says "nope, out of bounds".
Philip Guenther