<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 6, 2022 at 2:41 PM Paul Eggert <<a href="mailto:eggert@cs.ucla.edu">eggert@cs.ucla.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 6/6/22 13:25, enh wrote:<br>
<br>
> int saved_errno = errno;<br>
> errno = 0;<br>
> if (mktime() == -1 && errno != 0) {<br>
<br>
That isn't portable, because mktime can set errno and then successfully <br>
return -1, which means the caller can't rely on errno to decide whether <br>
mktime succeeded. I'm pretty sure this sort of behavior can happen on <br>
popular platforms.<br></blockquote><div><br></div><div>we certainly try to avoid that mistake on Android, but, yeah, i've definitely seen bugs like that.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
This sort of thing isn't a problem with syscalls like 'open', where the <br>
caller can portably distinguish success from failure by testing whether <br>
the return value is negative. Unfortunately, it is a problem with <br>
'mktime', where the caller cannot portably distinguish success from <br>
failure. Even main-branch TZDB strftime isn't 100% reliable here on all <br>
platforms; it's merely more reliable than inspecting errno would be.<br>
<br>
> (the specific issue on 32-bit Android [where time_t is 32-bit] is that this<br>
> ends up using mktime64() which takes a *const* struct tm for historical<br>
> reasons.<br>
<br>
Does Android mktime64() reliably leave errno alone when it succeeds? If <br>
so, perhaps we could add a compile-time macro like <br>
"MKTIME_SETS_ERRNO_ONLY_ON_FAILURE" that would let strftime use code <br>
like what's quoted above.<br></blockquote><div><br></div><div>it's your mktime(), so you tell me :-) but if you meant "does the extra cruft that _isn't_ tzcode mktime() touch errno?", no, it doesn't touch errno directly, nor does it call anything other than mktime() that might set errno. (or if you actually meant "look how hard it is to prove such things", yeah :-( in bionic we use RAII to make functions "errno clean" all the time to avoid this kind of problem because it's too hard to reason about...)</div></div></div>