[tz] Invalid tm handling in %s pattern in strftime

Paul Eggert eggert at cs.ucla.edu
Mon Jun 6 21:41:15 UTC 2022

On 6/6/22 13:25, enh wrote:

> int saved_errno = errno;
> errno = 0;
> if (mktime() == -1 && errno != 0) {

That isn't portable, because mktime can set errno and then successfully 
return -1, which means the caller can't rely on errno to decide whether 
mktime succeeded. I'm pretty sure this sort of behavior can happen on 
popular platforms.

This sort of thing isn't a problem with syscalls like 'open', where the 
caller can portably distinguish success from failure by testing whether 
the return value is negative. Unfortunately, it is a problem with 
'mktime', where the caller cannot portably distinguish success from 
failure. Even main-branch TZDB strftime isn't 100% reliable here on all 
platforms; it's merely more reliable than inspecting errno would be.

> (the specific issue on 32-bit Android [where time_t is 32-bit] is that this
> ends up using mktime64() which takes a *const* struct tm for historical
> reasons.

Does Android mktime64() reliably leave errno alone when it succeeds? If 
so, perhaps we could add a compile-time macro like 
"MKTIME_SETS_ERRNO_ONLY_ON_FAILURE" that would let strftime use code 
like what's quoted above.

More information about the tz mailing list