This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
RE: [perl #26136] localtime(3) calls tzset(3), but localtime_r(3) may not.
authorBenjamin Holzman <bah@ecnvantage.com>
Wed, 19 Jul 2006 07:11:09 +0000 (03:11 -0400)
committerH.Merijn Brand <h.m.brand@xs4all.nl>
Mon, 6 Nov 2006 09:27:56 +0000 (09:27 +0000)
Message-ID: <010801c6ab24$09b9ed30$ce0515ac@office.iseoptions.com>

p4raw-id: //depot/metaconfig@29207

U/threads/d_localtime_r.U

index 1101bed..24cae0e 100644 (file)
@@ -1,18 +1,24 @@
 ?RCS: $Id: d_localtime_r.U,v 0RCS:
 ?RCS: Copyright (c) 2002,2003 Jarkko Hietaniemi
+?RCS: Copyright (c) 2006,2006 H.Merijn Brand
 ?RCS:
 ?RCS: You may distribute under the terms of either the GNU General Public
 ?RCS: License or the Artistic License, as specified in the README file.
 ?RCS:
 ?RCS: Generated by the reentr.pl from the Perl 5.8 distribution.
 ?RCS:
-?MAKE:d_localtime_r localtime_r_proto: Inlibc Protochk Hasproto i_systypes usethreads i_time i_systime
+?MAKE:d_localtime_r d_localtime_r_needs_tzset localtime_r_proto: Inlibc cat \
+       Protochk Hasproto i_systypes usethreads i_time i_systime rm Compile
 ?MAKE: -pick add $@ %<
 ?S:d_localtime_r:
 ?S:    This variable conditionally defines the HAS_LOCALTIME_R symbol,
 ?S:    which indicates to the C program that the localtime_r()
 ?S:    routine is available.
 ?S:.
+?S:d_localtime_r_needs_tzset:
+?S:    This variable conditionally defines the LOCALTIME_R_NEEDS_TZSET
+?S:    symbol, which makes us call tzset before localtime_r()
+?S:.
 ?S:localtime_r_proto:
 ?S:    This variable encodes the prototype of localtime_r.
 ?S:    It is zero if d_localtime_r is undef, and one of the
 ?C:    This symbol, if defined, indicates that the localtime_r routine
 ?C:    is available to localtime re-entrantly.
 ?C:.
+?C:LOCALTIME_R_NEEDS_TZSET:
+?C:    Many libc's localtime_r implementations do not call tzset,
+?C:    making them differ from localtime(), and making timezone
+?C:    changes using $ENV{TZ} without explicitly calling tzset
+?C:    impossible. This symbol makes us call tzset before localtime_r
+?C:.
+?H:?%<:#$d_localtime_r_needs_tzset LOCALTIME_R_NEEDS_TZSET /**/
+?H:?%<:#ifdef LOCALTIME_R_NEEDS_TZSET
+?H:?%<:#define L_R_TZSET tzset(),
+?H:?%<:#else
+?H:?%<:#define L_R_TZSET
+?H:?%<:#endif
+?H:.
+?C:L_R_TZSET:
+?C:    If localtime_r() needs tzset, it is defined in this define
+?C:.
 ?C:LOCALTIME_R_PROTO:
 ?C:    This symbol encodes the prototype of localtime_r.
 ?C:    It is zero if d_localtime_r is undef, and one of the
@@ -33,7 +55,9 @@
 ?H:#define LOCALTIME_R_PROTO $localtime_r_proto           /**/
 ?H:.
 ?T:try hdrs d_localtime_r_proto
+?F:!try
 ?LINT:set d_localtime_r
+?LINT:set d_localtime_r_needs_tzset
 ?LINT:set localtime_r_proto
 : see if localtime_r exists
 set localtime_r d_localtime_r
@@ -80,3 +104,56 @@ case "$d_localtime_r" in
        ;;
 esac
 
+: see if localtime_r calls tzset
+case "$localtime_r_proto" in
+REENTRANT_PROTO*)
+       $cat >try.c <<EOCP
+/*  Does our libc's localtime_r call tzset ?
+ *  return 0 if so, 1 otherwise.
+ */
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <malloc.h>
+int main()
+{
+    time_t t = time(0L);
+    char w_tz[]="TZ" "=GMT+5",
+        e_tz[]="TZ" "=GMT-5",
+       *tz_e = (char*)malloc(16),
+       *tz_w = (char*)malloc(16);
+    struct tm tm_e, tm_w;
+    memset(&tm_e,'\0',sizeof(struct tm));
+    memset(&tm_w,'\0',sizeof(struct tm));
+    strcpy(tz_e,e_tz);
+    strcpy(tz_w,w_tz);
+
+    putenv(tz_e);
+    localtime_r(&t, &tm_e);
+
+    putenv(tz_w);
+    localtime_r(&t, &tm_w);
+
+    if( memcmp(&tm_e, &tm_w, sizeof(struct tm)) == 0 )
+       return 1;
+    return 0;
+}
+EOCP
+       set try
+       if eval $compile; then
+           if ./try; then
+               d_localtime_r_needs_tzset=undef;
+           else
+               d_localtime_r_needs_tzset=define;
+           fi;
+       else
+           d_localtime_r_needs_tzset=undef;
+       fi;
+     ;;
+  *)
+     d_localtime_r_needs_tzset=undef;
+     ;;
+esac
+$rm -f try try.* core
+