This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge pull request #71 from richardleach/patch-1
[metaconfig.git] / U / threads / d_localtime_r.U
index 7e6f577..53fa397 100644 (file)
@@ -1,34 +1,62 @@
 ?RCS: $Id: d_localtime_r.U,v 0RCS:
-?RCS: Copyright (c) 2002 Jarkko Hietaniemi
+?RCS: Copyright (c) 2002,2003 Jarkko Hietaniemi
+?RCS: Copyright (c) 2006,2007 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 i_systime i_time usethreads i_pthread
+?MAKE:d_localtime_r d_localtime_r_needs_tzset localtime_r_proto: Inlibc \
+       cat run Protochk Hasproto i_systypes usethreads i_time i_systime \
+       rm_try Compile extern_C i_stdlib i_unistd i_malloc
 ?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
+?S:    REENTRANT_PROTO_T_ABC macros of reentr.h if d_localtime_r
+?S:    is defined.
 ?S:.
 ?C:HAS_LOCALTIME_R:
 ?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
+?C:    REENTRANT_PROTO_T_ABC macros of reentr.h if d_localtime_r
+?C:    is defined.
 ?C:.
-?H:#$d_localtime_r HAS_LOCALTIME_R        /**/
-?H:#define LOCALTIME_R_PROTO $localtime_r_proto           /**/
+?H:#$d_localtime_r HAS_LOCALTIME_R     /**/
+?H:#define LOCALTIME_R_PROTO $localtime_r_proto        /**/
 ?H:.
 ?T:try hdrs d_localtime_r_proto
-?LINT:set d_localtime_r
-?LINT:set localtime_r_proto
+?F:!try
 : see if localtime_r exists
 set localtime_r d_localtime_r
 eval $inlibc
@@ -45,15 +73,15 @@ case "$d_localtime_r" in
        define)
        case "$localtime_r_proto" in
        ''|0) try='struct tm* localtime_r(const time_t*, struct tm*);'
-       ./protochk "extern $try" $hdrs && localtime_r_proto=S_TS ;;
+       ./protochk "$extern_C $try" $hdrs && localtime_r_proto=S_TS ;;
        esac
        case "$localtime_r_proto" in
        ''|0) try='int localtime_r(const time_t*, struct tm*);'
-       ./protochk "extern $try" $hdrs && localtime_r_proto=I_TS ;;
+       ./protochk "$extern_C $try" $hdrs && localtime_r_proto=I_TS ;;
        esac
        case "$localtime_r_proto" in
        ''|0)   d_localtime_r=undef
-               localtime_r_proto=0
+               localtime_r_proto=0
                echo "Disabling localtime_r, cannot determine prototype." >&4 ;;
        * )     case "$localtime_r_proto" in
                REENTRANT_PROTO*) ;;
@@ -74,3 +102,75 @@ 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.
+ */
+#$i_systypes   I_SYS_TYPES
+#$i_unistd     I_UNISTD
+#$i_time       I_TIME
+#$i_stdlib     I_STDLIB
+#$i_malloc     I_MALLOC
+#ifdef I_SYS_TYPES
+#  include <sys/types.h>
+#endif
+#ifdef I_UNISTD
+#  include <unistd.h>
+#endif
+#ifdef I_TIME
+#  include <time.h>
+#endif
+#ifdef I_STDLIB
+#include <stdlib.h>
+#endif
+#include <string.h>
+#ifdef I_MALLOC
+#  include <malloc.h>
+#endif
+int main()
+{
+    int result = 0;
+    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 )
+       result = 1;
+
+    free(tz_e);free(tz_w);
+    return result;
+}
+EOCP
+       set try
+       if eval $compile; then
+           if $run ./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_try
+