diff options
author | Michael G. Schwern <schwern@pobox.com> | 2008-09-29 11:05:17 -0400 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2009-01-03 18:38:42 +0100 |
commit | 948ea7a98bccf1ca837e75b5ea71b67365367ec4 (patch) | |
tree | e0fb84b317ba39c0f2a5c67b6acbb027075eeaac | |
parent | 750c447b413e71e62138b603e69a4ffe7ba754b2 (diff) | |
download | perl-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.c | 44 | ||||
-rw-r--r-- | localtime64.h | 19 | ||||
-rw-r--r-- | reentr.c | 12 | ||||
-rw-r--r-- | reentr.h | 43 | ||||
-rw-r--r-- | reentr.pl | 7 |
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 @@ -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 @@ -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 @@ -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* |