diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2009-10-12 18:11:22 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2009-10-12 18:11:22 +0000 |
commit | 3340aa359b7f1a5408b241506d923a8819934dce (patch) | |
tree | 7f684f171494914b3fc7979f440e6d6033ce01f1 /gnu/usr.bin/perl/Porting/timecheck.c | |
parent | 64682a72ac119a8b4edb1b8bd9f7419964f9c778 (diff) |
import perl 5.10.1
Diffstat (limited to 'gnu/usr.bin/perl/Porting/timecheck.c')
-rw-r--r-- | gnu/usr.bin/perl/Porting/timecheck.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/gnu/usr.bin/perl/Porting/timecheck.c b/gnu/usr.bin/perl/Porting/timecheck.c new file mode 100644 index 00000000000..cf0303aaf49 --- /dev/null +++ b/gnu/usr.bin/perl/Porting/timecheck.c @@ -0,0 +1,152 @@ +/* A helper tool for perl's 2038 support. + * See Porting/README.y2038 for details + */ + +#include <sys/types.h> +#include <stdio.h> +#include <time.h> +#include <errno.h> +#include <values.h> + +int opt_v = 0; +int i; +struct tm *tmp; +time_t pt, pt_max, pt_min; + +static char hexbuf[80]; +char *hex (time_t t) +{ + if ((long long)t < 0) + sprintf (hexbuf, " -0x%016lx", -t); + else + sprintf (hexbuf, " 0x%016lx", t); + return (hexbuf); + } /* hex */ + +void gm_check (time_t t, int min_year, int max_year) +{ + tmp = gmtime (&t); + if ( tmp == NULL || + /* Check tm_year overflow */ + tmp->tm_year < min_year || tmp->tm_year > max_year) { + if (opt_v) + fprintf (stderr, "gmtime (%ld) failed with errno %d\n", t, errno); + } + else { + if (opt_v) + fprintf (stderr, "%3d:%s: %12ld-%02d-%02d %02d:%02d:%02d\n", + i, hex (t), + tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + pt = t; + } + } /* gm_check */ + +int check_gm_max () +{ + tmp = NULL; + pt = 0; + if (tmp == NULL || tmp->tm_year < 0) { + for (i = 63; i >= 0; i--) { + time_t x = pt | ((time_t)1 << i); + if (x < 0 || x < pt) continue; + gm_check (x, 69, 0x7fffffff); + } + } + pt_max = pt; + return (0); + } /* check_gm_max */ + +int check_gm_min () +{ + tmp = NULL; + pt = 0; + if (tmp == NULL) { + for (i = 36; i >= 0; i--) { + time_t x = pt - ((time_t)1 << i); + if (x > 0) continue; + gm_check (x, -1900, 70); + } + } + pt_min = pt; + return (0); + } /* check_gm_min */ + +void lt_check (time_t t, int min_year, int max_year) +{ + if (sizeof (time_t) > 4 && t > 0x7ffffffffffff000LL) + tmp = NULL; + else + tmp = localtime (&t); + if ( tmp == NULL || + /* Check tm_year overflow */ + tmp->tm_year < min_year || tmp->tm_year > max_year) { + if (opt_v) + fprintf (stderr, "localtime (%ld) failed with errno %d\n", t, errno); + } + else { + if (opt_v) + fprintf (stderr, "%3d:%s: %12ld-%02d-%02d %02d:%02d:%02d\n", + i, hex (t), + tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + pt = t; + } + } /* lt_check */ + +int check_lt_max () +{ + tmp = NULL; + pt = 0; + if (tmp == NULL || tmp->tm_year < 0) { + for (i = 63; i >= 0; i--) { + time_t x = pt | ((time_t)1 << i); + if (x < 0 || x < pt) continue; + lt_check (x, 69, 0x7fffffff); + } + } + pt_max = pt; + return (0); + } /* check_lt_max */ + +int check_lt_min () +{ + tmp = NULL; + pt = 0; + if (tmp == NULL) { + for (i = 36; i >= 0; i--) { + time_t x = pt - ((time_t)1 << i); + if (x > 0) continue; + lt_check (x, -1900, 70); + } + } + pt_min = pt; + return (0); + } /* check_lt_min */ + +int main (int argc, char *argv[]) +{ + time_t gm_max, gm_min, lt_max, lt_min; + if (argc > 1 && strcmp (argv[1], "-v") == 0) opt_v++; + + check_gm_max (); gm_max = pt_max; + check_gm_min (); gm_min = pt_min; + check_lt_max (); lt_max = pt_max; + check_lt_min (); lt_min = pt_min; + + opt_v++; + printf ("======================\n"); + printf ("Sizeof time_t = %ld\n", (i = sizeof (time_t))); + printf ("gmtime () boundaries:\n"); + gm_check (gm_max, 69, 0x7fffffff); + gm_check (gm_min, -1900, 70); + printf ("localtime () boundaries:\n"); + lt_check (lt_max, 69, 0x7fffffff); + lt_check (lt_min, -1900, 70); + printf ("Configure variables:\n"); + printf ("sGMTIME_max='%ld'\n", gm_max); + printf ("sGMTIME_min='%ld'\n", gm_min); + printf ("sLOCALTIME_max='%ld'\n", lt_max); + printf ("sLOCALTIME_min='%ld'\n", lt_min); + return (0); + } /* main */ |