Date: Thu, 14 Nov 2024 10:19:00 -0700 From: Paul Eggert <eggert@cs.ucla.edu> Message-ID: <5ee435ad-7d6a-4e11-82a2-97931bd56b7a@cs.ucla.edu> | Here's a different example to illustrate the point. If an application | calls open(".", -1) where the "-1" contains bits that aren't valid for | oflag, EINVAL is a "may fail" error so POSIX does not require 'open' to | fail with EINVAL. An implementation is allowed to use the oflag bits it | understands while ignoring the flags it doesn't. Yes. | In other words, for a "may fail" error, the implementation is allowed to | not fail, and to support an extension instead. Provided that when it doesn't fail it does everything it is required to do, as it is specified, if the application doesn't actually make use of some not standard extension (such as by setting a non-standard bit in the flags for open, as one example). Once the application starts indulging in non-standard behaviour the implementation has much more latitude, the standard only applies as much as the implementation chooses to make it apply. | Different people may disagree on what extensions are reasonable; | POSIX itself doesn't take a position on that. Sure, and that's exactly the position wrt things like %? in strftime's format string. You think one thing, I think a different thing, neither of us is right or wrong as judged by the standard (but in real terms of course, I am right!;) But unless the user actually presents input in a form that is different than the standard says is defined, the implementation is required to make output in the form (or one of the forms) that the standard says it can, otherwise there's no way a portable application can predict what is going to happen. When it was written it might never have heard of your implementation, or its differences, it obeys the standard, you should return what the standard says you should (that or stop pretending that your implementation in any way is standards conforming.) When the user uses a local documented extension, then the implementation should do what it documents for that extension to do. If the user does something defined to produce unspecified results, or worse, undefined behaviour, then you get to do what you like. So, for example, with strftime, if the user passes a NULL pointer instead of the struct tm *, then you can largely do whatever the hell you please. (You could make that a shorthand for using the current time with the format string for example, or you could dump core with a segmentation violation). But you don't get to not produce a decimal representation of seconds since the epoch in place of %s (with no non-standard flags, or widths, etc) just because the result doesn't fit in a time_t. You either generate the correct result anyway, or return 0 and EOVERFLOW. No other options there. kre