summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael G. Schwern <schwern@pobox.com>2008-09-29 11:05:17 -0400
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2009-01-03 18:38:42 +0100
commit948ea7a98bccf1ca837e75b5ea71b67365367ec4 (patch)
treee0fb84b317ba39c0f2a5c67b6acbb027075eeaac
parent750c447b413e71e62138b603e69a4ffe7ba754b2 (diff)
downloadperl-948ea7a98bccf1ca837e75b5ea71b67365367ec4.tar.gz
Update from y2038
Work around a system that doesn't have gm/localtime_r(). This replaces Perl's own gm/localtime() wrapper which couldn't be called outside a PP anyway because it needs my_perl.
-rw-r--r--localtime64.c44
-rw-r--r--localtime64.h19
-rw-r--r--reentr.c12
-rw-r--r--reentr.h43
-rw-r--r--reentr.pl7
5 files changed, 67 insertions, 58 deletions
diff --git a/localtime64.c b/localtime64.c
index 72bd68f0f2..176cc407d2 100644
--- a/localtime64.c
+++ b/localtime64.c
@@ -258,6 +258,40 @@ int _safe_year(Year year)
}
+/* Simulate localtime_r() to the best of our ability */
+struct tm * fake_localtime_r(const time_t *clock, struct tm *result) {
+ const struct tm *static_result = localtime(clock);
+
+ assert(result != NULL);
+
+ if( static_result == NULL ) {
+ memset(result, 0, sizeof(*result));
+ return NULL;
+ }
+ else {
+ memcpy(result, static_result, sizeof(*result));
+ return result;
+ }
+}
+
+
+/* Simulate gmtime_r() to the best of our ability */
+struct tm * fake_gmtime_r(const time_t *clock, struct tm *result) {
+ const struct tm *static_result = gmtime(clock);
+
+ assert(result != NULL);
+
+ if( static_result == NULL ) {
+ memset(result, 0, sizeof(*result));
+ return NULL;
+ }
+ else {
+ memcpy(result, static_result, sizeof(*result));
+ return result;
+ }
+}
+
+
struct tm *gmtime64_r (const Time64_T *in_time, struct tm *p)
{
int v_tm_sec, v_tm_min, v_tm_hour, v_tm_mon, v_tm_wday;
@@ -267,10 +301,12 @@ struct tm *gmtime64_r (const Time64_T *in_time, struct tm *p)
Time64_T time = *in_time;
Year year = 70;
+ assert(p != NULL);
+
/* Use the system gmtime() if time_t is small enough */
if( SHOULD_USE_SYSTEM_GMTIME(*in_time) ) {
time_t safe_time = *in_time;
- gmtime_r(&safe_time, p);
+ GMTIME_R(&safe_time, p);
assert(_check_tm(p));
return p;
}
@@ -379,10 +415,12 @@ struct tm *localtime64_r (const Time64_T *time, struct tm *local_tm)
Year orig_year;
int month_diff;
+ assert(local_tm != NULL);
+
/* Use the system localtime() if time_t is small enough */
if( SHOULD_USE_SYSTEM_LOCALTIME(*time) ) {
safe_time = *time;
- localtime_r(&safe_time, local_tm);
+ LOCALTIME_R(&safe_time, local_tm);
assert(_check_tm(local_tm));
return local_tm;
}
@@ -400,7 +438,7 @@ struct tm *localtime64_r (const Time64_T *time, struct tm *local_tm)
}
safe_time = TIMEGM(&gm_tm);
- if( localtime_r(&safe_time, local_tm) == NULL )
+ if( LOCALTIME_R(&safe_time, local_tm) == NULL )
return NULL;
local_tm->tm_year = orig_year;
diff --git a/localtime64.h b/localtime64.h
index 37719775ac..db8ddbf1ea 100644
--- a/localtime64.h
+++ b/localtime64.h
@@ -4,6 +4,12 @@
/* Configuration. */
/* Define as appropriate for your system */
/*
+ HAS_GMTIME_R
+ Defined if your system has gmtime_r()
+
+ HAS_LOCALTIME_R
+ Defined if your system has localtime_r()
+
HAS_TIMEGM
Defined if your system has timegm()
@@ -43,4 +49,17 @@ struct tm *gmtime64_r (const Time64_T *, struct tm *);
struct tm *localtime64_r (const Time64_T *, struct tm *);
Time64_T timegm64 (struct tm *);
+
+/* Not everyone has gm/localtime_r() */
+#ifdef HAS_LOCALTIME_R
+# define LOCALTIME_R(clock, result) localtime_r(clock, result)
+#else
+# define LOCALTIME_R(clock, result) fake_localtime_r(clock, result)
+#endif
+#ifdef HAS_GMTIME_R
+# define GMTIME_R(clock, result) gmtime_r(clock, result)
+#else
+# define GMTIME_R(clock, result) fake_gmtime_r(clock, result)
+#endif
+
#endif
diff --git a/reentr.c b/reentr.c
index 25fccf858b..8d9ab2a2c1 100644
--- a/reentr.c
+++ b/reentr.c
@@ -115,10 +115,6 @@ Perl_reentrant_size(pTHX) {
# endif
# endif
#endif /* HAS_GETSPNAM_R */
-#ifdef HAS_GMTIME_R
-#endif /* HAS_GMTIME_R */
-#ifdef HAS_LOCALTIME_R
-#endif /* HAS_LOCALTIME_R */
#ifdef HAS_RANDOM_R
#endif /* HAS_RANDOM_R */
#ifdef HAS_READDIR_R
@@ -205,10 +201,6 @@ Perl_reentrant_init(pTHX) {
# endif
Newx(PL_reentrant_buffer->_spent_buffer, PL_reentrant_buffer->_spent_size, char);
#endif /* HAS_GETSPNAM_R */
-#ifdef HAS_GMTIME_R
-#endif /* HAS_GMTIME_R */
-#ifdef HAS_LOCALTIME_R
-#endif /* HAS_LOCALTIME_R */
#ifdef HAS_RANDOM_R
#endif /* HAS_RANDOM_R */
#ifdef HAS_READDIR_R
@@ -280,10 +272,6 @@ Perl_reentrant_free(pTHX) {
#ifdef HAS_GETSPNAM_R
Safefree(PL_reentrant_buffer->_spent_buffer);
#endif /* HAS_GETSPNAM_R */
-#ifdef HAS_GMTIME_R
-#endif /* HAS_GMTIME_R */
-#ifdef HAS_LOCALTIME_R
-#endif /* HAS_LOCALTIME_R */
#ifdef HAS_RANDOM_R
#endif /* HAS_RANDOM_R */
#ifdef HAS_READDIR_R
diff --git a/reentr.h b/reentr.h
index 05b06f8d5c..e66abd907f 100644
--- a/reentr.h
+++ b/reentr.h
@@ -185,13 +185,12 @@
#define REENTRANT_PROTO_S_SBIE 69
#define REENTRANT_PROTO_S_SBW 70
#define REENTRANT_PROTO_S_TISBI 71
-#define REENTRANT_PROTO_S_TS 72
-#define REENTRANT_PROTO_S_TSBI 73
-#define REENTRANT_PROTO_S_TSBIE 74
-#define REENTRANT_PROTO_S_TWISBIE 75
-#define REENTRANT_PROTO_V_D 76
-#define REENTRANT_PROTO_V_H 77
-#define REENTRANT_PROTO_V_ID 78
+#define REENTRANT_PROTO_S_TSBI 72
+#define REENTRANT_PROTO_S_TSBIE 73
+#define REENTRANT_PROTO_S_TWISBIE 74
+#define REENTRANT_PROTO_V_D 75
+#define REENTRANT_PROTO_V_H 76
+#define REENTRANT_PROTO_V_ID 77
/* Defines for indicating which special features are supported. */
@@ -740,12 +739,6 @@ typedef struct {
FILE* _spent_fptr;
# endif
#endif /* HAS_GETSPNAM_R */
-#ifdef HAS_GMTIME_R
- struct tm _gmtime_struct;
-#endif /* HAS_GMTIME_R */
-#ifdef HAS_LOCALTIME_R
- struct tm _localtime_struct;
-#endif /* HAS_LOCALTIME_R */
#ifdef HAS_RANDOM_R
struct random_data _random_struct;
# if RANDOM_R_PROTO == REENTRANT_PROTO_I_iS
@@ -1330,30 +1323,6 @@ typedef struct {
# endif /* HAS_GETSPNAM */
#endif /* HAS_GETSPNAM_R */
-#ifdef HAS_GMTIME_R
-# if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1)
-# undef gmtime
-# if !defined(gmtime) && GMTIME_R_PROTO == REENTRANT_PROTO_S_TS
-# define gmtime(a) (gmtime_r(a, &PL_reentrant_buffer->_gmtime_struct) ? &PL_reentrant_buffer->_gmtime_struct : 0)
-# endif /* if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1) */
-# if !defined(gmtime) && GMTIME_R_PROTO == REENTRANT_PROTO_I_TS
-# define gmtime(a) (gmtime_r(a, &PL_reentrant_buffer->_gmtime_struct) == 0 ? &PL_reentrant_buffer->_gmtime_struct : 0)
-# endif /* if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1) */
-# endif /* HAS_GMTIME */
-#endif /* HAS_GMTIME_R */
-
-#ifdef HAS_LOCALTIME_R
-# 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) (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) (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 */
-
#ifdef HAS_RANDOM_R
# if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1)
# undef random
diff --git a/reentr.pl b/reentr.pl
index ea327a09fe..89795cd2e1 100644
--- a/reentr.pl
+++ b/reentr.pl
@@ -504,7 +504,7 @@ EOF
EOF
pushssif $endif;
}
- elsif ($func =~ /^(drand48|gmtime|localtime|random|srandom)$/) {
+ elsif ($func =~ /^(drand48|random|srandom)$/) {
pushssif $ifdef;
push @struct, <<EOF;
$seent{$func} _${func}_struct;
@@ -716,9 +716,6 @@ EOF
}
my $call = "${func}_r($v$w)";
- if ($func eq 'localtime') {
- $call = "L_R_TZSET $call";
- }
# Must make OpenBSD happy
my $memzero = '';
@@ -1124,8 +1121,6 @@ getservbyname CC|netdb |struct servent |I_CCSBWR|S_CCSBI|I_CCSD|D=struct servent
getservbyport IC|netdb |struct servent |I_ICSBWR|S_ICSBI|I_ICSD|D=struct servent_data*
getservent |netdb |struct servent |I_SBWR|I_SBI|S_SBI|I_SD|D=struct servent_data*
getspnam C |shadow |struct spwd |I_CSBWR|S_CSBI
-gmtime T |time |struct tm |S_TS|I_TS|T=const time_t*
-localtime T |time |struct tm |S_TS|I_TS|T=const time_t*
random |stdlib |struct random_data|I_iS|I_lS|I_St|i=int*|l=long*|t=int32_t*
readdir T |dirent |struct dirent |I_TSR|I_TS|T=DIR*
readdir64 T |dirent |struct dirent64|I_TSR|I_TS|T=DIR*