<br><div class="gmail_quote">On Jan 10, 2008 10:00 PM, Russ Allbery <<a href="mailto:rra@stanford.edu">rra@stanford.edu</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="Ih2E3d">"Jonathan Leffler" <<a href="mailto:jonathan.leffler@gmail.com">jonathan.leffler@gmail.com</a>> writes:<br><br>> Actually, the subject pretty much says it all.<br>> In tzcode2007k (also in 2007h), the code in 
localtime.c is:<br>><br>>[...]<br>><br>> I can't immediately see a justification for the asymmetry in the POSIX<br>> specification of these functions, but I could be missing something.<br><br></div>My guess is it's because tzset() sets global variables and hence isn't
<br>threadsafe.<font color="#888888"></font></blockquote><div><br>I wondered about that...The POSIX specification says:<br><p style="margin-left: 40px;">Unlike <i>localtime</i>(), the reentrant version is not required to set 
<i>tzname</i>. <img src="http://www.opengroup.org/onlinepubs/009695399/images/opt-end.gif" alt="[Option End]" border="0"></p>

<p style="margin-left: 40px;"><sup>[<a href="javascript:open_code('TSF')">TSF</a>]</sup> <img src="http://www.opengroup.org/onlinepubs/009695399/images/opt-start.gif" alt="[Option Start]" border="0">
If the reentrant version does not set <i>tzname</i>, it shall not set <i>daylight</i> and shall not set <i>timezone</i>. <img src="http://www.opengroup.org/onlinepubs/009695399/images/opt-end.gif" alt="[Option End]" border="0">
</p>I interpret that as meaning "it might not call tzset() - but if it does call tzset(), tzset() shall do the whole job, not just part of the job".<br><br>However, consider the following simple test program ("Black JL:" is my Unix prompt on machine 'black'):
<br><br>Black JL: cat chk-localtime_r.c<br>#include <time.h><br>#include <stdio.h><br><br>int main(void)<br>{<br>    struct tm tp;<br>    time_t now = time(0);<br>    struct tm *tx = localtime_r(&now, &tp);
<br>    char buffer[30];<br>    if (tx != 0)<br>    {<br>        char *s = asctime_r(&tp, buffer);<br>        printf("%ld = %s", (long)now, s);<br>    }<br>    return(0);<br>}<br>Black JL: cc -D_XOPEN_SOURCE=500 -D_POSIX_THREAD_SEMANTICS=1 -o chk -I. chk-localtime_r.c 
libtz.a<br>Black JL: cc -D_XOPEN_SOURCE=500 -D_POSIX_THREAD_SEMANTICS=1 -o chk.sys chk-localtime_r.c<br>Black JL: date; ./chk; ./chk.sys<br>Thu Jan 10 22:35:52 PST 2008<br>1200033352 = Fri Jan 11 06:35:52 2008<br>1200033352 = Thu Jan 10 22:35:52 2008
<br>Black JL:<br><br>Using the Olson code  (tzcode2007k), the program defaults to UTC (GMT) because tzset() was never called explicitly.  Using the System code (Solaris 10), the same program defaults to my local time zone (US/Pacific).  So, at least there is a difference between the behaviour of the Solaris library and the Olson library in this respect.
<br><br>I guess the POSIX manual allows this - and the Olson implementation may well choose to implement localtime_r() without tzset() because tzset() is not re-entrant or thread-safe.<br><br>The POSIX standard says of localtime(), that:
<br><br><div style="margin-left: 40px;"><a href="javascript:open_code('CX')">CX</a>] <img src="http://www.opengroup.org/onlinepubs/009695399/images/opt-start.gif" alt="[Option Start]" border="0"> The
<i>localtime</i>() function need not be reentrant. A function that is not required to be reentrant is not required to be
thread-safe.<br></div></div></div><br>The same words are not said of tzset() -- which might conceivably be an omission, or it might imply that the function is supposed to be thread-safe and reentrant.<br clear="all"><br>
-- <br>Jonathan Leffler <<a href="mailto:jonathan.leffler@gmail.com">jonathan.leffler@gmail.com</a>>  #include <disclaimer.h><br>Guardian of DBD::Informix - v2007.0914 - <a href="http://dbi.perl.org">http://dbi.perl.org
</a><br>"Blessed are we who can laugh at ourselves, for we shall never cease to be amused."