From: Benjamin Holzman Date: Wed, 19 Jul 2006 07:11:09 +0000 (-0400) Subject: RE: [perl #26136] localtime(3) calls tzset(3), but localtime_r(3) may not. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8572b25d870f5a82a300ce816436b52f0f8afb0a;p=p5sagit%2Fp5-mst-13.2.git RE: [perl #26136] localtime(3) calls tzset(3), but localtime_r(3) may not. From: "Benjamin Holzman" Message-ID: <010801c6ab24$09b9ed30$ce0515ac@office.iseoptions.com> p4raw-id: //depot/perl@29209 --- diff --git a/Configure b/Configure index 1d428df..f0865f9 100755 --- a/Configure +++ b/Configure @@ -26,7 +26,7 @@ # $Id: Head.U,v 3.0.1.9 1997/02/28 15:02:09 ram Exp $ # -# Generated on Mon Oct 23 17:35:45 CEST 2006 [metaconfig 3.0 PL70] +# Generated on Mon Nov 6 10:30:43 CET 2006 [metaconfig 3.0 PL70] # (with additional metaconfig patches by perlbug@perl.org) cat >c1$$ <try.c < +#include +#include +#include +#include +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 + : see if localeconv exists set localeconv d_locconv eval $inlibc @@ -21505,6 +21559,7 @@ d_ldbl_dig='$d_ldbl_dig' d_libm_lib_version='$d_libm_lib_version' d_link='$d_link' d_localtime_r='$d_localtime_r' +d_localtime_r_needs_tzset='$d_localtime_r_needs_tzset' d_locconv='$d_locconv' d_lockf='$d_lockf' d_longdbl='$d_longdbl' diff --git a/config_h.SH b/config_h.SH index 7693c03..4812284 100644 --- a/config_h.SH +++ b/config_h.SH @@ -2287,6 +2287,13 @@ sed <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un * This symbol, if defined, indicates that the localtime_r routine * is available to localtime re-entrantly. */ +#$d_localtime_r_needs_tzset LOCALTIME_R_NEEDS_TZSET /**/ +#ifdef LOCALTIME_R_NEEDS_TZSET +#define L_R_TZSET tzset(), +#else +#define L_R_TZSET +#endif + /* LOCALTIME_R_PROTO: * This symbol encodes the prototype of localtime_r. * It is zero if d_localtime_r is undef, and one of the diff --git a/reentr.h b/reentr.h index e0273bd..ffa1090 100644 --- a/reentr.h +++ b/reentr.h @@ -1346,10 +1346,10 @@ typedef struct { # if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1) # undef localtime # if !defined(localtime) && LOCALTIME_R_PROTO == REENTRANT_PROTO_S_TS -# define localtime(a) (localtime_r(a, &PL_reentrant_buffer->_localtime_struct) ? &PL_reentrant_buffer->_localtime_struct : 0) +# define localtime(a) (L_R_TZSET localtime_r(a, &PL_reentrant_buffer->_localtime_struct) ? &PL_reentrant_buffer->_localtime_struct : 0) # endif /* if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1) */ # if !defined(localtime) && LOCALTIME_R_PROTO == REENTRANT_PROTO_I_TS -# define localtime(a) (localtime_r(a, &PL_reentrant_buffer->_localtime_struct) == 0 ? &PL_reentrant_buffer->_localtime_struct : 0) +# define localtime(a) (L_R_TZSET localtime_r(a, &PL_reentrant_buffer->_localtime_struct) == 0 ? &PL_reentrant_buffer->_localtime_struct : 0) # endif /* if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1) */ # endif /* HAS_LOCALTIME */ #endif /* HAS_LOCALTIME_R */ diff --git a/t/op/time.t b/t/op/time.t index fc73a7b..2f01c7a 100755 --- a/t/op/time.t +++ b/t/op/time.t @@ -1,10 +1,10 @@ #!./perl if ( $does_gmtime = gmtime(time) ) { - print "1..7\n" + print "1..8\n" } else { - print "1..4\n" + print "1..5\n" } @@ -52,6 +52,13 @@ ok(localtime() =~ /^(Sun|Mon|Tue|Wed|Thu|Fri|Sat)[ ] 'localtime(), scalar context' ); +# check that localtime respects changes to $ENV{TZ} +$ENV{TZ} = "GMT-5"; +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($beg); +$ENV{TZ} = "GMT+5"; +($sec,$min,$hour2,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($beg); +ok($hour != $hour2, 'changes to $ENV{TZ} respected'); + exit 0 unless $does_gmtime; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($beg);