summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Holzman <bah@ecnvantage.com>2006-07-19 03:11:09 -0400
committerH.Merijn Brand <h.m.brand@xs4all.nl>2006-11-06 09:43:30 +0000
commit8572b25d870f5a82a300ce816436b52f0f8afb0a (patch)
tree5b8af110b4d2e7e843e45f9f5b7e771b039847fe
parent296c5fee961dc8807527de4ac3a8363d8cea1a10 (diff)
downloadperl-8572b25d870f5a82a300ce816436b52f0f8afb0a.tar.gz
RE: [perl #26136] localtime(3) calls tzset(3), but localtime_r(3) may not.
From: "Benjamin Holzman" <bholzman@longitude.com> Message-ID: <010801c6ab24$09b9ed30$ce0515ac@office.iseoptions.com> p4raw-id: //depot/perl@29209
-rwxr-xr-xConfigure57
-rw-r--r--config_h.SH7
-rw-r--r--reentr.h4
-rwxr-xr-xt/op/time.t11
4 files changed, 74 insertions, 5 deletions
diff --git a/Configure b/Configure
index 1d428df559..f0865f97ce 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$$ <<EOF
@@ -549,6 +549,7 @@ d_ldbl_dig=''
d_libm_lib_version=''
d_link=''
d_localtime_r=''
+d_localtime_r_needs_tzset=''
localtime_r_proto=''
d_locconv=''
d_lockf=''
@@ -14514,6 +14515,59 @@ 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
+
: 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 7693c03cc4..48122845f1 100644
--- a/config_h.SH
+++ b/config_h.SH
@@ -2287,6 +2287,13 @@ sed <<!GROK!THIS! >$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 e0273bd4dd..ffa1090a77 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 fc73a7bf68..2f01c7ac91 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);